diff --git a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoLogicalView.java b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoLogicalView.java index f5b95beeafb..76621e88a09 100644 --- a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoLogicalView.java +++ b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoLogicalView.java @@ -5,8 +5,6 @@ import java.util.List; import javax.swing.Action; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import org.enso.tools.enso4igv.EnsoSbtClassPathProvider.EnsoSources; -import org.enso.tools.enso4igv.EnsoSbtClassPathProvider.OtherEnsoSources; import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; @@ -21,11 +19,11 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.ChildFactory; import org.openide.nodes.Children; import org.openide.nodes.Node; -import org.openide.util.NbCollections; import org.openide.util.lookup.Lookups; @ActionReferences({ - @ActionReference(position = 3100, id = @ActionID(category = "Project", id = "org-netbeans-modules-project-ui-CloseProject"), path = "Projects/ensosbtprj/Actions", separatorBefore = 3000), + @ActionReference(position = 3100, id = @ActionID(category = "Project", id = "org.netbeans,modules.project.ui.CloseProject"), path = "Projects/ensosbtprj/Actions", separatorBefore = 3000), + @ActionReference(position = 3200, id = @ActionID(category = "Project", id = "org.netbeans.modules.project.ui.actions.OpenSubprojects"), path = "Projects/ensosbtprj/Actions"), }) final class EnsoLogicalView implements LogicalViewProvider { private final EnsoSbtProject p; diff --git a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoProjectFactory.java b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoProjectFactory.java new file mode 100644 index 00000000000..1d2cf504aed --- /dev/null +++ b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoProjectFactory.java @@ -0,0 +1,63 @@ +package org.enso.tools.enso4igv; + +import java.io.IOException; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.spi.project.ProjectFactory; +import org.netbeans.spi.project.ProjectFactory2; +import org.netbeans.spi.project.ProjectState; +import org.openide.filesystems.FileObject; +import org.openide.util.ImageUtilities; +import org.openide.util.lookup.ServiceProvider; + +@ServiceProvider(service = ProjectFactory.class, position = 135) +public final class EnsoProjectFactory implements ProjectFactory2 { + static int isProjectCheck(FileObject fo) { + if (!fo.isFolder()) { + return 0; + } + if (fo.getFileObject(".enso-sources") != null) { + return 1; + } else if ( + fo.getFileObject("README.md") != null && + fo.getFileObject("build.sbt") != null && + fo.getFileObject("engine/runtime") != null + ) { + return 2; + } else { + return 0; + } + } + + private static Project createProjectOrNull(FileObject fo, ProjectState ps) { + return switch (isProjectCheck(fo)) { + case 1 -> new EnsoSbtProject(fo, ps); + case 2 -> new EnsoRootProject(fo, ps); + default -> null; + }; + } + + @Override + public boolean isProject(FileObject fo) { + return isProjectCheck(fo) != 0; + } + + @Override + public Project loadProject(FileObject fo, ProjectState ps) throws IOException { + return createProjectOrNull(fo, ps); + } + + + public void saveProject(Project prjct) throws IOException, ClassCastException { + } + + @Override + public ProjectManager.Result isProject2(FileObject fo) { + if (isProject(fo)) { + java.awt.Image img = ImageUtilities.loadImage("org/enso/tools/enso4igv/enso.svg"); + return new ProjectManager.Result(ImageUtilities.image2Icon(img)); + } + return null; + } + +} diff --git a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoRootProject.java b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoRootProject.java new file mode 100644 index 00000000000..bd8ab7e98a4 --- /dev/null +++ b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoRootProject.java @@ -0,0 +1,179 @@ +package org.enso.tools.enso4igv; + +import java.io.IOException; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import javax.swing.Action; +import javax.swing.event.ChangeListener; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectManager; +import org.netbeans.api.project.ProjectUtils; +import org.netbeans.spi.project.ProjectContainerProvider; +import org.netbeans.spi.project.ProjectState; +import org.netbeans.spi.project.SubprojectProvider; +import org.netbeans.spi.project.ui.LogicalViewProvider; +import org.netbeans.spi.project.ui.support.CommonProjectActions; +import org.openide.filesystems.FileObject; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectNotFoundException; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.ChildFactory; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.util.Lookup; +import org.openide.util.lookup.Lookups; + +final class EnsoRootProject implements Project { + + private final FileObject prj; + private final ProjectState ps; + private final Lookup lkp; + + EnsoRootProject(FileObject fo, ProjectState ps) { + this.prj = fo; + this.ps = ps; + this.lkp = Lookups.fixed( + this, + new LogicalView(), + new Subprojects() + ); + } + + @Override + public FileObject getProjectDirectory() { + return prj; + } + + @Override + public Lookup getLookup() { + return lkp; + } + + @Override + public String toString() { + return "EnsoRootProject{prj=" + prj + "}"; + } + + private final class LogicalView implements LogicalViewProvider { + + LogicalView() { + } + + @Override + public Node createLogicalView() { + return new MainNode(EnsoRootProject.this); + } + + @Override + public Node findPath(Node node, Object o) { + return org.openide.nodes.NodeOp.findChild(node, (String) o); + } + } + + private final class Subprojects implements ProjectContainerProvider, SubprojectProvider, Comparator { + @Override + public Set getSubprojects() { + var found = new TreeSet(this); + searchForProjects(getProjectDirectory(), found, 3); + System.err.println("subprojects: " + found); + return found; + } + + private static void searchForProjects(FileObject fo, Collection found, int depth) { + if (fo.isFolder() && depth > 0) { + if (EnsoProjectFactory.isProjectCheck(fo) == 1) { + try { + var p = ProjectManager.getDefault().findProject(fo); + if (p != null) { + found.add(p); + } + } catch (IllegalArgumentException | IOException ex) { + } + } else { + for (var ch : fo.getChildren()) { + searchForProjects(ch, found, depth - 1); + } + } + } + } + + @Override + public void addChangeListener(ChangeListener cl) { + } + + @Override + public void removeChangeListener(ChangeListener cl) { + } + + @Override + public int compare(Project o1, Project o2) { + var p1 = o1.getProjectDirectory().getPath(); + var p2 = o2.getProjectDirectory().getPath(); + return p1.compareTo(p2); + } + + @Override + public Result getContainedProjects() { + var result = new Result(getSubprojects(), false); + System.err.println("get contained fop: " + result.getProjects()); + return result; + } + + private final class Factory extends ChildFactory { + @Override + protected boolean createKeys(List list) { + list.add(getProjectDirectory().getFileObject("README.md")); + list.add(getProjectDirectory().getFileObject("build.sbt")); + for (var p : getSubprojects()) { + list.add(p.getProjectDirectory()); + } + return true; + } + + protected Node createNodeForKey(FileObject key) { + try { + try { + var p = ProjectManager.getDefault().findProject(key); + if (p != null && p.getLookup().lookup(LogicalViewProvider.class) instanceof LogicalViewProvider lvp) { + return lvp.createLogicalView(); + } + } catch (IOException | IllegalArgumentException ex) { + } + return DataObject.find(key).getNodeDelegate(); + } catch (DataObjectNotFoundException ex) { + return null; + } + } + } + + } + + private static final class MainNode extends AbstractNode { + + private final EnsoRootProject project; + + private MainNode(EnsoRootProject p) { + super(Children.create(p.getLookup().lookup(Subprojects.class).new Factory(), true), Lookups.fixed(p)); + this.project = p; + setDisplayName(); + setIconBaseWithExtension("org/enso/tools/enso4igv/enso.svg"); + } + + private void setDisplayName() { + setDisplayName(ProjectUtils.getInformation(project).getDisplayName()); + } + + @Override + public String getHtmlDisplayName() { + return null; + } + + @Override + public Action[] getActions(boolean context) { + return CommonProjectActions.forType("ensosbtprj"); // NOI18N + } + } +} diff --git a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoSbtProject.java b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoSbtProject.java index 9883a50b122..e144587b0e3 100644 --- a/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoSbtProject.java +++ b/tools/enso4igv/src/main/java/org/enso/tools/enso4igv/EnsoSbtProject.java @@ -1,23 +1,17 @@ package org.enso.tools.enso4igv; -import java.io.IOException; import org.netbeans.api.project.Project; -import org.netbeans.api.project.ProjectManager; -import org.netbeans.spi.project.ProjectFactory; -import org.netbeans.spi.project.ProjectFactory2; import org.netbeans.spi.project.ProjectState; import org.openide.filesystems.FileObject; -import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.lookup.Lookups; -import org.openide.util.lookup.ServiceProvider; public class EnsoSbtProject implements Project { private final FileObject prj; private final ProjectState ps; private final Lookup lkp; - private EnsoSbtProject(FileObject fo, ProjectState ps) { + EnsoSbtProject(FileObject fo, ProjectState ps) { this.prj = fo; this.ps = ps; this.lkp = Lookups.fixed( @@ -39,31 +33,4 @@ public class EnsoSbtProject implements Project { public String toString() { return "EnsoSbtProject{prj=" + prj + "}"; } - - @ServiceProvider(service = ProjectFactory.class) - public static final class Factory implements ProjectFactory2 { - public boolean isProject(FileObject fo) { - return fo.getFileObject(".enso-sources") != null; - } - - public Project loadProject(FileObject fo, ProjectState ps) throws IOException { - if (isProject(fo)) { - return new EnsoSbtProject(fo, ps); - } else { - return null; - } - } - - public void saveProject(Project prjct) throws IOException, ClassCastException { - } - - @Override - public ProjectManager.Result isProject2(FileObject fo) { - if (isProject(fo)) { - var img = ImageUtilities.loadImage("org/enso/tools/enso4igv/enso.svg"); - return new ProjectManager.Result(ImageUtilities.image2Icon(img)); - } - return null; - } - } }