/*******************************************************************************\r
- * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
* Industry THTH ry.\r
* All rights reserved. This program and the accompanying materials\r
* are made available under the terms of the Eclipse Public License v1.0\r
*******************************************************************************/\r
package org.simantics.sysdyn.ui.structure;\r
\r
-import java.util.Set;\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.custom.CTabFolder;\r
-import org.eclipse.swt.custom.CTabItem;\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.widgets.Label;\r
import org.eclipse.swt.widgets.Spinner;\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
-import org.simantics.utils.ui.ISelectionUtils;\r
\r
-public class Dependencies extends CTabItem {\r
+public class Dependencies extends StructureTabItem {\r
\r
- private GraphvizComponent component;\r
private boolean isInverted = false;\r
private Button bButton, fButton;\r
- private Resource currentSelection;\r
private int levels = 3;\r
- private GraphListener graphListener;\r
\r
- static int MAXLEVELS = 4;\r
- static int MINLEVELS = 1;\r
+ private static int MAXLEVELS = 4;\r
+ private static int MINLEVELS = 1;\r
\r
- public Dependencies(CTabFolder parent, ISelection selection, int style) {\r
+ public Dependencies(CTabFolder parent, int style) {\r
super(parent, style);\r
\r
- Composite dependencies = new Composite(parent, SWT.NONE);\r
- GridDataFactory.fillDefaults().grab(true, true).applyTo(dependencies);\r
- GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(dependencies);\r
-\r
- component = new GraphvizComponent(dependencies, SWT.NONE);\r
- GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
- \r
- Label line = new Label(dependencies, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);\r
+ Label line = new Label(structureComposite, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);\r
GridDataFactory.fillDefaults().grab(true, false).applyTo(line);\r
\r
- Composite composite = new Composite(dependencies, SWT.NONE);\r
+ Composite composite = new Composite(structureComposite, SWT.NONE);\r
RowLayout layout = new RowLayout();\r
layout.center = true;\r
composite.setLayout(layout);\r
}\r
});\r
\r
- drawSelection(selection);\r
- \r
this.setText("Dependencies");\r
- this.setControl(dependencies);\r
+ this.setControl(structureComposite);\r
}\r
\r
-\r
- public 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
- Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
- if(ress.isEmpty()) return;\r
- Resource r = (ress.toArray(Resource.NONE))[0];\r
- if(r != null && !r.equals(currentSelection)) {\r
- currentSelection = r;\r
- readGraph(currentSelection);\r
- }\r
- }\r
- } \r
- }\r
-\r
- private void readGraph(Resource resource) {\r
+ protected void readGraph(Resource resource) {\r
if(graphListener != null)\r
graphListener.dispose();\r
\r
resource, levels, isInverted), graphListener);\r
}\r
\r
- private class GraphListener implements Listener<Graph> {\r
- \r
- private boolean disposed = false;\r
- \r
- public void dispose() {\r
- disposed = true;\r
- }\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("Loading dependencies 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
+ protected String getJobLabel() {\r
+ return "Loading dependencies graph";\r
}\r
}\r
* @param levels How many steps of dependencies are calculated from the variable\r
* @param isInverted true => variables that affect root; false => variables that are affected by root \r
*/\r
- public LoopGraphRequest(Resource root, int levels, boolean isInverted) {\r
- super(root, levels, isInverted);\r
+ public LoopGraphRequest(Resource root) {\r
+ super(root, 999, false);\r
}\r
\r
@Override\r
}\r
SysdynResource sr = SysdynResource.getInstance(g);\r
if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) {\r
+ // Get ALL loops in the diagram in which the root exists.\r
List<List<Resource>> loops = ConfigurationUtils.getLoops(g, root);\r
setRoot(g, graph, root);\r
\r
+ // Add the edges to the graph.\r
edges = new MapList<Resource, Edge>();\r
for (List<Resource> loop : loops) {\r
Resource prev = null;\r
* @throws DatabaseException \r
*/\r
private void claimEdge(ReadGraph g, IGraph graph, Resource tail, Resource head) throws DatabaseException {\r
- // If edge exists, return\r
- for (Edge e : edges.getValues(tail))\r
+ // If edge exists, increase the size of the arrowhead and return.\r
+ for (Edge e : edges.getValues(tail)) {\r
if (((Node)e.getHead()).get("label").equals(getName(g, head))) {\r
// Change the size of the arrowhead (fancily :-)\r
String arrowsize = e.get("arrowsize");\r
e.setArrowsize(Math.min(2.2, Math.sqrt(Double.valueOf(arrowsize) + 0.8)));\r
return;\r
}\r
+ }\r
\r
for (Edge e : edges.getValues(head)) { // Seek for opposite edges\r
if (((Node)e.getHead()).get("label").equals(getName(g, tail))) {\r
*******************************************************************************/\r
package org.simantics.sysdyn.ui.structure;\r
\r
-import java.util.Set;\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.custom.CTabFolder;\r
-import org.eclipse.swt.custom.CTabItem;\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.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
-import org.simantics.utils.ui.ISelectionUtils;\r
-\r
-public class Loops extends CTabItem {\r
- \r
- private GraphvizComponent component;\r
- private boolean isInverted = false;\r
- private Button bButton, fButton;\r
- private Resource currentSelection;\r
- private int levels = 3;\r
- private GraphListener graphListener;\r
\r
- static int MAXLEVELS = 4;\r
- static int MINLEVELS = 1;\r
+/**\r
+ * Tab for loops.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class Loops extends StructureTabItem {\r
\r
public Loops(CTabFolder parent, int style) {\r
super(parent, style);\r
- \r
- Composite loops = new Composite(parent, SWT.NONE);\r
- GridDataFactory.fillDefaults().grab(true, true).applyTo(loops);\r
- GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(loops);\r
-\r
- component = new GraphvizComponent(loops, SWT.NONE);\r
- GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
- \r
- Label line = new Label(loops, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);\r
- GridDataFactory.fillDefaults().grab(true, false).applyTo(line);\r
- \r
- Composite composite = new Composite(loops, SWT.NONE);\r
- RowLayout layout = new RowLayout();\r
- layout.center = true;\r
- composite.setLayout(layout);\r
-\r
- Label label = new Label(composite, SWT.NONE);\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.NONE);\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
this.setText("Loops");\r
- this.setControl(loops);\r
+ this.setControl(structureComposite);\r
}\r
\r
-\r
- public 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
- Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
- if(ress.isEmpty()) return;\r
- Resource r = (ress.toArray(Resource.NONE))[0];\r
- if(r != null && !r.equals(currentSelection)) {\r
- currentSelection = r;\r
- readGraph(currentSelection);\r
- }\r
- }\r
- } \r
- }\r
-\r
- private void readGraph(Resource resource) {\r
+ protected void readGraph(Resource resource) {\r
if(graphListener != null)\r
graphListener.dispose();\r
\r
graphListener = new GraphListener();\r
SimanticsUI.getSession().asyncRequest(new LoopGraphRequest(\r
- resource, levels, isInverted), graphListener);\r
+ resource), graphListener);\r
}\r
\r
- private class GraphListener implements Listener<Graph> {\r
- \r
- private boolean disposed = false;\r
- \r
- public void dispose() {\r
- disposed = true;\r
- }\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("Loading loops 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
+ protected String getJobLabel() {\r
+ return "Loading loops graph";\r
}\r
+ \r
}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import java.util.Set;\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.custom.CTabFolder;\r
+import org.eclipse.swt.custom.CTabItem;\r
+import org.eclipse.swt.widgets.Composite;\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.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Super class for certain kinds of structure tabs.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public abstract class StructureTabItem extends CTabItem {\r
+ \r
+ protected GraphvizComponent component;\r
+ protected GraphListener graphListener;\r
+ protected Composite structureComposite;\r
+ protected Resource currentSelection;\r
+ \r
+ public StructureTabItem(CTabFolder parent, int style) {\r
+ super(parent, style);\r
+ \r
+ structureComposite = new Composite(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(structureComposite);\r
+ GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(structureComposite);\r
+\r
+ component = new GraphvizComponent(structureComposite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
+ }\r
+\r
+\r
+ public 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
+ Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
+ if(ress.isEmpty()) return;\r
+ Resource r = (ress.toArray(Resource.NONE))[0];\r
+ if(r != null && !r.equals(currentSelection)) {\r
+ currentSelection = r;\r
+ readGraph(currentSelection);\r
+ }\r
+ }\r
+ } \r
+ }\r
+\r
+ abstract protected void readGraph(Resource resource);\r
+\r
+ class GraphListener implements Listener<Graph> {\r
+ \r
+ private boolean disposed = false;\r
+ \r
+ public void dispose() {\r
+ disposed = true;\r
+ }\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(getJobLabel()) {\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
+ protected String getJobLabel() {\r
+ return "Loading dependencies graph";\r
+ }\r
+}\r
\r
private CTabFolder tabFolder;\r
private ISelectionListener selectionListener;\r
- private Dependencies dependencies;\r
+ private StructureTabItem dependencies;\r
private ModuleStructure moduleStructure;\r
private Loops loops;\r
\r
final ISelection currentSeletion = getSite().getWorkbenchWindow().getSelectionService().getSelection();\r
\r
// Dependencies\r
- dependencies = new Dependencies(tabFolder, currentSeletion, SWT.NONE);\r
-\r
+ dependencies = new Dependencies(tabFolder, SWT.NONE);\r
+ dependencies.drawSelection(currentSeletion);\r
\r
// Hierarchical model structure\r
moduleStructure = new ModuleStructure(tabFolder, SWT.NONE);\r
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
package org.simantics.sysdyn.utils;\r
\r
import java.util.ArrayList;\r
HashMap<Resource, ElementaryLoopItem> elementaryLoopItems = new HashMap<Resource, ElementaryLoopItem>();\r
for (Resource variable : variables) {\r
ArrayList<Resource> dependingVariables = new ArrayList<Resource>();\r
+ // Add forward dependencies and flows.\r
Collection<Resource> dependencies = g.getObjects(variable, sr.Variable_isTailOf);\r
for (Resource dependency : dependencies) {\r
Resource head = g.getPossibleObject(dependency, sr.Variable_HasHead);\r
- if (!g.isInstanceOf(head, sr.Module)) {\r
+ if (head != null \r
+ && !g.isInstanceOf(head, sr.Module)\r
+ && !g.isInstanceOf(head, sr.Cloud)) {\r
dependingVariables.add(head);\r
}\r
}\r
+ // Add backward flows.\r
+ Collection<Resource> backwardFlows = g.getObjects(variable, sr.Variable_isHeadOf);\r
+ for (Resource flow : backwardFlows) {\r
+ if (g.isInstanceOf(flow, sr.Flow)) {\r
+ Resource tail = g.getPossibleObject(flow, sr.Variable_HasTail);\r
+ if (tail != null && !g.isInstanceOf(tail, sr.Cloud)) {\r
+ dependingVariables.add(tail);\r
+ }\r
+ }\r
+ }\r
+ // Put the variable in the hash map.\r
elementaryLoopItems.put(variable, new ElementaryLoopItem(k, dependingVariables));\r
nodes[k++] = variable;\r
}\r