]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Dependency -view for showing backward and forward dependencies of variables.
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 19 May 2010 13:33:32 +0000 (13:33 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 19 May 2010 13:33:32 +0000 (13:33 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@15778 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.sysdyn.ui/META-INF/MANIFEST.MF
org.simantics.sysdyn.ui/plugin.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java

index 1f8985dd5734b0c0ad9f68c663f3db39f402945b..df09a233e0003057e1a85775ca08bb7e4f8956a4 100644 (file)
@@ -24,6 +24,8 @@ Require-Bundle: org.simantics.h2d;bundle-version="1.0.0",
  org.simantics.browsing.ui.graph;bundle-version="0.9.0",
  org.simantics.browsing.ui.swt;bundle-version="0.9.0",
  org.simantics.modeling.ui;bundle-version="1.0.0",
- org.eclipse.ui.cheatsheets
+ org.eclipse.ui.cheatsheets,
+ org.simantics.graphviz.ui;bundle-version="1.0.0",
+ org.simantics.graphviz;bundle-version="1.0.0"
 Bundle-Activator: org.simantics.sysdyn.ui.Activator
 Bundle-ActivationPolicy: lazy
index 5fd3e91f1e1ffd0d439c043212e437a7106ddbdc..bdc19f6952400546333e1535cfb29032e9029c76 100644 (file)
             name="Configuration View"\r
             restorable="true">\r
       </view>\r
+      <view\r
+            allowMultiple="false"\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.dependencies.DependencyView"\r
+            id="org.simantics.sysdyn.ui.dependencies.view"\r
+            name="Dependencies"\r
+            restorable="true">\r
+      </view>\r
    </extension>\r
    <extension\r
          point="org.eclipse.ui.perspectives">\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java
new file mode 100644 (file)
index 0000000..2d6f5e0
--- /dev/null
@@ -0,0 +1,102 @@
+package org.simantics.sysdyn.ui.dependencies;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graphviz.Edge;\r
+import org.simantics.graphviz.Graph;\r
+import org.simantics.graphviz.IGraph;\r
+import org.simantics.graphviz.Node;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class CreateDependencyGraph implements Read<Graph> {\r
+\r
+    Resource root;\r
+    HashMap<Resource, Node> nodes;\r
+    boolean isInverted;\r
+    int levels;\r
+\r
+    public CreateDependencyGraph(Resource root, int levels, boolean isInverted) {\r
+        this.root = root;\r
+        this.nodes = new HashMap<Resource, Node>();\r
+        this.isInverted = isInverted;    \r
+        this.levels = levels;\r
+    }\r
+\r
+    @Override\r
+    public Graph perform(ReadGraph g) throws DatabaseException {\r
+        Graph graph = new Graph();\r
+        graph.setRankdir("LR");\r
+        if (g.isInstanceOf(root, SysdynResource.getInstance(g).IndependentVariable)) {\r
+            Collection<Resource> resources = new ArrayList<Resource>(); \r
+            resources.add(root);\r
+            for (int i = 0; i < levels && !resources.isEmpty(); i++) {\r
+                Collection<Resource> newResources = new ArrayList<Resource>();\r
+                for(Resource r : resources) {\r
+                    newResources.addAll(getDependencies(g, graph, r));\r
+                }\r
+                resources = new ArrayList<Resource>(newResources);\r
+            }\r
+        }\r
+        return graph;\r
+    }\r
+    \r
+    private Collection<Resource> getDependencies(ReadGraph g, IGraph graph, Resource r) throws DatabaseException{\r
+        SysdynResource sr = SysdynResource.getInstance(g);\r
+        Resource headRelation = sr.IsHeadOf;\r
+        Resource tailRelation = sr.HasTail;   \r
+        if(isInverted) {\r
+            headRelation = sr.IsTailOf;\r
+            tailRelation = sr.HasHead;\r
+        }\r
+        \r
+        Node n;\r
+        if (!nodes.containsKey(r)) {\r
+            n = new Node(graph, getName(g, r));\r
+            setShape(g, r, n);\r
+            n.set("style", "filled");\r
+            n.setFillColor("#d3d3d3");\r
+            nodes.put(r, n);\r
+        }\r
+        \r
+        Collection<Resource> dependencies = g.getObjects(r, headRelation);\r
+        Collection<Resource> dependants = new ArrayList<Resource>();\r
+        for(Resource d : dependencies) {\r
+            Resource dependant = g.getSingleObject(d, tailRelation);\r
+            if(!g.isInstanceOf(dependant, sr.IndependentVariable)) {\r
+                break;\r
+            }\r
+            if( !nodes.containsKey(dependant)) {\r
+                n= new Node(graph, getName(g, dependant));\r
+                setShape(g, dependant, n);\r
+                nodes.put(dependant, n);\r
+                dependants.add(dependant);\r
+            } else {\r
+                n = nodes.get(dependant);\r
+            }\r
+            if(isInverted) \r
+                new Edge(graph, nodes.get(r), n);\r
+            else\r
+                new Edge(graph, n, nodes.get(r));\r
+        }\r
+        return dependants;\r
+    }\r
+\r
+    private void setShape(ReadGraph g, Resource r, Node n) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(g);\r
+        if(g.isInstanceOf(r, sr.Stock))\r
+            n.setShape("rectangle");\r
+        else\r
+            n.setShape("ellipse");\r
+    }\r
+\r
+    private String getName(ReadGraph g, Resource r) throws DatabaseException {\r
+        return (String)g.getRelatedValue(r, g.getBuiltins().HasName);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java
new file mode 100644 (file)
index 0000000..7383d03
--- /dev/null
@@ -0,0 +1,177 @@
+package org.simantics.sysdyn.ui.dependencies;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.RowLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.graphviz.Graph;\r
+import org.simantics.graphviz.ui.GraphvizComponent;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class DependencyView extends ViewPart {\r
+\r
+    private GraphvizComponent component;\r
+    private boolean disposed, isInverted = false;\r
+    private Button bButton, fButton;\r
+    private Resource currentSelection;\r
+    private int levels = 3;\r
+    private ISelectionListener selectionListener;\r
+\r
+    static int MAXLEVELS = 4;\r
+    static int MINLEVELS = 1;\r
+\r
+    @Override\r
+    public void createPartControl(Composite parent) {\r
+        disposed = false;\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(parent);\r
+\r
+        component = new GraphvizComponent(parent, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
+\r
+        Composite composite = new Composite(parent, SWT.NULL);\r
+        RowLayout layout = new RowLayout();\r
+        layout.center = true;\r
+        composite.setLayout(layout);\r
+\r
+        Label label = new Label(composite, SWT.NULL);\r
+        label.setText("Direction: ");\r
+\r
+        bButton = new Button(composite, SWT.RADIO);\r
+        bButton.setText("Backward");\r
+        bButton.setSelection(true);\r
+        bButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent event) {\r
+                if(bButton.getSelection())\r
+                    isInverted = false;\r
+                else \r
+                    isInverted = true;\r
+                if(currentSelection != null) {\r
+                    readGraph(currentSelection);\r
+                }\r
+            }\r
+        });\r
+\r
+        fButton = new Button(composite, SWT.RADIO);\r
+        fButton.setText("Forward");\r
+\r
+        label = new Label(composite, SWT.NULL);\r
+        label.setText("Steps: ");\r
+\r
+        Spinner spinner = new Spinner(composite, SWT.BORDER);\r
+        spinner.setMaximum(MAXLEVELS);\r
+        spinner.setMinimum(MINLEVELS);\r
+        spinner.setTextLimit(1);\r
+        spinner.setSelection(levels);\r
+\r
+        spinner.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Spinner s = (Spinner)e.widget;\r
+                int lvls = Integer.parseInt(s.getText());\r
+                if(lvls > MAXLEVELS)\r
+                    levels = MAXLEVELS;\r
+                else if (lvls < MINLEVELS)\r
+                    levels = MINLEVELS;\r
+                levels = lvls;\r
+                if(currentSelection != null) {\r
+                    readGraph(currentSelection);\r
+                }\r
+                    \r
+            }\r
+        });\r
+\r
+        drawSelection(getSite().getWorkbenchWindow().getSelectionService().getSelection());\r
+\r
+        selectionListener = new ISelectionListener() {\r
+\r
+            @Override\r
+            public void selectionChanged(IWorkbenchPart part, ISelection selection) {\r
+                drawSelection(selection);\r
+            }\r
+        };    \r
+        getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(selectionListener);\r
+    }\r
+\r
+    private void drawSelection(ISelection selection) {\r
+        if(selection == null || selection.isEmpty())\r
+            return;\r
+        if(selection instanceof IStructuredSelection) {                    \r
+            Object[] els = ((IStructuredSelection) selection).toArray();\r
+            if(els.length == 1) {\r
+                if(els[0] instanceof Resource && !els[0].equals(currentSelection)) {\r
+                    currentSelection = (Resource)els[0];\r
+                    readGraph(currentSelection);\r
+                }\r
+            }\r
+        }           \r
+    }\r
+\r
+    private void readGraph(Resource resource) {\r
+        SimanticsUI.getSession().asyncRequest(new CreateDependencyGraph(\r
+                resource, levels, isInverted),\r
+                new Listener<Graph>() {\r
+\r
+            @Override\r
+            public void exception(Throwable e) {\r
+                e.printStackTrace();\r
+            }\r
+\r
+            @Override\r
+            public void execute(final Graph graph) {\r
+                Job job = new Job("Layout composite graph") {\r
+\r
+                    @Override\r
+                    protected IStatus run(IProgressMonitor monitor) {\r
+                        if(!isDisposed()) {\r
+                            component.setGraph(graph, "dot");\r
+                            component.fit();                            \r
+                        }\r
+                        return Status.OK_STATUS;\r
+                    }\r
+                };\r
+                job.schedule();\r
+            }\r
+\r
+            @Override\r
+            public boolean isDisposed() {\r
+                return disposed;\r
+            }\r
+        });\r
+    }\r
+\r
+\r
+    @Override\r
+    public void setFocus() {\r
+        if (component != null && !component.isDisposed())\r
+            component.requestFocus();\r
+    }\r
+\r
+    \r
+    @Override\r
+    public void dispose() {\r
+        super.dispose();\r
+        getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener);\r
+        disposed = true;\r
+    }\r
+\r
+}\r
index 2777b6304bd4bc5dbb2d5811aa005d9e03a1ed4c..1d86dbe6d53b730a3e36eced5218b43f8d4c733a 100644 (file)
@@ -39,6 +39,7 @@ public class SysdynPerspectiveFactory implements IPerspectiveFactory {
         bottom1.addView(IConsoleConstants.ID_CONSOLE_VIEW);\r
         bottom1.addView("org.simantics.sysdyn.ui.configurationView");\r
         bottom2.addView("org.simantics.sysdyn.ui.trend.view");\r
+        bottom2.addView("org.simantics.sysdyn.ui.dependencies.view");\r
 \r
         IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.25f, editorArea);\r
         left.addView("org.simantics.sysdyn.ui.browser");\r