--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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;\r
+\r
+import org.apache.log4j.BasicConfigurator;\r
+import org.apache.log4j.ConsoleAppender;\r
+import org.apache.log4j.Level;\r
+import org.apache.log4j.Logger;\r
+import org.apache.log4j.SimpleLayout;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.plugin.AbstractUIPlugin;\r
+import org.osgi.framework.BundleContext;\r
+\r
+public class Activator extends AbstractUIPlugin {\r
+\r
+ // The plug-in ID\r
+ public static final String PLUGIN_ID = "org.simantics.sysdyn.ui";\r
+ \r
+ // The shared instance\r
+ private static Activator plugin;\r
+ \r
+ private static LocalResourceManager resourceManager;\r
+\r
+ @Override\r
+ public void start(BundleContext context) throws Exception {\r
+ super.start(context);\r
+ ConsoleAppender appender =\r
+ new ConsoleAppender(new SimpleLayout());\r
+ BasicConfigurator.configure(appender);\r
+ Logger.getRootLogger().setLevel(Level.WARN);\r
+ plugin = this;\r
+ }\r
+ \r
+ @Override\r
+ public void stop(BundleContext context) throws Exception {\r
+ plugin = null;\r
+ super.stop(context);\r
+ }\r
+\r
+ public static Activator getDefault() {\r
+ return plugin;\r
+ }\r
+ \r
+ public static ResourceManager initializeResourceManager(Display display) {\r
+ if (resourceManager == null) {\r
+ resourceManager = new LocalResourceManager(JFaceResources.getResources(display));\r
+ }\r
+ return resourceManager;\r
+ }\r
+\r
+ public static ResourceManager getResources() {\r
+ if (resourceManager == null)\r
+ throw new IllegalStateException("ResourceManager of bundle '" + PLUGIN_ID + "' is not initialized.");\r
+ return resourceManager;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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;\r
+\r
+import javax.swing.JFrame;\r
+\r
+import org.simantics.h2d.canvas.EditorCanvas;\r
+import org.simantics.h2d.diagram.Diagram;\r
+import org.simantics.h2d.editor.impl.DiagramEditor;\r
+import org.simantics.h2d.event.handler.DefaultEventHandlers;\r
+import org.simantics.sysdyn.ui.actions.Connect;\r
+import org.simantics.sysdyn.ui.actions.CreateAuxiliary;\r
+import org.simantics.sysdyn.ui.actions.CreateCloud;\r
+import org.simantics.sysdyn.ui.actions.CreateStock;\r
+import org.simantics.sysdyn.ui.actions.CreateValve;\r
+\r
+public class TestDiagramEditor extends JFrame {\r
+\r
+ public TestDiagramEditor() {\r
+ super("Test Canvas");\r
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
+ \r
+ Diagram diagram = new Diagram();\r
+ final DiagramEditor editor = new DiagramEditor(getRootPane(), diagram);\r
+ \r
+ DefaultEventHandlers.configure(editor);\r
+ editor.addEventHandler(1, "key(A)", new CreateAuxiliary());\r
+ editor.addEventHandler(1, "key(S)", new CreateStock());\r
+ editor.addEventHandler(1, "key(V)", new CreateValve());\r
+ editor.addEventHandler(1, "key(C)", new CreateCloud());\r
+ editor.addEventHandler(1, "drag(alt+left)", new Connect());\r
+ \r
+ getContentPane().add(new EditorCanvas(editor));\r
+\r
+ setSize(800, 600);\r
+ }\r
+ \r
+ public static void main(String[] args) {\r
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {\r
+ public void run() {\r
+ new TestDiagramEditor().setVisible(true);\r
+ }\r
+ }); \r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.event.DragEvent;\r
+import org.simantics.h2d.event.handler.DragEventHandler;\r
+import org.simantics.h2d.node.RectangleNode;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryElement;\r
+import org.simantics.sysdyn.ui.elements.CloudElement;\r
+import org.simantics.sysdyn.ui.elements.DependencyElement;\r
+import org.simantics.sysdyn.ui.elements.FlowElement;\r
+import org.simantics.sysdyn.ui.elements.StockElement;\r
+import org.simantics.sysdyn.ui.elements.ValveElement;\r
+\r
+public class Connect extends DragEventHandler {\r
+\r
+ Connectable from;\r
+ Connectable to;\r
+ \r
+ RectangleNode fromNode = new RectangleNode(); \r
+ RectangleNode toNode = new RectangleNode();\r
+ \r
+ @Override\r
+ protected boolean begin(IDiagramEditor editor, DragEvent event) {\r
+ for(IElement element : event.pickedElements) {\r
+ Connectable connectable = element.getInterface(Connectable.class);\r
+ if(connectable != null) {\r
+ this.from = connectable;\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ @Override\r
+ protected void update(IDiagramEditor editor, DragEvent event) {\r
+ for(IElement element : editor.pickElements(event.current)) {\r
+ Connectable connectable = element.getInterface(Connectable.class); \r
+ if(connectable != null && connectable != from) {\r
+ if(connectable == to)\r
+ return;\r
+ to = connectable;\r
+ \r
+ Rectangle2D bounds = new Rectangle2D.Double(); \r
+ to.getBounds(bounds);\r
+ bounds.setFrame(\r
+ bounds.getX()-2.0, \r
+ bounds.getY()-2.0, \r
+ bounds.getWidth()+4.0, \r
+ bounds.getHeight()+4.0); \r
+ toNode.init(bounds);\r
+ \r
+ editor.requestRepaint(); \r
+ return;\r
+ }\r
+ }\r
+ to = null;\r
+ toNode.init(fromNode.getBounds());\r
+ editor.requestRepaint();\r
+ }\r
+ \r
+ @Override\r
+ protected void end(IDiagramEditor editor, DragEvent event) {\r
+ if(to != null) {\r
+ IElement newElement;\r
+ if(from instanceof ValveElement && to instanceof StockElement)\r
+ newElement = new FlowElement(from, to);\r
+ else if(from instanceof StockElement && to instanceof ValveElement)\r
+ newElement = new FlowElement(from, to);\r
+ else if( (from instanceof StockElement || from instanceof CloudElement) \r
+ && (to instanceof StockElement || to instanceof CloudElement)) {\r
+ Point2D fromOrigo = from.getOrigo();\r
+ Point2D toOrigo = to.getOrigo();\r
+ newElement = new ValveElement(\r
+ 0.5 * (fromOrigo.getX() + toOrigo.getX()),\r
+ 0.5 * (fromOrigo.getY() + toOrigo.getY())\r
+ );\r
+ editor.getDiagram().addElement(new FlowElement(from, (ValveElement)newElement));\r
+ editor.getDiagram().addElement(new FlowElement((ValveElement)newElement, to)); \r
+ }\r
+ else if(from instanceof ValveElement && to instanceof AuxiliaryElement)\r
+ newElement = new DependencyElement(to, from);\r
+ else if(from instanceof AuxiliaryElement && to instanceof StockElement)\r
+ newElement = new DependencyElement(to, from);\r
+ else \r
+ newElement = new DependencyElement(from, to);\r
+ editor.getDiagram().addElement(newElement);\r
+ if(newElement instanceof ValveElement)\r
+ ((ValveElement)newElement).beginRenameAction(editor);\r
+ }\r
+ \r
+ from = null;\r
+ to = null;\r
+ }\r
+ \r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ fromNode = parent.addNode(RectangleNode.class);\r
+ toNode = parent.addNode(RectangleNode.class);\r
+ \r
+ Rectangle2D bounds = new Rectangle2D.Double(); \r
+ from.getBounds(bounds);\r
+ bounds.setFrame(\r
+ bounds.getX()-2.0, \r
+ bounds.getY()-2.0, \r
+ bounds.getWidth()+4.0, \r
+ bounds.getHeight()+4.0);\r
+ \r
+ fromNode.init(bounds);\r
+ toNode.init(bounds);\r
+ }\r
+ \r
+ @Override\r
+ public void remove() {\r
+ fromNode.remove();\r
+ toNode.remove();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.event.DragEvent;\r
+import org.simantics.h2d.event.handler.DragEventHandler;\r
+import org.simantics.h2d.node.RectangleNode;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+public abstract class ConnectBase extends DragEventHandler {\r
+\r
+ protected Connectable from;\r
+ protected Connectable to;\r
+ \r
+ RectangleNode fromNode = new RectangleNode(); \r
+ RectangleNode toNode = new RectangleNode();\r
+ \r
+ /**\r
+ * This is called when starting to make a connection.\r
+ */\r
+ protected abstract boolean isAllowedTail(Connectable tail);\r
+ \r
+ /**\r
+ * This is called when the mouse hovers over another connection point.\r
+ */\r
+ protected abstract boolean isAllowedHead(Connectable head);\r
+ \r
+ protected abstract void connect(IDiagramEditor editor);\r
+ \r
+ @Override\r
+ protected boolean begin(IDiagramEditor editor, DragEvent event) {\r
+ for(IElement element : event.pickedElements) {\r
+ Connectable connectable = element.getInterface(Connectable.class);\r
+ if(connectable != null && isAllowedTail(connectable)) {\r
+ this.from = connectable;\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ @Override\r
+ protected void update(IDiagramEditor editor, DragEvent event) {\r
+ for(IElement element : editor.pickElements(event.current)) {\r
+ Connectable connectable = element.getInterface(Connectable.class); \r
+ if(connectable != null && connectable != from) {\r
+ if(connectable == to)\r
+ return;\r
+ if(!isAllowedHead(connectable))\r
+ continue;\r
+ to = connectable;\r
+ \r
+ Rectangle2D bounds = new Rectangle2D.Double(); \r
+ to.getBounds(bounds);\r
+ bounds.setFrame(\r
+ bounds.getX()-2.0, \r
+ bounds.getY()-2.0, \r
+ bounds.getWidth()+4.0, \r
+ bounds.getHeight()+4.0); \r
+ toNode.init(bounds);\r
+ \r
+ editor.requestRepaint(); \r
+ return;\r
+ }\r
+ }\r
+ to = null;\r
+ toNode.init(fromNode.getBounds());\r
+ editor.requestRepaint();\r
+ }\r
+ \r
+ @Override\r
+ protected void end(IDiagramEditor editor, DragEvent event) {\r
+ if(to != null)\r
+ connect(editor);\r
+ \r
+ from = null;\r
+ to = null;\r
+ }\r
+ \r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ fromNode = parent.addNode(RectangleNode.class);\r
+ toNode = parent.addNode(RectangleNode.class);\r
+ \r
+ Rectangle2D bounds = new Rectangle2D.Double(); \r
+ from.getBounds(bounds);\r
+ bounds.setFrame(\r
+ bounds.getX()-2.0, \r
+ bounds.getY()-2.0, \r
+ bounds.getWidth()+4.0, \r
+ bounds.getHeight()+4.0);\r
+ \r
+ fromNode.init(bounds);\r
+ toNode.init(bounds);\r
+ }\r
+ \r
+ @Override\r
+ public void remove() {\r
+ fromNode.remove();\r
+ toNode.remove();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryElement;\r
+import org.simantics.sysdyn.ui.elements.DependencyElement;\r
+import org.simantics.sysdyn.ui.elements.StockElement;\r
+import org.simantics.sysdyn.ui.elements.ValveElement;\r
+\r
+public class ConnectDependency extends ConnectBase {\r
+\r
+ @Override\r
+ protected boolean isAllowedTail(Connectable tail) {\r
+ return tail instanceof AuxiliaryElement \r
+ || tail instanceof StockElement\r
+ || tail instanceof ValveElement \r
+ ;\r
+ }\r
+ \r
+ @Override\r
+ protected boolean isAllowedHead(Connectable head) {\r
+ return head instanceof AuxiliaryElement \r
+ || head instanceof ValveElement\r
+ ; \r
+ }\r
+\r
+ @Override\r
+ protected void connect(IDiagramEditor editor) {\r
+ editor.getDiagram().addElement(new DependencyElement(from, to)); \r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import java.awt.geom.Point2D;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.sysdyn.ui.elements.CloudElement;\r
+import org.simantics.sysdyn.ui.elements.FlowElement;\r
+import org.simantics.sysdyn.ui.elements.StockElement;\r
+import org.simantics.sysdyn.ui.elements.ValveElement;\r
+\r
+public class ConnectFlow extends ConnectBase {\r
+\r
+ @Override\r
+ protected boolean isAllowedTail(Connectable tail) {\r
+ return tail instanceof CloudElement \r
+ || tail instanceof StockElement\r
+ || tail instanceof ValveElement\r
+ ;\r
+ }\r
+ \r
+ @Override\r
+ protected boolean isAllowedHead(Connectable head) {\r
+ return head instanceof CloudElement \r
+ || head instanceof StockElement \r
+ || (head instanceof ValveElement && !(from instanceof ValveElement))\r
+ ; \r
+ }\r
+\r
+ @Override\r
+ protected void connect(IDiagramEditor editor) {\r
+ if(from instanceof ValveElement || to instanceof ValveElement)\r
+ editor.getDiagram().addElement(new FlowElement(from, to));\r
+ else {\r
+ Point2D fromOrigo = from.getOrigo();\r
+ Point2D toOrigo = to.getOrigo();\r
+ ValveElement valveElement = new ValveElement(\r
+ 0.5 * (fromOrigo.getX() + toOrigo.getX()),\r
+ 0.5 * (fromOrigo.getY() + toOrigo.getY())\r
+ );\r
+ editor.getDiagram().addElement(valveElement);\r
+ editor.getDiagram().addElement(new FlowElement(from, valveElement));\r
+ editor.getDiagram().addElement(new FlowElement(valveElement, to));\r
+ \r
+ valveElement.beginRenameAction(editor);\r
+ }\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ILocatableEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryElement;\r
+\r
+public class CreateAuxiliary implements IEventHandler {\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ ILocatableEvent event = (ILocatableEvent)_event;\r
+ AuxiliaryElement element = new AuxiliaryElement("Auxiliary", \r
+ event.getLocation().getX(),\r
+ event.getLocation().getY());\r
+ editor.getDiagram().addElement(element);\r
+ element.beginRenameAction(editor);\r
+ editor.requestRepaint();\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ILocatableEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.sysdyn.ui.elements.CloudElement;\r
+\r
+public class CreateCloud implements IEventHandler {\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ ILocatableEvent event = (ILocatableEvent)_event;\r
+ CloudElement element = new CloudElement( \r
+ event.getLocation().getX(),\r
+ event.getLocation().getY());\r
+ editor.getDiagram().addElement(element); \r
+ editor.requestRepaint();\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ILocatableEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.sysdyn.ui.elements.StockElement;\r
+\r
+public class CreateStock implements IEventHandler {\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ ILocatableEvent event = (ILocatableEvent)_event;\r
+ StockElement element = new StockElement("Stock", \r
+ event.getLocation().getX(),\r
+ event.getLocation().getY());\r
+ editor.getDiagram().addElement(element);\r
+ element.beginRenameAction(editor);\r
+ editor.requestRepaint();\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ILocatableEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.sysdyn.ui.elements.ValveElement;\r
+\r
+public class CreateValve implements IEventHandler {\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ ILocatableEvent event = (ILocatableEvent)_event;\r
+ editor.getDiagram().addElement(new ValveElement( \r
+ event.getLocation().getX(),\r
+ event.getLocation().getY()));\r
+ editor.requestRepaint();\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+\r
+public class DiagramContextMenuData {\r
+ public final IDiagramEditor diagramEditor;\r
+ public final IEvent event;\r
+ \r
+ public DiagramContextMenuData(IDiagramEditor diagramEditor, IEvent event) {\r
+ this.diagramEditor = diagramEditor;\r
+ this.event = event;\r
+ } \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+import org.eclipse.jface.action.GroupMarker;\r
+import org.eclipse.jface.action.IMenuListener;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.action.MenuManager;\r
+import org.eclipse.jface.action.Separator;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.ui.IWorkbenchActionConstants;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ReleaseEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+\r
+public class OpenContextMenu implements IEventHandler {\r
+\r
+ Control control;\r
+ IWorkbenchPartSite site;\r
+ String menuId;\r
+\r
+ MenuManager menuManager;\r
+\r
+ public OpenContextMenu(Control control, IWorkbenchPartSite site,\r
+ String menuId) {\r
+ super();\r
+ this.control = control;\r
+ this.site = site;\r
+ this.menuId = menuId;\r
+ menuManager = createPopupMenu();\r
+ if (menuManager != null) {\r
+ Menu menu = menuManager.createContextMenu(control);\r
+ control.setMenu(menu);\r
+ if (site != null) {\r
+ site.registerContextMenu(menuManager.getId(), menuManager,\r
+ site.getSelectionProvider());\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean handle(final IDiagramEditor editor, IEvent _event) {\r
+ final ReleaseEvent event = (ReleaseEvent)_event;\r
+ control.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ if (control.isDisposed())\r
+ return;\r
+ //Point p = control.toDisplay(event.getLocation().get(int) cp.getX(), (int) cp.getY());\r
+ menuManager.getMenu().setLocation(\r
+ new Point((int)event.dispPoint.getX(), (int)event.dispPoint.getY()));\r
+ menuManager.getMenu().setData(\r
+ new DiagramContextMenuData(editor, event)\r
+ );\r
+ menuManager.getMenu().setVisible(true);\r
+ }\r
+\r
+ });\r
+ return true;\r
+ }\r
+\r
+ protected MenuManager createPopupMenu() {\r
+ final MenuManager mm = new MenuManager("Diagram Popup", menuId);\r
+ mm.setRemoveAllWhenShown(true);\r
+ mm.addMenuListener(new IMenuListener() {\r
+ public void menuAboutToShow(IMenuManager manager) {\r
+ mm.add(new GroupMarker(IWorkbenchActionConstants.WB_START));\r
+ mm.add(new GroupMarker(IWorkbenchActionConstants.NEW_EXT));\r
+ mm.add(new GroupMarker(IWorkbenchActionConstants.IMPORT_EXT));\r
+ mm.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));\r
+ mm.add(new GroupMarker(IWorkbenchActionConstants.WB_END));\r
+ }\r
+ });\r
+ return mm;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.actions;\r
+\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.Command;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.core.commands.State;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.commands.ICommandService;\r
+import org.eclipse.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.ui.handlers.RunBasicExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ToggleSimulation extends AbstractHandler implements IElementUpdater {\r
+\r
+ public static final String COMMAND = "org.simantics.sysdyn.ui.toggleSimulation";\r
+ public static final String STATE = "org.simantics.sysdyn.ui.toggleSimulation.state";\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = service.getCommand(COMMAND);\r
+ State state = command.getState(STATE);\r
+ Boolean value = (Boolean) state.getValue();\r
+ value = !value;\r
+ state.setValue(value);\r
+ service.refreshElements(RunBasicExperiment.COMMAND, null);\r
+ \r
+ IExperimentManager manager = \r
+ SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment instanceof SysdynExperiment) {\r
+ if(getState()) {\r
+ ((SysdynExperiment)experiment).toggleSimulation(true);\r
+ } else {\r
+ ((SysdynExperiment)experiment).toggleSimulation(false);\r
+ }\r
+ }\r
+ \r
+ \r
+ return null;\r
+ }\r
+\r
+ public static Boolean getState() {\r
+ ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = service.getCommand(COMMAND);\r
+ State state = command.getState(STATE);\r
+ return (Boolean)state.getValue();\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public void updateElement(UIElement element, Map parameters) {\r
+ ICommandService commandService =\r
+ (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = commandService.getCommand(COMMAND);\r
+ boolean checked = (Boolean) command.getState(STATE).getValue();\r
+ element.setChecked(checked);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser;\r
+\r
+import java.util.Collections;\r
+import java.util.Set;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.ContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.GraphExplorerView;\r
+import org.simantics.browsing.ui.swt.IContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.IPropertyPage;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+\r
+\r
+public class SysdynBrowser extends GraphExplorerView {\r
+ \r
+ private static final Set<String> browseContexts = Collections.singleton("http://www.simantics.org/Sysdyn-1.0/Browser");\r
+ \r
+ @Override\r
+ protected IContextMenuInitializer getContextMenuInitializer() {\r
+ return new ContextMenuInitializer("#SysdynBrowserPopup");\r
+ }\r
+ \r
+ @Override\r
+ protected Set<String> getBrowseContexts() {\r
+ return browseContexts;\r
+ }\r
+ \r
+ @Override\r
+ protected void createControls(Composite parent) {\r
+ // Make sure the resource manager of this plug-in is initialized\r
+ // properly before using it in this browser.\r
+ Activator.initializeResourceManager(parent.getDisplay());\r
+\r
+ super.createControls(parent);\r
+ //IToolBarManager toolBar = getViewSite().getActionBars().getToolBarManager();\r
+ //toolBar.add(new HomeAction());\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public Object getAdapter(Class adapter) {\r
+ if (adapter == IPropertyPage.class)\r
+ return new SysdynPropertyPage(getSite(), Collections.singleton("http://www.simantics.org/Sysdyn-1.0/Browser"));\r
+ return super.getAdapter(adapter);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.swt.ImagerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.InputNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.OperatingInterfacesFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+\r
+public class AbstractNodeImager extends ImagerContributor<AbstractNode> {\r
+\r
+ @Override\r
+ public ImageDescriptor getDescriptor(ReadGraph graph, AbstractNode node) throws DatabaseException {\r
+ \r
+ String image = null;\r
+ if (node instanceof ExperimentsFolder || \r
+ node instanceof OperatingInterfacesFolder || \r
+ node instanceof ModulesNode)\r
+ image = "icons/folder.png";\r
+ else if (node instanceof ModuleTypeNode || node instanceof ModuleNode || node instanceof ConfigurationNode)\r
+ image = "icons/bricks.png";\r
+ else if (node instanceof ExperimentNode)\r
+ image = "icons/time.png";\r
+ else if (node instanceof InputNode)\r
+ image = "icons/brick_link.png";\r
+ else if (node instanceof ModelNode)\r
+ image = "icons/chart_organisation.png";\r
+ else if (node instanceof VariableNode)\r
+ image = "icons/brick.png";\r
+ \r
+ if (image != null)\r
+ return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image));\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+\r
+public class AbstractNodeLabeler extends LabelerContributor<AbstractNode> {\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, AbstractNode node) throws DatabaseException {\r
+ if (!graph.hasStatement(node.resource))\r
+ return "";\r
+ return graph.adapt(node.resource, String.class);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+\r
+public class Configuration extends ViewpointContributor<ConfigurationNode> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ConfigurationNode configuration) throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(configuration.resource, b.ConsistsOf, sr.IndependentVariable))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(configuration.resource, b.ConsistsOf, sr.Input))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(configuration.resource, b.ConsistsOf, sr.Module))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+\r
+public class ConfigurationLabeler extends LabelerContributor<ConfigurationNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ConfigurationNode conf) throws DatabaseException {\r
+ return "Configuration";\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+\r
+public class Experiment extends ViewpointContributor<ExperimentsFolder> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ExperimentsFolder experimentsFolder) throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ Builtins b = graph.getBuiltins();\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(experimentsFolder.resource, b.ConsistsOf, b.Experiment))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.swt.SWT;\r
+import org.simantics.browsing.ui.content.LabelDecorator;\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelDecoratorContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+\r
+public class ExperimentLabelDecorator extends LabelDecoratorContributor<ExperimentNode> {\r
+\r
+ @Override\r
+ public LabelDecorator getDecorator(ReadGraph graph, ExperimentNode experimentNode) throws DatabaseException {\r
+ if (graph.hasStatement(experimentNode.resource, graph.getBuiltins().IsActive)) {\r
+ return new LabelDecorator.Stub() {\r
+ @Override\r
+ public String decorateLabel(String label, String column, int itemIndex) {\r
+ return label + " [ACTIVE]";\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <F> F decorateFont(F font, String column, int itemIndex) {\r
+ return (F) ((FontDescriptor) font).withStyle(SWT.BOLD);\r
+ }\r
+ };\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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
+\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+\r
+public class ExperimentLabeler extends LabelerContributor<ExperimentNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ExperimentNode experiment) throws DatabaseException {\r
+ String name = graph.getPossibleRelatedValue(experiment.resource, graph.getBuiltins().HasLabel);\r
+ return name == null ? "Experiment (no name)" : name;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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
+\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+\r
+public class ExperimentsLabeler extends LabelerContributor<ExperimentsFolder> {\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ExperimentsFolder experiments) throws DatabaseException {\r
+ return "Experiments";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.InputNode;\r
+\r
+public class InputLabeler extends LabelerContributor<InputNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, InputNode var) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ Resource varres = var.resource;\r
+ StringBuilder sb = new StringBuilder();\r
+ for(Resource r : graph.getObjects(varres, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ sb.append(" : ");\r
+ for(Resource t : graph.getObjects(varres, b.InstanceOf))\r
+ for(Resource r : graph.getObjects(t, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ return sb.toString();\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\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.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ *\r
+ * @param <T> input library node type\r
+ */\r
+public abstract class LibraryViewpointContributor<T extends AbstractNode> extends ViewpointContributor<T> {\r
+\r
+ protected abstract Read<Collection<Resource>> getChildRequest(ReadGraph graph, T lib) throws DatabaseException;\r
+\r
+ @Override\r
+ public final Collection<?> getContribution(ReadGraph graph, T lib) throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ for (Resource r : graph.syncRequest(getChildRequest(graph, lib))) {\r
+ try {\r
+ AbstractNode n = graph.adapt(r, AbstractNode.class);\r
+ result.add(n);\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.OperatingInterfacesFolder;\r
+\r
+public class Model extends ViewpointContributor<ModelNode> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ModelNode model)\r
+ throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ result.add(new ConfigurationNode(\r
+ graph.getSingleObject(\r
+ model.resource, \r
+ graph.getBuiltins().HasConfiguration))\r
+ );\r
+ result.add(new ExperimentsFolder(model.resource));\r
+ result.add(new OperatingInterfacesFolder(model.resource));\r
+ result.add(new ModulesNode(model.resource));\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class ModelLabeler extends LabelerContributor<ModelNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ModelNode model) throws DatabaseException {\r
+ String label = graph.getPossibleRelatedValue(model.resource, graph.getBuiltins().HasLabel);\r
+ return label == null ? "Model (no name)" : label;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleNode;\r
+\r
+public class Module extends ViewpointContributor<ModuleNode> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ModuleNode module) throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ StructuralResource2 str = StructuralResource2.getInstance(graph);\r
+ Resource instance = graph.getPossibleObject(module.resource, b.InstanceOf);\r
+ if(instance == null) return result;\r
+ Resource conf = graph.getSingleObject(instance, str.IsDefinedBy);\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(conf, b.ConsistsOf, sr.IndependentVariable))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(conf, b.ConsistsOf, sr.Input))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(conf, b.ConsistsOf, sr.Module))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleNode;\r
+\r
+public class ModuleLabeler extends LabelerContributor<ModuleNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ModuleNode module) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ Resource resource = module.resource;\r
+ StringBuilder sb = new StringBuilder();\r
+ for(Resource r : graph.getObjects(resource, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ sb.append(" : ");\r
+ for(Resource t : graph.getObjects(resource, b.InstanceOf))\r
+ for(Resource r : graph.getObjects(t, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ return sb.toString();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode;\r
+\r
+public class ModuleTypeLabeler extends LabelerContributor<ModuleTypeNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ModuleTypeNode moduleType) throws DatabaseException {\r
+ ModelingResources mr = ModelingResources.getInstance(graph);\r
+ Resource typeResource = graph.getPossibleObject(moduleType.resource, mr.SymbolToComponentType);\r
+ String label = graph.getPossibleRelatedValue(typeResource, graph.getBuiltins().HasName);\r
+ return label == null ? "ModuleType (no name)" : label;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
+\r
+public class Modules extends ViewpointContributor<ModulesNode> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ModulesNode model)\r
+ throws DatabaseException {\r
+\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ Builtins b = graph.getBuiltins();\r
+ StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(model.resource, b.ConsistsOf, st.ComponentType))) {\r
+ Resource symbol = graph.getPossibleObject(r,ModelingResources.getInstance(graph).ComponentTypeToSymbol);\r
+ result.add(new ModuleTypeNode(symbol));\r
+ }\r
+ return result;\r
+\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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
+\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
+\r
+public class ModulesLabeler extends LabelerContributor<ModulesNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, ModulesNode input) throws DatabaseException {\r
+ return "Modules";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.OperatingInterfacesFolder;\r
+\r
+public class OperatingInterfacesLabeler extends LabelerContributor<OperatingInterfacesFolder> {\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, OperatingInterfacesFolder input) throws DatabaseException {\r
+ return "Operating interfaces";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+\r
+public class Project extends ViewpointContributor<Resource> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, Resource project)\r
+ throws DatabaseException {\r
+\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ for(Resource r : graph.syncRequest(new ObjectsWithType(project, b.ConsistsOf, sr.SysdynModel))) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ return result;\r
+\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+\r
+public class SimulationResult extends ViewpointContributor<ExperimentNode> {\r
+\r
+ @Override\r
+ public Collection<?> getContribution(ReadGraph graph, ExperimentNode experiment) throws DatabaseException {\r
+ ArrayList<AbstractNode> result = new ArrayList<AbstractNode>();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ for(final Resource r : graph.syncRequest(new ObjectsWithType(experiment.resource, sr.HasResult, sr.Result))) {\r
+ String resultPath = (String)graph.getPossibleRelatedValue(r, sr.HasResultFile);\r
+ File file = new File(resultPath);\r
+ if(file.exists()) {\r
+ try {\r
+ result.add(graph.adapt(r, AbstractNode.class));\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ } else {\r
+ graph.asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ graph.deny(r, b.PartOf);\r
+ graph.deny(r, graph.getInverse(SysdynResource.getInstance(graph).HasResult));\r
+ \r
+ }\r
+ });\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public String getViewpointId() {\r
+ return "Standard";\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.swt.SWT;\r
+import org.simantics.browsing.ui.content.LabelDecorator;\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelDecoratorContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultDecorator extends LabelDecoratorContributor<SimulationResultNode>{\r
+\r
+ @Override\r
+ public LabelDecorator getDecorator(ReadGraph graph, SimulationResultNode result) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ if (graph.hasStatement(result.resource, b.IsActive)) {\r
+ return new LabelDecorator.Stub() {\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <F> F decorateFont(F font, String column, int itemIndex) {\r
+ return (F) ((FontDescriptor) font).withStyle(SWT.BOLD);\r
+ }\r
+ };\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.swt.ImagerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultImager extends ImagerContributor<SimulationResultNode>{\r
+\r
+ @Override\r
+ public ImageDescriptor getDescriptor(ReadGraph graph, SimulationResultNode result) throws DatabaseException {\r
+ if(graph.hasStatement(result.resource, graph.getBuiltins().IsActive))\r
+ return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar.png"));\r
+ else\r
+ return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_blackAndWhite.png"));\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultLabeler extends LabelerContributor<SimulationResultNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, SimulationResultNode result) throws DatabaseException {\r
+ String name = graph.getPossibleRelatedValue(result.resource, graph.getBuiltins().HasLabel);\r
+ return name == null ? "Experiment (no name)" : name;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.graph.contributor.labeler.LabelerContributor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+\r
+public class VariableLabeler extends LabelerContributor<VariableNode>{\r
+\r
+ @Override\r
+ public String getLabel(ReadGraph graph, VariableNode var) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ Resource varres = var.resource;\r
+ StringBuilder sb = new StringBuilder();\r
+ for(Resource r : graph.getObjects(varres, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ sb.append(" : ");\r
+ for(Resource t : graph.getObjects(varres, b.InstanceOf))\r
+ for(Resource r : graph.getObjects(t, b.HasName))\r
+ sb.append(graph.getValue(r));\r
+ return sb.toString();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.simantics.db.Resource;\r
+\r
+public abstract class AbstractNode implements IAdaptable {\r
+ public final Resource resource;\r
+\r
+ public AbstractNode(Resource resource) {\r
+ assert(resource != null);\r
+ this.resource = resource;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ return resource.hashCode() + getClass().hashCode();\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj)\r
+ return true;\r
+ if (obj == null)\r
+ return false;\r
+ if (getClass() != obj.getClass())\r
+ return false;\r
+ AbstractNode other = (AbstractNode) obj;\r
+ return resource.equals(other.resource);\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public Object getAdapter(Class adapter) {\r
+ if(adapter.equals(Resource.class))\r
+ return resource;\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+\r
+public class ConfigurationNode extends AbstractNode implements IDeletable {\r
+\r
+ public ConfigurationNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.browsing.ui.common.node.IDoubleClickableNode;\r
+import org.simantics.browsing.ui.common.node.IModifiableNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.browsing.ui.graph.impl.LabelModifier;\r
+import org.simantics.db.Resource;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+public class ExperimentNode extends AbstractNode implements IDoubleClickableNode, IDeletable, IModifiableNode{\r
+\r
+ public ExperimentNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+ @Override\r
+ public boolean handleDoubleClick() {\r
+ if (resource == null)\r
+ return false;\r
+ IProject project = SimanticsUI.getProject();\r
+ IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ if (experimentManager == null) {\r
+ ErrorLogger.defaultLogWarning("Experiment manager not available.", new Exception());\r
+ return false;\r
+ }\r
+ SysdynExperimentActivator.scheduleActivation(SimanticsUI.getSession(), project, experimentManager, resource);\r
+ return true;\r
+ }\r
+ \r
+ @Override\r
+ public Modifier getModifier(String columnId) {\r
+ LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), resource) {\r
+ @Override\r
+ public String isValid(String label) {\r
+ if (label.isEmpty())\r
+ return "Empty label not allowed";\r
+ return null;\r
+ }\r
+ };\r
+ return modifier;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+public class ExperimentsFolder extends AbstractNode {\r
+\r
+ public ExperimentsFolder(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+public class InputNode extends AbstractNode {\r
+\r
+ public InputNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.browsing.ui.common.node.IModifiableNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.browsing.ui.graph.impl.LabelModifier;\r
+import org.simantics.db.Resource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModelNode extends AbstractNode implements IDeletable, IModifiableNode {\r
+\r
+ public ModelNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+ @Override\r
+ public Modifier getModifier(String columnId) {\r
+ LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), resource) {\r
+ @Override\r
+ public String isValid(String label) {\r
+ if (label.isEmpty())\r
+ return "Empty label not allowed";\r
+ if (label.contains(" "))\r
+ return "Spaces are not allowed";\r
+ return null;\r
+ }\r
+ };\r
+ return modifier;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+\r
+public class ModuleNode extends AbstractNode implements IDeletable {\r
+\r
+ public ModuleNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+\r
+public class ModuleTypeNode extends AbstractNode implements IDeletable {\r
+\r
+ public ModuleTypeNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+public class ModulesNode extends AbstractNode {\r
+ \r
+ public ModulesNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+public class OperatingInterfacesFolder extends AbstractNode {\r
+\r
+ public OperatingInterfacesFolder(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.browsing.ui.common.node.IModifiableNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.browsing.ui.graph.impl.LabelModifier;\r
+import org.simantics.db.Resource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class SimulationResultNode extends AbstractNode implements IDeletable, IModifiableNode {\r
+\r
+ public SimulationResultNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+ \r
+ \r
+ @Override\r
+ public Modifier getModifier(String columnId) {\r
+ LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), resource) {\r
+ @Override\r
+ public String isValid(String label) {\r
+ if (label.isEmpty())\r
+ return "Empty label not allowed";\r
+ return null;\r
+ }\r
+ };\r
+ return modifier;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+\r
+public class SymbolNode extends AbstractNode implements IDeletable {\r
+\r
+ public SymbolNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+public class VariableNode extends AbstractNode {\r
+\r
+ public VariableNode(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+}\r
--- /dev/null
+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.modeling.ModelingResources;\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.isInverted = isInverted; \r
+ this.levels = levels;\r
+ }\r
+\r
+ @Override\r
+ public Graph perform(ReadGraph g) throws DatabaseException {\r
+ nodes = new HashMap<Resource, Node>();\r
+ Graph graph = new Graph();\r
+ graph.setRankdir("LR");\r
+ ModelingResources mr = ModelingResources.getInstance(g);\r
+ Resource element = g.getPossibleObject(root, mr.ElementToComponent);\r
+ if (element != null) {\r
+ root = element;\r
+ }\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ if (g.isInstanceOf(root, sr.IndependentVariable) || g.isInstanceOf(root, sr.Input)) {\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
+ Collection<Resource> dependants = new ArrayList<Resource>();\r
+ SysdynResource sr = SysdynResource.getInstance(g);\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
+ // stop here if element is a module\r
+ if (g.isInstanceOf(r, sr.Module))\r
+ return dependants;\r
+ \r
+ Resource headRelation = sr.IsHeadOf;\r
+ Resource tailRelation = sr.HasTail; \r
+ if(isInverted) {\r
+ headRelation = sr.IsTailOf;\r
+ tailRelation = sr.HasHead;\r
+ }\r
+ \r
+ Collection<Resource> dependencies = g.getObjects(r, headRelation);\r
+ for(Resource d : dependencies) {\r
+ Resource dependant = g.getPossibleObject(d, tailRelation);\r
+ if(dependant == null)\r
+ continue;\r
+ if(g.isInstanceOf(dependant, sr.Cloud)) {\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 if(g.isInstanceOf(r, sr.Module))\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
--- /dev/null
+package org.simantics.sysdyn.ui.dependencies;\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.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
+import org.simantics.utils.ui.ISelectionUtils;\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
+ private Composite baseComposite;\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
+ baseComposite = new Composite(parent, \r
+ SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+ GridLayoutFactory.fillDefaults().applyTo(baseComposite);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(baseComposite);\r
+\r
+ component = new GraphvizComponent(baseComposite, 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
+ 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
+ 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(baseComposite != null && !baseComposite.isDisposed()) {\r
+ baseComposite.setFocus();\r
+ component.setFocus();\r
+ }\r
+ }\r
+\r
+\r
+\r
+\r
+ @Override\r
+ public void dispose() {\r
+ super.dispose();\r
+ getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener);\r
+ disposed = true;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.editor;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.binaryPredicates.InversePredicate;\r
+import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate;\r
+import org.simantics.mapping.constraint.instructions.IInstruction;\r
+import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;\r
+import org.simantics.mapping.rule.instructions.IRuleInstruction;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class DiagramToCompositeMapping3 extends org.simantics.modeling.mapping.DiagramToCompositeMapping3 {\r
+\r
+ private SysdynResource sdr;\r
+\r
+ public DiagramToCompositeMapping3(ReadGraph g, Resource mapping)\r
+ throws DatabaseException {\r
+ super(g, mapping);\r
+ }\r
+\r
+ @Override\r
+ protected void setup(ReadGraph graph) {\r
+ sdr = SysdynResource.getInstance(graph);\r
+ }\r
+\r
+ @Override\r
+ protected Resource getConfigurationConnectionType() {\r
+ return sdr.DependencyConnection;\r
+ }\r
+\r
+ @Override\r
+ public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) {\r
+ return new SysdynCreationInstruction(project, configurationRoot, component, componentType, configuration);\r
+ }\r
+\r
+ @Override\r
+ protected IRuleInstruction additiveRule() {\r
+ return \r
+ \r
+ if_(bf(OrderedSetElementsPredicate.INSTANCE, Diagram, Element),\r
+ query(\r
+ if_(and(bf(b.InstanceOf, Element, ElementType),\r
+ bf(mr.SymbolToComponentType, ElementType, ComponentType)\r
+ ),\r
+ // If element type of the element has a corresponding component type\r
+ createComponentRule(),\r
+ \r
+ if_(and(b(dr.Connection, Element), bf(b.InstanceOf, Element, ElementType), bf(mr.DiagramConnectionTypeToConnectionType, ElementType, ComponentType)),\r
+ createNormalConnectionRule(),\r
+\r
+ if_(b(dr.Flag, Element),\r
+ createFlagRule()\r
+ )\r
+ )\r
+ )\r
+ )\r
+ );\r
+ }\r
+\r
+ @Override\r
+ protected IRuleInstruction destructiveRule() {\r
+ return\r
+ if_(and(bf(b.ConsistsOf, Configuration, Component),\r
+ b(mapped, Component) // handle only mapped components\r
+ ),\r
+ query(\r
+ if_(and(bf(mr.ComponentToElement, Component, Element),\r
+ bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram)\r
+ ),\r
+ // If component has a corresponding element in the diagram\r
+ if_(and(statement_bff(Component, ConnectionRelation, Connection, sr.IsConnectedTo),\r
+ b(mapped, Connection)\r
+ ),\r
+ // If component has a mapped connection\r
+ unless(\r
+ bf(mr.ConnectionToDiagramConnection, Connection, DiagramConnectionRelation),\r
+ // If the configuration connection does not have a correspondence in the diagram remove it\r
+ and(deny(exists(Connection)))\r
+ )\r
+ ),\r
+\r
+ unless(\r
+ bf(mr.ConnectionToDiagramConnection, Component, Element),\r
+ // If the configuration connection does not have a correspondence in the diagram remove it\r
+ and(deny(exists(Component)))\r
+ )\r
+\r
+ )\r
+ )\r
+ );\r
+ }\r
+\r
+ @Override\r
+ protected IInstruction claimBasicConnection() {\r
+ return and(exists(\r
+ bf(mr.DiagramConnectionToConnection, Element, Connection),\r
+ Connection\r
+ ),\r
+ bb(b.InstanceOf, Connection, ComponentType),\r
+ bb(b.PartOf, Connection, Configuration),\r
+ b(mapped, Connection)\r
+\r
+ );\r
+ }\r
+ \r
+// @Override\r
+// protected IInstruction claimBasicConnection() {\r
+// return and(exists(\r
+// bf(mr.DiagramConnectionToConnection, Element, Connection),\r
+// Connection\r
+// ),\r
+// bb(b.InstanceOf, Connection, ComponentType),\r
+// b(mapped, Connection),\r
+// bb(b.PartOf, Connection, Configuration)\r
+// );\r
+// }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.IPropertyPage;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.diagram.adapter.FlagClassFactory;\r
+import org.simantics.diagram.handler.CopyPasteHandler;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.diagram.ui.WorkbenchSelectionProvider;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.CanvasContext;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.participant.DeleteHandler;\r
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
+import org.simantics.g2d.element.ElementClassProviders;\r
+import org.simantics.g2d.element.ElementClasses;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.IElementClassProvider;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.modeling.ui.diagramEditor.handlers.LinkBrowsingHandler;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements2.connections.ConnectionClasses;\r
+import org.simantics.sysdyn.ui.elements2.connections.SysdynConnectionClass;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.utils.datastructures.hints.HintContext;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.DiagramViewer {\r
+\r
+ protected String getPopupId() {\r
+ return "#SysdynDiagramPopup";\r
+ }\r
+\r
+ @Override\r
+ protected Set<String> getPropertyPageContexts() {\r
+ return Collections.singleton("http://www.simantics.org/Sysdyn-1.0/Browser");\r
+ }\r
+\r
+ @Override\r
+ protected IPropertyPage createPropertyPage(IWorkbenchPartSite site, Set<String> contexts) {\r
+ return new SysdynPropertyPage(site, contexts);\r
+ }\r
+\r
+ @Override\r
+ protected IElementClassProvider createElementClassProvider(ReadGraph graph) {\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ return ElementClassProviders.mappedProvider(\r
+ ElementClasses.CONNECTION, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)),\r
+ ElementClasses.FLAG, FlagClassFactory.createFlagClass(dr.Flag),\r
+ ConnectionClasses.FLOW, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection)),\r
+ ConnectionClasses.DEPENDENCY, SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.DependencyConnection))\r
+ );\r
+ \r
+ \r
+ }\r
+\r
+ @Override\r
+ protected void onCreated() {\r
+ sourceDiagram.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE);\r
+ }\r
+\r
+ @Override\r
+ protected void addKeyBindingParticipants(CanvasContext ctx) {\r
+ ctx.add(new DeleteHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+ ctx.add(new CopyPasteHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+ }\r
+\r
+ @Override\r
+ protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {\r
+ super.initializeSynchronizationContext(graph, context);\r
+\r
+ // Make sure SysdynResource is available.\r
+ SysdynResource.getInstance(graph);\r
+ }\r
+\r
+ @Override\r
+ protected void addStructureParticipants(ICanvasContext ctx) {\r
+\r
+ ctx.add(new WorkbenchSelectionProvider(swt, getSite()) {\r
+\r
+ @Override\r
+ protected ISelection constructAdaptableSelection(Iterable<?> selection) {\r
+ ArrayList<Object> objects = new ArrayList<Object>();\r
+ Resource runtime = sourceDiagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
+ for (Object o : selection) {\r
+ if (o instanceof IElement) {\r
+ IElement e = (IElement) o;\r
+ Object object = e.getHint(ElementHints.KEY_OBJECT);\r
+ if (object != null && runtime != null) {\r
+ IHintContext context = new AdaptableHintContext(SelectionHints.KEY_MAIN);\r
+ context.setHint(SelectionHints.KEY_MAIN, object);\r
+ if (runtime != null)\r
+ context.setHint(SelectionHints.KEY_VARIABLE_RESOURCE, runtime);\r
+ objects.add(context);\r
+ }\r
+ } else {\r
+ System.out.println(" unrecognized selection: " + o.getClass() + ": " + o);\r
+ }\r
+ }\r
+ if(objects.isEmpty() && runtime != null) {\r
+ HintContext context = new HintContext();\r
+ context.setHint(SelectionHints.KEY_VARIABLE_RESOURCE, runtime);\r
+ objects.add(context);\r
+ }\r
+ return new StructuredSelection(objects);\r
+ }\r
+\r
+ });\r
+ // Add visual browsing capabilities for structural models\r
+ \r
+// Remove double click handler, because it is not working properly\r
+// ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, getResourceInput2()));\r
+ ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));\r
+\r
+ }\r
+\r
+ @Override\r
+ protected void addOtherParticipants(CanvasContext ctx) {\r
+ }\r
+ \r
+ @Override \r
+ protected PointerInteractor getPointerInteractor() {\r
+ return new org.simantics.sysdyn.ui.editor.participant.PointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider());\r
+ }\r
+ \r
+ @Override\r
+ protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) {\r
+ return new SysdynConnectionAdvisor(modelingRules, sessionContext.getSession());\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.editor;\r
+\r
+\r
+public class OpenDiagramFromConfigurationAdapter extends org.simantics.modeling.ui.diagramEditor.OpenDiagramFromConfigurationAdapter {\r
+\r
+ private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+\r
+ public OpenDiagramFromConfigurationAdapter() {\r
+ super();\r
+ }\r
+\r
+ @Override\r
+ protected String getEditorId() {\r
+ return EDITOR_ID;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.content.ConnectionUtil;\r
+import org.simantics.diagram.content.ResourceTerminal;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.elementclass.FlagHandler;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.CPFlag;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgementType;\r
+import org.simantics.structural2.modelingRules.IConnectionPoint;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class SysdynConnectionAdvisor implements IConnectionAdvisor {\r
+\r
+ IModelingRules modelingRules;\r
+ RequestProcessor processor;\r
+\r
+ public SysdynConnectionAdvisor(IModelingRules modelingRules,\r
+ RequestProcessor processor) {\r
+ this.modelingRules = modelingRules;\r
+ this.processor = processor;\r
+ }\r
+\r
+ IConnectionPoint getConnectionPoint(ReadGraph g, IElement element, Terminal term) throws DatabaseException {\r
+ Object obj = null;\r
+ if (element != null)\r
+ obj = ElementUtils.getObject(element);\r
+\r
+ if (obj instanceof Resource) {\r
+ Resource elementResource = (Resource) obj;\r
+ return ConnectionUtil.toConnectionPoint(g, elementResource, term);\r
+ }\r
+\r
+ if(element.getElementClass().containsClass(FlagHandler.class)) {\r
+ return new CPFlag(null);\r
+ }\r
+\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public Object canBeConnected(Object backend,\r
+ final IElement element1, final Terminal term1,\r
+ final IElement element2, final Terminal term2) {\r
+ try {\r
+ if(backend == null)\r
+ backend = processor;\r
+ return ((RequestProcessor)backend).syncRequest(new Read<Object>() {\r
+\r
+ @Override\r
+ public Object perform(ReadGraph g) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ DiagramResource dr = DiagramResource.getInstance(g);\r
+ StructuralResource2 str2 = StructuralResource2.getInstance(g);\r
+ Resource terminal2 = ((ResourceTerminal) term2).getResource();\r
+ Resource connectionVariable = g.getPossibleObject(terminal2, dr.HasConnectionVariable);\r
+ if(!g.hasStatement(connectionVariable, str2.Binds, sr.IsHeadOfTerminal)) {\r
+ return null;\r
+ }\r
+\r
+ // Only one incoming dependency allowed in inputs. That dependency must be from a module\r
+ Object obj1 = ElementUtils.getObject(element1);\r
+ Object obj2 = ElementUtils.getObject(element2);\r
+ if(obj2 instanceof Resource) {\r
+ Resource startElementResource = (Resource)obj1;\r
+ Resource endElementResource = (Resource)obj2;\r
+ if(g.isInstanceOf(endElementResource, sr.InputSymbol)) {\r
+ if(g.isInheritedFrom(startElementResource, sr.ModuleSymbol)) return null;\r
+ if(g.getObjects(endElementResource, sr.IsHeadOfTerminal).size() > 0) return null;\r
+ }\r
+ }\r
+\r
+ ArrayList<IConnectionPoint> cps = new ArrayList<IConnectionPoint>();\r
+ cps.add(getConnectionPoint(g, element1, term1));\r
+ if(element2 != null)\r
+ cps.add(getConnectionPoint(g, element2, term2));\r
+ ConnectionJudgement judgement = \r
+ modelingRules.judgeConnection(g, cps); \r
+ \r
+ if(judgement.type == ConnectionJudgementType.LEGAL)\r
+ return judgement.connectionType;\r
+ else\r
+ return null;\r
+ }\r
+\r
+ });\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ return null;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean canBeginConnection(Object backend,\r
+ final IElement element, final Terminal term) {\r
+ try {\r
+ if(backend == null)\r
+ backend = processor;\r
+ return ((RequestProcessor)backend).syncRequest(new Read<Boolean>() {\r
+\r
+ @Override\r
+ public Boolean perform(ReadGraph g) throws DatabaseException {\r
+ return modelingRules.judgeConnection(g,\r
+ Arrays.asList(getConnectionPoint(g, element, term)))\r
+ .type != ConnectionJudgementType.ILLEGAL;\r
+ }\r
+\r
+ });\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ return false;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.editor;\r
+\r
+import gnu.trove.TIntIntHashMap;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.URIStringUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;\r
+import org.simantics.modeling.services.ComponentNamingUtil;\r
+import org.simantics.modeling.services.NamingException;\r
+import org.simantics.project.IProject;\r
+\r
+public class SysdynCreationInstruction extends CreationInstruction {\r
+\r
+ IProject project;\r
+ Resource configurationRoot;\r
+ int lComponentType;\r
+ int lConfiguration;\r
+\r
+ public SysdynCreationInstruction(IProject project, Resource configurationRoot, int variableId, int componentType,\r
+ int configuration) {\r
+ super(variableId);\r
+ this.project = project;\r
+ this.configurationRoot = configurationRoot;\r
+ lComponentType = componentType;\r
+ lConfiguration = configuration;\r
+ }\r
+\r
+ @Override\r
+ public Resource create(WriteGraph g, Object[] bindings) throws DatabaseException {\r
+ Resource componentType = (Resource) bindings[lComponentType];\r
+ Resource configuration = (Resource) bindings[lConfiguration];\r
+\r
+ try {\r
+ String proposition = URIStringUtils.escape(ComponentNamingUtil.findFreshInstanceName(g, project, configurationRoot, configuration, componentType));\r
+ Resource result = GraphUtils.create(g,\r
+ g.getBuiltins().HasName, proposition\r
+ );\r
+ return result;\r
+ } catch (NamingException e1) {\r
+ throw new DatabaseException(e1);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void mapVariables(TIntIntHashMap map) {\r
+ super.mapVariables(map);\r
+ lComponentType = map.get(lComponentType);\r
+ lConfiguration = map.get(lConfiguration);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.editor;\r
+\r
+import java.awt.Frame;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.awt.SWT_AWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorSite;\r
+import org.eclipse.ui.PartInitException;\r
+import org.simantics.browsing.ui.swt.IPropertyPage;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.diagram.DiagramTypeUtils;\r
+import org.simantics.diagram.symbolcontribution.ISymbolProvider;\r
+import org.simantics.h2d.canvas.EditorCanvas;\r
+import org.simantics.h2d.diagram.IDiagram;\r
+import org.simantics.h2d.diagram.IDiagramListener;\r
+import org.simantics.h2d.editor.ISelection;\r
+import org.simantics.h2d.editor.ISelectionListener;\r
+import org.simantics.h2d.editor.impl.DiagramEditor;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.IElementListener;\r
+import org.simantics.h2d.event.handler.DefaultEventHandlers;\r
+import org.simantics.layer0.utils.triggers.IActivation;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.objmap.IMapping;\r
+import org.simantics.objmap.IMappingListener;\r
+import org.simantics.objmap.MappingException;\r
+import org.simantics.objmap.Mappings;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.sysdyn.ui.actions.ConnectDependency;\r
+import org.simantics.sysdyn.ui.actions.ConnectFlow;\r
+import org.simantics.sysdyn.ui.actions.CreateAuxiliary;\r
+import org.simantics.sysdyn.ui.actions.CreateCloud;\r
+import org.simantics.sysdyn.ui.actions.CreateStock;\r
+import org.simantics.sysdyn.ui.actions.CreateValve;\r
+import org.simantics.sysdyn.ui.actions.OpenContextMenu;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorPart;\r
+import org.simantics.ui.workbench.TitleRequest;\r
+import org.simantics.ui.workbench.TitleUpdater;\r
+import org.simantics.utils.datastructures.Callable;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.jface.ActiveSelectionProvider;\r
+\r
+public class SysdynDiagramEditor extends ResourceEditorPart {\r
+\r
+ EditorCanvas canvas;\r
+ IDiagram diagram;\r
+ IMapping mapping;\r
+ Frame frame;\r
+ boolean disposed = false; \r
+ Composite frameComposite;\r
+ Resource diagramResource;\r
+ protected ISessionContextProvider sessionContextProvider;\r
+ protected ISessionContext sessionContext;\r
+ protected IActivation activation;\r
+\r
+ IElementListener elementUpdateListener = new IElementListener() {\r
+\r
+ @Override\r
+ public void elementUpdated(IElement element) {\r
+ mapping.rangeModified(element);\r
+ }\r
+\r
+ @Override\r
+ public void elementRemoved(IElement element) {\r
+ }\r
+ };\r
+\r
+ protected void readDiagram(ReadGraph g) throws DatabaseException {\r
+ SysdynDiagramSchema schema = new SysdynDiagramSchema(g);\r
+ mapping = Mappings.createWithListening(schema);\r
+\r
+ try {\r
+ diagram = (IDiagram)mapping.map(g, getInputResource());\r
+ for(IElement element : diagram.getElements())\r
+ element.addListener(elementUpdateListener);\r
+ } catch (MappingException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ final Session session = g.getSession();\r
+ mapping.addMappingListener(new IMappingListener() {\r
+\r
+ @Override\r
+ public void rangeModified() {\r
+ SwingUtilities.invokeLater(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ try {\r
+ session.syncRequest(new WriteRequest() { \r
+ @Override\r
+ public void perform(WriteGraph graph)\r
+ throws DatabaseException {\r
+ mapping.updateDomain(graph);\r
+ } \r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ } \r
+ }\r
+\r
+ }); \r
+ }\r
+\r
+ @Override\r
+ public void domainModified() {\r
+ SwingUtilities.invokeLater(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ try {\r
+ session.syncRequest(new ReadRequest() { \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ mapping.updateRange(graph);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ } \r
+ }\r
+\r
+ }); \r
+ }\r
+\r
+ });\r
+\r
+ diagram.addDiagramListener(new IDiagramListener() {\r
+\r
+ @Override\r
+ public void elementAdded(IElement element) {\r
+ mapping.rangeModified(diagram); \r
+ element.addListener(elementUpdateListener);\r
+ }\r
+\r
+ @Override\r
+ public void elementRemoved(IElement element) {\r
+ mapping.rangeModified(element);\r
+ mapping.rangeModified(diagram); \r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void init(IEditorSite site, IEditorInput input)\r
+ throws PartInitException {\r
+ super.init(site, input);\r
+\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
+\r
+ @Override\r
+ public void run(ReadGraph g) throws DatabaseException {\r
+ diagramResource = g.getSingleObject(getInputResource(), ModelingResources.getInstance(g).CompositeToDiagram);\r
+ readDiagram(g); \r
+ }\r
+\r
+ });\r
+\r
+ SimanticsUI.getSession().asyncRequest(\r
+ new TitleRequest(site.getId(), getResourceInput()) {\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ Resource r = graph.getSingleObject(\r
+ getResourceInput().getResource(),\r
+ b.IsConfigurationOf);\r
+ String label = graph.getPossibleRelatedValue(r, b.HasLabel);\r
+ return label;\r
+ }\r
+ },\r
+ new TitleUpdater(site.getShell().getDisplay(), new Callback<String>() {\r
+ @Override\r
+ public void run(String partName) {\r
+ setPartName(partName);\r
+ }\r
+ }, new Callable<Boolean>() {\r
+ @Override\r
+ public Boolean call() {\r
+ return disposed;\r
+ }\r
+ }));\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void createPartControl(final Composite parent) {\r
+ frameComposite = new Composite(parent, \r
+ SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+ frame = SWT_AWT.new_Frame(frameComposite);\r
+ \r
+ \r
+ /// KOKEILLAAN\r
+ \r
+ /*\r
+ sessionContextProvider = SimanticsUI.getSessionContextProvider();\r
+ sessionContext = sessionContextProvider.getSessionContext();\r
+\r
+ IActivationManager activationManager = sessionContext.getSession().peekService(IActivationManager.class);\r
+ if (activationManager != null) {\r
+ activation = activationManager.activate(diagramResource);\r
+ }\r
+ */\r
+ /// LOPPUU\r
+\r
+ final ActiveSelectionProvider selectionProvider = new ActiveSelectionProvider();\r
+ getSite().setSelectionProvider(selectionProvider);\r
+\r
+ final OpenContextMenu openContextMenu = new OpenContextMenu(\r
+ parent, getSite(), "#SysdynDiagramPopup");\r
+\r
+ SwingUtilities.invokeLater(new Runnable() {\r
+\r
+ @Override\r
+ public void run() { \r
+ DiagramEditor editor = new DiagramEditor(null, diagram); \r
+\r
+ DefaultEventHandlers.configure(editor);\r
+ editor.addEventHandler(1, "key(A)", new CreateAuxiliary());\r
+ editor.addEventHandler(1, "key(S)", new CreateStock());\r
+ editor.addEventHandler(1, "key(V)", new CreateValve());\r
+ editor.addEventHandler(1, "key(C)", new CreateCloud());\r
+ editor.addEventHandler(1, "drag(alt+left)", new ConnectDependency());\r
+ editor.addEventHandler(1, "drag(alt+right)", new ConnectFlow());\r
+ editor.addEventHandler(1, "release(right)", openContextMenu); \r
+\r
+ canvas = new EditorCanvas(editor);\r
+ frame.add(canvas);\r
+\r
+ frameComposite.getDisplay().asyncExec(new Runnable() { \r
+ @Override\r
+ public void run() {\r
+ setFocus();\r
+ }\r
+ });\r
+\r
+\r
+ editor.getSelection().addSelectionListener(new ISelectionListener() {\r
+\r
+ @Override\r
+ public void selectionChanged(ISelection selection) {\r
+ final ArrayList<Resource> resources = new ArrayList<Resource>(selection.size());\r
+ for(IElement element : selection)\r
+ resources.add(mapping.inverseGet(element));\r
+ frameComposite.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ if(!frameComposite.isDisposed())\r
+ selectionProvider.setSelection(new StructuredSelection(resources));\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void setFocus() { \r
+ if(frameComposite != null && !frameComposite.isDisposed()) {\r
+ frameComposite.setFocus();\r
+ if(canvas!=null)\r
+ canvas.requestFocus();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ mapping.dispose();\r
+ frame.dispose();\r
+ disposed = true;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public Object getAdapter(Class adapter) {\r
+ if (adapter == INode.class) {\r
+ return canvas.getEditor().getSceneGraph();\r
+ }\r
+ if (adapter == ISymbolProvider.class) {\r
+ try {\r
+\r
+ return DiagramTypeUtils.readSymbolContributions(SimanticsUI.getSession(), diagramResource);\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogError(getClass() + " failed to adapt to ISymbolProvider, see exception for details.", e);\r
+ return null;\r
+ }\r
+ }\r
+ if (adapter == IPropertyPage.class) {\r
+ return new SysdynPropertyPage(getSite(), Collections.singleton("http://www.simantics.org/Sysdyn-1.0/Browser"));\r
+ }\r
+ return super.getAdapter(adapter);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.editor;\r
+\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.h2d.diagram.Diagram;\r
+import org.simantics.objmap.rules.MappedElementsRule;\r
+import org.simantics.objmap.rules.domain.RelatedObjectsAccessor;\r
+import org.simantics.objmap.rules.range.FieldAccessor;\r
+import org.simantics.objmap.schema.MappingSchemas;\r
+import org.simantics.objmap.schema.SimpleLinkType;\r
+import org.simantics.objmap.schema.SimpleSchema;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryElement;\r
+import org.simantics.sysdyn.ui.elements.CloudElement;\r
+import org.simantics.sysdyn.ui.elements.DependencyElement;\r
+import org.simantics.sysdyn.ui.elements.FlowElement;\r
+import org.simantics.sysdyn.ui.elements.StockElement;\r
+import org.simantics.sysdyn.ui.elements.ValveElement;\r
+\r
+public class SysdynDiagramSchema extends SimpleSchema {\r
+\r
+ public SysdynDiagramSchema(ReadGraph g) throws DatabaseException {\r
+ Builtins b = g.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ try {\r
+ {\r
+ SimpleLinkType linkType = \r
+ new SimpleLinkType(sr.Configuration, Diagram.class);\r
+ linkType.addRule(new MappedElementsRule(\r
+ new RelatedObjectsAccessor(b.ConsistsOf, true),\r
+ new FieldAccessor<Collection<Object>>(Diagram.class.getField("elements"))\r
+ ));\r
+ addLinkType(linkType);\r
+ } \r
+ \r
+ addLinkType(MappingSchemas.fromAnnotations(g, AuxiliaryElement.class)); \r
+ addLinkType(MappingSchemas.fromAnnotations(g, StockElement.class));\r
+ addLinkType(MappingSchemas.fromAnnotations(g, CloudElement.class));\r
+ addLinkType(MappingSchemas.fromAnnotations(g, ValveElement.class));\r
+ addLinkType(MappingSchemas.fromAnnotations(g, DependencyElement.class));\r
+ addLinkType(MappingSchemas.fromAnnotations(g, FlowElement.class));\r
+ } catch(NoSuchFieldException e) {\r
+ e.printStackTrace();\r
+ } catch (InstantiationException e) {\r
+ e.printStackTrace();\r
+ } catch (IllegalAccessException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.awt.AlphaComposite;\r
+import java.awt.Composite;\r
+import java.awt.geom.Point2D;\r
+import java.util.ArrayDeque;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Deque;\r
+import java.util.HashMap;\r
+import java.util.List;\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.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGCleanup;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\r
+import org.simantics.g2d.command.CommandEvent;\r
+import org.simantics.g2d.command.Commands;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.connection.handler.ConnectionHandler;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.DiagramMutator;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.PickContext;\r
+import org.simantics.g2d.diagram.handler.Topology;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
+import org.simantics.g2d.diagram.handler.TransactionContext.TransactionType;\r
+import org.simantics.g2d.diagram.impl.Diagram;\r
+import org.simantics.g2d.diagram.impl.MutatedDiagram;\r
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
+import org.simantics.g2d.diagram.participant.ElementPainter;\r
+import org.simantics.g2d.diagram.participant.TerminalPainter;\r
+import org.simantics.g2d.diagram.participant.TerminalPainter.TerminalHoverStrategy;\r
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.Parent;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.elementclass.BranchPoint;\r
+import org.simantics.g2d.elementclass.FlagClass;\r
+import org.simantics.g2d.elementclass.FlagHandler;\r
+import org.simantics.g2d.event.Event;\r
+import org.simantics.g2d.event.KeyEvent;\r
+import org.simantics.g2d.event.MouseEvent;\r
+import org.simantics.g2d.event.EventHandlerReflection.EventHandler;\r
+import org.simantics.g2d.event.KeyEvent.KeyPressedEvent;\r
+import org.simantics.g2d.event.MouseEvent.MouseButtonEvent;\r
+import org.simantics.g2d.event.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.g2d.event.MouseEvent.MouseMovedEvent;\r
+import org.simantics.g2d.participant.KeyUtil;\r
+import org.simantics.g2d.participant.MouseUtil;\r
+import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.g2d.snap.ISnapAdvisor;\r
+import org.simantics.scenegraph.Node;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+public class ConnectTool extends AbstractDiagramParticipant {\r
+\r
+\r
+ public static final Key KEY_SG_NODE = new SceneGraphNodeKey(Node.class, "CONNECT_SG_NODE");\r
+\r
+ @Dependency TransformUtil util;\r
+ @Dependency ElementPainter diagramPainter;\r
+ @Dependency PickContext pickContext;\r
+ @Dependency PointerInteractor pi;\r
+ @Dependency MouseUtil mouseUtil;\r
+ @Dependency KeyUtil keys;\r
+\r
+ boolean createFlags;\r
+ Point2D startPos;\r
+\r
+ IElement startElement;\r
+ Terminal startTerminal;\r
+\r
+ IElement endElement;\r
+ Terminal endTerminal;\r
+\r
+ IDiagram inputDiagram;\r
+ MutatedDiagram ghostDiagram;\r
+ Topology topology;\r
+\r
+ ElementClass connectionClass;\r
+\r
+ ConnectionHandler connectionHandler;\r
+ IElement connection;\r
+ Deque<IElement> edges = new ArrayDeque<IElement>();\r
+ Deque<IElement> controlPoints = new ArrayDeque<IElement>();\r
+ int mouseId;\r
+\r
+ Collection<Terminal> terminals = new ArrayList<Terminal>();\r
+\r
+ TerminalHoverStrategy originalStrategy = null;\r
+ TerminalHoverStrategy terminalHoverStrategy = new TerminalHoverStrategy() {\r
+ @Override\r
+ public boolean highlightEnabled() {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean highlight(TerminalInfo ti) {\r
+ IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
+ return canConnect(advisor, ti.e, ti.t) != null;\r
+ }\r
+ };\r
+\r
+ public ConnectTool(IDiagram diagram, ElementClass connectionClass, IElement startElement, Terminal startTerminal, int mouseId, Point2D mouseDiagramPos)\r
+ {\r
+ this.inputDiagram = diagram;\r
+ this.connectionClass = connectionClass;\r
+ this.mouseId = mouseId;\r
+ this.startPos = mouseDiagramPos;\r
+ this.startElement = startElement;\r
+ this.startTerminal = startTerminal;\r
+ }\r
+\r
+ @Override\r
+ public void addedToContext(ICanvasContext ctx) {\r
+\r
+ super.addedToContext(ctx);\r
+\r
+ // Force terminals to always be highlighted.\r
+ originalStrategy = getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY);\r
+ setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, terminalHoverStrategy);\r
+\r
+ // See if flags should be created or not\r
+ this.createFlags = Boolean.TRUE.equals(inputDiagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS));\r
+\r
+ // Mutate current diagram and add the connection to the mutated copy.\r
+ ghostDiagram = Diagram.mutate(inputDiagram);\r
+ topology = ghostDiagram.getDiagramClass().getSingleItem(Topology.class);\r
+\r
+ IElement firstElement = null;\r
+ Terminal firstTerminal = null;\r
+\r
+ // Where is start terminal?\r
+ if (startElement != null && startTerminal != null) {\r
+ // Whoomp, there it is. Is it already a part of an existing connection?\r
+ assert ElementUtils.peekDiagram(startElement) == inputDiagram;\r
+ IElement possibleConnection = getConnectionFromPart(startElement);\r
+ if (possibleConnection != null) {\r
+ // TODO: broken.\r
+ connection = ghostDiagram.getMutatedCorrespondence(possibleConnection);\r
+ } else {\r
+ connection = createConnection(connectionClass);\r
+ ghostDiagram.addElement(connection);\r
+ }\r
+\r
+ connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class);\r
+ assert connectionHandler != null;\r
+\r
+ firstElement = ghostDiagram.getMutatedCorrespondence(startElement);\r
+ firstTerminal = startTerminal;\r
+ } else {\r
+ connection = createConnection(connectionClass);\r
+ connectionHandler = connection.getElementClass().getSingleItem(ConnectionHandler.class);\r
+ assert connectionHandler != null;\r
+ ghostDiagram.addElement(connection);\r
+\r
+ firstElement = createBranchPointOrFlag(startPos, EdgeEnd.Begin);\r
+ firstTerminal = ElementUtils.getSingleTerminal(firstElement);\r
+ startElement = firstElement;\r
+ startTerminal = firstTerminal;\r
+ }\r
+\r
+ IElement secondElement = connectionHandler.newBranchPoint(connection);\r
+ controlPoints.add(secondElement);\r
+// ghostDiagram.addElement(secondElement);\r
+ ElementUtils.setPos(secondElement, startPos);\r
+ Terminal secondTerminal = ElementUtils.getSingleTerminal(secondElement);\r
+\r
+ IElement edge = connectionHandler.newEdge(connection);\r
+ edges.add(edge);\r
+// ghostDiagram.addElement(edge);\r
+\r
+ topology.connect(edge, EdgeEnd.Begin, firstElement, firstTerminal);\r
+ topology.connect(edge, EdgeEnd.End, secondElement, secondTerminal);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void removedFromContext(ICanvasContext ctx) {\r
+\r
+ if (getHint(TerminalPainter.TERMINAL_HOVER_STRATEGY) == terminalHoverStrategy) {\r
+ if (originalStrategy != null)\r
+ setHint(TerminalPainter.TERMINAL_HOVER_STRATEGY, originalStrategy);\r
+ else\r
+ removeHint(TerminalPainter.TERMINAL_HOVER_STRATEGY);\r
+ }\r
+\r
+ ghostDiagram.destroy();\r
+\r
+ super.removedFromContext(ctx);\r
+ }\r
+\r
+ final static Composite ALPHA_COMPOSITE = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.75f);\r
+ public static final int PAINT_PRIORITY = ElementPainter.ELEMENT_PAINT_PRIORITY + 5;\r
+\r
+ protected G2DParentNode node = null;\r
+\r
+ @SGInit\r
+ public void initSG(G2DParentNode parent) {\r
+ node = parent.addNode(G2DParentNode.class);\r
+ node.setZIndex(PAINT_PRIORITY);\r
+ update();\r
+ }\r
+\r
+ public void update() {\r
+ if (ghostDiagram != null) {\r
+ diagramPainter.paintDiagram(node, ghostDiagram, ghostDiagram.getDifferences(), KEY_SG_NODE);\r
+ }\r
+ }\r
+\r
+ @SGCleanup\r
+ public void cleanupSG() {\r
+ node.remove();\r
+ node = null;\r
+ }\r
+\r
+ boolean cancelPreviousBend() {\r
+ if (!routePointsAllowed())\r
+ return false;\r
+\r
+ // If not at the first branch point, remove the last branch\r
+ // point and edge. Otherwise, cancel action\r
+ if (controlPoints.size() < 2) {\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ mutator.clear();\r
+ update();\r
+ remove();\r
+ return true;\r
+ }\r
+ // Cancel prev bend\r
+ IElement lastControlPoint = controlPoints.removeLast();\r
+ IElement prevControlPoint = controlPoints.peekLast();\r
+ IElement lastEdge = edges.removeLast();\r
+ for (Terminal t : ElementUtils.getTerminals(lastControlPoint, terminals, true))\r
+ topology.disconnect(lastEdge, EdgeEnd.End, lastControlPoint, t);\r
+ for (Terminal t : ElementUtils.getTerminals(prevControlPoint, terminals, true))\r
+ topology.disconnect(lastEdge, EdgeEnd.Begin, prevControlPoint, t);\r
+ connectionHandler.removeBranchPoint(connection, lastControlPoint);\r
+ connectionHandler.removeEdge(connection, lastEdge);\r
+ Point2D mousePos = mouseUtil.getMouseInfo(mouseId).canvasPosition;\r
+ ElementUtils.setPos(controlPoints.peekLast(), mousePos);\r
+ DiagramUtils.validateAndFix(ghostDiagram, getContext());\r
+ update();\r
+ setDirty();\r
+ return true;\r
+ }\r
+\r
+ @EventHandler(priority = 20)\r
+ public boolean handleEvent(Event e) {\r
+ // Back-space, cancel prev bend\r
+ if (e instanceof KeyPressedEvent) {\r
+ KeyEvent ke = (KeyEvent) e;\r
+ if (ke.keyCode == java.awt.event.KeyEvent.VK_BACK_SPACE) {\r
+ return cancelPreviousBend();\r
+ }\r
+ }\r
+ if (e instanceof CommandEvent) {\r
+ CommandEvent ce = (CommandEvent) e;\r
+ if (ce.command.equals(Commands.CANCEL))\r
+ {\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ mutator.clear();\r
+ update();\r
+ remove();\r
+ return true;\r
+ }\r
+ }\r
+ if (e instanceof MouseMovedEvent) {\r
+ MouseMovedEvent me = (MouseMovedEvent) e;\r
+ Point2D mouseControlPos = me.controlPosition;\r
+ Point2D mouseCanvasPos = util.controlToCanvas(mouseControlPos, new Point2D.Double());\r
+\r
+ ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR);\r
+ if (snapAdvisor != null)\r
+ snapAdvisor.snap(mouseCanvasPos);\r
+\r
+ List<TerminalInfo> tiList = ((org.simantics.sysdyn.ui.editor.participant.PointerInteractor)pi).pickTerminals(me.controlPosition);\r
+ TerminalInfo ti = null;\r
+\r
+ IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
+ for(TerminalInfo info : tiList) {\r
+ if(advisor == null || info.e == null || info.t == null)\r
+ continue;\r
+ Object canConnect = canConnect(advisor, info.e, info.t);\r
+ if (canConnect != null) {\r
+ connection.setHint(ElementHints.KEY_CONNECTION_TYPE, canConnect);\r
+ ti = info;\r
+ }\r
+ }\r
+\r
+ if (ti != null && !(ti.e == startElement && ti.t == startTerminal)) {\r
+ if (endElement == null) {\r
+ endElement = ti.e;\r
+ endTerminal = ti.t;\r
+\r
+ IElement lastControlPoint = controlPoints.pollLast();\r
+ topology.disconnect(edges.peekLast(), EdgeEnd.End, lastControlPoint, ElementUtils.getSingleTerminal(lastControlPoint));\r
+ connectionHandler.removeBranchPoint(connection, lastControlPoint);\r
+\r
+ topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal);\r
+ DiagramUtils.validateAndFix(ghostDiagram, getContext());\r
+ } else if (!ti.e.equals(endElement) || !ti.t.equals(endTerminal)) {\r
+ topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal);\r
+\r
+ endElement = ti.e;\r
+ endTerminal = ti.t;\r
+\r
+ topology.connect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal);\r
+ DiagramUtils.validateAndFix(ghostDiagram, getContext());\r
+ }\r
+\r
+ update();\r
+ setDirty();\r
+ return false;\r
+ }\r
+\r
+ {\r
+ connection.removeHint(ElementHints.KEY_CONNECTION_TYPE);\r
+ if (endElement != null) {\r
+ topology.disconnect(edges.peekLast(), EdgeEnd.End, ghostDiagram.getMutatedCorrespondence(endElement), endTerminal);\r
+\r
+ endElement = null;\r
+ endTerminal = null;\r
+\r
+ IElement bp = connectionHandler.newBranchPoint(connection);\r
+ controlPoints.add(bp);\r
+// ghostDiagram.addElement(bp);\r
+ ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos);\r
+\r
+ topology.connect(edges.peekLast(), EdgeEnd.End, bp, ElementUtils.getSingleTerminal(bp));\r
+ } else {\r
+ ElementUtils.setPos(controlPoints.peekLast(), mouseCanvasPos);\r
+ }\r
+ DiagramUtils.validateAndFix(ghostDiagram, getContext());\r
+\r
+ update();\r
+ setDirty();\r
+ }\r
+\r
+ }\r
+\r
+ if (e instanceof MouseButtonPressedEvent) {\r
+ MouseButtonEvent me = (MouseButtonEvent) e;\r
+ if (me.button==MouseEvent.LEFT_BUTTON && me.mouseId==mouseId) {\r
+ Point2D mouseControlPos = me.controlPosition;\r
+ Point2D mouseCanvasPos = util.getInverseTransform().transform(mouseControlPos, new Point2D.Double());\r
+\r
+ ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR);\r
+ if (snapAdvisor != null)\r
+ snapAdvisor.snap(mouseCanvasPos);\r
+\r
+ // Clicked on a terminal .. End connection, End mode\r
+ if (endElement != null) {\r
+ attachToBranchPoint();\r
+ commitDiagram();\r
+ update();\r
+ remove(); // Remove ConnectTool participant\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Don't let any events slip to creator participant\r
+ if (e instanceof MouseEvent) {\r
+ MouseEvent me = (MouseEvent) e;\r
+ return me.mouseId == mouseId;\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ private void attachToBranchPoint() {\r
+ DiagramUtils.inDiagramTransaction(diagram, TransactionType.WRITE, new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+\r
+ // We are attaching to a branch point - some reordering is needed!\r
+ if (endElement.getElementClass().containsClass(BranchPoint.class)) {\r
+\r
+ // Scrap everything we have and reconstruct\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ mutator.clear();\r
+\r
+ HashMap<IElement, IElement> bps = new HashMap<IElement, IElement>();\r
+ for(IElement bp : controlPoints) {\r
+ IElement nbp = mutator.newBranchPoint(endElement);\r
+ Point2D pos = ElementUtils.getPos(bp);\r
+ ElementUtils.setPos(nbp, pos);\r
+ bps.put(bp, nbp);\r
+ }\r
+\r
+ for(IElement edge : edges) {\r
+ IElement newEdge = mutator.newEdge(endElement);\r
+\r
+ // Disconnect and remove old edge\r
+ Connection b = mutator.getConnection(edge, EdgeEnd.Begin);\r
+ Connection e = mutator.getConnection(edge, EdgeEnd.End);\r
+\r
+ IElement mappedB = bps.get(b.node) != null ? bps.get(b.node) : b.node;\r
+ IElement mappedE = bps.get(e.node) != null ? bps.get(e.node) : e.node;\r
+\r
+ mutator.connect(newEdge, b.end, mappedB, b.terminal);\r
+ mutator.connect(newEdge, e.end, mappedE, e.terminal);\r
+ }\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ private void commitDiagram() {\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ mutator.commit();\r
+ }\r
+\r
+ FlagClass.Type endToFlagType(EdgeEnd end) {\r
+ switch (end) {\r
+ case Begin: return FlagClass.Type.In;\r
+ case End: return FlagClass.Type.Out;\r
+ default: throw new IllegalArgumentException("unrecognized edge end: " + end);\r
+ }\r
+ }\r
+\r
+ IElement createConnection(ElementClass element) {\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ return mutator.newConnection(element);\r
+ }\r
+\r
+ IElement createFlag(Point2D pos, EdgeEnd connectionEnd) {\r
+\r
+ DiagramMutator mutator = diagram.getHint(DiagramHints.KEY_MUTATOR);\r
+ IElement e = mutator.newFlag();\r
+\r
+ FlagHandler fh = e.getElementClass().getSingleItem(FlagHandler.class);\r
+ fh.setType(e, endToFlagType(connectionEnd));\r
+ //fh.setMode(e, FlagClass.Mode.Internal);\r
+ ElementUtils.setPos(e, pos);\r
+\r
+ ghostDiagram.addElement(e);\r
+\r
+ return e;\r
+\r
+ }\r
+\r
+ /**\r
+ * Try to get a connection element from a connection part element.\r
+ *\r
+ * @param e a potential connection part\r
+ * @return <code>null</code> if e is not part a part of a connection.\r
+ */\r
+ IElement getConnectionFromPart(IElement e) {\r
+ Parent parent = e.getElementClass().getAtMostOneItemOfClass(Parent.class);\r
+ if (parent == null)\r
+ return null;\r
+ IElement p = parent.getParent(e);\r
+ if (!p.getElementClass().containsClass(ConnectionHandler.class))\r
+ return null;\r
+ return p;\r
+ }\r
+\r
+ IElement createBranchPointOrFlag(Point2D pos, EdgeEnd connectionEnd) {\r
+ IElement e = null;\r
+ if (createFlags) {\r
+ e = createFlag(pos, connectionEnd);\r
+ } else {\r
+ e = connectionHandler.newBranchPoint(connection);\r
+ ElementUtils.setPos(e, pos);\r
+ }\r
+ return e;\r
+ }\r
+\r
+ boolean routePointsAllowed() {\r
+ return Boolean.TRUE.equals(diagram.getHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS));\r
+ }\r
+\r
+ Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) {\r
+ if(startElement.equals(endElement)) return null;\r
+ \r
+ try {\r
+ return SimanticsUI.getSession().syncRequest(new Read<Object>() {\r
+\r
+ @Override\r
+ public Object perform(ReadGraph g) throws DatabaseException {\r
+ \r
+ // Checking if connection type can be connected to the intended endElement\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ if(connection != null) {\r
+ StaticObjectAdapter soa = connectionClass.getSingleItem(StaticObjectAdapter.class);\r
+ Resource conntype = soa.adapt(Resource.class);\r
+ soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class);\r
+ Resource end = soa.adapt(Resource.class);\r
+ if(conntype.equals(sr.DependencyConnection)) {\r
+ if(end.equals(sr.CloudSymbol)) return null;\r
+ //if(!(end.equals(sr.AuxiliarySymbol) || end.equals(sr.ValveSymbol))) return null;\r
+ } else if (conntype.equals(sr.FlowConnection)) {\r
+ if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null;\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ \r
+ if (advisor == null)\r
+ return Boolean.TRUE; \r
+ return advisor.canBeConnected(g, startElement, startTerminal, endElement, endTerminal);\r
+ }\r
+\r
+ });\r
+ } catch(DatabaseException e) {\r
+ e.printStackTrace();\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.editor.participant;\r
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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
+\r
+import java.awt.Shape;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.List;\r
+\r
+import org.simantics.g2d.canvas.Hints;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Reference;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.handler.PickContext;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.diagram.participant.TerminalPainter;\r
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;\r
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.IElementClassProvider;\r
+import org.simantics.g2d.event.MouseEvent;\r
+import org.simantics.g2d.event.EventHandlerReflection.EventHandler;\r
+import org.simantics.g2d.event.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.g2d.participant.KeyUtil;\r
+import org.simantics.g2d.participant.MouseUtil;\r
+import org.simantics.g2d.participant.TransformUtil;\r
+import org.simantics.g2d.routing.RouterFactory;\r
+import org.simantics.g2d.utils.GeometryUtils;\r
+import org.simantics.sysdyn.ui.elements2.AuxiliaryFactory;\r
+import org.simantics.sysdyn.ui.elements2.CloudFactory;\r
+import org.simantics.sysdyn.ui.elements2.connections.ConnectionClasses;\r
+\r
+/**\r
+ * Pointer tool does the following operations with mouse:\r
+ * - Selections\r
+ * - Scale\r
+ * - Rotate\r
+ * - Translate\r
+ * - Draws connections\r
+ *\r
+ *\r
+ * Pointer tool is active only when KEY_TOOLMODE is PointerToolMode\r
+ *\r
+ * TODO Pick rectangle not a point\r
+ *\r
+ * @author Toni Kalajainen\r
+ */\r
+public class PointerInteractor extends org.simantics.g2d.diagram.participant.pointertool.PointerInteractor {\r
+\r
+ @Dependency Selection selection;\r
+ @Dependency KeyUtil keys;\r
+ @Dependency TransformUtil util;\r
+ @Dependency PickContext pickContext;\r
+ @Dependency MouseUtil mice;\r
+ @Reference TerminalPainter terminalPainter;\r
+\r
+ public PointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider) {\r
+ super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider);\r
+ }\r
+\r
+ @EventHandler(priority = TOOL_PRIORITY)\r
+ public boolean handlePress(MouseButtonPressedEvent me) {\r
+ if (!connects()) return false;\r
+// if (me.button != MouseEvent.LEFT_BUTTON) return false;\r
+ if (getHint(Hints.KEY_TOOL) != Hints.POINTERTOOL) return false;\r
+ assertDependencies();\r
+ Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null);\r
+ \r
+ // Pick Terminal\r
+ TerminalInfo ti = pickTerminal(me.controlPosition);\r
+ \r
+ if(ti != null && elementClassProvider != null) {\r
+ \r
+ IElement terminalElement = ti.e;\r
+ \r
+ ElementClass connectionClass = null;\r
+ if( me.button == MouseEvent.LEFT_BUTTON && (me.stateMask & MouseEvent.ALT_MASK) != 0) {\r
+ if(terminalElement.getElementClass().getId().equals(CloudFactory.class.getSimpleName())) return false;\r
+ diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false));\r
+ connectionClass = elementClassProvider.get(ConnectionClasses.DEPENDENCY);\r
+ \r
+ } else if (me.button == MouseEvent.RIGHT_BUTTON && (me.stateMask & MouseEvent.ALT_MASK) != 0) {\r
+ if(terminalElement.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName())) return false;\r
+ diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(true, true));\r
+ connectionClass = elementClassProvider.get(ConnectionClasses.FLOW);\r
+ } else {\r
+ return false;\r
+ }\r
+ \r
+ ConnectTool bsi = null;\r
+ if (ti != null) {\r
+ IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
+ if (advisor == null || (advisor != null && advisor.canBeginConnection(null, ti.e, ti.t))) {\r
+ bsi = new ConnectTool(diagram, connectionClass, ti.e, ti.t, me.mouseId, curCanvasPos);\r
+ }\r
+ } \r
+ /* Cannot be null\r
+ else {\r
+ ISnapAdvisor snapAdvisor = getHint(DiagramHints.SNAP_ADVISOR);\r
+ if(snapAdvisor != null) \r
+ snapAdvisor.snap(curCanvasPos);\r
+\r
+ // Start connection out of thin air, without a terminal.\r
+ bsi = new ConnectTool(diagram, elementClassProvider.get(ConnectionClasses.DEPENDENCY), null, null, me.mouseId, curCanvasPos);\r
+ }\r
+ */\r
+ if (bsi != null) {\r
+ getContext().add(bsi);\r
+ return true;\r
+ }\r
+ \r
+ }\r
+ return false;\r
+ }\r
+ \r
+ public List<TerminalInfo> pickTerminals(Point2D controlPos)\r
+ {\r
+ Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-PointerInteractor.PICK_DIST, controlPos.getY()-PointerInteractor.PICK_DIST, PointerInteractor.PICK_DIST*2+1, PointerInteractor.PICK_DIST*2+1);\r
+ Shape canvasPickRect = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform());\r
+ List<TerminalInfo> ti = TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true);\r
+ return ti;\r
+ }\r
+\r
+ /**\r
+ * Paint bend handles. Handle is a selectable and draggable object.\r
+ *\r
+ * @param gc\r
+ */\r
+// @Painter(priority = TerminalPainter.PAINT_PRIORITY + 10)\r
+// public void paintBendHandles(GraphicsContext gc) {\r
+// if (!connects()) return;\r
+// double controlScale = GeometryUtils.getScale(gc.getGraphics2D().getTransform());\r
+// // TODO: use another key for setting the bend point stroke color\r
+// //Color bgColor = getHint(Hints.KEY_BACKGROUND_COLOR);\r
+// Color bgColor = null;\r
+// if (bgColor==null) bgColor = Color.GRAY;\r
+// Graphics2D g = gc.createClone();\r
+// util.controlToCanvas(g);\r
+// if (!connects()) return;\r
+// ArrayList<Bend> bends = new ArrayList<Bend>();\r
+// AffineTransform _at = g.getTransform();\r
+// Point2D bendPos = new Point2D.Double();\r
+// for (IElement e : selection.getAllSelections())\r
+// {\r
+// BendsHandler bh = e.getElementClass().getAtMostOneItemOfClass(BendsHandler.class);\r
+// if (bh==null) continue;\r
+// bends.clear(); bh.getBends(e, bends);\r
+// if (bends.isEmpty()) continue;\r
+// g.setTransform(_at);\r
+// g.transform( ElementUtils.getTransform(e) );\r
+// double scale = GeometryUtils.getScale( g.getTransform() );\r
+// for (Bend b : bends) {\r
+// bh.getBendPosition(e, b, bendPos);\r
+// g.translate(bendPos.getX(), bendPos.getY());\r
+// g.setColor(Color.WHITE);\r
+// g.scale(controlScale / scale, controlScale / scale);\r
+// g.fill(BENDS);\r
+// g.setColor(bgColor);\r
+// g.draw(BENDS);\r
+// g.scale(scale / controlScale, scale / controlScale);\r
+// g.translate(-bendPos.getX(), -bendPos.getY());\r
+// }\r
+// }\r
+// }\r
+// static final Shape BENDS = new Rectangle2D.Double(-5, -5, 11, 11);\r
+\r
+\r
+\r
+ // <SCALING>\r
+ /*\r
+ @EventHandler(priority = -1)\r
+ public boolean scaleKey(KeyEvent ke) {\r
+ boolean alt = (ke.stateMask & java.awt.event.MouseEvent.ALT_DOWN_MASK) != 0;\r
+ if (alt && ke.keyCode == java.awt.event.KeyEvent.VK_S) {\r
+ //ScaleMode sm = new ScaleMode(me.startCanvasPos, curCanvasPos, me.mouseId, elementsToScale);\r
+ //getContext().add(sm);\r
+ }\r
+ return false;\r
+ }\r
+ // </SCALING>\r
+ */\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+public class Arcs {\r
+\r
+ public static final double PI2 = Math.PI*2.0;\r
+ \r
+ /**\r
+ * Returns angle + 2PI * n such that the\r
+ * result is between -PI and PI.\r
+ */\r
+ public static double normalizeAngle(double angle) {\r
+ return Math.IEEEremainder(angle, PI2);\r
+ }\r
+ \r
+ /**\r
+ * Returns true, if three normalized angles are clockwise oriented.\r
+ */\r
+ public static boolean areClockwiseOrdered(double angle1, double angle2, double angle3) {\r
+ //System.out.println(angle1 + " " + angle2 + " " + angle3);\r
+ return angle1 < angle2 \r
+ ? (angle2 < angle3 || angle3 < angle1)\r
+ : (angle2 < angle3 && angle3 < angle1)\r
+ ;\r
+ }\r
+ \r
+ /**\r
+ * Returns an angle in radians between straight line from (x0,y0) to (x2,y2)\r
+ * and an arc from (x0,y0) to (x2,y2) thru (x1,y1). The angle\r
+ * is measured at (x0,y0) and is between -PI and PI.\r
+ */\r
+ public static double angleOfArc(\r
+ double x0, double y0, \r
+ double x1, double y1,\r
+ double x2, double y2) {\r
+ double dx0 = x1-x0;\r
+ double dy0 = y1-y0;\r
+ double dx1 = x1-x2;\r
+ double dy1 = y1-y2;\r
+ double dx = x2-x0;\r
+ double dy = y2-y0;\r
+ // Length of cross product (p1-p0)x(p2-p0)\r
+ double dd = dx0*dy - dy0*dx; \r
+ \r
+ if(Math.abs(dd) < 1e-6) // Points are (almost) collinear\r
+ return 0.0;\r
+ else { \r
+ // (p1-p0)*(p1-p2) / dd\r
+ double offset = (dx0*dx1 + dy0*dy1) / dd;\r
+ double angle = Math.PI*0.5 - Math.atan(offset);\r
+ if(dd > 0.0)\r
+ angle = angle-Math.PI;\r
+ return angle;\r
+ \r
+ }\r
+ }\r
+ \r
+ private static double updateBestNextAngle(double curAngle, double bestAngle, double newAngle) {\r
+ if(newAngle < curAngle)\r
+ newAngle += PI2;\r
+ if(newAngle < bestAngle)\r
+ return newAngle;\r
+ return bestAngle; \r
+ } \r
+ \r
+ private static double updateBestPrevAngle(double curAngle, double bestAngle, double newAngle) {\r
+ if(newAngle > curAngle)\r
+ newAngle -= PI2;\r
+ if(newAngle > bestAngle)\r
+ return newAngle;\r
+ return bestAngle; \r
+ } \r
+ \r
+ public static double nextIntersectingAngle(double cx, double cy, double r,\r
+ double curAngle, Rectangle2D rect, boolean dir) {\r
+ if(!dir) {\r
+ double bestAngle = curAngle + PI2;\r
+ {\r
+ double dx = rect.getMinX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dx = rect.getMaxX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMinY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMaxY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ return normalizeAngle(bestAngle);\r
+ } \r
+ else {\r
+ double bestAngle = curAngle - PI2;\r
+ {\r
+ double dx = rect.getMinX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dx = rect.getMaxX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMinY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMaxY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ return normalizeAngle(bestAngle);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import org.simantics.objmap.annotations.GraphType;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Auxiliary")\r
+public class AuxiliaryElement extends TextElement {\r
+ \r
+ public AuxiliaryElement() { \r
+ }\r
+ \r
+ public AuxiliaryElement(String label, double x, double y) {\r
+ super(label, x, y);\r
+ } \r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.geom.Path2D;\r
+\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.node.ShapeNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Cloud")\r
+public class CloudElement extends RectangularElement implements Connectable {\r
+ \r
+ public static final double CLOUD_SIZE_X = 5.0;\r
+ public static final double CLOUD_SIZE_Y = 3.0;\r
+ \r
+ public static final double CLOUD_CURVES = 7;\r
+ \r
+ ShapeNode cloudNode;\r
+ boolean rotated = false;\r
+ \r
+ public CloudElement() { \r
+ }\r
+ \r
+ public CloudElement(double x, double y) {\r
+ this.posX = x;\r
+ this.posY = y; \r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ cloudNode = parent.addNode(ShapeNode.class);\r
+ cloudNode.setColor(Color.BLACK);\r
+ cloudNode.setScaleStroke(true);\r
+ cloudNode.setStroke(new BasicStroke(1));\r
+ update();\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ cloudNode.remove();\r
+ }\r
+ \r
+ protected void update() {\r
+ //bounds.setFrame(posX-CLOUD_SIZE_X, posY-CLOUD_SIZE_Y, 2.0*CLOUD_SIZE_X, 2.0*CLOUD_SIZE_Y);\r
+ Path2D path = new Path2D.Double(); \r
+ double ox = CLOUD_SIZE_X;\r
+ double oy = 0.0;\r
+ path.moveTo(posX+ox, posY+oy); \r
+ for(int i=1;i<CLOUD_CURVES+1;++i) {\r
+ double angle = (Math.PI * 2.0 / CLOUD_CURVES) * i;\r
+ double x = Math.cos(angle) * CLOUD_SIZE_X;\r
+ double y = Math.sin(angle) * CLOUD_SIZE_Y;\r
+ path.curveTo(\r
+ posX+(2*ox + x)*0.5, posY+(2*oy + y)*0.5,\r
+ posX+(ox + 2*x)*0.5, posY+(oy + 2*y)*0.5,\r
+ posX + x, posY + y);\r
+ ox = x;\r
+ oy = y;\r
+ }\r
+ cloudNode.setShape(path);\r
+ bounds = path.getBounds2D();\r
+ fireElementUpdated();\r
+ }\r
+\r
+ public boolean isRotated() {\r
+ return rotated;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Shape;\r
+import java.awt.geom.Arc2D;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.Element;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.IElementListener;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.event.DragEvent;\r
+import org.simantics.h2d.event.handler.DragEventHandler;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.h2d.node.FilledShapeNode;\r
+import org.simantics.h2d.node.ShapeNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.objmap.annotations.RelatedElement;\r
+import org.simantics.objmap.annotations.RelatedValue;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Dependency")\r
+public class DependencyElement extends Element implements IElementListener {\r
+ \r
+ /*\r
+ * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
+ */\r
+ public static double ARROW_LENGTH1 = 0.2;\r
+ public static double ARROW_LENGTH2 = 3.0;\r
+ public static double ARROW_WIDTH = 1.8;\r
+ \r
+ @RelatedElement("http://www.simantics.org/Sysdyn-1.0/HasTail")\r
+ Connectable tail;\r
+ @RelatedElement("http://www.simantics.org/Sysdyn-1.0/HasHead")\r
+ Connectable head;\r
+ @RelatedValue("http://www.simantics.org/Sysdyn-1.0/HasAngle")\r
+ double angle = 0.1;\r
+\r
+ // Auxiliary \r
+ double angle0;\r
+ double angle1;\r
+ double cx;\r
+ double cy;\r
+ double r;\r
+ \r
+ // Scene graph\r
+ ShapeNode arcNode;\r
+ FilledShapeNode arrowNode;\r
+ \r
+ public DependencyElement() { \r
+ }\r
+ \r
+ public DependencyElement(Connectable tail, Connectable head) {\r
+ super();\r
+ this.tail = tail;\r
+ this.head = head;\r
+ }\r
+ \r
+ @Override\r
+ public void elementUpdated(IElement element) {\r
+ update(); \r
+ } \r
+\r
+ @Override\r
+ public void remove() {\r
+ arcNode.remove();\r
+ arrowNode.remove();\r
+ tail.removeListener(this);\r
+ head.removeListener(this);\r
+ super.remove();\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ tail.addListener(this);\r
+ head.addListener(this);\r
+ \r
+ arcNode = parent.addNode(ShapeNode.class);\r
+ arcNode.setScaleStroke(true);\r
+ arcNode.setStroke(new BasicStroke(1));\r
+ arrowNode = parent.addNode(FilledShapeNode.class);\r
+ update();\r
+ }\r
+ \r
+ protected Shape createArrow(double x, double y, double dx, double dy) {\r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy);\r
+ x -= ARROW_LENGTH2*dx;\r
+ y -= ARROW_LENGTH2*dy;\r
+ path.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx);\r
+ path.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx);\r
+ path.closePath();\r
+ return path;\r
+ }\r
+ \r
+ protected void updateSceneGraph() {\r
+ double x0 = tail.getOrigo().getX();\r
+ double y0 = tail.getOrigo().getY();\r
+ double x1 = head.getOrigo().getX();\r
+ double y1 = head.getOrigo().getY();\r
+ \r
+ double offset = \r
+ Math.abs(angle) < 1.0e-6\r
+ ? 1e3 * Math.signum(angle)\r
+ : Math.tan(Math.PI*0.5-angle)*0.5;\r
+ cx = 0.5*(x0+x1) + offset * (y1-y0);\r
+ cy = 0.5*(y0+y1) + offset * (x0-x1);\r
+ double dx0 = x0 - cx;\r
+ double dy0 = y0 - cy;\r
+ double dx1 = x1 - cx;\r
+ double dy1 = y1 - cy;\r
+ r = Math.sqrt(dx0*dx0 + dy0*dy0);\r
+ Rectangle2D bounds = new Rectangle2D.Double();\r
+ tail.getBounds(bounds);\r
+ angle0 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy0, dx0), bounds, angle < 0.0);\r
+ head.getBounds(bounds);\r
+ angle1 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy1, dx1), bounds, angle > 0.0);\r
+ double extent = angle1-angle0;\r
+ //double arcAngle = angle0;\r
+ if(angle < 0.0) {\r
+ double temp = angle0; \r
+ angle0 = angle1;\r
+ angle1 = temp;\r
+ extent = -extent;\r
+ } \r
+ if(extent < 0)\r
+ extent += Math.PI*2.0;\r
+ else if(extent >= 360.0)\r
+ extent -= Math.PI*2.0;\r
+ Shape shape = new Arc2D.Double(cx-r, cy-r, 2*r, 2*r, \r
+ Math.toDegrees(angle0), \r
+ Math.toDegrees(extent), \r
+ Arc2D.OPEN); \r
+ arcNode.setShape(shape);\r
+ \r
+ double xx = Math.cos(angle > 0.0 ? angle1 : angle0);\r
+ double yy = -Math.sin(angle > 0.0 ? angle1 : angle0);\r
+ Shape arrowShape = createArrow(cx + r*xx, cy + r*yy, \r
+ angle < 0.0 ? -yy : yy, \r
+ angle > 0.0 ? -xx : xx);\r
+ arrowNode.setShape(arrowShape);\r
+ }\r
+ \r
+ public void update() {\r
+ if(arcNode != null)\r
+ updateSceneGraph();\r
+ fireElementUpdated();\r
+ }\r
+ \r
+ @Override\r
+ public void getBounds(Rectangle2D bounds) {\r
+ bounds.setFrame(arcNode.getBounds());\r
+ }\r
+\r
+ @Override\r
+ public boolean hitTest(double x, double y, double tolerance) {\r
+ double dx = x-cx;\r
+ double dy = y-cy;\r
+ double dist = dx*dx + dy*dy;\r
+ if(dist < (r+tolerance)*(r+tolerance) &&\r
+ dist > (r-tolerance)*(r-tolerance)) {\r
+ double angle = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
+ if(Arcs.areClockwiseOrdered(angle0, angle, angle1))\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ \r
+ class EventHandler extends DragEventHandler {\r
+ @Override\r
+ protected boolean begin(IDiagramEditor editor, DragEvent event) {\r
+ return event.startModifiers.equals("left");\r
+ }\r
+ \r
+ @Override\r
+ protected void update(IDiagramEditor editor, DragEvent event) {\r
+ if(event == null)\r
+ return;\r
+ angle = Arcs.angleOfArc(\r
+ tail.getOrigo().getX(), tail.getOrigo().getY(), \r
+ event.current.getX(), event.current.getY(), \r
+ head.getOrigo().getX(), head.getOrigo().getY()\r
+ );\r
+ DependencyElement.this.update();\r
+ editor.requestRepaint();\r
+ }\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public <T> T getInterface(Class<T> clazz) {\r
+ if(clazz == IEventHandler.class) \r
+ return (T)new EventHandler();\r
+ return super.getInterface(clazz);\r
+ }\r
+\r
+ @Override\r
+ public void elementRemoved(IElement element) {\r
+ remove(); \r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.h2d.element.Element;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.IElementListener;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.node.FilledShapeNode;\r
+import org.simantics.h2d.node.ShapeNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.objmap.annotations.RelatedElement;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Flow")\r
+public class FlowElement extends Element implements IElementListener {\r
+\r
+ public static double ARROW_LENGTH = 3.2;\r
+ public static double ARROW_WIDTH = 3;\r
+\r
+ static final double OFFSET = 1.5;\r
+ static final double ARROW_OFFSET = 3.2;\r
+\r
+ /*\r
+ * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
+ */ \r
+ @RelatedElement("http://www.simantics.org/Sysdyn-1.0/HasTail")\r
+ Connectable tail;\r
+ @RelatedElement("http://www.simantics.org/Sysdyn-1.0/HasHead")\r
+ Connectable head;\r
+\r
+ // Auxiliary \r
+ double angle0;\r
+ double angle1;\r
+ double cx;\r
+ double cy;\r
+ double r;\r
+\r
+ // Scene graph\r
+ ShapeNode lineNode1;\r
+ ShapeNode lineNode2;\r
+ FilledShapeNode arrowNode;\r
+\r
+ public FlowElement() { \r
+ }\r
+\r
+ public FlowElement(Connectable tail, Connectable head) {\r
+ super();\r
+ this.tail = tail;\r
+ this.head = head;\r
+ tail.addListener(this);\r
+ head.addListener(this);\r
+ }\r
+\r
+ @Override\r
+ public void elementUpdated(IElement element) {\r
+ update(); \r
+ } \r
+\r
+ @Override\r
+ public void remove() {\r
+ lineNode1.remove();\r
+ lineNode2.remove();\r
+ arrowNode.remove();\r
+ tail.removeListener(this);\r
+ head.removeListener(this);\r
+ super.remove();\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ tail.addListener(this);\r
+ head.addListener(this);\r
+\r
+ lineNode1 = parent.addNode(ShapeNode.class);\r
+ lineNode1.setScaleStroke(true);\r
+ lineNode2 = parent.addNode(ShapeNode.class);\r
+ lineNode2.setScaleStroke(true);\r
+\r
+ arrowNode = parent.addNode(FilledShapeNode.class);\r
+ update();\r
+ }\r
+\r
+ protected void createArrow(Connectable head, Connectable tail) { \r
+ double x = tail.getOrigo().getX();\r
+ double y = tail.getOrigo().getY();\r
+\r
+ Rectangle2D rect = new Rectangle2D.Double();\r
+ head.getBounds(rect);\r
+ double cx = rect.getCenterX();\r
+ double minx = rect.getMinX();\r
+ double maxx = rect.getMaxX();\r
+ double miny = rect.getMinY();\r
+ double maxy = rect.getMaxY();\r
+\r
+ Path2D path = new Path2D.Double();\r
+\r
+ // approach from top\r
+ if (y < miny) {\r
+ path.moveTo(cx, miny);\r
+ path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ } \r
+\r
+ // approach from beneath\r
+ else if (y > maxy) {\r
+ path.moveTo(cx, maxy);\r
+ path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ }\r
+\r
+ // approach from left\r
+ else if (x < minx) {\r
+ path.moveTo(minx, y);\r
+ path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
+ path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
+ }\r
+\r
+ // approach from right\r
+ else if (x > maxx) {\r
+ path.moveTo(maxx, y);\r
+ path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
+ path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH);\r
+ }\r
+ else\r
+ return; // FIXME (HN) This is just a quick bugfix, didn't understand the logic completely \r
+\r
+ path.closePath();\r
+ arrowNode.setShape(path);\r
+ }\r
+\r
+ // TODO\r
+\r
+ private void draw(boolean vertical, double ... coordinates) {\r
+ lineNode1.setShape(Flows.createOffsetLine(vertical, OFFSET, coordinates));\r
+ lineNode2.setShape(Flows.createOffsetLine(vertical, -OFFSET, coordinates));\r
+ }\r
+\r
+ private void draw(boolean hasArrow, Connectable valve, Connectable node) {\r
+ double x0 = valve.getOrigo().getX();\r
+ double y0 = valve.getOrigo().getY(); \r
+ double x1 = node.getOrigo().getX();\r
+ double y1 = node.getOrigo().getY();\r
+\r
+ Rectangle2D rect = new Rectangle2D.Double();\r
+ node.getBounds(rect);\r
+ \r
+ double minY = hasArrow ? rect.getMinY() - ARROW_OFFSET : rect.getMinY();\r
+ double maxY = hasArrow ? rect.getMaxY() + ARROW_OFFSET : rect.getMaxY();\r
+ double minX = hasArrow ? rect.getMinX() - ARROW_OFFSET : rect.getMinX();\r
+ double maxX = hasArrow ? rect.getMaxX() + ARROW_OFFSET : rect.getMaxX();\r
+ \r
+ \r
+ if( ((ValveElement)valve).rotated ) {\r
+ if(y1 > y0)\r
+ y0 += OFFSET;\r
+ else\r
+ y0 -= OFFSET;\r
+ if(rect.getMinX() <= x0 && rect.getMaxX() >= x0) {\r
+ if(y1 > y0)\r
+ draw(true, y0, x0, minY);\r
+ else\r
+ draw(true, y0, x0, maxY);\r
+ }\r
+ else {\r
+ if(x1 > x0)\r
+ draw(true, y0, x0, y1, minX);\r
+ else\r
+ draw(true, y0, x0, y1, maxX);\r
+ }\r
+ }\r
+ else {\r
+ if(x1 > x0)\r
+ x0 += OFFSET;\r
+ else\r
+ x0 -= OFFSET;\r
+ if(rect.getMinY() <= y0 && rect.getMaxY() >= y0) {\r
+ if(x1 > x0)\r
+ draw(false, x0, y0, minX);\r
+ else\r
+ draw(false, x0, y0, maxX);\r
+ }\r
+ else {\r
+ if(y1 > y0)\r
+ draw(false, x0, y0, x1, minY);\r
+ else\r
+ draw(false, x0, y0, x1, maxY);\r
+ }\r
+ }\r
+\r
+\r
+ }\r
+\r
+ protected void updateSceneGraph() {\r
+ boolean hasArrow = tail instanceof ValveElement && !(head instanceof ValveElement);\r
+ if(tail instanceof ValveElement)\r
+ draw(hasArrow, tail, head);\r
+ else if(head instanceof ValveElement)\r
+ draw(hasArrow, head, tail);\r
+ if(hasArrow)\r
+ createArrow(head, tail);\r
+ }\r
+\r
+ // TODO\r
+\r
+ public void update() {\r
+ if(lineNode1 != null)\r
+ updateSceneGraph();\r
+ fireElementUpdated();\r
+ }\r
+\r
+ @Override\r
+ public void getBounds(Rectangle2D bounds) {\r
+ bounds.setFrame(lineNode1.getBoundsInLocal());\r
+ bounds.add(lineNode2.getBoundsInLocal());\r
+ }\r
+\r
+ @Override\r
+ public boolean hitTest(double x, double y, double tolerance) {\r
+ // FIXME totally incorrect\r
+ /*Rectangle2D rect = new Rectangle2D.Double();\r
+ getBounds(rect);\r
+ return rect.contains(x, y);*/\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public <T> T getInterface(Class<T> clazz) { \r
+ return super.getInterface(clazz);\r
+ }\r
+\r
+ @Override\r
+ public void elementRemoved(IElement element) {\r
+ remove(); \r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.geom.Path2D;\r
+\r
+public class Flows {\r
+ public static Path2D createLine(boolean vertical, double ... coordinates) {\r
+ Path2D path = new Path2D.Double();\r
+ if(vertical)\r
+ path.moveTo(coordinates[1], coordinates[0]);\r
+ else\r
+ path.moveTo(coordinates[0], coordinates[1]);\r
+ for(int i=2;i<coordinates.length;++i, vertical = !vertical) {\r
+ if(vertical)\r
+ path.lineTo(coordinates[i-1], coordinates[i]);\r
+ else\r
+ path.lineTo(coordinates[i], coordinates[i-1]);\r
+ }\r
+ return path;\r
+ }\r
+ \r
+ public static Path2D createOffsetLine(boolean vertical, double offset, double ... coordinates) {\r
+ double[] newCoordinats = new double[coordinates.length];\r
+ newCoordinats[0] = coordinates[0];\r
+ newCoordinats[coordinates.length-1] = coordinates[coordinates.length-1];\r
+ for(int i=1;i<coordinates.length-1;++i) {\r
+ if(coordinates[i-1] < coordinates[i+1] ^ (i&1)==1)\r
+ newCoordinats[i] = coordinates[i]+offset;\r
+ else\r
+ newCoordinats[i] = coordinates[i]-offset;\r
+ }\r
+ return createLine(vertical, newCoordinats);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.h2d.element.Element;\r
+import org.simantics.h2d.element.handler.Movable;\r
+import org.simantics.objmap.annotations.RelatedValue;\r
+\r
+/**\r
+ * Base class of elements that have rectangular shape (for hit testing)\r
+ * and which can be moved.\r
+ * @author Hannu Niemistö\r
+ */\r
+public abstract class RectangularElement extends Element implements Movable {\r
+ \r
+ protected Rectangle2D bounds = new Rectangle2D.Double();\r
+ \r
+ @RelatedValue("http://www.simantics.org/Sysdyn-1.0/HasX")\r
+ protected double posX;\r
+ @RelatedValue("http://www.simantics.org/Sysdyn-1.0/HasY")\r
+ protected double posY; \r
+ \r
+ public RectangularElement() { \r
+ }\r
+ \r
+ @Override\r
+ public void getBounds(Rectangle2D bounds) {\r
+ bounds.setFrame(this.bounds);\r
+ }\r
+\r
+ @Override\r
+ public boolean hitTest(double x, double y, double tolerance) {\r
+ return bounds.intersects(x-tolerance, y-tolerance, 2.0*tolerance, 2.0*tolerance);\r
+ } \r
+ \r
+ protected abstract void update();\r
+ \r
+ @Override\r
+ public void move(double deltaX, double deltaY) {\r
+ posX += deltaX;\r
+ posY += deltaY;\r
+ update();\r
+ }\r
+ \r
+ public Point2D getOrigo() {\r
+ return new Point2D.Double(posX, posY);\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import org.simantics.h2d.node.RectangleNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Stock")\r
+public class StockElement extends TextElement {\r
+ \r
+ RectangleNode rectangleNode;\r
+ \r
+ public StockElement() { \r
+ }\r
+ \r
+ public StockElement(String label, double x, double y) {\r
+ super(label, x, y);\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ rectangleNode = parent.addNode(RectangleNode.class);\r
+ super.init(parent);\r
+ }\r
+ \r
+ @Override\r
+ public void remove() {\r
+ rectangleNode.remove();\r
+ super.remove();\r
+ }\r
+\r
+ @Override\r
+ protected void update() {\r
+ super.update();\r
+ if(rectangleNode != null)\r
+ rectangleNode.init(bounds);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.awt.font.FontRenderContext;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.h2d.action.IAction;\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.element.handler.Movable;\r
+import org.simantics.h2d.event.ClickEvent;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.KeyboardEvent;\r
+import org.simantics.h2d.event.handler.IEventHandler;\r
+import org.simantics.h2d.node.ITextListener;\r
+import org.simantics.h2d.node.TextNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.objmap.annotations.RelatedValue;\r
+import org.simantics.objmap.annotations.UpdateMethod;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Auxiliary")\r
+public class TextElement extends RectangularElement implements Movable, Connectable, IEventHandler {\r
+\r
+ static final Font FONT = new Font("sans-serif", Font.PLAIN, 12);\r
+ static final double FONT_SCALE = 0.3;\r
+ static final AffineTransform FONT_TRANSFORM = new AffineTransform(FONT_SCALE, 0.0, 0.0, FONT_SCALE, 0.0, 0.0);\r
+\r
+ static final double XPADDING = 4.0;\r
+ static final double YPADDING = 2.0;\r
+ static final FontRenderContext FRC = new FontRenderContext(FONT_TRANSFORM, true, true);\r
+\r
+ // Properties\r
+ @RelatedValue("http://www.simantics.org/Layer0-1.0/HasName")\r
+ public String label = "Unnamed";\r
+\r
+ @RelatedValue("http://www.simantics.org/Layer0-1.0/HasType")\r
+ public String type = "Real";\r
+\r
+ // Auxiliary fields\r
+ double textX;\r
+ double textY;\r
+\r
+ TextNode textNode;\r
+\r
+ public TextElement() { \r
+ }\r
+\r
+ public double getTextDeltaX() {\r
+ return 0.0;\r
+ }\r
+\r
+ public double getTextDeltaY() {\r
+ return 0.0;\r
+ }\r
+\r
+ public TextElement(String label, double x, double y) {\r
+ this.label = label;\r
+ this.posX = x;\r
+ this.posY = y;\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ textNode.remove();\r
+ super.remove();\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ textNode = parent.addNode(TextNode.class);\r
+ update();\r
+ }\r
+\r
+ protected void updateText() {\r
+ Rectangle2D textBounds = FONT.getStringBounds(label, FRC);\r
+ textBounds.setFrame(\r
+ textBounds.getX()*FONT_SCALE,\r
+ textBounds.getY()*FONT_SCALE,\r
+ textBounds.getWidth()*FONT_SCALE,\r
+ textBounds.getHeight()*FONT_SCALE\r
+ );\r
+\r
+ textX = posX+getTextDeltaX()-textBounds.getCenterX();\r
+ textY = posY+getTextDeltaY()-textBounds.getCenterY();\r
+ bounds.setFrame(\r
+ posX+getTextDeltaX()-textBounds.getWidth()*0.5-XPADDING,\r
+ posY+getTextDeltaY()-textBounds.getHeight()*0.5-YPADDING,\r
+ textBounds.getWidth()+XPADDING*2,\r
+ textBounds.getHeight()+YPADDING*2\r
+ ); \r
+\r
+ if(textNode != null) {\r
+ textNode.init(label, FONT, hasEquation ? Color.BLACK : Color.RED, \r
+ textX, textY, FONT_SCALE);\r
+ oldHasEquation = hasEquation;\r
+ }\r
+ }\r
+\r
+ protected void update() {\r
+ updateText(); \r
+ fireElementUpdated();\r
+ }\r
+\r
+ class TextEditingAction implements IAction, ITextListener {\r
+\r
+ String oldText;\r
+ IDiagramEditor editor;\r
+\r
+ public TextEditingAction(IDiagramEditor editor) {\r
+ super();\r
+ this.editor = editor;\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ oldText = textNode.getText();\r
+ textNode.setEditMode(true); \r
+ textNode.setTextListener(this);\r
+ /*textFieldNode = parent.addNode(TextFieldNode.class);\r
+ textFieldNode.init(10.0, 10.0);*/\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ textNode.setEditMode(false);\r
+ textNode.setTextListener(null);\r
+ //textFieldNode.remove(); \r
+ }\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ if(_event instanceof KeyboardEvent) {\r
+ KeyboardEvent event = (KeyboardEvent)_event;\r
+ if(event.key.equals("Escape")) {\r
+ label = oldText;\r
+ update();\r
+ editor.removeAction(this); \r
+ editor.requestRepaint(); \r
+ }\r
+ else if(event.key.equals("Enter")) {\r
+ validateNewName();\r
+ update(); \r
+ editor.removeAction(this);\r
+ editor.requestRepaint();\r
+ }\r
+ return true;\r
+ }\r
+ else if(_event instanceof ClickEvent) {\r
+ validateNewName();\r
+ update();\r
+ editor.removeAction(this);\r
+ editor.requestRepaint();\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public void textChanged() {\r
+ label = textNode.getText();\r
+ //update();\r
+ editor.requestRepaint();\r
+ }\r
+ \r
+ private void validateNewName(){\r
+ if(!label.equals(oldText)) {\r
+ List<IElement> elements = editor.getDiagram().getElements();\r
+ for(IElement e : elements) {\r
+ if(e instanceof TextElement) {\r
+ TextElement t = (TextElement) e;\r
+ if(t != TextElement.this && t.label.equals(textNode.getText())) {\r
+ label = oldText;\r
+ //update();\r
+ //editor.requestRepaint(); \r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ public void beginRenameAction(IDiagramEditor editor) {\r
+ editor.addAction(new TextEditingAction(editor));\r
+ }\r
+\r
+ @Override\r
+ public boolean handle(IDiagramEditor editor, IEvent _event) {\r
+ if(_event instanceof KeyboardEvent) {\r
+ KeyboardEvent event = (KeyboardEvent)_event;\r
+ if(event.key.equals("F3") || event.key.equals("F2")) {\r
+ beginRenameAction(editor);\r
+ return true;\r
+ } \r
+ }\r
+ return false;\r
+ } \r
+\r
+ boolean oldHasEquation = false;\r
+\r
+ boolean hasEquation = true;\r
+ String oldLabel = label;\r
+\r
+ @UpdateMethod\r
+ boolean updateCheck(ReadGraph g, Resource resource) {\r
+// SysdynResource sr = SysdynResource.getInstance(g);\r
+ boolean update = false;\r
+// try {\r
+// hasEquation = \r
+// !g.getObjects(resource, sr.HasExpression).isEmpty();\r
+// if(oldHasEquation != hasEquation) \r
+// update = true;\r
+ if(!label.equals(oldLabel)) {\r
+ oldLabel = label; \r
+ update = true;\r
+ }\r
+ if(update) \r
+ update();\r
+// } catch (DatabaseException e) {\r
+// e.printStackTrace();\r
+// } \r
+ return false;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.geom.Path2D;\r
+\r
+import org.simantics.h2d.element.handler.Rotatable;\r
+import org.simantics.h2d.node.ShapeNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Valve")\r
+public class ValveElement extends TextElement implements Rotatable {\r
+ \r
+ public static final double VALVE_SIZE = 5.0;\r
+ \r
+ ShapeNode valveNode;\r
+ boolean rotated = false;\r
+ \r
+ public ValveElement() { \r
+ }\r
+ \r
+ public ValveElement(double x, double y) {\r
+ this.posX = x;\r
+ this.posY = y; \r
+ }\r
+ \r
+ @Override\r
+ public double getTextDeltaY() {\r
+ return 8.0;\r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ valveNode = parent.addNode(ShapeNode.class);\r
+ valveNode.setColor(Color.BLACK);\r
+ valveNode.setScaleStroke(true);\r
+ valveNode.setStroke(new BasicStroke(1));\r
+ super.init(parent);\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ valveNode.remove();\r
+ super.remove();\r
+ }\r
+ \r
+ @Override\r
+ protected void update() { \r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(posX-VALVE_SIZE, posY-VALVE_SIZE);\r
+ if(rotated) {\r
+ path.lineTo(posX-VALVE_SIZE, posY+VALVE_SIZE);\r
+ path.lineTo(posX+VALVE_SIZE, posY-VALVE_SIZE);\r
+ }\r
+ else { \r
+ path.lineTo(posX+VALVE_SIZE, posY-VALVE_SIZE);\r
+ path.lineTo(posX-VALVE_SIZE, posY+VALVE_SIZE); \r
+ }\r
+ path.lineTo(posX+VALVE_SIZE, posY+VALVE_SIZE);\r
+ path.closePath();\r
+ valveNode.setShape(path);\r
+ updateText();\r
+ bounds.setFrame(posX-VALVE_SIZE, posY-VALVE_SIZE, 2.0*VALVE_SIZE, 2.0*VALVE_SIZE);\r
+ fireElementUpdated();\r
+ }\r
+\r
+ @Override\r
+ public void rotate(int amount) {\r
+ if((amount & 1) == 1) {\r
+ rotated = !rotated;\r
+ update();\r
+ }\r
+ }\r
+\r
+ public boolean isRotated() {\r
+ return rotated;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.geom.Path2D;\r
+\r
+import org.simantics.h2d.element.handler.Connectable;\r
+import org.simantics.h2d.element.handler.Rotatable;\r
+import org.simantics.h2d.node.ShapeNode;\r
+import org.simantics.objmap.annotations.GraphType;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+@GraphType("http://www.simantics.org/Sysdyn-1.0/Valve")\r
+public class ValveElementOld extends RectangularElement implements Connectable, Rotatable {\r
+ \r
+ public static final double VALVE_SIZE = 5.0;\r
+ \r
+ ShapeNode valveNode;\r
+ boolean rotated = false;\r
+ \r
+ public ValveElementOld() { \r
+ }\r
+ \r
+ public ValveElementOld(double x, double y) {\r
+ this.posX = x;\r
+ this.posY = y; \r
+ }\r
+\r
+ @Override\r
+ public void init(G2DParentNode parent) {\r
+ valveNode = parent.addNode(ShapeNode.class);\r
+ valveNode.setColor(Color.BLACK);\r
+ valveNode.setScaleStroke(true);\r
+ valveNode.setStroke(new BasicStroke(1));\r
+ update();\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ valveNode.remove();\r
+ }\r
+ \r
+ protected void update() {\r
+ bounds.setFrame(posX-VALVE_SIZE, posY-VALVE_SIZE, 2.0*VALVE_SIZE, 2.0*VALVE_SIZE);\r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(posX-VALVE_SIZE, posY-VALVE_SIZE);\r
+ if(rotated) {\r
+ path.lineTo(posX-VALVE_SIZE, posY+VALVE_SIZE);\r
+ path.lineTo(posX+VALVE_SIZE, posY-VALVE_SIZE);\r
+ }\r
+ else { \r
+ path.lineTo(posX+VALVE_SIZE, posY-VALVE_SIZE);\r
+ path.lineTo(posX-VALVE_SIZE, posY+VALVE_SIZE); \r
+ }\r
+ path.lineTo(posX+VALVE_SIZE, posY+VALVE_SIZE);\r
+ path.closePath();\r
+ valveNode.setShape(path);\r
+ fireElementUpdated();\r
+ }\r
+\r
+ @Override\r
+ public void rotate(int amount) {\r
+ if((amount & 1) == 1) {\r
+ rotated = !rotated;\r
+ update();\r
+ }\r
+ }\r
+\r
+ public boolean isRotated() {\r
+ return rotated;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.geom.Ellipse2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class AuxiliaryFactory extends SysdynElementFactory {\r
+\r
+ // TODO: make the static symbol image a text "AUX"\r
+ private static final Image AUX_STATIC_IMAGE = new ShapeImage(new Ellipse2D.Double(-5, -2, 10, 4), null, new BasicStroke(1), true);\r
+\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ TextFontImpl.DEFAULT,\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(AUX_STATIC_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ HoverTextElementHandler.INSTANCE,\r
+ BoundsOutline.INSTANCE,\r
+// HoverImpl.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(AuxiliaryFactory.class.getSimpleName());\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.geom.AffineTransform;\r
+\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.h2d.node.RectangleNode;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+public class BorderSceneGraph implements SceneGraph, Callback<RectangleNode> {\r
+\r
+ public static final BorderSceneGraph INSTANCE = new BorderSceneGraph();\r
+\r
+ private static final long serialVersionUID = 5544256245734478634L;\r
+\r
+ private static final Key BORDER_NODE = new SceneGraphNodeKey(RectangleNode.class, "BORDER_NODE");\r
+\r
+ @Override\r
+ public void init(IElement e, G2DParentNode parent) {\r
+ RectangleNode node = ElementUtils.getOrCreateNode(e, parent, BORDER_NODE, "border", RectangleNode.class, this);\r
+\r
+ // Calculate borders from text node bounds.\r
+ node.init(ElementUtils.getElementBounds(e));\r
+ AffineTransform transform = ElementUtils.getTransform(e);\r
+ if(transform != null)\r
+ node.setTransform(transform);\r
+ }\r
+\r
+ @Override\r
+ public void run(RectangleNode node) {\r
+ node.setZIndex(-10);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ ElementUtils.removePossibleNode(e, BORDER_NODE);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.HandleMouseEvent;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.HoverImpl;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.event.MouseEvent;\r
+import org.simantics.g2d.event.MouseEvent.MouseEnterEvent;\r
+import org.simantics.g2d.event.MouseEvent.MouseExitEvent;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+public class CloudFactory extends SysdynElementFactory {\r
+\r
+ public static final double CLOUD_SIZE_X = 5.0;\r
+ public static final double CLOUD_SIZE_Y = 3.0;\r
+ public static final double CLOUD_CURVES = 7;\r
+\r
+ private static final BasicStroke STROKE = new BasicStroke(1f);\r
+ private static final Image DEFAULT_IMAGE = new ShapeImage(getCloudShape(), null, STROKE, true);\r
+\r
+ static Shape getCloudShape() {\r
+ Path2D path = new Path2D.Double();\r
+ double ox = CLOUD_SIZE_X;\r
+ double oy = 0.0;\r
+ double posX = 0;\r
+ double posY = 0;\r
+ path.moveTo(posX + ox, posY + oy);\r
+ for (int i = 1; i < CLOUD_CURVES + 1; ++i) {\r
+ double angle = (Math.PI * 2.0 / CLOUD_CURVES) * i;\r
+ double x = Math.cos(angle) * CLOUD_SIZE_X;\r
+ double y = Math.sin(angle) * CLOUD_SIZE_Y;\r
+ path.curveTo(\r
+ posX + (2*ox + x)*0.5, posY + (2*oy + y)*0.5,\r
+ posX + (ox + 2*x)*0.5, posY + (oy + 2*y)*0.5,\r
+ posX + x, posY + y);\r
+ ox = x;\r
+ oy = y;\r
+ }\r
+ return path;\r
+ }\r
+\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ TextFontImpl.DEFAULT,\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(DEFAULT_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ CloudSceneGraph.INSTANCE,\r
+ HoverImpl.INSTANCE,\r
+ BoundsOutline.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(CloudFactory.class.getSimpleName());\r
+ }\r
+\r
+ public static class CloudSceneGraph implements SceneGraph, InternalSize, HandleMouseEvent {\r
+\r
+ private static final long serialVersionUID = 5544256245734478634L;\r
+\r
+ public static final CloudSceneGraph INSTANCE = new CloudSceneGraph();\r
+\r
+ private static final Key NODE = new SceneGraphNodeKey(ShapeNode.class, "VALVE_NODE");\r
+ \r
+ private IHintListener hoverHintListener;\r
+\r
+ @Override\r
+ public void init(IElement e, G2DParentNode parent) {\r
+ AffineTransform at = ElementUtils.getTransform(e);\r
+ HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "valve", HoverShapeNode.class);\r
+\r
+ node.setStroke(STROKE);\r
+ node.setScaleStroke(true);\r
+ node.setColor(Color.BLACK);\r
+ node.setShape(getCloudShape());\r
+ AffineTransform transform = ElementUtils.getTransform(e);\r
+ if(transform != null)\r
+ node.setTransform(transform);\r
+ \r
+ if(at != null)\r
+ node.setTransform(at);\r
+ \r
+ hoverHintListener = new IHintListener() {\r
+ \r
+ @Override\r
+ public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ IElement e = (IElement)sender;\r
+ HoverShapeNode shape = (HoverShapeNode) e.getHint(NODE);\r
+ shape.setHover(ElementUtils.isHovering(e));\r
+ }\r
+ };\r
+ e.addHintListener(hoverHintListener);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ e.removeHintListener(hoverHintListener);\r
+ ElementUtils.removePossibleNode(e, NODE);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+ if (size == null)\r
+ size = new Rectangle2D.Double();\r
+ size.setFrame(getCloudShape().getBounds2D());\r
+ return size;\r
+ }\r
+\r
+ @Override\r
+ public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {\r
+ if (me instanceof MouseEnterEvent) {\r
+ ElementUtils.setHover(e, true);\r
+ return false;\r
+ } else if (me instanceof MouseExitEvent) {\r
+ ElementUtils.setHover(e, false);\r
+ return false;\r
+ }\r
+ return false;\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.diagram.synchronization.IModificationQueue;\r
+import org.simantics.diagram.synchronization.ISynchronizationContext;\r
+import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.RelatedPropertyModification;\r
+import org.simantics.diagram.synchronization.graph.ResourceSynchronizer;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ComponentNameSynchronizer extends ResourceSynchronizer {\r
+\r
+ public static final ComponentNameSynchronizer INSTANCE = new ComponentNameSynchronizer();\r
+\r
+ private static final Key[] SYNCHRONIZED_HINTS = {\r
+ ElementHints.KEY_TEXT\r
+ };\r
+\r
+ @Override\r
+ public Key[] getSynchronizedHints() {\r
+ return SYNCHRONIZED_HINTS;\r
+ }\r
+\r
+ @Override\r
+ public boolean hintChanged(ISynchronizationContext context, IModificationQueue queue, Resource object, IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ if (ElementHints.KEY_TEXT.equals(key)) {\r
+ Session session = context.get(GraphSynchronizationHints.SESSION);\r
+ Builtins b = session.getBuiltins();\r
+ ModelingResources mr = session.getService(ModelingResources.class);\r
+ return queue.offer(new RelatedPropertyModification(object, mr.ElementToComponent, b.HasName, b.String, newValue, StringBindingDefault.INSTANCE), null);\r
+ }\r
+ return false;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.adaption.Adapter;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.DiagramClassAdapter;\r
+import org.simantics.g2d.diagram.DiagramClass;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.LifeCycle;\r
+import org.simantics.g2d.routing.RouterFactory;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ConfigurationDiagramClassAdapter implements Adapter<DiagramClass> {\r
+\r
+ @Override\r
+ public void adapt(AsyncReadGraph g, Resource r, AsyncProcedure<DiagramClass> procedure) {\r
+ procedure.execute(g, DiagramClassAdapter.INSTANCE.newClassWith(\r
+ Initializer.INSTANCE\r
+ ));\r
+ }\r
+\r
+ static class Initializer extends LifeCycle.Stub {\r
+ public static final Initializer INSTANCE = new Initializer();\r
+\r
+ @Override\r
+ public void onDiagramCreated(IDiagram diagram) {\r
+ diagram.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false));\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.AWTEvent;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.geom.Rectangle2D;\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.lang.reflect.Field;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.scenegraph.g2d.G2DNode;\r
+import org.simantics.scenegraph.g2d.events.SGMouseEvent;\r
+\r
+abstract public class GraphPropertyNode extends G2DNode {\r
+\r
+ private static final long serialVersionUID = 245761992671850588L;\r
+\r
+ HashMap<String, Field> fields = new HashMap<String, Field>();\r
+\r
+ private PropertyChangeListener fieldListener = null;\r
+ \r
+ protected GraphPropertyNode() {\r
+ for(Field f : getClass().getFields()) {\r
+// System.out.println("register field '" + f.getName() + "'");\r
+ fields.put(f.getName(), f);\r
+ }\r
+ }\r
+ \r
+ public void setFieldListener(PropertyChangeListener listener) {\r
+ this.fieldListener = listener;\r
+ }\r
+ \r
+ public void propertyChange(String field, Object value) {\r
+ }\r
+ \r
+ public void setProperty(String field, Object value) {\r
+ Field f = fields.get(field);\r
+ if(f == null) {\r
+ System.err.println("GraphPropertyNode tried to set undefined property '" + field + "'");\r
+ return;\r
+ }\r
+ try {\r
+ //System.out.println("setting field '" + field + "'");\r
+ f.set(this, value);\r
+ propertyChange(field, value);\r
+ } catch (IllegalArgumentException e) {\r
+ e.printStackTrace();\r
+ } catch (IllegalAccessException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ public void commitProperty(String field, Object value) {\r
+ if(fieldListener != null) {\r
+ fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value));\r
+ }\r
+ }\r
+\r
+ boolean pressHit = false;\r
+ \r
+ public boolean hitTest(double x, double y, double tolerance) {\r
+ return false;\r
+ }\r
+ \r
+ @Override\r
+ public void handleEvent(AWTEvent event) {\r
+ if(event instanceof SGMouseEvent) {\r
+ SGMouseEvent e = (SGMouseEvent)event;\r
+ boolean hit = hitTest(e.getDoubleX(), e.getDoubleY(), 3.0);\r
+ if(e.getID() == MouseEvent.MOUSE_DRAGGED) {\r
+ mouseDragged((SGMouseEvent)event, pressHit, hit);\r
+ }\r
+ if(e.getID() == MouseEvent.MOUSE_PRESSED) {\r
+ pressHit = hit;\r
+ mouseReleased((SGMouseEvent)event, hit);\r
+ }\r
+ if(e.getID() == MouseEvent.MOUSE_RELEASED)\r
+ mouseReleased((SGMouseEvent)event, hit);\r
+ if(e.getID() == MouseEvent.MOUSE_MOVED)\r
+ mouseMoved((SGMouseEvent)event, hit);\r
+ }\r
+ }\r
+ \r
+ public void mouseDragged(SGMouseEvent event, boolean pressHit, boolean currentHit) {\r
+ \r
+ }\r
+ \r
+ public void mouseReleased(SGMouseEvent event, boolean hit) {\r
+ \r
+ }\r
+\r
+ public void mouseMoved(SGMouseEvent event, boolean hit) {\r
+ \r
+ }\r
+\r
+ @Override\r
+ public Rectangle2D getBoundsInLocal() {\r
+ return null;\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+\r
+public class HoverShapeNode extends ShapeNode {\r
+\r
+ private static final long serialVersionUID = -4580969977763722602L;\r
+\r
+ transient public boolean hover = false;\r
+ \r
+ @Override\r
+ protected void renderShape(Graphics2D g2d, Shape s) {\r
+ boolean fill = Boolean.TRUE.equals(dynamicFill) ? true : this.fill;\r
+ if (fill)\r
+ g2d.fill(s);\r
+ \r
+ if(hover) {\r
+ BasicStroke oldStroke = (BasicStroke)g2d.getStroke();\r
+ Color oldColor = g2d.getColor();\r
+ g2d.setColor(Color.LIGHT_GRAY);\r
+ float lineWidth = oldStroke.getLineWidth() * 6;\r
+ g2d.setStroke(new BasicStroke(lineWidth < 1.0f ? lineWidth : 1.0f));\r
+ g2d.draw(s);\r
+ g2d.setColor(oldColor);\r
+ g2d.setStroke(oldStroke);\r
+ }\r
+\r
+ Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke;\r
+ if (stroke != null)\r
+ g2d.draw(s);\r
+ \r
+ }\r
+ \r
+ public void setHover(boolean hover) {\r
+ this.hover = hover;\r
+ repaint();\r
+ }\r
+\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.utils.Alignment;\r
+\r
+public class HoverTextElementHandler extends HoverTextElementNoBounds implements InternalSize {\r
+\r
+ private static final long serialVersionUID = 8800738238681432901L;\r
+ \r
+ public static final HoverTextElementHandler INSTANCE = new HoverTextElementHandler();\r
+\r
+ public HoverTextElementHandler() {\r
+ super();\r
+ }\r
+\r
+ public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment) {\r
+ super(originX, originY, horizontalAlignment);\r
+ }\r
+\r
+ public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+ super(originX, originY, horizontalAlignment, borderWidth);\r
+ }\r
+\r
+ public HoverTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth,\r
+ double paddingX, double paddingY, boolean editable) {\r
+ super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+ HoverTextNode node = (HoverTextNode) e.getHint(SG_NODE);\r
+ if (size == null)\r
+ size = new Rectangle2D.Double();\r
+ if (node != null)\r
+ size.setRect(node.getBoundsInLocal());\r
+ else\r
+ size.setFrame(0, 0, 0, 0);\r
+ return size;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.awt.geom.AffineTransform;\r
+\r
+import org.simantics.diagram.elements.ITextListener;\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+/**\r
+ * ElementHandler for text elements\r
+ * In-line editing supported.\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ */\r
+public class HoverTextElementNoBounds extends TextElementNoBounds {\r
+\r
+ private static final long serialVersionUID = -148784588840819612L;\r
+\r
+ public static final HoverTextElementNoBounds INSTANCE = new HoverTextElementNoBounds();\r
+\r
+ private IHintListener hoverHintListener;\r
+\r
+ public HoverTextElementNoBounds() {\r
+ super(0, 0, Alignment.LEADING, 0);\r
+ }\r
+\r
+ public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {\r
+ super(originX, originY, horizontalAlignment, 0);\r
+ }\r
+\r
+ public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+ super(originX, originY, horizontalAlignment, borderWidth);\r
+ }\r
+\r
+ public HoverTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
+ super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\r
+ }\r
+\r
+ @Override\r
+ public void init(final IElement e, G2DParentNode parent) {\r
+ HoverTextNode node = ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", HoverTextNode.class, new Callback<HoverTextNode>() {\r
+ @Override\r
+ public void run(HoverTextNode node) {\r
+ node.setTextListener(new ITextListener() {\r
+ @Override\r
+ public void textChanged() {}\r
+\r
+ @Override\r
+ public void textEditingStarted() {}\r
+\r
+ @Override\r
+ public void textEditingCancelled() {\r
+ TextNode node = (TextNode) e.getHint(SG_NODE);\r
+ if (node != null)\r
+ endEdit(node);\r
+ }\r
+\r
+ @Override\r
+ public void textEditingEnded() {\r
+ TextNode node = (TextNode) e.getHint(SG_NODE);\r
+ if (node == null)\r
+ return;\r
+ //System.out.println("Node text changed: " + node.getText());\r
+ ElementUtils.setText(e, node.getText());\r
+ IDiagram diagram = ElementUtils.getDiagram(e);\r
+ DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
+ endEdit(node);\r
+ }\r
+ });\r
+ }\r
+ });\r
+\r
+ //Font font = new Font("Tahoma", 0, 12);\r
+ Font font = ElementUtils.getTextFont(e);\r
+ Color color = ElementUtils.getTextColor(e);\r
+ Color fillColor = ElementUtils.getFillColor(e);\r
+ Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK);\r
+ String text = ElementUtils.getText(e);\r
+ AffineTransform at = ElementUtils.getTransform(e);\r
+ node.init(text, font, color, originX, originY, 0.235);\r
+ node.setBackgroundColor(fillColor);\r
+ node.setBorderColor(borderColor);\r
+ node.setHorizontalAlignment((byte) horizontalAlignment.ordinal());\r
+ node.setPadding(paddingX, paddingY);\r
+ node.setBorderWidth((float) borderWidth);\r
+ node.setEditable(editable);\r
+ if(at != null)\r
+ node.setTransform(at);\r
+ \r
+ this.hoverHintListener = new IHintListener() {\r
+ @Override\r
+ public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
+\r
+ }\r
+\r
+ @Override\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ if(key == ElementHints.KEY_HOVER) {\r
+ IElement e = (IElement)sender;\r
+ TextNode name = (TextNode) e.getHint(SG_NODE);\r
+ if(name != null)\r
+ name.setHover((Boolean)e.getHint(ElementHints.KEY_HOVER));\r
+ }\r
+ }\r
+ };\r
+ e.addHintListener(hoverHintListener);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ if(hoverHintListener != null)\r
+ e.removeHintListener(hoverHintListener);\r
+ ElementUtils.removePossibleNode(e, SG_NODE);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.font.FontRenderContext;\r
+import java.awt.geom.NoninvertibleTransformException;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+\r
+public class HoverTextNode extends TextNode {\r
+\r
+ private static final long serialVersionUID = 3539499125943249895L;\r
+
+\r
+ @Override\r
+ public void render(Graphics2D g) {\r
+ \r
+ g.transform(transform);\r
+ if(horizontalAlignment == Alignment.CENTER.ordinal()) {\r
+ FontRenderContext frc = g.getFontRenderContext();\r
+ Rectangle2D stringBounds = font.getStringBounds(getText(), frc);\r
+ g.translate(- stringBounds.getWidth() / 2 * scale, 0);\r
+ }\r
+ Rectangle2D r = getBoundsInLocal();\r
+ \r
+ boolean selected = NodeUtil.isSelected(this, 1);\r
+ if (!selected && hover){\r
+ \r
+ BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+ Color oldColor = g.getColor();\r
+ g.setColor(Color.LIGHT_GRAY);\r
+ g.setStroke(new BasicStroke((float)(2.0f * scale)));\r
+ g.translate(x, y);\r
+ g.draw(r);\r
+ g.translate(-x, -y);\r
+ g.setColor(oldColor);\r
+ g.setStroke(oldStroke);\r
+ }\r
+ try {\r
+ g.transform(transform.createInverse());\r
+ } catch (NoninvertibleTransformException e) {\r
+ e.printStackTrace();\r
+ }\r
+ super.render(g);\r
+ \r
+\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+\r
+public class Input implements ElementHandler {\r
+\r
+ private static final long serialVersionUID = -1526125969376635502L;\r
+ \r
+ public static final Input INSTANCE = new Input();\r
+ \r
+ public String getInputReference(IElement e) {\r
+ return e.getHint(SysdynElementHints.KEY_INPUT_REFERENCE);\r
+ }\r
+\r
+ \r
+ public void setInputReference(IElement e, String inputReference) {\r
+ if (inputReference != null)\r
+ e.setHint(SysdynElementHints.KEY_INPUT_REFERENCE, inputReference);\r
+ else\r
+ e.removeHint(SysdynElementHints.KEY_INPUT_REFERENCE);\r
+ }\r
+ \r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.HoverImpl;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+public class InputFactory extends SysdynElementFactory {\r
+\r
+ private static final BasicStroke STROKE = new BasicStroke(1f);\r
+ private static final Image INPUT_IMAGE = new ShapeImage(getInputShape(), null, STROKE, true);\r
+\r
+ static Shape getInputShape() {\r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(0, -1);\r
+ path.lineTo(5, -1);\r
+ path.lineTo(5, -2.5);\r
+ path.lineTo(7.5, 0);\r
+ path.curveTo(7.5, -2.5, 12.5, -2.5, 12.5, 0);\r
+ path.curveTo(12.5, 2.5, 7.5, 2.5, 7.5, 0);\r
+ path.lineTo(5, 2.5);\r
+ path.lineTo(5, 1);\r
+ path.lineTo(0, 1);\r
+ path.closePath();\r
+ return path;\r
+ }\r
+\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ TextFontImpl.DEFAULT,\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(INPUT_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ Input.INSTANCE,\r
+ new InputSceneGraph(0, 0, Alignment.LEADING),\r
+ BoundsOutline.INSTANCE,\r
+ HoverImpl.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(InputFactory.class.getSimpleName());\r
+ }\r
+\r
+ @Override\r
+ public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
+ super.load(graph, canvas, diagram, element, e);\r
+ Builtins b = graph.getBuiltins();\r
+ ModelingResources mr = ModelingResources.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource component = null;\r
+ Resource dependency = null;\r
+ Resource refersTo = null;\r
+ Resource module = null;\r
+ String moduleName = "";\r
+ String referenceName = "";\r
+ component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+ if(component != null) \r
+ dependency = graph.getPossibleObject(component, sr.IsHeadOf);\r
+ if(dependency != null) {\r
+ refersTo = graph.getPossibleObject(dependency, sr.RefersTo);\r
+ if(refersTo != null) {\r
+ referenceName = (String) graph.getPossibleRelatedValue(refersTo, b.HasName);\r
+ module = graph.getPossibleObject(dependency, sr.HasTail);\r
+ moduleName = (String) graph.getPossibleRelatedValue(module, b.HasName);\r
+ }\r
+ } else {\r
+ Resource runtime = diagram.getHint((DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE));\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+ String variable = (String)graph.getRelatedValue(runtime, dr.HasVariable);\r
+ Resource moduleRepresentation = graph.getPossibleResource(variable);\r
+ if(moduleRepresentation != null)\r
+ module = graph.getPossibleObject(moduleRepresentation, b.Represents);\r
+ if(module != null)\r
+ for(Resource dep : graph.getObjects(module, sr.IsHeadOf)) {\r
+ Resource reference = graph.getPossibleObject(dep, sr.RefersTo);\r
+ if(reference!= null && reference.equals(component)) {\r
+ refersTo = graph.getSingleObject(dep, sr.HasTail);\r
+ referenceName = (String) graph.getPossibleRelatedValue(refersTo, b.HasName);\r
+ moduleRepresentation = graph.getPossibleResource(variable.substring(0, variable.lastIndexOf("/")));\r
+ Resource parent = graph.getPossibleObject(moduleRepresentation, b.PartOf);\r
+ String parentURI = graph.getURI(parent);\r
+ String modelURI = diagram.getHint((DiagramModelHints.KEY_DIAGRAM_MODEL_URI));\r
+ module = graph.getPossibleObject(moduleRepresentation, b.Represents);\r
+ if(parentURI.equals(modelURI) || module == null)\r
+ moduleName = "";\r
+ else {\r
+ moduleName = (String) graph.getPossibleRelatedValue(module, b.HasName);\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ String inputReference = null;\r
+ if (moduleName != null && refersTo != null) {\r
+ inputReference = moduleName + "." + referenceName;\r
+ }\r
+ if (inputReference == null) {\r
+ inputReference = "";\r
+ }\r
+\r
+ SysdynElementUtils.setInputReference(e, inputReference);\r
+\r
+ Font font = ElementUtils.getTextFont(e);\r
+ font = font.deriveFont(font.getStyle() + Font.ITALIC);\r
+ ElementUtils.setTextFont(e, font);\r
+ ElementUtils.setHover(e, false);\r
+ }\r
+\r
+\r
+ public static class InputSceneGraph extends HoverTextElementNoBounds implements InternalSize {\r
+\r
+ private static final long serialVersionUID = -3713275157729126409L;\r
+ public static final Key INPUT_SG_NODE = new SceneGraphNodeKey(TextNode.class, "INPUT_SG_NODE");\r
+\r
+ private final double originX;\r
+ private final Alignment horizontalAlignment;\r
+\r
+ public InputSceneGraph(double originX, double originY, Alignment horizontalAlignment) {\r
+ super(originX, originY, horizontalAlignment, 0.0, 2.0, 2.0, true);\r
+ this.originX = originX;\r
+ this.horizontalAlignment = horizontalAlignment;\r
+ }\r
+\r
+ @Override\r
+ public void init(final IElement e, G2DParentNode parent) {\r
+ super.init(e, parent);\r
+ TextNode node = ElementUtils.getOrCreateNode(e, parent, INPUT_SG_NODE, "input", TextNode.class);\r
+ Font font = ElementUtils.getTextFont(e);\r
+ font = font.deriveFont((float) 10.0);\r
+ font = font.deriveFont(Font.ITALIC);\r
+ Color color = new Color(150, 150, 150);\r
+ Color fillColor = ElementUtils.getFillColor(e);\r
+ Color borderColor = ElementUtils.getBorderColor(e, Color.BLACK);\r
+ String text = SysdynElementUtils.getInputReference(e);\r
+ double scale = 0.235;\r
+ AffineTransform at = ElementUtils.getTransform(e);\r
+ node.init(text, font, color, originX, font.getSize2D() * scale, scale);\r
+ node.setBackgroundColor(fillColor);\r
+ node.setBorderColor(borderColor);\r
+ node.setHorizontalAlignment((byte) horizontalAlignment.ordinal());\r
+ node.setBorderWidth((float) 0);\r
+ node.setEditable(false);\r
+ node.setShowSelection(false);\r
+ \r
+ if(at != null)\r
+ node.setTransform(at);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+ TextNode name = (TextNode) e.getHint(SG_NODE);\r
+ TextNode reference = (TextNode) e.getHint(INPUT_SG_NODE);\r
+ if (size == null)\r
+ size = new Rectangle2D.Double();\r
+ if (name != null)\r
+ size.setRect(name.getBoundsInLocal());\r
+ if(reference != null) {\r
+ if (reference.getBoundsInLocal().getWidth() > size.getWidth())\r
+ size.setRect(size.getX(), size.getY(), reference.getBoundsInLocal().getWidth(), size.getHeight());\r
+ }\r
+ else\r
+ size.setFrame(0, 0, 0, 0);\r
+ return size;\r
+ }\r
+\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Font;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.utils.Alignment;\r
+\r
+public class ModuleFactory extends SysdynElementFactory {\r
+\r
+ private static final BasicStroke STROKE = new BasicStroke(1f);\r
+ private static final Image DEFAULT_IMAGE = new ShapeImage(new Rectangle2D.Double(-5, -2.5, 10, 5), null, STROKE, true);\r
+\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ new TextFontImpl(new Font("arial", Font.PLAIN, 25)),\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(DEFAULT_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ new HoverTextElementHandler(0, 0, Alignment.LEADING, 1f , 7, 7, false),\r
+ BoundsOutline.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(ModuleFactory.class.getSimpleName());\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.utils.Alignment;\r
+\r
+public class StockFactory extends SysdynElementFactory {\r
+\r
+ private static final BasicStroke STROKE = new BasicStroke(1f);\r
+ private static final Image DEFAULT_IMAGE = new ShapeImage(new Rectangle2D.Double(-5, -2.5, 10, 5), null, STROKE, true);\r
+\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ TextFontImpl.DEFAULT,\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(DEFAULT_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ new HoverTextElementHandler(0, 0, Alignment.LEADING, 1f),\r
+ BoundsOutline.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(StockFactory.class.getSimpleName());\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.Font;\r
+import java.awt.geom.AffineTransform;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.diagram.adapter.SyncElementFactory;\r
+import org.simantics.diagram.content.ResourceTerminal;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.CompositeHintSynchronizer;\r
+import org.simantics.diagram.synchronization.IHintSynchronizer;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.diagram.synchronization.graph.TransformSynchronizer;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * An ElementFactory that gathers common functionality for system dynamics symbols.\r
+ * Just implement {@link #compileElementClass(Resource, Collection)} to add a symbol.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public abstract class SysdynElementFactory extends SyncElementFactory {\r
+\r
+ public static final IHintSynchronizer SYNCHRONIZER = new CompositeHintSynchronizer(\r
+ ComponentNameSynchronizer.INSTANCE,\r
+ TransformSynchronizer.INSTANCE);\r
+\r
+ @Override\r
+ public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ G2DResource g2d = G2DResource.getInstance(graph);\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+ ModelingResources mr = ModelingResources.getInstance(graph);\r
+\r
+ Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+ String text = null;\r
+ if (component != null) {\r
+ text = (String) graph.getPossibleRelatedValue(component, b.HasName);\r
+ }\r
+ if (text == null)\r
+ text = "[empty]";\r
+\r
+ ElementUtils.setText(e, text);\r
+\r
+ if (graph.isInstanceOf(element, dr.FontProvider)) {\r
+ Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);\r
+ if (fontResource != null)\r
+ ElementUtils.setTextFont(e, G2DUtils.getFont(graph, fontResource));\r
+ }\r
+ if (graph.isInstanceOf(element, dr.ColorProvider)) {\r
+ Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);\r
+ if (colorResource != null)\r
+ ElementUtils.setTextColor(e, G2DUtils.getColor(graph, colorResource));\r
+ }\r
+\r
+ if (component != null && graph.hasStatement(component, SysdynResource.getInstance(graph).IsOutput)) {\r
+ Font font = ElementUtils.getTextFont(e);\r
+ font = font.deriveFont(Font.BOLD);\r
+ ElementUtils.setTextFont(e, font);\r
+ }\r
+\r
+ AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element);\r
+ ElementUtils.setTransform(e, at);\r
+\r
+ // This synchronizes only text and transformation (not font and color)\r
+ e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, SYNCHRONIZER);\r
+ \r
+ e.setHint(ElementHints.KEY_HOVER, false);\r
+ }\r
+\r
+ @Override\r
+ public ElementClass create(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType)\r
+ throws DatabaseException {\r
+ StructuralResource2 sr = StructuralResource2.getInstance(graph);\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+\r
+ Resource definedByList = graph.getPossibleObject(elementType, sr.IsDefinedBy);\r
+ Collection<Resource> definedBy = Collections.emptyList();\r
+ if (definedByList != null)\r
+ definedBy = OrderedSetUtils.toList(graph, definedByList);\r
+ Collection<ObjectTerminal> terminals = new ArrayList<ObjectTerminal>(definedBy.size());\r
+ for (Resource r : definedBy) {\r
+ if (graph.isInstanceOf(r, dr.Terminal)) {\r
+ terminals.add(new ResourceTerminal(r));\r
+ }\r
+ }\r
+\r
+ return compileElementClass(elementType, terminals);\r
+ }\r
+\r
+ /**\r
+ * @param elementType the type of the loaded element\r
+ * @param terminals the terminals of the element type being loaded\r
+ * @return an {@link ElementClass} representing the loaded element type\r
+ */\r
+ protected abstract ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals);\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+public class SysdynElementHints {\r
+\r
+ public static final Key KEY_INPUT_REFERENCE = new KeyOf(String.class, "INPUT_REFERENCE");\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+\r
+public class SysdynElementUtils {\r
+\r
+ \r
+ public static void setInputReference(IElement e, String inputReference)\r
+ {\r
+ Input i = e.getElementClass().getSingleItem(Input.class);\r
+ i.setInputReference(e, inputReference);\r
+ }\r
+\r
+ public static String getInputReference(IElement e)\r
+ {\r
+ Input i = e.getElementClass().getSingleItem(Input.class);\r
+ return i.getInputReference(e);\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.HandleMouseEvent;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
+import org.simantics.g2d.element.handler.impl.HoverImpl;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.OutlinePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
+import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
+import org.simantics.g2d.element.handler.impl.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+\r
+public class ValveFactory extends SysdynElementFactory {\r
+\r
+ public static final Key KEY_ROTATED = new KeyOf(Boolean.class, "ROTATED");\r
+\r
+ public static final double VALVE_SIZE = 2.5;\r
+\r
+ private static final BasicStroke STROKE = new BasicStroke(1f);\r
+ private static final Image VALVE_STATIC_IMAGE = new ShapeImage(createShape(VALVE_SIZE, false), null, STROKE, true);\r
+\r
+ /* (non-Javadoc)\r
+ * @see org.simantics.sysdyn.ui.elements2.SysdynElementFactory#compileElementClass(org.simantics.db.Resource, java.util.Collection)\r
+ */\r
+ @Override\r
+ protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+ return ElementClass.compile(\r
+ SimpleElementLayers.INSTANCE,\r
+ OutlinePick.INSTANCE,\r
+ TextImpl.INSTANCE,\r
+ TextColorImpl.BLACK,\r
+ TextFontImpl.DEFAULT,\r
+ DefaultTransform.INSTANCE,\r
+ new StaticObjectAdapter(elementType),\r
+ new StaticSymbolImpl(VALVE_STATIC_IMAGE),\r
+ StaticSymbolImageInitializer.INSTANCE,\r
+ HoverImpl.INSTANCE,\r
+ ValveSceneGraph.INSTANCE,\r
+ BoundsOutline.INSTANCE,\r
+ new WholeElementTerminals(terminals)\r
+ ).setId(ValveFactory.class.getSimpleName());\r
+ }\r
+ \r
+ /**\r
+ * @param valveSize\r
+ * @param rotated <code>true</code> for vertical valve, <code>false</code>\r
+ * for horizontal\r
+ * @return\r
+ */\r
+ private static Path2D createShape(double valveSize, boolean rotated) {\r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(-valveSize, -valveSize);\r
+ if(rotated) {\r
+ path.lineTo(-valveSize, +valveSize);\r
+ path.lineTo(+valveSize, -valveSize);\r
+ } else {\r
+ path.lineTo(+valveSize, -valveSize);\r
+ path.lineTo(-valveSize, +valveSize);\r
+ }\r
+ path.lineTo(+valveSize, +valveSize);\r
+ path.closePath();\r
+ return path;\r
+ }\r
+\r
+ public static class ValveSceneGraph extends HoverTextElementNoBounds implements InternalSize, HandleMouseEvent {\r
+\r
+ private static final long serialVersionUID = 5544256245734478634L;\r
+\r
+ public static final ValveSceneGraph INSTANCE = new ValveSceneGraph();\r
+\r
+ private static final Key NODE = new SceneGraphNodeKey(ShapeNode.class, "VALVE_NODE");\r
+ \r
+ private IHintListener hoverHintListener;\r
+\r
+ public ValveSceneGraph() {\r
+ super(0, VALVE_SIZE + 3.0, Alignment.CENTER);\r
+ }\r
+ @Override\r
+ public void init(IElement e, G2DParentNode parent) {\r
+ super.init(e, parent);\r
+ AffineTransform at = ElementUtils.getTransform(e);\r
+ final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "valve", HoverShapeNode.class);\r
+\r
+ // Calculate borders from text node bounds.\r
+ node.setStroke(STROKE);\r
+ node.setScaleStroke(true);\r
+ node.setColor(Color.BLACK);\r
+ node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))));\r
+ node.setHover(ElementUtils.isHovering(e));\r
+\r
+ if(at != null)\r
+ node.setTransform(at);\r
+ \r
+ hoverHintListener = new IHintListener() {\r
+ \r
+ @Override\r
+ public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+ IElement e = (IElement)sender;\r
+ HoverShapeNode shape = (HoverShapeNode) e.getHint(NODE);\r
+ if(shape == null) {\r
+ return;\r
+ }\r
+ boolean hover = ElementUtils.isHovering(e);\r
+ shape.setHover(hover);\r
+ }\r
+ };\r
+ e.addHintListener(hoverHintListener);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ e.removeHintListener(hoverHintListener);\r
+ ElementUtils.removePossibleNode(e, NODE);\r
+ }\r
+\r
+ @Override\r
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+ if (size == null)\r
+ size = new Rectangle2D.Double();\r
+ size.setFrame(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))).getBounds2D());\r
+ double paddingX = 2.0;\r
+ double paddingY = 2.0;\r
+ size.setRect(size.getX() - paddingX, size.getY() -paddingY, size.getWidth() + paddingX + paddingX, size.getHeight() + paddingY + paddingY);\r
+ return size;\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2;\r
+\r
+import java.awt.Shape;\r
+import java.util.Collection;\r
+\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.impl.ObjectTerminal;\r
+import org.simantics.g2d.element.handler.impl.Terminals;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class WholeElementTerminals extends Terminals {\r
+\r
+ private static final long serialVersionUID = -8209833430671135001L;\r
+\r
+ public WholeElementTerminals(Collection<ObjectTerminal> ts) {\r
+ super(ts);\r
+ }\r
+\r
+ @Override\r
+ public Shape getTerminalShape(IElement node, Terminal t) {\r
+ // For each terminal, return the shape of the element.\r
+ return ElementUtils.getElementShapeOrBounds(node);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+public class Arcs {\r
+\r
+ public static final double PI2 = Math.PI*2.0;\r
+ \r
+ /**\r
+ * Returns angle + 2PI * n such that the\r
+ * result is between -PI and PI.\r
+ */\r
+ public static double normalizeAngle(double angle) {\r
+ return Math.IEEEremainder(angle, PI2);\r
+ }\r
+ \r
+ /**\r
+ * Returns true, if three normalized angles are clockwise oriented.\r
+ */\r
+ public static boolean areClockwiseOrdered(double angle1, double angle2, double angle3) {\r
+ //System.out.println(angle1 + " " + angle2 + " " + angle3);\r
+ return angle1 < angle2 \r
+ ? (angle2 < angle3 || angle3 < angle1)\r
+ : (angle2 < angle3 && angle3 < angle1)\r
+ ;\r
+ }\r
+ \r
+ /**\r
+ * Returns an angle in radians between straight line from (x0,y0) to (x2,y2)\r
+ * and an arc from (x0,y0) to (x2,y2) thru (x1,y1). The angle\r
+ * is measured at (x0,y0) and is between -PI and PI.\r
+ */\r
+ public static double angleOfArc(\r
+ double x0, double y0, \r
+ double x1, double y1,\r
+ double x2, double y2) {\r
+ double dx0 = x1-x0;\r
+ double dy0 = y1-y0;\r
+ double dx1 = x1-x2;\r
+ double dy1 = y1-y2;\r
+ double dx = x2-x0;\r
+ double dy = y2-y0;\r
+ // Length of cross product (p1-p0)x(p2-p0)\r
+ double dd = dx0*dy - dy0*dx; \r
+ \r
+ if(Math.abs(dd) < 1e-6) // Points are (almost) collinear\r
+ return 0.0;\r
+ else { \r
+ // (p1-p0)*(p1-p2) / dd\r
+ double offset = (dx0*dx1 + dy0*dy1) / dd;\r
+ double angle = Math.PI*0.5 - Math.atan(offset);\r
+ if(dd > 0.0)\r
+ angle = angle-Math.PI;\r
+ return angle;\r
+ \r
+ }\r
+ }\r
+ \r
+ private static double updateBestNextAngle(double curAngle, double bestAngle, double newAngle) {\r
+ if(newAngle < curAngle)\r
+ newAngle += PI2;\r
+ if(newAngle < bestAngle)\r
+ return newAngle;\r
+ return bestAngle; \r
+ } \r
+ \r
+ private static double updateBestPrevAngle(double curAngle, double bestAngle, double newAngle) {\r
+ if(newAngle > curAngle)\r
+ newAngle -= PI2;\r
+ if(newAngle > bestAngle)\r
+ return newAngle;\r
+ return bestAngle; \r
+ } \r
+ \r
+ public static double nextIntersectingAngle(double cx, double cy, double r,\r
+ double curAngle, Rectangle2D rect, boolean dir) {\r
+ if(!dir) {\r
+ double bestAngle = curAngle + PI2;\r
+ {\r
+ double dx = rect.getMinX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dx = rect.getMaxX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMinY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMaxY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestNextAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ return normalizeAngle(bestAngle);\r
+ } \r
+ else {\r
+ double bestAngle = curAngle - PI2;\r
+ {\r
+ double dx = rect.getMinX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dx = rect.getMaxX() - cx;\r
+ if(Math.abs(dx) < r) {\r
+ double angle = normalizeAngle(Math.acos(dx / r));\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle);\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMinY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ {\r
+ double dy = cy - rect.getMaxY();\r
+ if(Math.abs(dy) < r) {\r
+ double angle = Math.asin(dy / r);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle);\r
+ bestAngle = updateBestPrevAngle(curAngle, bestAngle, \r
+ normalizeAngle(Math.PI-angle));\r
+ }\r
+ }\r
+ return normalizeAngle(bestAngle);\r
+ }\r
+ }\r
+ \r
+ public static boolean hitTest(Rectangle2D beginBounds, Rectangle2D endBounds, double angle, double x, double y, double tolerance) {\r
+ \r
+ boolean clockWise = angle > 0;\r
+ \r
+ double x0 = beginBounds.getCenterX();\r
+ double y0 = beginBounds.getCenterY();\r
+ double x1 = endBounds.getCenterX();\r
+ double y1 = endBounds.getCenterY();\r
+ \r
+ double offset = \r
+ Math.abs(angle) < 1.0e-6\r
+ ? 1e3 * Math.signum(angle)\r
+ : Math.tan(Math.PI*0.5-angle)*0.5;\r
+ double cx = 0.5*(x0+x1) + offset * (y1-y0);\r
+ double cy = 0.5*(y0+y1) + offset * (x0-x1);\r
+ double dx0 = x0 - cx;\r
+ double dy0 = y0 - cy;\r
+ double dx1 = x1 - cx;\r
+ double dy1 = y1 - cy;\r
+ double r = Math.sqrt(dx0*dx0 + dy0*dy0);\r
+ double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy0, dx0), beginBounds, angle < 0.0);\r
+ double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy1, dx1), endBounds, angle > 0.0);\r
+ \r
+ double dx = x-cx;\r
+ double dy = y-cy;\r
+ double dist = dx*dx + dy*dy;\r
+ \r
+// System.out.println("HitTest: x0=" + x0 + " y0=" + y0 + " y=" + y + " x=" + x + " dist=" + dist + " r2=" + r*r);\r
+ \r
+ if(dist < (r+tolerance)*(r+tolerance) &&\r
+ dist > (r-tolerance)*(r-tolerance)) {\r
+ double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
+// System.out.println("test " + angle0 + " " + ang + " " + angle1);\r
+ if(Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) {\r
+// System.out.println("hit");\r
+ return true;\r
+ }\r
+ }\r
+ \r
+ return false;\r
+ \r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+public class ConnectionClasses {\r
+\r
+ public static final Object CONNECTION = new Object() {\r
+ public String toString() { return "CONNECTION"; }\r
+ };\r
+\r
+ public static final Object FLAG = new Object() {\r
+ public String toString() { return "FLAG"; }\r
+ };\r
+\r
+ public static final Object FLOW = new Object() {\r
+ public String toString() { return "FLOW"; }\r
+ };\r
+\r
+ public static final Object DEPENDENCY = new Object() {\r
+ public String toString() { return "DEPENDENCY"; }\r
+ };\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.Arc2D;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class Dependencies {\r
+ \r
+ /*\r
+ * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
+ */\r
+ public static double ARROW_LENGTH1 = 0.2;\r
+ public static double ARROW_LENGTH2 = 1.0;\r
+ public static double ARROW_WIDTH = 0.5;\r
+ \r
+//\r
+// // Auxiliary \r
+// double angle0;\r
+// double angle1;\r
+// double cx;\r
+// double cy;\r
+// double r;\r
+// \r
+// // Scene graph\r
+// ShapeNode arcNode;\r
+// FilledShapeNode arrowNode;\r
+// \r
+// public Dependencies() { \r
+// }\r
+// \r
+// public Dependencies(Connectable tail, Connectable head) {\r
+// super();\r
+// this.tail = tail;\r
+// this.head = head;\r
+// }\r
+// \r
+// @Override\r
+// public void elementUpdated(IElement element) {\r
+// update(); \r
+// } \r
+//\r
+// @Override\r
+// public void remove() {\r
+// arcNode.remove();\r
+// arrowNode.remove();\r
+// tail.removeListener(this);\r
+// head.removeListener(this);\r
+// super.remove();\r
+// }\r
+//\r
+// @Override\r
+// public void init(G2DParentNode parent) {\r
+// tail.addListener(this);\r
+// head.addListener(this);\r
+// \r
+// arcNode = parent.addNode(ShapeNode.class);\r
+// arcNode.setScaleStroke(true);\r
+// arcNode.setStroke(new BasicStroke(1));\r
+// arrowNode = parent.addNode(FilledShapeNode.class);\r
+// update();\r
+// }\r
+// \r
+ \r
+ private static Shape createArrow(double x, double y, double dx, double dy) {\r
+ Path2D path = new Path2D.Double();\r
+ path.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy);\r
+ x -= ARROW_LENGTH2*dx;\r
+ y -= ARROW_LENGTH2*dy;\r
+ path.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx);\r
+ path.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx);\r
+ path.closePath();\r
+ return path;\r
+ }\r
+ \r
+ public static Point2D computeCenter(Rectangle2D tail, Rectangle2D head, double angle) {\r
+\r
+ double x0 = tail.getCenterX();\r
+ double y0 = tail.getCenterY();\r
+ double x1 = head.getCenterX();\r
+ double y1 = head.getCenterY();\r
+ \r
+// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1);\r
+ \r
+ double offset = \r
+ Math.abs(angle) < 1.0e-6\r
+ ? 1e3 * Math.signum(angle)\r
+ : Math.tan(Math.PI*0.5-angle)*0.5;\r
+ \r
+ double cx = 0.5*(x0+x1) + offset * (y1-y0);\r
+ double cy = 0.5*(y0+y1) + offset * (x0-x1);\r
+ \r
+ return new Point2D.Double(cx, cy);\r
+ \r
+ }\r
+ \r
+ public static Pair<Shape, Shape> createArrowShape(Rectangle2D tail, Rectangle2D head, double angle) {\r
+\r
+ double x0 = tail.getCenterX();\r
+ double y0 = tail.getCenterY();\r
+ double x1 = head.getCenterX();\r
+ double y1 = head.getCenterY();\r
+ \r
+// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1);\r
+ \r
+ double offset = \r
+ Math.abs(angle) < 1.0e-6\r
+ ? 1e3 * Math.signum(angle)\r
+ : Math.tan(Math.PI*0.5-angle)*0.5;\r
+ \r
+ double cx = 0.5*(x0+x1) + offset * (y1-y0);\r
+ double cy = 0.5*(y0+y1) + offset * (x0-x1);\r
+ double dx0 = x0 - cx;\r
+ double dy0 = y0 - cy;\r
+ double dx1 = x1 - cx;\r
+ double dy1 = y1 - cy;\r
+ \r
+ double r = Math.sqrt(dx0*dx0 + dy0*dy0);\r
+ \r
+// Rectangle2D bounds = new Rectangle2D.Double();\r
+// tail.getBounds(bounds);\r
+ double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy0, dx0), tail, angle < 0.0);\r
+// head.getBounds(bounds);\r
+ double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+ Math.atan2(-dy1, dx1), head, angle > 0.0);\r
+ double extent = angle1-angle0;\r
+ //double arcAngle = angle0;\r
+ if(angle < 0.0) {\r
+ double temp = angle0; \r
+ angle0 = angle1;\r
+ angle1 = temp;\r
+ extent = -extent;\r
+ } \r
+ if(extent < 0)\r
+ extent += Math.PI*2.0;\r
+ else if(extent >= 360.0)\r
+ extent -= Math.PI*2.0;\r
+ Shape shape1 = new Arc2D.Double(cx-r, cy-r, 2*r, 2*r, \r
+ Math.toDegrees(angle0), \r
+ Math.toDegrees(extent), \r
+ Arc2D.OPEN);\r
+// \r
+ double xx = Math.cos(angle > 0.0 ? angle1 : angle0);\r
+ double yy = -Math.sin(angle > 0.0 ? angle1 : angle0);\r
+\r
+ Shape arrowShape = createArrow(cx + r*xx, cy + r*yy, \r
+ angle < 0.0 ? -yy : yy, \r
+ angle > 0.0 ? -xx : xx);\r
+\r
+ return Pair.make(shape1, arrowShape);\r
+ \r
+ }\r
+// \r
+// public void update() {\r
+// if(arcNode != null)\r
+// updateSceneGraph();\r
+// fireElementUpdated();\r
+// }\r
+// \r
+// @Override\r
+// public void getBounds(Rectangle2D bounds) {\r
+// bounds.setFrame(arcNode.getBounds());\r
+// }\r
+//\r
+// @Override\r
+// public boolean hitTest(double x, double y, double tolerance) {\r
+// double dx = x-cx;\r
+// double dy = y-cy;\r
+// double dist = dx*dx + dy*dy;\r
+// if(dist < (r+tolerance)*(r+tolerance) &&\r
+// dist > (r-tolerance)*(r-tolerance)) {\r
+// double angle = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
+// if(Arcs.areClockwiseOrdered(angle0, angle, angle1))\r
+// return true;\r
+// }\r
+// return false;\r
+// }\r
+// \r
+// class EventHandler extends DragEventHandler {\r
+// @Override\r
+// protected boolean begin(IDiagramEditor editor, DragEvent event) {\r
+// return event.startModifiers.equals("left");\r
+// }\r
+// \r
+// @Override\r
+// protected void update(IDiagramEditor editor, DragEvent event) {\r
+// if(event == null)\r
+// return;\r
+// angle = Arcs.angleOfArc(\r
+// tail.getOrigo().getX(), tail.getOrigo().getY(), \r
+// event.current.getX(), event.current.getY(), \r
+// head.getOrigo().getX(), head.getOrigo().getY()\r
+// );\r
+// Dependencies.this.update();\r
+// editor.requestRepaint();\r
+// }\r
+// }\r
+//\r
+// @SuppressWarnings("unchecked")\r
+// @Override\r
+// public <T> T getInterface(Class<T> clazz) {\r
+// if(clazz == IEventHandler.class) \r
+// return (T)new EventHandler();\r
+// return super.getInterface(clazz);\r
+// }\r
+//\r
+// @Override\r
+// public void elementRemoved(IElement element) {\r
+// remove(); \r
+// }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.util.HashMap;\r
+import java.util.concurrent.ConcurrentSkipListMap;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.AsyncMultiProcedure;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.routing.RouterFactory;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * An element class for single connection entity elements. A connection entity\r
+ * consists of connection edge segments and branch points as its children.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class DependencyConnectionFactory extends ElementFactoryAdapter {\r
+\r
+ public static final ElementClass CLASS = SysdynConnectionClass.CLASS;\r
+\r
+ @Override\r
+ public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
+ DiagramResource dr = graph.getService(DiagramResource.class);\r
+ graph.forSingleType(elementType, dr.Connection, new AsyncProcedure<Resource>() {\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ procedure.exception(graph, throwable);\r
+ }\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, Resource connectionType) {\r
+ procedure.execute(graph, SysdynConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(connectionType)));\r
+ }\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, final Resource elementResource,\r
+ final IElement element, final AsyncProcedure<IElement> procedure) {\r
+ \r
+ final AtomicInteger ready = new AtomicInteger(1);\r
+ final ConcurrentSkipListMap<String, Pair<Resource, Object>> properties = new ConcurrentSkipListMap<String, Pair<Resource, Object>>();\r
+ \r
+ element.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false));\r
+\r
+ graph.forEachPredicate(elementResource, new AsyncMultiProcedure<Resource>() {\r
+\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ throwable.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, final Resource property) {\r
+ \r
+ ready.incrementAndGet();\r
+\r
+ graph.forIsSubrelationOf(property, graph.getBuiltins().HasProperty, new AsyncProcedure<Boolean>() {\r
+\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ throwable.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, final Boolean isProperty) {\r
+ \r
+ if(isProperty) {\r
+ \r
+ graph.forPossibleRelatedValue(elementResource, property, new AsyncProcedure<Object>() {\r
+\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ throwable.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, final Object value) {\r
+\r
+ graph.forPossibleRelatedValue(property, graph.getBuiltins().HasName, StringBindingDefault.INSTANCE, new AsyncProcedure<String>() {\r
+\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ throwable.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, String name) {\r
+ \r
+ properties.put(name, Pair.make(property, value));\r
+// System.out.println("load properties " + name + " => " + value);\r
+ if(ready.decrementAndGet() == 0) {\r
+ element.setHint(DiagramHints.PROPERTIES, new HashMap<String, Pair<Resource, Object>>(properties));\r
+ procedure.execute(graph, element);\r
+ }\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ \r
+ } else {\r
+\r
+ if(ready.decrementAndGet() == 0) {\r
+ element.setHint(DiagramHints.PROPERTIES, new HashMap<String, Pair<Resource, Object>>(properties));\r
+ procedure.execute(graph, element);\r
+ }\r
+ \r
+ }\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void finished(AsyncReadGraph graph) {\r
+ \r
+ if(ready.decrementAndGet() == 0) {\r
+ element.setHint(DiagramHints.PROPERTIES, new HashMap<String, Object>(properties));\r
+ procedure.execute(graph, element);\r
+ }\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.util.Map;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.DiagramMutator;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.Topology;\r
+import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.EdgeVisuals;\r
+import org.simantics.g2d.element.handler.Pick;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.g2d.element.handler.TerminalLayout;\r
+import org.simantics.g2d.element.handler.Transform;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;\r
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
+import org.simantics.g2d.element.handler.impl.FillColorImpl;\r
+import org.simantics.g2d.element.handler.impl.ParentImpl;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+public class DependencyEdgeClass {\r
+\r
+ public static class NodePick implements Pick {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public boolean pickTest(IElement e, Shape s, PickPolicy policy) {\r
+ Rectangle2D pickRect = null;\r
+ if (s instanceof Rectangle2D)\r
+ pickRect = (Rectangle2D) s;\r
+ else\r
+ // FIXME: suboptimal, but works.\r
+ pickRect = s.getBounds2D();\r
+\r
+ DependencyNode node = e.getHint(SysdynEdgeSceneGraph.KEY_SG_NODE);\r
+ if(node == null) {\r
+ System.out.println("pickTest no node!");\r
+ return false;\r
+ }\r
+ \r
+ return Arcs.hitTest(node.beginBounds, node.endBounds, node.angle, pickRect.getCenterX(), pickRect.getCenterY(), 3.0);\r
+ \r
+ }\r
+\r
+ }\r
+ \r
+ // TODO scale, rotate, move, transform\r
+ public static final ElementClass CLASS =\r
+ ElementClass.compile(\r
+ SysdynEdgeSceneGraph.INSTANCE,\r
+ EdgeHandler.INSTANCE,\r
+ ConfigurableEdgeVisuals.DEFAULT,\r
+ FillColorImpl.BLACK,\r
+ FixedTransform.INSTANCE,\r
+ new NodePick(),\r
+ ConnectionSelectionOutline.INSTANCE,\r
+ SimpleElementLayers.INSTANCE,\r
+ ParentImpl.INSTANCE\r
+ ).setId("EdgeClass.STRAIGHT");\r
+\r
+ public static class SysdynEdgeSceneGraph implements SceneGraph {\r
+\r
+ private static final long serialVersionUID = 2914383071126238996L;\r
+\r
+ public static final SysdynEdgeSceneGraph INSTANCE = new SysdynEdgeSceneGraph();\r
+\r
+ public static final Stroke ARROW_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);\r
+\r
+ public static final Key KEY_SG_NODE = new SceneGraphNodeKey(DependencyNode.class, "EDGE_NODE");\r
+\r
+ @Override\r
+ public void init(IElement e, G2DParentNode parent) {\r
+ ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), DependencyNode.class);\r
+ update(e);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ ElementUtils.removePossibleNode(e, KEY_SG_NODE);\r
+ }\r
+ \r
+ public void update(final IElement e) {\r
+ \r
+ DependencyNode node = e.getHint(KEY_SG_NODE);\r
+ if(node == null) return;\r
+ \r
+ final IDiagram diagram = ElementUtils.peekDiagram(e);\r
+ \r
+ node.setFieldListener(new PropertyChangeListener() {\r
+\r
+ @Override\r
+ public void propertyChange(final PropertyChangeEvent event) {\r
+ \r
+ String field = event.getPropertyName();\r
+ Map<String, Pair<Resource, Object>> properties = e.getHint(DiagramHints.PROPERTIES);\r
+ if(properties == null) return;\r
+ final Pair<Resource, Object> property = properties.get(field);\r
+ if(property == null) return;\r
+\r
+ DiagramUtils.mutateDiagram(diagram, new Callback<DiagramMutator>() {\r
+ \r
+ @Override\r
+ public void run(DiagramMutator mutator) {\r
+ mutator.modifyProperty(e, property.first, event.getNewValue());\r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ });\r
+\r
+ EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class);\r
+ Stroke stroke = vh.getStroke(e);\r
+ Color c = ElementUtils.getFillColor(e, Color.BLACK);\r
+\r
+ Shape beginTerminalShape = null;\r
+ Shape endTerminalShape = null;\r
+ if (diagram != null) {\r
+ Topology topology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
+ if (topology != null) {\r
+ Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin);\r
+ Connection endConnection = topology.getConnection(e, EdgeEnd.End);\r
+ beginTerminalShape = getCanvasTerminalShape(beginConnection);\r
+ endTerminalShape = getCanvasTerminalShape(endConnection);\r
+ }\r
+ }\r
+ \r
+ if(beginTerminalShape == null || endTerminalShape == null) return;\r
+ \r
+ node.setProperty("beginBounds", beginTerminalShape.getBounds2D());\r
+ node.setProperty("endBounds", endTerminalShape.getBounds2D());\r
+ node.setProperty("stroke", stroke);\r
+ node.setProperty("color", c);\r
+ node.setProperty("angle", 0.1);\r
+\r
+ Map<String, Pair<Resource, Object>> properties = e.getHint(DiagramHints.PROPERTIES);\r
+ if(properties != null) {\r
+ for(Map.Entry<String, Pair<Resource, Object>> entry : properties.entrySet()) {\r
+ node.setProperty(entry.getKey(), entry.getValue().second);\r
+// System.out.println("setProperty " + entry.getKey() + " => " + entry.getValue().second);\r
+ }\r
+ }\r
+ \r
+ Pair<Shape, Shape> shapes = Dependencies.createArrowShape(beginTerminalShape.getBounds2D(), endTerminalShape.getBounds2D(), node.angle);\r
+ EdgeHandler eh = e.getElementClass().getAtMostOneItemOfClass(EdgeHandler.class);\r
+ Path2D path = new Path2D.Double(shapes.first);\r
+ eh.setPath(e, path);\r
+\r
+ }\r
+\r
+ private static Shape getCanvasTerminalShape(Connection connection) {\r
+ if (connection != null && connection.node != null && connection.terminal != null) {\r
+ TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class);\r
+ if (layout != null) {\r
+ //return layout.getTerminalShape(connection.node, connection.terminal);\r
+ Shape shp = layout.getTerminalShape(connection.node, connection.terminal);\r
+ Transform tr = connection.node.getElementClass().getAtMostOneItemOfClass(Transform.class);\r
+ if (tr == null)\r
+ return shp;\r
+\r
+ return tr.getTransform(connection.node).createTransformedShape(shp);\r
+ \r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+\r
+/**\r
+ * An element class factory for sysdyn dependency connection edge segments.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class DependencyEdgeFactory extends ElementFactoryAdapter {\r
+\r
+ private static final ElementClass CLASS = DependencyEdgeClass.CLASS;\r
+\r
+ @Override\r
+ public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
+ AsyncProcedure<ElementClass> procedure) {\r
+ procedure.execute(graph, CLASS);\r
+ }\r
+\r
+ @Override\r
+ public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource,\r
+ AsyncProcedure<ElementClass> procedure) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.RenderingHints;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.scenegraph.ISelectionPainterNode;\r
+import org.simantics.scenegraph.g2d.events.SGMouseEvent;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.ui.elements2.GraphPropertyNode;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class DependencyNode extends GraphPropertyNode implements ISelectionPainterNode {\r
+\r
+ private static final long serialVersionUID = 1294351381209071074L;\r
+\r
+ public Color color;\r
+ public Stroke stroke;\r
+ public Rectangle2D beginBounds;\r
+ public Rectangle2D endBounds;\r
+ public double angle = 0.1;\r
+ \r
+ transient public boolean hover = false;\r
+ \r
+ @Override\r
+ public void render(Graphics2D g) {\r
+\r
+ // NICENESS\r
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+\r
+// System.out.println("dep " + angle + " " + beginBounds + " " + endBounds);\r
+ \r
+ Pair<Shape, Shape> shapes = Dependencies.createArrowShape(beginBounds, endBounds, angle);\r
+\r
+ boolean selected = NodeUtil.isSelected(this, 2);\r
+ if(selected) {\r
+ g.setColor(Color.PINK);\r
+ g.setStroke(new BasicStroke(1.0f));\r
+ g.draw(shapes.first);\r
+ g.fill(shapes.second);\r
+ if(color != null) g.setColor(color);\r
+ g.setStroke(stroke);\r
+ g.draw(shapes.first);\r
+ g.fill(shapes.second);\r
+ } else if (hover){\r
+ g.setColor(Color.LIGHT_GRAY);\r
+ g.setStroke(new BasicStroke(1.0f));\r
+ g.draw(shapes.first);\r
+ g.fill(shapes.second);\r
+ if(color != null) g.setColor(color);\r
+ g.setStroke(stroke);\r
+ g.draw(shapes.first);\r
+ g.fill(shapes.second);\r
+ } else {\r
+ if(color != null) g.setColor(color);\r
+ if(stroke != null) g.setStroke(stroke);\r
+ g.draw(shapes.first);\r
+ g.fill(shapes.second);\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public boolean hitTest(double x, double y, double tolerance) {\r
+ return Arcs.hitTest(beginBounds, endBounds, angle, x, y, tolerance);\r
+ }\r
+ \r
+ @Override\r
+ public void mouseDragged(SGMouseEvent event, boolean pressHit, boolean currentHit) {\r
+ \r
+ if(!pressHit) return;\r
+ \r
+ angle = Arcs.angleOfArc(\r
+ beginBounds.getCenterX(), beginBounds.getCenterY(), \r
+ event.getDoubleX(), event.getDoubleY(), \r
+ endBounds.getCenterX(), endBounds.getCenterY());\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void mouseReleased(SGMouseEvent event, boolean hit) {\r
+ if(hit) commitProperty("angle", angle);\r
+ }\r
+ \r
+ @Override\r
+ public void mouseMoved(SGMouseEvent event, boolean hit) {\r
+ if(hit != hover) {\r
+ hover = hit;\r
+ repaint();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.elementclass.connection.ConnectionClass;\r
+import org.simantics.g2d.routing.RouterFactory;\r
+\r
+/**\r
+ * An element class for single connection entity elements. A connection entity\r
+ * consists of connection edge segments and branch points as its children.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class FlowConnectionFactory extends ElementFactoryAdapter {\r
+\r
+ public static final ElementClass CLASS = SysdynConnectionClass.CLASS;\r
+\r
+ @Override\r
+ public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
+ DiagramResource dr = graph.getService(DiagramResource.class);\r
+ graph.forSingleType(elementType, dr.Connection, new AsyncProcedure<Resource>() {\r
+ @Override\r
+ public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+ procedure.exception(graph, throwable);\r
+ }\r
+ @Override\r
+ public void execute(AsyncReadGraph graph, Resource connectionType) {\r
+ procedure.execute(graph, ConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(connectionType)));\r
+ }\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource,\r
+ final IElement element, final AsyncProcedure<IElement> procedure) {\r
+ element.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(true, true));\r
+ procedure.execute(graph, element);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.util.Map;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.DiagramMutator;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.Topology;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.g2d.element.handler.TerminalLayout;\r
+import org.simantics.g2d.element.handler.Transform;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals;\r
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
+import org.simantics.g2d.element.handler.impl.FillColorImpl;\r
+import org.simantics.g2d.element.handler.impl.ParentImpl;\r
+import org.simantics.g2d.element.handler.impl.ShapePick;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.sysdyn.ui.elements2.ValveFactory.ValveSceneGraph;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+\r
+/**\r
+ * @author Toni Kalajainen\r
+ */\r
+public class FlowEdgeClass {\r
+\r
+ // TODO scale, rotate, move, transform\r
+ public static final ElementClass CLASS =\r
+ ElementClass.compile(\r
+ SysdynEdgeSceneGraph.INSTANCE,\r
+ EdgeHandler.INSTANCE,\r
+ ConfigurableEdgeVisuals.DEFAULT,\r
+ FillColorImpl.BLACK,\r
+ FixedTransform.INSTANCE,\r
+ ShapePick.INSTANCE,\r
+ ConnectionSelectionOutline.INSTANCE,\r
+ SimpleElementLayers.INSTANCE,\r
+ ParentImpl.INSTANCE\r
+ ).setId("EdgeClass.STRAIGHT");\r
+\r
+ public static class SysdynEdgeSceneGraph implements SceneGraph {\r
+\r
+ private static final long serialVersionUID = 2914383071126238996L;\r
+\r
+ public static final SysdynEdgeSceneGraph INSTANCE = new SysdynEdgeSceneGraph();\r
+\r
+ public static final Stroke ARROW_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);\r
+\r
+ public static final Key KEY_SG_NODE = new SceneGraphNodeKey(FlowNode.class, "EDGE_NODE");\r
+\r
+ @Override\r
+ public void init(IElement e, G2DParentNode parent) {\r
+ ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), FlowNode.class);\r
+ update(e);\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ ElementUtils.removePossibleNode(e, KEY_SG_NODE);\r
+ }\r
+\r
+ public void update(final IElement e) {\r
+ \r
+ FlowNode node = e.getHint(KEY_SG_NODE);\r
+ if(node == null) return;\r
+\r
+ final IDiagram diagram = ElementUtils.peekDiagram(e);\r
+ \r
+ node.setFieldListener(new PropertyChangeListener() {\r
+\r
+ @Override\r
+ public void propertyChange(final PropertyChangeEvent event) {\r
+ \r
+ DiagramUtils.mutateDiagram(diagram, new Callback<DiagramMutator>() {\r
+ \r
+ @Override\r
+ public void run(DiagramMutator mutator) {\r
+\r
+ String field = event.getPropertyName();\r
+ Map<String, Pair<Resource, Object>> properties = e.getHint(DiagramHints.PROPERTIES);\r
+ Pair<Resource, Object> property = properties.get(field);\r
+ \r
+ mutator.modifyProperty(e, property.first, event.getNewValue());\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ Stroke stroke = new BasicStroke(0.1f);\r
+ Color c = ElementUtils.getFillColor(e, Color.BLACK);\r
+\r
+ Shape beginTerminalShape = null;\r
+ Shape endTerminalShape = null;\r
+ boolean toValve = false;\r
+ if (diagram != null) {\r
+ Topology topology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class);\r
+ if (topology != null) {\r
+ Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin);\r
+ Connection endConnection = topology.getConnection(e, EdgeEnd.End);\r
+ beginTerminalShape = getCanvasTerminalShape(beginConnection);\r
+ endTerminalShape = getCanvasTerminalShape(endConnection);\r
+ toValve = endConnection.node.getElementClass().containsClass(ValveSceneGraph.class);\r
+// System.out.println("end connection class = " + endConnection.node.getElementClass());\r
+ }\r
+ }\r
+\r
+ if(beginTerminalShape == null || endTerminalShape == null) return;\r
+ \r
+ node.setProperty("beginBounds", beginTerminalShape.getBounds2D());\r
+ node.setProperty("endBounds", endTerminalShape.getBounds2D());\r
+ node.setProperty("stroke", stroke);\r
+ node.setProperty("color", c);\r
+ node.setProperty("toValve", toValve);\r
+// System.out.println("set toValve = " + toValve);\r
+ node.toValve = toValve;\r
+\r
+ Map<String, Pair<Resource, Object>> properties = e.getHint(DiagramHints.PROPERTIES);\r
+ if(properties != null) {\r
+ for(Map.Entry<String, Pair<Resource, Object>> entry : properties.entrySet()) {\r
+ node.setProperty(entry.getKey(), entry.getValue().second);\r
+ }\r
+ }\r
+ \r
+ }\r
+\r
+ private static Shape getCanvasTerminalShape(Connection connection) {\r
+ if (connection != null && connection.node != null && connection.terminal != null) {\r
+ TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class);\r
+ if (layout != null) {\r
+ //return layout.getTerminalShape(connection.node, connection.terminal);\r
+ Shape shp = layout.getTerminalShape(connection.node, connection.terminal);\r
+ Transform tr = connection.node.getElementClass().getAtMostOneItemOfClass(Transform.class);\r
+ if (tr == null)\r
+ return shp;\r
+\r
+ return tr.getTransform(connection.node).createTransformedShape(shp);\r
+ \r
+ }\r
+ }\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementClass;\r
+\r
+/**\r
+ * An element class factory for sysdyn flow connection edge segments.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class FlowEdgeFactory extends ElementFactoryAdapter {\r
+\r
+ private static final ElementClass CLASS = FlowEdgeClass.CLASS;\r
+\r
+ @Override\r
+ public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
+ AsyncProcedure<ElementClass> procedure) {\r
+ procedure.execute(graph, CLASS);\r
+ }\r
+\r
+ @Override\r
+ public void getClass(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource,\r
+ AsyncProcedure<ElementClass> procedure) {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.RenderingHints;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.scenegraph.ISelectionPainterNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.ui.elements2.GraphPropertyNode;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class FlowNode extends GraphPropertyNode implements ISelectionPainterNode {\r
+\r
+ private static final long serialVersionUID = 328942356917631237L;\r
+ \r
+ public Color color;\r
+ public Stroke stroke;\r
+ public Rectangle2D beginBounds;\r
+ public Rectangle2D endBounds;\r
+ public Boolean toValve;\r
+ \r
+ @Override\r
+ public void render(Graphics2D g) {\r
+ \r
+ // NICENESS\r
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+\r
+ /*\r
+ * There are two cases, first is from Stock|Cloud to Valve and second is from Valve to Stock|Cloud\r
+ * -In the first case there is no arrow and valve is endBounds\r
+ * -In the second case there is an arrow and valve is beginBounds\r
+ */\r
+ \r
+ Pair<Shape, Shape> lines = null;\r
+ Shape arrow = null;\r
+\r
+// System.out.println("FlowNode.render toValve = " + toValve);\r
+ \r
+ if(toValve) {\r
+ \r
+ lines = Flows.createLines(false, endBounds, beginBounds);\r
+\r
+ } else {\r
+\r
+ lines = Flows.createLines(true, beginBounds, endBounds);\r
+ arrow = Flows.createArrow(beginBounds, endBounds);\r
+ \r
+ }\r
+ \r
+ boolean selected = NodeUtil.isSelected(this, 2);\r
+ if(selected) {\r
+ g.setColor(Color.PINK);\r
+ g.setStroke(new BasicStroke(1.0f));\r
+ g.draw(lines.first);\r
+ g.draw(lines.second);\r
+ if(color != null) g.setColor(color);\r
+ g.setStroke(stroke);\r
+ g.draw(lines.first);\r
+ g.draw(lines.second);\r
+ if(arrow != null) g.fill(arrow);\r
+ } else {\r
+ if(color != null) g.setColor(color);\r
+ if(stroke != null) g.setStroke(stroke);\r
+ g.draw(lines.first);\r
+ g.draw(lines.second);\r
+ if(arrow != null) g.fill(arrow);\r
+ }\r
+ \r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.elements2.connections;\r
+\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+\r
+public class FlowStroke implements Stroke {\r
+ private Stroke stroke1, stroke2;\r
+\r
+ public FlowStroke( Stroke stroke1, Stroke stroke2 ) {\r
+ this.stroke1 = stroke1;\r
+ this.stroke2 = stroke2;\r
+ }\r
+\r
+ public Shape createStrokedShape( Shape shape ) {\r
+ return stroke2.createStrokedShape( stroke1.createStrokedShape( shape ) );\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class Flows {\r
+ \r
+ public static double ARROW_LENGTH = 3.2;\r
+ public static double ARROW_WIDTH = 2;\r
+\r
+ static final double OFFSET = 1.0;\r
+ static final double ARROW_OFFSET = 3.2;\r
+\r
+ public static Path2D createArrow(Rectangle2D tail, Rectangle2D head) { \r
+\r
+ double x = tail.getCenterX();\r
+ double y = tail.getCenterY();\r
+\r
+// Rectangle2D rect = new Rectangle2D.Double();\r
+// head.getBounds(rect);\r
+ double cx = head.getCenterX();\r
+ double minx = head.getMinX();\r
+ double maxx = head.getMaxX();\r
+ double miny = head.getMinY();\r
+ double maxy = head.getMaxY();\r
+\r
+ Path2D path = new Path2D.Double();\r
+\r
+ // approach from top\r
+ if (y < miny) {\r
+ path.moveTo(cx, miny);\r
+ path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
+ } \r
+\r
+ // approach from beneath\r
+ else if (y > maxy) {\r
+ path.moveTo(cx, maxy);\r
+ path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+ }\r
+\r
+ // approach from left\r
+ else if (x < minx) {\r
+ path.moveTo(minx, y);\r
+ path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
+ path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
+ }\r
+\r
+ // approach from right\r
+ else if (x > maxx) {\r
+ path.moveTo(maxx, y);\r
+ path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
+ path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH);\r
+ }\r
+ else\r
+ return null; // FIXME (HN) This is just a quick bugfix, didn't understand the logic completely \r
+\r
+ path.closePath();\r
+ \r
+ return path;\r
+ \r
+ }\r
+ \r
+ private static Pair<Shape, Shape> createLines(boolean vertical, double ... coordinates) {\r
+ \r
+// lineNode1.setShape(createOffsetLine(vertical, OFFSET, coordinates));\r
+// lineNode2.setShape(createOffsetLine(vertical, -OFFSET, coordinates));\r
+ return new Pair<Shape, Shape>(createOffsetLine(vertical, OFFSET, coordinates), Flows.createOffsetLine(vertical, -OFFSET, coordinates));\r
+ \r
+ }\r
+\r
+ public static Pair<Shape, Shape> createLines(boolean hasArrow, Rectangle2D valve, Rectangle2D node) {\r
+ \r
+ double x0 = valve.getCenterX();\r
+ double y0 = valve.getCenterY(); \r
+ double x1 = node.getCenterX();\r
+ double y1 = node.getCenterY();\r
+ \r
+// System.out.println("FlowNode " + x0 + " " + y0 + " x1 " + x1 + " y1 " + y1);\r
+\r
+// Rectangle2D rect = new Rectangle2D.Double();\r
+// node.getBounds(rect);\r
+ \r
+ double minY = hasArrow ? node.getMinY() - ARROW_OFFSET : node.getMinY();\r
+ double maxY = hasArrow ? node.getMaxY() + ARROW_OFFSET : node.getMaxY();\r
+ double minX = hasArrow ? node.getMinX() - ARROW_OFFSET : node.getMinX();\r
+ double maxX = hasArrow ? node.getMaxX() + ARROW_OFFSET : node.getMaxX();\r
+ \r
+// boolean rotated = ((ValveElement)valve).rotated;\r
+ boolean rotated = false;\r
+ \r
+ if( rotated ) {\r
+ if(y1 > y0)\r
+ y0 += OFFSET;\r
+ else\r
+ y0 -= OFFSET;\r
+ if(node.getMinX() <= x0 && node.getMaxX() >= x0) {\r
+ if(y1 > y0)\r
+ return createLines(true, y0, x0, minY);\r
+ else\r
+ return createLines(true, y0, x0, maxY);\r
+ }\r
+ else {\r
+ if(x1 > x0)\r
+ return createLines(true, y0, x0, y1, minX);\r
+ else\r
+ return createLines(true, y0, x0, y1, maxX);\r
+ }\r
+ }\r
+ else {\r
+ if(x1 > x0)\r
+ x0 += OFFSET;\r
+ else\r
+ x0 -= OFFSET;\r
+ if(node.getMinY() <= y0 && node.getMaxY() >= y0) {\r
+ if(x1 > x0)\r
+ return createLines(false, x0, y0, minX);\r
+ else\r
+ return createLines(false, x0, y0, maxX);\r
+ }\r
+ else {\r
+ if(y1 > y0)\r
+ return createLines(false, x0, y0, x1, minY);\r
+ else\r
+ return createLines(false, x0, y0, x1, maxY);\r
+ }\r
+ }\r
+\r
+\r
+ }\r
+\r
+ public static Path2D createLine(boolean vertical, double ... coordinates) {\r
+ Path2D path = new Path2D.Double();\r
+ if(vertical)\r
+ path.moveTo(coordinates[1], coordinates[0]);\r
+ else\r
+ path.moveTo(coordinates[0], coordinates[1]);\r
+ for(int i=2;i<coordinates.length;++i, vertical = !vertical) {\r
+ if(vertical)\r
+ path.lineTo(coordinates[i-1], coordinates[i]);\r
+ else\r
+ path.lineTo(coordinates[i], coordinates[i-1]);\r
+ }\r
+ return path;\r
+ }\r
+ \r
+ public static Path2D createOffsetLine(boolean vertical, double offset, double ... coordinates) {\r
+ double[] newCoordinats = new double[coordinates.length];\r
+ newCoordinats[0] = coordinates[0];\r
+ newCoordinats[coordinates.length-1] = coordinates[coordinates.length-1];\r
+ for(int i=1;i<coordinates.length-1;++i) {\r
+ if(coordinates[i-1] < coordinates[i+1] ^ (i&1)==1)\r
+ newCoordinats[i] = coordinates[i]+offset;\r
+ else\r
+ newCoordinats[i] = coordinates[i]-offset;\r
+ }\r
+ return createLine(vertical, newCoordinats);\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.elements2.connections;\r
+\r
+import java.awt.Composite;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Area;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.g2d.connection.ConnectionEntity;\r
+import org.simantics.g2d.connection.ConnectionEntity.ConnectionEvent;\r
+import org.simantics.g2d.connection.ConnectionEntity.ConnectionListener;\r
+import org.simantics.g2d.connection.handler.ConnectionHandler;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.Children;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.Outline;\r
+import org.simantics.g2d.element.handler.Pick;\r
+import org.simantics.g2d.element.handler.Pick2;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.g2d.element.handler.SelectionOutline;\r
+import org.simantics.g2d.element.handler.Transform;\r
+import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline;\r
+import org.simantics.g2d.element.handler.impl.ParentImpl;\r
+import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
+import org.simantics.g2d.element.handler.impl.TextImpl;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
+import org.simantics.g2d.utils.GeometryUtils;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.IG2DNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
+import org.simantics.utils.datastructures.ListenerList;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+/**\r
+ * An element class for single connection entity elements. A sysdyn connection\r
+ * entity consists of a single edge. Sysdyn connections can't be branched.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class SysdynConnectionClass {\r
+\r
+ public static final ElementClass CLASS =\r
+ ElementClass.compile(\r
+ TextImpl.INSTANCE,\r
+ FixedTransform.INSTANCE,\r
+ ConnectionPick.INSTANCE,\r
+ ConnectionBounds.INSTANCE,\r
+ ConnectionSelectionOutline.INSTANCE,\r
+ ConnectionHandlerImpl.INSTANCE,\r
+ ConnectionChildren.INSTANCE,\r
+ ParentImpl.INSTANCE,\r
+ ConnectionSceneGraph.INSTANCE,\r
+ SimpleElementLayers.INSTANCE\r
+ ).setId(SysdynConnectionClass.class.getSimpleName());\r
+\r
+ private static final ThreadLocal<List<IElement>> perThreadElementList = new ThreadLocal<List<IElement>>() {\r
+ @Override\r
+ protected java.util.List<IElement> initialValue() {\r
+ return new ArrayList<IElement>();\r
+ }\r
+ };\r
+\r
+ static class ConnectionHandlerImpl implements ConnectionHandler {\r
+\r
+ public static final ConnectionHandlerImpl INSTANCE = new ConnectionHandlerImpl();\r
+\r
+ private static final long serialVersionUID = 3267139233182458330L;\r
+\r
+ @Override\r
+ public Collection<IElement> getBranchPoints(IElement connection, Collection<IElement> result) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ return Collections.emptySet();\r
+ return entity.getBranchPoints(result);\r
+ }\r
+\r
+ @Override\r
+ public Collection<IElement> getChildren(IElement connection, Collection<IElement> result) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ return Collections.emptySet();\r
+ result = entity.getSegments(result);\r
+ return entity.getBranchPoints(result);\r
+ }\r
+\r
+ @Override\r
+ public Collection<IElement> getSegments(IElement connection, Collection<IElement> result) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ return Collections.emptySet();\r
+ return entity.getSegments(result);\r
+ }\r
+\r
+ @Override\r
+ public Collection<Connection> getTerminalConnections(IElement connection, Collection<Connection> result) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ return Collections.emptySet();\r
+ return entity.getTerminalConnections(result);\r
+ }\r
+\r
+ @Override\r
+ public IElement newBranchPoint(IElement connection) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ throw new IllegalArgumentException("element '" + connection + "' is not a connection element");\r
+ return entity.newBranchPoint();\r
+ }\r
+\r
+ @Override\r
+ public IElement newEdge(IElement connection) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ throw new IllegalArgumentException("element '" + connection + "' is not a connection element");\r
+ return entity.newEdge();\r
+ }\r
+\r
+ @Override\r
+ public void removeBranchPoint(IElement connection, IElement branchPoint) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ throw new IllegalArgumentException("element '" + connection + "' is not a connection element");\r
+ entity.removeBranchPoint(branchPoint);\r
+ }\r
+\r
+ @Override\r
+ public void removeEdge(IElement connection, IElement edge) {\r
+ ConnectionEntity entity = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (entity == null)\r
+ throw new IllegalArgumentException("element '" + connection + "' is not a connection element");\r
+ entity.removeEdge(edge);\r
+ }\r
+ }\r
+\r
+ static final class ConnectionSceneGraph implements SceneGraph {\r
+\r
+ public static final ConnectionSceneGraph INSTANCE = new ConnectionSceneGraph();\r
+\r
+ private static final long serialVersionUID = 4232871859964883266L;\r
+\r
+ @Override\r
+ public void init(IElement connection, G2DParentNode parent) {\r
+ ConnectionEntity ce = connection.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null)\r
+ return;\r
+\r
+ // Painting is single-threaded, it is OK to use a single thread-local collection here.\r
+ List<IElement> children = perThreadElementList.get();\r
+ children.clear();\r
+ ce.getSegments(children);\r
+ ce.getBranchPoints(children);\r
+ //new Exception("painting connection entity " + ce.hashCode() + " with " + children.size() + " segments and branch points").printStackTrace();\r
+ if (children.isEmpty())\r
+ return;\r
+\r
+ Set<SingleElementNode> tmp = new HashSet<SingleElementNode>();\r
+\r
+ Map<String, Pair<Resource, Object>> properties = connection.getHint(DiagramHints.PROPERTIES);\r
+ \r
+ int zIndex = 0;\r
+ for (IElement child : children) {\r
+ \r
+ ElementClass ec = child.getElementClass();\r
+\r
+ Transform transform = child.getElementClass().getSingleItem(Transform.class);\r
+ assert (transform != null);\r
+ AffineTransform at2 = transform.getTransform(child);\r
+ if (at2 == null)\r
+ continue;\r
+\r
+ if(properties != null)\r
+ child.setHint(DiagramHints.PROPERTIES, properties);\r
+ \r
+ SingleElementNode holder = child.getHint(ElementHints.KEY_SG_NODE);\r
+ if (holder == null) {\r
+ holder = parent.addNode(ElementUtils.generateNodeId(child), SingleElementNode.class);\r
+ child.setHint(ElementHints.KEY_SG_NODE, holder);\r
+ }\r
+ holder.setZIndex(++zIndex);\r
+\r
+ Composite composite = child.getHint(ElementHints.KEY_COMPOSITE);\r
+\r
+ holder.setTransform(at2);\r
+ holder.setComposite(composite);\r
+ holder.setVisible(true);\r
+\r
+ // New node handler\r
+ for (SceneGraph n : ec.getItemsByClass(SceneGraph.class)) {\r
+ n.init(child, holder);\r
+ }\r
+ tmp.add(holder);\r
+ }\r
+\r
+ // Hide unaccessed nodes (but don't remove)\r
+ for (IG2DNode node : parent.getNodes()) {\r
+ if (node instanceof SingleElementNode) {\r
+ if (!tmp.contains(node)) {\r
+ ((SingleElementNode)node).setVisible(false);\r
+ }\r
+ } else {\r
+ //System.out.println("WHAT IS THIS: ");\r
+ //NodeDebug.printSceneGraph(((Node) node));\r
+ }\r
+ }\r
+\r
+ // Don't leave dangling references behind.\r
+ children.clear();\r
+ }\r
+\r
+ @Override\r
+ public void cleanup(IElement e) {\r
+ }\r
+ }\r
+\r
+ static final class ConnectionBounds implements InternalSize, Outline {\r
+\r
+ public static final ConnectionBounds INSTANCE = new ConnectionBounds();\r
+\r
+ private static final long serialVersionUID = 4232871859964883266L;\r
+\r
+ @Override\r
+ public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+\r
+ if (size == null)\r
+ size = new Rectangle2D.Double();\r
+ size.setFrame(0, 0, 0, 0);\r
+\r
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null)\r
+ return size;\r
+\r
+ Collection<IElement> parts = ce.getSegments(null);\r
+ if (parts.isEmpty())\r
+ return size;\r
+ parts = ce.getBranchPoints(parts);\r
+\r
+ Rectangle2D temp = null;\r
+ for (IElement part : parts) {\r
+ // Using on-diagram coordinates because neither connections nor\r
+ // edges have a non-identity transform which means that\r
+ // coordinates are always absolute. Therefore branch point\r
+ // bounds also need to be calculated in absolute coordinates.\r
+ ElementUtils.getElementBoundsOnDiagram(part, size);\r
+// System.out.println("InternalSize BOUNDS: " + size + " for part " + part + " " + part.getElementClass());\r
+ if (temp == null) {\r
+ temp = new Rectangle2D.Double();\r
+ temp.setRect(size);\r
+ } else\r
+ Rectangle2D.union(temp, size, temp);\r
+ //System.out.println("InternalSize Combined BOUNDS: " + temp);\r
+ }\r
+ size.setRect(temp);\r
+ return size;\r
+ \r
+ }\r
+\r
+ private Shape getSelectionShape(IElement forPart) {\r
+ for (SelectionOutline so : forPart.getElementClass().getItemsByClass(SelectionOutline.class)) {\r
+ Shape shape = so.getSelectionShape(forPart);\r
+ if (shape != null)\r
+ return shape;\r
+ }\r
+ // Using on-diagram coordinates because neither connections nor\r
+ // edges have a non-identity transform which means that\r
+ // coordinates are always absolute. Therefore branch point\r
+ // shape also needs to be calculated in absolute coordinates.\r
+ Shape shape = ElementUtils.getElementShapeOrBoundsOnDiagram(forPart);\r
+ return shape;\r
+ //return shape.getBounds2D();\r
+ }\r
+\r
+ @Override\r
+ public Shape getElementShape(IElement e) {\r
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null)\r
+ return new Rectangle2D.Double();\r
+\r
+ Collection<IElement> parts = ce.getSegments(null);\r
+ if (parts.isEmpty())\r
+ return new Rectangle2D.Double();\r
+ parts = ce.getBranchPoints(parts);\r
+\r
+ if (parts.size() == 1) {\r
+ Shape shape = getSelectionShape(parts.iterator().next());\r
+ //System.out.println("Outline SHAPE: " + shape);\r
+ //System.out.println("Outline BOUNDS: " + shape.getBounds2D());\r
+ return shape;\r
+ }\r
+\r
+ //System.out.println("Outline: " + e);\r
+ Area area = new Area();\r
+ for (IElement part : parts) {\r
+ //System.out.println(part);\r
+\r
+ Shape shape = getSelectionShape(part);\r
+\r
+ Rectangle2D bounds = shape.getBounds2D();\r
+// System.out.println(" shape: " + shape);\r
+// System.out.println(" bounds: " + bounds);\r
+\r
+ if (bounds.isEmpty()) {\r
+ double w = bounds.getWidth();\r
+ double h = bounds.getHeight();\r
+ if (w <= 0.0 && h <= 0.0)\r
+ continue;\r
+\r
+ // Need to expand shape in either width or height to make it visible.\r
+ final double exp = 0.1;\r
+ if (w <= 0.0)\r
+ shape = GeometryUtils.expandRectangle(bounds, 0, 0, exp, exp);\r
+ else if (h <= 0.0)\r
+ shape = GeometryUtils.expandRectangle(bounds, exp, exp, 0, 0);\r
+ }\r
+\r
+ //System.out.println(" final shape: " + shape);\r
+ //shape = bounds;\r
+\r
+ Area a = null;\r
+ if (shape instanceof Area)\r
+ a = (Area) shape;\r
+ else\r
+ a = new Area(shape);\r
+ area.add(a);\r
+ }\r
+\r
+ //System.out.println(" connection area outline: " + area);\r
+ //System.out.println(" connection area outline bounds: " + area.getBounds2D());\r
+ return area;\r
+ }\r
+ }\r
+\r
+ public static class ConnectionPick implements Pick2 {\r
+\r
+ public final static ConnectionPick INSTANCE = new ConnectionPick();\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public boolean pickTest(IElement e, Shape s, PickPolicy policy) {\r
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null)\r
+ return false;\r
+\r
+ // Primarily pick branch points and then edges.\r
+ Collection<IElement> parts = ce.getBranchPoints(null);\r
+ parts = ce.getSegments(parts);\r
+ if (parts.isEmpty())\r
+ return false;\r
+\r
+ for (IElement part : parts) {\r
+ for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) {\r
+// System.out.println("TESTING: " + part + " : " + s + " : " + policy);\r
+ if (pick.pickTest(part, s, policy)) {\r
+ //System.out.println(" HIT!");\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public int pick(IElement e, Shape s, PickPolicy policy, Collection<IElement> result) {\r
+ int oldResultSize = result.size();\r
+\r
+// new Exception("SysdynConnectionClass.pick: " + e + " : " + s + " : " + policy).printStackTrace();\r
+ \r
+ ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null)\r
+ return 0;\r
+\r
+ // Primarily pick branch points and then edges.\r
+ List<IElement> parts = perThreadElementList.get();\r
+ parts.clear();\r
+\r
+ ce.getSegments(parts);\r
+ int edges = parts.size();\r
+ ce.getBranchPoints(parts);\r
+ int branchPoints = parts.size() - edges;\r
+\r
+ boolean singleEdge = branchPoints == 0 && edges == 1;\r
+\r
+ if (parts.isEmpty())\r
+ return 0;\r
+\r
+ // See whether the whole connection is to be picked..\r
+ boolean pickConnection = false;\r
+ wholeConnectionPick:\r
+ for (Outline outline : e.getElementClass().getItemsByClass(Outline.class)) {\r
+ Shape elementShape = outline.getElementShape(e);\r
+ if (elementShape == null)\r
+ continue;\r
+\r
+ switch (policy) {\r
+ case PICK_CONTAINED_OBJECTS:\r
+ if (GeometryUtils.contains(s, elementShape)) {\r
+ pickConnection = true;\r
+ break wholeConnectionPick;\r
+ }\r
+ break;\r
+ case PICK_INTERSECTING_OBJECTS:\r
+ if (GeometryUtils.intersects(s, elementShape)) {\r
+ pickConnection = true;\r
+ break wholeConnectionPick;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ ArrayList<IElement> picks = null;\r
+\r
+ // Pick connection segments\r
+ for (int i = 0; i < edges; ++i) {\r
+ IElement part = parts.get(i);\r
+ for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) {\r
+// System.out.println("TESTING SEGMENT: " + part + " : " + s + " : " + policy);\r
+ if (pick.pickTest(part, s, policy)) {\r
+// System.out.println(" HIT!");\r
+ if (picks == null)\r
+ picks = new ArrayList<IElement>(4);\r
+ picks.add(e);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Pick the whole connection ?\r
+ if (pickConnection) {\r
+ if (picks == null)\r
+ picks = new ArrayList<IElement>(4);\r
+ picks.add(e);\r
+ }\r
+\r
+ // Pick branch/route points\r
+ for (int i = edges; i < parts.size(); ++i) {\r
+ IElement part = parts.get(i);\r
+ for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) {\r
+ //System.out.println("TESTING BRANCHPOINT: " + part + " : " + s + " : " + policy);\r
+ if (pick.pickTest(part, s, policy)) {\r
+ //System.out.println(" HIT!");\r
+ if (picks == null)\r
+ picks = new ArrayList<IElement>(4);\r
+ picks.add(part);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (picks != null) {\r
+ // Add the discovered pickable children to the result after the\r
+ // parent to make the parent the primary pickable.\r
+ // Skip the children if there is only one child.\r
+ if (!singleEdge) {\r
+ result.addAll(picks);\r
+ } else {\r
+ result.add(e);\r
+ }\r
+ }\r
+\r
+// System.out.println("pick result size = " + result.size());\r
+ \r
+ return result.size() - oldResultSize;\r
+ }\r
+ }\r
+\r
+ private static final Key CHILD_LISTENERS = new KeyOf(ListenerList.class, "CHILD_LISTENERS");\r
+\r
+ public static class ConnectionChildren implements Children, ConnectionListener {\r
+\r
+ public final static ConnectionChildren INSTANCE = new ConnectionChildren();\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ @Override\r
+ public Collection<IElement> getChildren(IElement element, Collection<IElement> result) {\r
+ ConnectionEntity ce = element.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ if (ce == null) {\r
+ if (result == null)\r
+ result = new ArrayList<IElement>(0);\r
+ return result;\r
+ }\r
+ result = ce.getSegments(result);\r
+ result = ce.getBranchPoints(result);\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public void addChildListener(IElement element, ChildListener listener) {\r
+ ListenerList<ChildListener> ll = null;\r
+ synchronized (element) {\r
+ ll = element.getHint(CHILD_LISTENERS);\r
+ if (ll == null) {\r
+ ll = new ListenerList<ChildListener>(ChildListener.class);\r
+ element.setHint(CHILD_LISTENERS, ll);\r
+ ConnectionEntity entity = element.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ entity.setListener(this);\r
+ }\r
+ }\r
+ ll.add(listener);\r
+ }\r
+\r
+ @Override\r
+ public void removeChildListener(IElement element, ChildListener listener) {\r
+ synchronized (element) {\r
+ ListenerList<ChildListener> ll = element.getHint(CHILD_LISTENERS);\r
+ if (ll == null)\r
+ return;\r
+ ll.remove(listener);\r
+ if (ll.isEmpty()) {\r
+ ConnectionEntity entity = element.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+ entity.setListener(null);\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void connectionChanged(ConnectionEvent event) {\r
+ fireChildrenChanged(event);\r
+ }\r
+\r
+ private void fireChildrenChanged(ConnectionEvent event) {\r
+ ListenerList<ChildListener> ll = event.connection.getHint(CHILD_LISTENERS);\r
+ if (ll == null)\r
+ return;\r
+ ChildEvent ce = new ChildEvent(event.connection, event.removedParts, event.addedParts);\r
+ for (ChildListener cl : ll.getListeners()) {\r
+ cl.elementChildrenChanged(ce);\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\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.StyledText;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.IWorkbenchPartReference;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.expressionParser.ParseException;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.ui.equation.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.equation.expressions.StockExpressionViewFactor;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+import org.eclipse.jface.text.Position;\r
+\r
+public class EquationView extends ViewPart implements ISelectionListener {\r
+\r
+ static final Font FONT = new Font(null, "Courier New", 12, SWT.NORMAL);\r
+\r
+ //Resources\r
+ Resource variable;\r
+ Resource configuration;\r
+\r
+ boolean disposed = false;\r
+ org.eclipse.ui.IPartListener2 focusLostListener; \r
+\r
+ NameComposite nameComposite;\r
+ ShortcutTabs shortcutTabs;\r
+ ExpressionTypeSelector expressionController; \r
+ Composite unitComposite;\r
+ UnitSelector unitSelector; \r
+ ExpressionComposite expressionComposite; \r
+\r
+ @Override \r
+ public void createPartControl(Composite parent) {\r
+ // Listeners\r
+ getSite().getPage().addPostSelectionListener(this);\r
+ focusLostListener = new org.eclipse.ui.IPartListener2()\r
+ {\r
+ public void partInputChanged(IWorkbenchPartReference partRef) {}\r
+ public void partVisible(IWorkbenchPartReference partRef) {}\r
+ public void partHidden(IWorkbenchPartReference partRef) {}\r
+ public void partOpened(IWorkbenchPartReference partRef) {}\r
+ public void partDeactivated(IWorkbenchPartReference partRef)\r
+ {\r
+ if(partRef.getPart(false) instanceof EquationView) {\r
+ // Save expressions\r
+ if(expressionComposite != null) {\r
+ expressionComposite.save();\r
+ }\r
+\r
+\r
+ // Save unit\r
+ if(unitSelector != null) {\r
+ unitSelector.save(); \r
+ }\r
+\r
+ if(nameComposite != null) {\r
+ nameComposite.save(variable);\r
+ }\r
+ }\r
+\r
+ }\r
+ public void partClosed(IWorkbenchPartReference partRef) {}\r
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {}\r
+ public void partActivated(IWorkbenchPartReference partRef) {}\r
+ };\r
+ getViewSite().getPage().addPartListener(focusLostListener);\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(4).margins(3, 3).applyTo(parent);\r
+\r
+\r
+\r
+ // Upper part of the view: Name (and renaming)\r
+ nameComposite = new NameComposite(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameComposite);\r
+\r
+\r
+ // Upper part of the view: Expression type\r
+ expressionController = new ExpressionTypeSelector(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().applyTo(expressionController);\r
+ addVariableTypeSelectionListener();\r
+\r
+ // Upper part of the view: Unit input/selection\r
+ unitComposite = new Composite(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().applyTo(unitComposite);\r
+ GridLayoutFactory.fillDefaults().applyTo(unitComposite);\r
+ unitSelector = new UnitSelector(unitComposite, SWT.NONE);\r
+\r
+ // Center of the view: variables and possible functions\r
+ shortcutTabs = new ShortcutTabs(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().span(1, 4).applyTo(shortcutTabs);\r
+ addVariableTableListeners();\r
+\r
+ // Below variable name: Equation\r
+ expressionComposite = new ExpressionComposite(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().span(3, 1).grab(true, true).applyTo(expressionComposite);\r
+\r
+ } \r
+\r
+ static class Auxiliary {\r
+ String name;\r
+ Resource configuration;\r
+ boolean isVariable;\r
+ }\r
+\r
+ class UpdateViewRequest implements Read<Auxiliary> {\r
+\r
+ Resource resource;\r
+\r
+ public UpdateViewRequest(Resource resource) {\r
+ this.resource = resource;\r
+ }\r
+\r
+ @Override\r
+ public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ ModelingResources mr = ModelingResources.getInstance(graph);\r
+ \r
+ Resource map = graph.getPossibleObject(resource, mr.ElementToComponent);\r
+ if(map != null) resource = map;\r
+ \r
+ Auxiliary a = new Auxiliary();\r
+ variable = resource;\r
+ a.configuration = graph.getPossibleObject(variable, b.PartOf);\r
+ a.name = graph.getPossibleRelatedValue(resource, b.HasName);\r
+ a.isVariable = graph.isInstanceOf(variable, sr.IndependentVariable);\r
+ if(a.name == null)\r
+ a.name = "";\r
+ return a;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {\r
+ if(selection instanceof IStructuredSelection) {\r
+ IStructuredSelection structuredSelection = \r
+ (IStructuredSelection)selection;\r
+ if(structuredSelection.size() == 1) {\r
+// Object element = structuredSelection.getFirstElement();\r
+ Resource res = ISelectionUtils.filterSingleSelection(structuredSelection, Resource.class);\r
+ if(res != null)\r
+ SimanticsUI.getSession().asyncRequest(\r
+ new UpdateViewRequest(res),\r
+ new Listener<Auxiliary>() {\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(final Auxiliary result) {\r
+ if(isDisposed())\r
+ return;\r
+ expressionComposite.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run(){ \r
+ if(isDisposed())\r
+ return;\r
+ if(result.isVariable) {\r
+ unitSelector.setEnabled(true);\r
+ expressionController.setEnabled(true);\r
+ expressionComposite.setEnabled(true);\r
+ nameComposite.setEnabled(true);\r
+ if(configuration == null || !configuration.equals(result.configuration)) {\r
+ configuration = result.configuration;\r
+ if(unitSelector!= null) {\r
+ unitSelector.dispose();\r
+ unitSelector = new UnitSelector(unitComposite, SWT.NONE);\r
+ }\r
+ } else {\r
+ unitSelector.updateUnits(variable);\r
+ }\r
+\r
+ if(shortcutTabs != null) shortcutTabs.updateTables(variable);\r
+ String expressionType = expressionComposite.resetExpressionView(variable);\r
+ addExpressionFieldListeners();\r
+ validateExpressionFields();\r
+ expressionController.setExpressionTypes(expressionComposite.getExpressionTypes()); \r
+ expressionController.select(expressionType);\r
+ nameComposite.setName(result.name);\r
+ } else {\r
+ unitSelector.setEnabled(false);\r
+ expressionController.setEnabled(false);\r
+ expressionComposite.setEnabled(false);\r
+ nameComposite.setEnabled(false);\r
+\r
+ unitSelector.clear(); // empty units\r
+ shortcutTabs.updateTables(variable);\r
+ expressionController.setExpressionTypes(null); \r
+ nameComposite.setName("");\r
+ expressionComposite.resetExpressionView(variable);\r
+ }\r
+ }\r
+ }); \r
+\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return disposed;\r
+ }\r
+\r
+ }\r
+ );\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ if(expressionComposite.getExpressionViewFactor() != null)\r
+ expressionComposite.focus();\r
+ else\r
+ nameComposite.setFocus();\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ disposed = true;\r
+ getViewSite().getPage().removePartListener(focusLostListener);\r
+ super.dispose();\r
+ }\r
+\r
+\r
+ private void addVariableTypeSelectionListener() { \r
+ expressionController.getTypeCombo().addSelectionListener(new SelectionListener() {\r
+\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ expressionComposite.displayExpressionView(expressionController.getSelecetedType());\r
+ addExpressionFieldListeners();\r
+ validateExpressionFields();\r
+ }\r
+\r
+ @Override\r
+ public void widgetDefaultSelected(SelectionEvent e) {\r
+ }\r
+ });\r
+ }\r
+\r
+ private void addVariableTableListeners() {\r
+ Table[] tables = this.shortcutTabs.getTables();\r
+ for(final Table table : tables) {\r
+ table.addMouseListener(new MouseListener(){\r
+\r
+ @Override\r
+ public void mouseDoubleClick(MouseEvent e) {\r
+ TableItem item = table.getItem(new Point(e.x, e.y));\r
+ if(item != null) {\r
+ final String var = (String)item.getData();\r
+ table.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ if(expressionComposite!= null && !expressionComposite.isDisposed()) {\r
+ expressionComposite.replaceSelection(var);\r
+ validateExpressionFields();\r
+ }\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void mouseDown(MouseEvent e) {\r
+ expressionComposite.focus();\r
+ }\r
+\r
+ @Override\r
+ public void mouseUp(MouseEvent e) {\r
+ expressionComposite.focus();\r
+ }\r
+\r
+ });\r
+\r
+ table.addFocusListener(new FocusListener() {\r
+\r
+ @Override\r
+ public void focusGained(FocusEvent e) { \r
+ }\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ table.deselectAll();\r
+ }\r
+\r
+ });\r
+ }\r
+ }\r
+\r
+ private void addExpressionFieldListeners() {\r
+ if(expressionComposite.getExpressionViewFactor() != null)\r
+ for(final ExpressionField ef : expressionComposite.getExpressionViewFactor().getExpressionFields()) {\r
+ StyledText st = ef.getSourceViewer().getTextWidget();\r
+ st.addModifyListener(new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ validateExpressionFields();\r
+ }\r
+ });\r
+ st.addKeyListener(new KeyListener() {\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) {\r
+ }\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if(e.keyCode == SWT.ESC && ef.getExpression() != null) {\r
+ ((StyledText)e.widget).setText(ef.getExpression());\r
+ ((StyledText)e.widget).setSelection(ef.getExpression().length());\r
+ } \r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ private void validateExpressionFields() {\r
+ ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
+ Set<String> variables = new HashSet<String>();\r
+ HashMap<ExpressionField, HashMap<String, List<Token>>> references = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
+\r
+\r
+ // Build references and variable array\r
+ if(expressionComposite.getExpressionViewFactor() != null)\r
+ for(ExpressionField ef : expressionComposite.getExpressionViewFactor().getExpressionFields()) {\r
+ ef.resetAnnotations();\r
+ String textString = ef.getExpression();\r
+ parser.ReInit(new StringReader(textString));\r
+ try {\r
+ parser.expr();\r
+ HashMap<String, List<Token>> cr = parser.getReferences();\r
+ references.put(ef, cr);\r
+ for(String t : cr.keySet())\r
+ variables.add(t);\r
+ } catch (ParseException e1) {\r
+ ef.setSyntaxError(e1.currentToken);\r
+ }\r
+ }\r
+\r
+ // Remove variables from variable array that don't exist in the model. Create annotations\r
+ if(!variables.isEmpty()) {\r
+ ArrayList<String> modelVariables = new ArrayList<String>();\r
+ Set<String> noSuchVariables = new HashSet<String>();\r
+ SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+ SysdynModel model = sdm.getModel(configuration);\r
+ Configuration conf = model.getConfiguration();\r
+ ArrayList<IElement> elements = conf.getElements();\r
+ for(IElement e : elements) {\r
+ if(e instanceof IndependentVariable) {\r
+ IndependentVariable v = (IndependentVariable) e;\r
+ modelVariables.add(v.getName());\r
+ }\r
+ }\r
+\r
+\r
+ for(String v : variables) {\r
+ if(!modelVariables.contains(v)) {\r
+ noSuchVariables.add(v);\r
+ }\r
+ }\r
+\r
+ if(!noSuchVariables.isEmpty()) {\r
+ // remove no such variables from variable list\r
+ for(String s : noSuchVariables)\r
+ variables.remove(s);\r
+ // create annotations\r
+ HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, noSuchVariables);\r
+ for(ExpressionField ef : positions.keySet()) {\r
+ ef.setNoSuchVariableAnnotations(positions.get(ef));\r
+ }\r
+ } \r
+ }\r
+\r
+ // Check that the variables that exist have connections and the connected variables have references in the expressions\r
+ if(!(expressionComposite.getExpressionViewFactor() instanceof StockExpressionViewFactor)) { \r
+ for(TableItem ti : this.shortcutTabs.getVariableTable().getItems()) {\r
+ if(!variables.contains(ti.getText())) {\r
+ ti.setForeground(new Color(ti.getDisplay(), 255, 0, 0));\r
+ } else {\r
+ ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));\r
+ variables.remove(ti.getText());\r
+ }\r
+ }\r
+\r
+ if(!variables.isEmpty()) {\r
+ HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, variables);\r
+ for(ExpressionField ef : positions.keySet()) {\r
+ ef.setMissingLinkAnnotations(positions.get(ef));\r
+ }\r
+\r
+ }\r
+ } \r
+\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ private HashMap<ExpressionField ,ArrayList<Position>> getPositionsForVariables(HashMap<ExpressionField, HashMap<String, List<Token>>> references, Set<String> variables) {\r
+ HashMap<ExpressionField ,ArrayList<Position>> result = new HashMap<ExpressionField ,ArrayList<Position>>();\r
+ for(String s : variables) {\r
+ List<Token> tlist = new ArrayList<Token>();\r
+ for(ExpressionField ef : references.keySet()) {\r
+ ArrayList<Position> positions = new ArrayList<Position>();\r
+ tlist = references.get(ef).get(s);\r
+ if(tlist != null)\r
+ for(Token t : tlist) {\r
+ StyledText st = ef.getSourceViewer().getTextWidget();\r
+ int start = st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1;\r
+ int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start;\r
+ positions.add(new Position(\r
+ start,\r
+ offset));\r
+ }\r
+ if(result.keySet().contains(ef)) {\r
+ result.get(ef).addAll((ArrayList<Position>)positions.clone());\r
+ } else {\r
+ result.put(ef, (ArrayList<Position>)positions.clone());\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\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.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.equation.expressions.AuxiliaryExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.ConstantExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.DelayExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.EmptyExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.IExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.LookupExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.ParameterExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.StockExpressionViewFactor;\r
+import org.simantics.sysdyn.ui.equation.expressions.WithLookupExpressionViewFactor;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ExpressionComposite extends Composite {\r
+\r
+ static enum ExpressionType {Auxiliary, Parameter, Constant, Lookup, WithLookup, Stock, Delay, Empty};\r
+\r
+ ExpressionType[] auxiliaryExpressions = new ExpressionType[] {\r
+ ExpressionType.Parameter, \r
+ ExpressionType.Auxiliary, \r
+ ExpressionType.Constant, \r
+ ExpressionType.Lookup, \r
+ ExpressionType.WithLookup};\r
+\r
+ ExpressionType[] valveExpressions = new ExpressionType[] {\r
+ ExpressionType.Auxiliary, \r
+ ExpressionType.Parameter, \r
+ ExpressionType.Constant, \r
+ ExpressionType.WithLookup};\r
+\r
+ ExpressionType[] stockExpressions = new ExpressionType[] {\r
+ ExpressionType.Stock};\r
+\r
+\r
+ IExpressionViewFactor expressionViewFactor;\r
+ Map<String, Object> data;\r
+ Map<String, Object> origData;\r
+ Resource variable;\r
+ ArrayList<String> dependencies;\r
+\r
+ public ExpressionComposite(Composite parent, int style) {\r
+ super(parent, style);\r
+ \r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+ \r
+ this.data = new HashMap<String, Object>();\r
+ this.origData = new HashMap<String, Object>();\r
+ }\r
+\r
+ public void save() {\r
+ if(variable != null && data != null)\r
+ this.expressionViewFactor.writeData(variable, data);\r
+ }\r
+\r
+ public void displayExpressionView(String expressionType) {\r
+ displayExpressionView(expressionType, false);\r
+ }\r
+\r
+ public String resetExpressionView(Resource variable) {\r
+ this.data.clear();\r
+ this.origData.clear();\r
+ this.variable = variable;\r
+ this.expressionViewFactor = null;\r
+ String origExpressionType = getOriginalExpressionType().toString();\r
+ displayExpressionView(origExpressionType, true);\r
+ return origExpressionType;\r
+ }\r
+\r
+\r
+ public void displayExpressionView(String expressionType, boolean original) {\r
+ if(expressionType == null)\r
+ return;\r
+\r
+ if(this.expressionViewFactor != null) expressionViewFactor.updateData(data);\r
+ ExpressionType et = ExpressionType.valueOf(expressionType);\r
+ IExpressionViewFactor evf = null;\r
+ switch (et) {\r
+ case Auxiliary: \r
+ evf = new AuxiliaryExpressionViewFactor(); break;\r
+ case Parameter: \r
+ evf = new ParameterExpressionViewFactor(); break;\r
+ case Constant: \r
+ evf = new ConstantExpressionViewFactor(); break;\r
+ case Lookup: \r
+ evf = new LookupExpressionViewFactor(); break;\r
+ case WithLookup: \r
+ evf = new WithLookupExpressionViewFactor(variable); break;\r
+ case Stock: \r
+ evf = new StockExpressionViewFactor(); break;\r
+ case Delay: \r
+ evf = new DelayExpressionViewFactor(); break;\r
+ default: \r
+ evf = new EmptyExpressionViewFactor();\r
+ }\r
+\r
+ if (evf != null) {\r
+ for(Control c : this.getChildren()) {\r
+ c.dispose();\r
+ } \r
+\r
+ if(original) {\r
+ evf.readData(variable, data);\r
+ for(String key : data.keySet()) {\r
+ origData.put(key, data.get(key));\r
+ }\r
+ }\r
+ \r
+ evf.createView(this, data);\r
+ this.expressionViewFactor = evf;\r
+ this.layout();\r
+ } \r
+ }\r
+\r
+\r
+ public ExpressionType[] getExpressionTypes() {\r
+ ExpressionType[] expressionTypes = null;\r
+\r
+ if(variable != null) {\r
+ try {\r
+ expressionTypes = SimanticsUI.getSession().syncRequest(new Read< ExpressionType[]>() {\r
+\r
+ @Override\r
+ public ExpressionType[] perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ ExpressionType[] expressionTypes;\r
+ if(graph.isInstanceOf(variable, sr.Auxiliary)) {\r
+ expressionTypes = auxiliaryExpressions;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Valve)) {\r
+ expressionTypes = valveExpressions;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Stock)) {\r
+ expressionTypes = stockExpressions;\r
+ }\r
+ else\r
+ expressionTypes = null;\r
+\r
+ return expressionTypes;\r
+ }\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ }\r
+\r
+ return expressionTypes;\r
+ }\r
+ \r
+ public void focus() {\r
+ if(this.expressionViewFactor != null)\r
+ this.expressionViewFactor.focus();\r
+ }\r
+ \r
+ public void replaceSelection(String var) {\r
+ this.expressionViewFactor.replaceSelection(var);\r
+ }\r
+ \r
+ public IExpressionViewFactor getExpressionViewFactor() {\r
+ return this.expressionViewFactor;\r
+ }\r
+ \r
+ private ExpressionType getOriginalExpressionType() {\r
+\r
+ ExpressionType et = null;\r
+\r
+ try {\r
+ et = SimanticsUI.getSession().syncRequest(new Read< ExpressionType>() {\r
+\r
+ @Override\r
+ public ExpressionType perform(ReadGraph graph) throws DatabaseException {\r
+\r
+ ExpressionType et = null;\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if(expression == null) {\r
+ if(graph.isInstanceOf(variable, sr.Auxiliary)) {\r
+ et = ExpressionType.Auxiliary;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Valve)) {\r
+ et = ExpressionType.Auxiliary;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Stock)) {\r
+ et = ExpressionType.Stock;\r
+ } else\r
+ et = ExpressionType.Empty;\r
+ } else {\r
+\r
+ if(graph.isInstanceOf(expression, sr.NormalExpression)) {\r
+ et = ExpressionType.Auxiliary;\r
+ } else if (graph.isInstanceOf(expression, sr.StockExpression)) {\r
+ et = ExpressionType.Stock;\r
+ } else if (graph.isInstanceOf(expression, sr.ParameterExpression)) {\r
+ et = ExpressionType.Parameter;\r
+ } else if (graph.isInstanceOf(expression, sr.ConstantExpression)) {\r
+ et = ExpressionType.Constant;\r
+ } else if (graph.isInstanceOf(expression, sr.DelayExpression)) {\r
+ et = ExpressionType.Delay;\r
+ } else if (graph.isInstanceOf(expression, sr.LookupExpression)) {\r
+ et = ExpressionType.Lookup;\r
+ } else if (graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ et = ExpressionType.WithLookup;\r
+ } else {\r
+ et = ExpressionType.Empty;\r
+ }\r
+ }\r
+ return et;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return et;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+\r
+import org.eclipse.swt.graphics.FontMetrics;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+\r
+public class ExpressionTypeSelector extends Composite {\r
+\r
+ Combo typeCombo;\r
+\r
+ public ExpressionTypeSelector(final Composite parent, int style) {\r
+ super(parent, style);\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(this);\r
+\r
+\r
+ Label label = new Label(this, SWT.SINGLE );\r
+ label.setFont(EquationView.FONT);\r
+ label.setText("Type:");\r
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+ typeCombo = new Combo(this, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+ typeCombo.setFont(EquationView.FONT);\r
+\r
+ int columns = 6;\r
+ GC gc = new GC (typeCombo);\r
+ FontMetrics fm = gc.getFontMetrics ();\r
+ int width = columns * fm.getAverageCharWidth ();\r
+ int height = fm.getHeight ();\r
+ gc.dispose (); \r
+ GridDataFactory.fillDefaults().hint(typeCombo.computeSize(width, height)).applyTo(typeCombo);\r
+ \r
+ }\r
+ \r
+ public Combo getTypeCombo() {\r
+ return this.typeCombo;\r
+ }\r
+ \r
+ public String getSelecetedType() {\r
+ return this.typeCombo.getItem(this.typeCombo.getSelectionIndex());\r
+ }\r
+ \r
+ public void setExpressionTypes(ExpressionComposite.ExpressionType[] expressionTypes) {\r
+ typeCombo.removeAll();\r
+ if(expressionTypes != null) {\r
+ for(ExpressionComposite.ExpressionType et : expressionTypes) {\r
+ typeCombo.add(et.toString());\r
+ }\r
+ }\r
+ }\r
+ \r
+ public void select(String expressionType) {\r
+ int index = typeCombo.indexOf(expressionType);\r
+ if (index > -1) {\r
+ typeCombo.select(index);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.VerifyEvent;\r
+import org.eclipse.swt.events.VerifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.IEditorInput;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorInput;\r
+\r
+public class NameComposite extends Composite {\r
+\r
+ Text nameText;\r
+ String originalName = "";\r
+\r
+\r
+ public NameComposite(Composite parent, int style) {\r
+ super(parent, style);\r
+ GridLayoutFactory.fillDefaults().spacing(3, 3).applyTo(this);\r
+\r
+ nameText = new Text(this, SWT.SINGLE | SWT.BORDER);\r
+ nameText.setFont(EquationView.FONT);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText);\r
+\r
+ nameText.addVerifyListener(new VerifyListener() {\r
+\r
+ @Override\r
+ public void verifyText(VerifyEvent e) {\r
+ e.doit = false;\r
+ char c = e.character;\r
+ if(c != ' ') {\r
+ e.doit = true;\r
+ }\r
+ }\r
+ });\r
+\r
+ nameText.addModifyListener(new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ Text t = (Text) e.widget;\r
+ String txt = t.getText();\r
+ // Don't allow this to produce an eternal loop\r
+ if (!txt.equals(originalName) && txt.contains(" ")) {\r
+ t.setText(originalName);\r
+ }\r
+ }\r
+ });\r
+\r
+ nameText.addKeyListener(new KeyListener() {\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) {\r
+\r
+ }\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if(e.keyCode == SWT.ESC && originalName != null) {\r
+ ((Text)e.widget).setText(originalName);\r
+ ((Text)e.widget).setSelection(originalName.length());\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ public void setName(String name) {\r
+ if (name == null)\r
+ throw new NullPointerException("null name");\r
+ this.originalName = name;\r
+ this.nameText.setText(name);\r
+ }\r
+\r
+ public void save(final Resource variable) {\r
+ final String nameNew = this.nameText.getText();\r
+ if(nameNew != null && !nameNew.equals(this.originalName) && variable != null) {\r
+\r
+ final IEditorPart editor =\r
+ PlatformUI.getWorkbench()\r
+ .getActiveWorkbenchWindow().getActivePage().getActiveEditor();\r
+ IEditorInput input = editor.getEditorInput();\r
+ ResourceEditorInput rei = (ResourceEditorInput) input;\r
+ SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+ SysdynModel model = sdm.getModel(rei.getResource());\r
+ Configuration conf = model.getConfiguration();\r
+ IElement thisElement = model.getElement(variable);\r
+ ArrayList<IElement> elements = conf.getElements();\r
+ for(IElement e : elements) {\r
+ if(e instanceof IndependentVariable) {\r
+ IndependentVariable v = (IndependentVariable)e;\r
+ if(v != thisElement && v.getName().equals(this.nameText.getText())) {\r
+ this.nameText.setText(this.originalName);\r
+ this.nameText.setSelection(this.originalName.length());\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ Builtins b = g.getBuiltins();\r
+ g.claimValue(variable, b.HasName, nameNew);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.TabFolder;\r
+import org.eclipse.swt.widgets.TabItem;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.simantics.db.Builtins;\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class ShortcutTabs extends Composite {\r
+\r
+ TabFolder tabFolder;\r
+ TabItem variables;\r
+ TabItem functions;\r
+ Table variableTable;\r
+ Table functionTable;\r
+\r
+ public ShortcutTabs(Composite parent, int style) {\r
+ super(parent, style);\r
+\r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+\r
+ tabFolder = new TabFolder (this, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(tabFolder);\r
+ GridLayoutFactory.fillDefaults().applyTo(tabFolder);\r
+ variables = new TabItem(tabFolder, SWT.NULL);\r
+ variables.setText("Variables");\r
+ variableTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);\r
+\r
+ variables.setControl(variableTable);\r
+\r
+ functions = new TabItem(tabFolder, SWT.NULL);\r
+ functions.setText("Functions"); \r
+ functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);\r
+ TableItem item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("min()");\r
+ item.setData("min({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("max()");\r
+ item.setData("max({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("abs()");\r
+ item.setData("abs({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("if then else");\r
+ item.setData("if then else");\r
+ functions.setControl(functionTable);\r
+\r
+ this.layout();\r
+ }\r
+\r
+ public HashSet<String> updateTables(Resource variable) {\r
+ HashSet<String> dependencies = getDependencies(variable);\r
+ variableTable.removeAll();\r
+ TableItem item;\r
+ for(String d : dependencies) {\r
+ item = new TableItem(variableTable, SWT.NONE);\r
+ item.setText(d);\r
+ item.setData(d);\r
+ }\r
+ return dependencies;\r
+ }\r
+\r
+ // Returns the names of the related variables (dependencies)\r
+ private HashSet<String> getDependencies(final Resource r){\r
+ HashSet<String> variables = null;\r
+ if(r != null)\r
+ try {\r
+ variables = SimanticsUI.getSession().syncRequest(new Read<HashSet<String>>() {\r
+\r
+ @Override\r
+ public HashSet<String> perform(ReadGraph graph)\r
+ throws DatabaseException {\r
+ HashSet<String> variables = new HashSet<String>();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+\r
+ Collection<Resource> dependencies = graph.getObjects(r, sr.IsHeadOf);\r
+\r
+ for(Resource d : dependencies) {\r
+ if(graph.isInstanceOf(d, sr.Dependency)) {\r
+ Resource tail = graph.getPossibleObject(d, sr.HasTail);\r
+ if(tail != null) {\r
+ Object name = graph.getPossibleRelatedValue(tail, b.HasName);\r
+ if(name != null)\r
+ variables.add((String)name);\r
+ }\r
+ }\r
+ }\r
+\r
+ return variables;\r
+\r
+ }\r
+\r
+\r
+ });\r
+ } catch (DatabaseException ee) {\r
+ ExceptionUtils.logAndShowError(ee);\r
+ }\r
+\r
+ return variables;\r
+ }\r
+\r
+ public Table getVariableTable() {\r
+ return this.variableTable;\r
+ }\r
+\r
+ public Table[] getTables() {\r
+ Table[] ret = {this.variableTable, this.functionTable};\r
+ return ret;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.FontMetrics;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class UnitSelector extends Composite {\r
+\r
+ Combo unitCombo;\r
+ Resource variable;\r
+ String unit = null;\r
+ ArrayList<String> units;\r
+\r
+ public UnitSelector(Composite parent, int style) {\r
+ super(parent, style);\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(this);\r
+\r
+ this.units = getUnits();\r
+\r
+ Label label = new Label(this, SWT.SINGLE );\r
+ label.setFont(EquationView.FONT);\r
+ label.setText("Unit:");\r
+ //label.setAlignment(SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+\r
+ unitCombo = new Combo(this, SWT.DROP_DOWN | SWT.BORDER);\r
+ unitCombo.setFont(EquationView.FONT);\r
+\r
+ int columns = 6;\r
+ GC gc = new GC (unitCombo);\r
+ FontMetrics fm = gc.getFontMetrics ();\r
+ int width = columns * fm.getAverageCharWidth ();\r
+ int height = fm.getHeight ();\r
+ gc.dispose (); \r
+ GridDataFactory.fillDefaults().hint(unitCombo.computeSize(width, height)).applyTo(unitCombo);\r
+\r
+ parent.layout();\r
+\r
+ }\r
+\r
+ public String save(){\r
+ final String unitNew = unitCombo.getText();\r
+\r
+ if(unitNew != null && !unitNew.equals("") && !units.contains(unitNew)) {\r
+ units.add(unitNew);\r
+ Collections.sort(units);\r
+ }\r
+\r
+ if(unitNew != null && !unitNew.equals(unit) && variable != null) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ if (!unitNew.equals("")) {\r
+ g.claimValue(variable, sr.HasUnit, unitNew);\r
+ }\r
+ else if (g.getPossibleRelatedValue(variable, sr.HasUnit) != null)\r
+ g.deny(variable, sr.HasUnit);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return unitNew;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public void updateUnits(Resource variable) {\r
+ if(unitCombo != null) {\r
+ this.variable = variable;\r
+ if(unitCombo.getItemCount() > 0) unitCombo.removeAll();\r
+ for(String unit : this.units) {\r
+ unitCombo.add(unit);\r
+ }\r
+\r
+ setUnit();\r
+ }\r
+ }\r
+ \r
+ public void clear() {\r
+ this.unitCombo.removeAll();\r
+ }\r
+\r
+ private void setUnit() {\r
+\r
+ if(variable != null) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ unit = graph.getPossibleRelatedValue(variable, sr.HasUnit);\r
+ return null;\r
+ }\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ }\r
+\r
+ if (unit != null)\r
+ if(unitCombo.indexOf(unit) >= 0)\r
+ unitCombo.select(unitCombo.indexOf(unit));\r
+ else\r
+ unitCombo.setText(unit);\r
+ }\r
+\r
+\r
+ // Returns all the used units in the model\r
+ private ArrayList<String> getUnits() {\r
+ ArrayList<String> units = new ArrayList<String>();\r
+ if(variable != null) {\r
+ try {\r
+ units = SimanticsUI.getSession().syncRequest(new Read<ArrayList<String>>() {\r
+\r
+ @Override\r
+ public ArrayList<String> perform(ReadGraph graph)\r
+ throws DatabaseException {\r
+ ArrayList<String> units = new ArrayList<String>();\r
+\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+ Resource model = graph.getPossibleObject(variable, b.PartOf);\r
+ if (model != null) {\r
+ Collection<Resource> variables = graph.getObjects(model, b.ConsistsOf);\r
+ for(Resource v : variables) {\r
+ Object unit = graph.getPossibleRelatedValue(v, sr.HasUnit);\r
+ if (unit != null && !units.contains((String) unit)) {\r
+ units.add((String)unit);\r
+ }\r
+ }\r
+ }\r
+\r
+ return units;\r
+\r
+ }\r
+\r
+\r
+ });\r
+ } catch (DatabaseException ee) {\r
+ ExceptionUtils.logAndShowError(ee);\r
+ }\r
+ }\r
+ return units;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class AuxiliaryExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ private Label equationLabel;\r
+ private ExpressionField expression;\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+\r
+ final String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
+ equationLabel = new Label(parent, SWT.NONE);\r
+ equationLabel.setFont(FONT);\r
+ equationLabel.setText("=");\r
+ GridDataFactory.fillDefaults().applyTo(equationLabel);\r
+\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setFont(FONT);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String equation = null;\r
+ if (variable != null && data.get("equation") == null) {\r
+ try {\r
+ equation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.NormalExpression)) {\r
+ return graph.getRelatedValue(expression, sr.HasEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", equation);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void writeData(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ if(currentText != null) {\r
+ data.put("equation", currentText);\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null) {\r
+ g.deny(variable, sr.HasExpression);\r
+ }\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.NormalExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasEquation, currentText);\r
+ }\r
+\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.expression != null) this.expression.focus();\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression());\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.text.source.ISharedTextColors;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+public class ColorManager implements ISharedTextColors {\r
+\r
+ protected HashMap<RGB, Color> colorTable = new HashMap<RGB, Color>();\r
+\r
+ @Override\r
+ public void dispose() {\r
+ for(Color c : colorTable.values())\r
+ c.dispose();\r
+ colorTable.clear();\r
+ }\r
+\r
+ @Override\r
+ public Color getColor(RGB rgb) {\r
+ Color color = colorTable.get(rgb);\r
+ if (color == null) {\r
+ color = new Color(Display.getCurrent(), rgb);\r
+ colorTable.put(rgb, color);\r
+ }\r
+ return color;\r
+\r
+\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ConstantExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ private Label equationLabel;\r
+ private ExpressionField expression;\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+\r
+ final String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
+ equationLabel = new Label(parent, SWT.NONE);\r
+ equationLabel.setFont(FONT);\r
+ equationLabel.setText("=");\r
+ GridDataFactory.fillDefaults().applyTo(equationLabel);\r
+\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setFont(FONT);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.expression != null) this.expression.focus();\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String equation = null; \r
+ if (variable != null && data.get("equation") == null) {\r
+ try {\r
+ equation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.ConstantExpression)) {\r
+ return graph.getRelatedValue(expression, sr.HasEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", equation);\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void writeData(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ if(currentText != null) {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null) {\r
+ g.deny(variable, sr.HasExpression);\r
+ }\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.ConstantExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasEquation, currentText);\r
+ }\r
+\r
+ });\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression()); \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class DelayExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void readData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void writeData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class EmptyExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void readData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void writeData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.Document;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.PaintManager;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.AnnotationModel;\r
+import org.eclipse.jface.text.source.AnnotationPainter;\r
+import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;\r
+import org.eclipse.jface.text.source.IAnnotationAccess;\r
+import org.eclipse.jface.text.source.MatchingCharacterPainter;\r
+import org.eclipse.jface.text.source.SourceViewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+\r
+public class ExpressionField extends Composite {\r
+\r
+ protected SourceViewer _sourceViewer;\r
+ protected IDocument _document;\r
+ protected AnnotationModel _annotationModel;\r
+\r
+ ColorManager cManager = new ColorManager();\r
+\r
+ IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();\r
+\r
+ public ExpressionField(Composite parent, int style) {\r
+ super(parent, style);\r
+\r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+\r
+ int styles = SWT.V_SCROLL\r
+ | SWT.MULTI\r
+ | SWT.FULL_SELECTION\r
+ | SWT.WRAP;\r
+\r
+ _document = new Document();\r
+ _document.set("");\r
+\r
+ _annotationModel = new AnnotationModel();\r
+ _annotationModel.connect(_document);\r
+\r
+ _sourceViewer = new SourceViewer(this,\r
+\r
+ null,\r
+ null,\r
+ true,\r
+ styles);\r
+ _sourceViewer.configure(new ExpressionFieldConfiguration(cManager));\r
+\r
+ AnnotationPainter painter = new AnnotationPainter(_sourceViewer, annotationAccess);\r
+ _sourceViewer.addPainter(painter);\r
+\r
+ painter.addAnnotationType("MissingLink");\r
+ painter.setAnnotationTypeColor("MissingLink", new Color(this.getDisplay(), 255,0,0));\r
+ painter.addAnnotationType("NoSuchVariable");\r
+ painter.setAnnotationTypeColor("NoSuchVariable", new Color(this.getDisplay(), 255,0,0));\r
+ \r
+ _sourceViewer.setDocument(_document, _annotationModel);\r
+\r
+ _sourceViewer.getControl().setLayoutData(new GridData(SWT.FILL,\r
+ SWT.FILL,\r
+ true,\r
+ true)); \r
+\r
+ PaintManager paintManager = new PaintManager(_sourceViewer);\r
+ MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(_sourceViewer,\r
+ new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} ));\r
+ matchingCharacterPainter.setColor(new Color(Display.getCurrent(), new RGB(160, 160, 160)));\r
+ paintManager.addPainter(matchingCharacterPainter);\r
+\r
+\r
+ }\r
+\r
+ public SourceViewer getSourceViewer() {\r
+ return this._sourceViewer;\r
+ }\r
+\r
+ public void setMissingLinkAnnotations(List<Position> positions){\r
+ for(Position p : positions) {\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("MissingLink");\r
+ annotation.setText("No link to this variable");\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+ }\r
+ \r
+ public void setNoSuchVariableAnnotations(List<Position> positions){\r
+ for(Position p : positions) {\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("NoSuchVariable");\r
+ annotation.setText("No such variable in model");\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+ }\r
+\r
+ public void setSyntaxError(Token token){\r
+ int start = 0;\r
+ int offset = this._document.getLength();\r
+ if(token.image != null && this._document.getLength() > 0) {\r
+ try {\r
+ start = this._document.getLineOffset(token.beginLine - 1) + token.beginColumn - 1;\r
+ offset = this._document.getLineOffset(token.endLine - 1) + token.endColumn - start;\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("MissingLink");\r
+ annotation.setText("Syntax error");\r
+ Position p = new Position(start, offset);\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+\r
+ public void resetAnnotations() {\r
+ _annotationModel.removeAllAnnotations();\r
+ }\r
+ public void setExpression(String expression) {\r
+ _document.set(expression);\r
+ }\r
+\r
+ public String getExpression() {\r
+ return this._document.get();\r
+ }\r
+\r
+ public Point getSelection() {\r
+ return _sourceViewer.getSelectedRange();\r
+ }\r
+\r
+ public void setSelection(int selection) {\r
+ this._sourceViewer.setSelectedRange(selection, 0);\r
+ }\r
+\r
+ public IDocument getDocument() {\r
+ return _document;\r
+ }\r
+\r
+ public void focus() {\r
+ this._sourceViewer.getTextWidget().forceFocus();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.text.DefaultTextHover;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.ITextHover;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.presentation.IPresentationReconciler;\r
+import org.eclipse.jface.text.presentation.PresentationReconciler;\r
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.ITokenScanner;\r
+import org.eclipse.jface.text.rules.IWordDetector;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+import org.eclipse.jface.text.rules.WordRule;\r
+import org.eclipse.jface.text.source.DefaultAnnotationHover;\r
+import org.eclipse.jface.text.source.IAnnotationHover;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.RGB;\r
+\r
+public class ExpressionFieldConfiguration extends SourceViewerConfiguration {\r
+\r
+\r
+ ColorManager colorManager;\r
+\r
+ public ExpressionFieldConfiguration(ColorManager colorManager) {\r
+ super();\r
+ this.colorManager = colorManager;\r
+ }\r
+\r
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {\r
+ return new String[] {\r
+ IDocument.DEFAULT_CONTENT_TYPE\r
+ };\r
+ }\r
+\r
+ /*\r
+ @Override\r
+ public IAutoEditStrategy[] getAutoEditStrategies(\r
+ ISourceViewer sourceViewer, String contentType) {\r
+ return new IAutoEditStrategy[] {\r
+ new ReplaceTabsBySpaces(),\r
+ new IndentLineEditStrategy(),\r
+ new MatchingBracketsEditStrategy()\r
+ };\r
+ }\r
+ */\r
+\r
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {\r
+ PresentationReconciler reconciler = new PresentationReconciler();\r
+\r
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSclTokenScanner());\r
+\r
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+\r
+ return reconciler;\r
+ }\r
+\r
+ /*\r
+ * \r
+ */\r
+ ITokenScanner getSclTokenScanner() {\r
+ RuleBasedScanner scanner = new RuleBasedScanner();\r
+\r
+ final Token reserved = new Token(\r
+ new TextAttribute(\r
+ colorManager.getColor(new RGB(127, 0, 85)),\r
+ null,\r
+ SWT.BOLD\r
+ ));\r
+ \r
+\r
+ WordRule reservedWord = new WordRule(new IWordDetector() { \r
+ @Override\r
+ public boolean isWordStart(char c) {\r
+ return Character.isLetter(c);\r
+ }\r
+\r
+ @Override\r
+ public boolean isWordPart(char c) {\r
+ return Character.isLetter(c);\r
+ }\r
+ });\r
+\r
+ for(String s : keywords) {\r
+ reservedWord.addWord(s, reserved);\r
+ }\r
+\r
+ IRule[] rules = new IRule[] {\r
+ reservedWord\r
+ };\r
+ scanner.setRules(rules);\r
+\r
+ return scanner; \r
+ }\r
+\r
+ @Override\r
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {\r
+ return new DefaultTextHover(sourceViewer);\r
+ }\r
+\r
+ @Override\r
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {\r
+ return new DefaultAnnotationHover();\r
+ }\r
+\r
+ static final Set<String> keywords = new HashSet<String>();\r
+ \r
+ static {\r
+ keywords.add("within");\r
+ keywords.add("final");\r
+ keywords.add("public");\r
+ keywords.add("protected");\r
+ keywords.add("connect");\r
+ keywords.add("when");\r
+ keywords.add("then");\r
+ keywords.add("elsewhen");\r
+ keywords.add("if");\r
+ keywords.add("end");\r
+ keywords.add("elseif");\r
+ keywords.add("else");\r
+ keywords.add("for");\r
+ keywords.add("while");\r
+ keywords.add("loop");\r
+ keywords.add("der");\r
+ keywords.add("enumeration");\r
+ keywords.add("extends");\r
+ keywords.add("class");\r
+ keywords.add("partial");\r
+ keywords.add("encapsulated");\r
+ keywords.add("model");\r
+ keywords.add("record");\r
+ keywords.add("block");\r
+ keywords.add("expandable");\r
+ keywords.add("connector");\r
+ keywords.add("type");\r
+ keywords.add("package");\r
+ keywords.add("function");\r
+ keywords.add("import");\r
+ keywords.add("external");\r
+ keywords.add("constrainedby");\r
+ keywords.add("redeclare");\r
+ keywords.add("replaceable");\r
+ keywords.add("flow");\r
+ keywords.add("discrete");\r
+ keywords.add("parameter");\r
+ keywords.add("constant");\r
+ keywords.add("input");\r
+ keywords.add("output");\r
+ keywords.add("annotation");\r
+ keywords.add("false");\r
+ keywords.add("true");\r
+ keywords.add("each");\r
+ keywords.add("initial");\r
+ keywords.add("algorithm");\r
+ keywords.add("equation");\r
+ keywords.add("or");\r
+ keywords.add("and");\r
+ keywords.add("not");\r
+ keywords.add("break");\r
+ keywords.add("return"); \r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Font;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public interface IExpressionViewFactor {\r
+\r
+ static final Font FONT = new Font(null, "Courier New", 12, SWT.NORMAL);\r
+ \r
+ /**\r
+ * Creates expression type specific user interface and initializes\r
+ * the components by the given data. The given map is linked \r
+ * to the ui components and updated.\r
+ * @param parent\r
+ * @param data\r
+ */\r
+ void createView(Composite parent, Map<String, Object> data);\r
+ /**\r
+ * Reads expression type specific data from database.\r
+ * @param variable\r
+ * @return\r
+ */\r
+ void readData(Resource variable, Map<String, Object> data);\r
+ \r
+ /**\r
+ * Writes expression type specific data to database.\r
+ * @param variable\r
+ * @return\r
+ */\r
+ void writeData(Resource variable, Map<String, Object> data);\r
+ \r
+ /**\r
+ * Focuses to some part of the expression view.\r
+ */\r
+ void focus();\r
+ \r
+ /**\r
+ * Replaces the current selection with a variable name.\r
+ * @param var\r
+ */\r
+ void replaceSelection(String var);\r
+ \r
+ /**\r
+ * Updates data from text inputs to the data map\r
+ * @param data\r
+ */\r
+ void updateData(Map<String, Object> data);\r
+ \r
+ /**\r
+ * @return all individual expression fields for modelica validation\r
+ */\r
+ List<ExpressionField> getExpressionFields();\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.equation.expressions;\r
+\r
+import java.util.Map;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class LookupChartInfo {\r
+\r
+ String lookupTable, expression;\r
+ Double minX, maxX, minY, maxY;\r
+\r
+ private static Double MINX = 0.0;\r
+ private static Double MAXX = 10.0;\r
+ private static Double MINY = 0.0;\r
+ private static Double MAXY = 10.0;\r
+\r
+ public LookupChartInfo(String expression, String lookupTable, final Resource variable, Map<String, Object> data) {\r
+ this.lookupTable = lookupTable != null ? lookupTable : "";\r
+ this.expression = expression != null ? expression : "";\r
+ this.minX = (Double)data.get("minX");\r
+ this.maxX = (Double)data.get("maxX");\r
+ this.minY = (Double)data.get("minY");\r
+ this.maxY = (Double)data.get("maxY");\r
+ if(variable != null && (minX == null || maxX == null || minY == null || maxY == null)) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if(expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) { \r
+ minX = graph.getPossibleRelatedValue(expression, sr.HasMinX); \r
+ if(minX == null) minX = MINX;\r
+ maxX = graph.getPossibleRelatedValue(expression, sr.HasMaxX); \r
+ if(maxX == null) maxX = MAXX;\r
+ minY = graph.getPossibleRelatedValue(expression, sr.HasMinY); \r
+ if(minY == null) minY = MINY;\r
+ maxY = graph.getPossibleRelatedValue(expression, sr.HasMaxY);\r
+ if(maxY == null) maxY = MAXY;\r
+ } else {\r
+ defaultValues();\r
+ }\r
+\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+ \r
+ private void defaultValues() {\r
+ minX = MINX;\r
+ maxX = MAXX;\r
+ minY = MINY;\r
+ maxY = MAXY;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.equation.expressions;\r
+\r
+import java.awt.Point;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.ChartRenderingInfo;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.axis.ValueAxis;\r
+import org.jfree.chart.entity.ChartEntity;\r
+import org.jfree.chart.entity.PlotEntity;\r
+import org.jfree.chart.entity.XYItemEntity;\r
+import org.jfree.chart.plot.XYPlot;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
+\r
+@SuppressWarnings("serial")\r
+public class LookupChartPanel extends ChartPanel {\r
+\r
+ private XYItemEntity dragPrevEntity;\r
+ private boolean drawing;\r
+ private XYSeries series; \r
+ private JFreeChart chart;\r
+ private LookupInputOutputTable table;\r
+\r
+ public LookupChartPanel(JFreeChart chart) {\r
+ super(chart);\r
+ this.chart = chart;\r
+ XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
+ series = collection.getSeries(0); \r
+ }\r
+\r
+ public void setTable(LookupInputOutputTable table) {\r
+ this.table = table;\r
+ }\r
+\r
+ public void mouseDragged(MouseEvent e)\r
+ {\r
+ if(dragPrevEntity != null) {\r
+\r
+ int item = dragPrevEntity.getItem();\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+ Point2D location = getLocationOnChart(getMouseLocation(e));\r
+ Number prevX = item == 0 ? null : series.getX(item - 1);\r
+ Number nextX = item == series.getItemCount() - 1 ? null : series.getX(item + 1);\r
+\r
+\r
+ if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item)\r
+ return;\r
+ else if (prevX != null && location.getX() < prevX.doubleValue())\r
+ location.setLocation(series.getX(item).doubleValue(), location.getY());\r
+ else if (nextX != null && location.getX() > nextX.doubleValue())\r
+ location.setLocation(series.getX(item).doubleValue(), location.getY());\r
+ else if (location.getX() > domainAxis.getUpperBound())\r
+ location.setLocation(domainAxis.getUpperBound(), location.getY());\r
+ else if (location.getX() < domainAxis.getLowerBound()) \r
+ location.setLocation(domainAxis.getLowerBound(), location.getY()); \r
+\r
+ if (location.getY() > rangeAxis.getUpperBound())\r
+ location.setLocation(location.getX(), rangeAxis.getUpperBound());\r
+ else if (location.getY() < rangeAxis.getLowerBound()) \r
+ location.setLocation(location.getX(), rangeAxis.getLowerBound()); \r
+\r
+ removeItemFromSeries(dragPrevEntity.getItem());\r
+ addLocationToSeries(location);\r
+ } else {\r
+ ChartEntity currEntity = this.getEntityForPoint(e.getX(),e.getY());\r
+ if(!drawing && currEntity instanceof XYItemEntity) {\r
+ dragPrevEntity = ((XYItemEntity)currEntity);\r
+ } else if (currEntity instanceof PlotEntity){\r
+ drawing = true;\r
+ Point2D locationOnChart = getLocationOnChart(getMouseLocation(e));\r
+ int item = series.indexOf(locationOnChart.getX());\r
+ if (item >= 0) {\r
+ Point2D location = new Point2D.Double(series.getX(item).doubleValue(), series.getY(item).doubleValue());\r
+ Point2D javaLocation = getLocationOnJava2D(location);\r
+ removeItemFromSeries(item);\r
+ addLocationToSeries(getLocationOnChart(new Point2D.Double(javaLocation.getX(), e.getY())));\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ public void mouseReleased(MouseEvent e) {\r
+\r
+ dragPrevEntity = null;\r
+ drawing = false;\r
+ }\r
+\r
+ public void mouseClicked(MouseEvent e)\r
+ {\r
+ if(e.getButton() == MouseEvent.BUTTON1) {\r
+ addLocationToSeries(getLocationOnChart(getMouseLocation(e)));\r
+ } else if (e.getButton() == MouseEvent.BUTTON3) {\r
+ ChartEntity entity = this.getEntityForPoint(e.getX(),e.getY());\r
+ if(entity instanceof XYItemEntity) {\r
+ XYItemEntity xyentity = ((XYItemEntity)entity);\r
+ removeItemFromSeries(xyentity.getItem());\r
+ }\r
+ }\r
+ } \r
+\r
+ private Point2D getLocationOnChart(Point2D coordinates) {\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ChartRenderingInfo info = getChartRenderingInfo();\r
+ Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
+ double chartX = plot.getDomainAxis().java2DToValue(coordinates.getX(), dataArea,\r
+ plot.getDomainAxisEdge());\r
+ double chartY = plot.getRangeAxis().java2DToValue(coordinates.getY(), dataArea,\r
+ plot.getRangeAxisEdge());\r
+ return new Point2D.Double(chartX, chartY);\r
+ }\r
+\r
+ private Point2D getLocationOnJava2D(Point2D location) {\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ChartRenderingInfo info = getChartRenderingInfo();\r
+ Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
+ double javaX = plot.getDomainAxis().valueToJava2D(location.getX(), dataArea,\r
+ plot.getDomainAxisEdge());\r
+ double javaY = plot.getRangeAxis().valueToJava2D(location.getY(), dataArea,\r
+ plot.getRangeAxisEdge());\r
+ return new Point2D.Double(javaX, javaY);\r
+ }\r
+\r
+ public void addLocationToSeries(Point2D location) {\r
+ if(series.indexOf(location.getX()) < 0) {\r
+ series.add(location.getX(), location.getY());\r
+ table.addLocation(location);\r
+ }\r
+ }\r
+\r
+ public void removeItemFromSeries(int item){\r
+ Point2D location = new Point2D.Double(series.getX(item).doubleValue(),series.getY(item).doubleValue()); \r
+ series.remove(item);\r
+ table.removeLocation(location);\r
+ }\r
+\r
+ private Point2D getMouseLocation(MouseEvent e) {\r
+ int mouseX = e.getX();\r
+ int mouseY = e.getY();\r
+ Point2D p = translateScreenToJava2D(\r
+ new Point(mouseX, mouseY));\r
+ return p;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class LookupExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void readData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void writeData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.equation.expressions;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ITableLabelProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerComparator;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+\r
+public class LookupInputOutputTable extends Composite {\r
+\r
+ public static final String INPUT = "Input";\r
+ public static final String OUTPUT = "Output";\r
+ public static final String[] PROPS = { INPUT, OUTPUT };\r
+\r
+ Table table;\r
+ TableViewer tableViewer;\r
+ List<InputOutput> tableRows;\r
+\r
+ public LookupInputOutputTable(Composite parent, int style) {\r
+ super(parent, style);\r
+\r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(this);\r
+ table = new Table(this, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(table);\r
+ table.setHeaderVisible (true);\r
+ table.setLinesVisible(true);\r
+ table.getVerticalBar().setVisible(true);\r
+ TableColumn column1 = new TableColumn (table, SWT.LEFT);\r
+ column1.setText (INPUT);\r
+ column1.setWidth (85);\r
+ \r
+ TableColumn column2 = new TableColumn (table, SWT.LEFT);\r
+ column2.setText (OUTPUT);\r
+ column2.setWidth (85);\r
+\r
+ // Create the viewer and connect it to the view\r
+ tableViewer = new TableViewer (table);\r
+\r
+ tableViewer.setContentProvider (new ArrayContentProvider());\r
+ tableViewer.setLabelProvider (new InputOutputLabelProvider());\r
+\r
+ tableRows = new ArrayList<InputOutput>(); \r
+ tableViewer.setInput(tableRows);\r
+\r
+ CellEditor[] editors = new CellEditor[2];\r
+ editors[0] = new TextCellEditor(table);\r
+ editors[1] = new TextCellEditor(table);\r
+ tableViewer.setCellEditors(editors);\r
+ tableViewer.setColumnProperties(PROPS);\r
+ \r
+ }\r
+\r
+ private class InputOutputLabelProvider extends LabelProvider implements ITableLabelProvider {\r
+ public Image getColumnImage (Object element, int columnIndex) {\r
+ return null;\r
+ }\r
+ public String getColumnText (Object element, int columnIndex) {\r
+ if(element instanceof InputOutput) {\r
+ InputOutput io = (InputOutput)element;\r
+ switch (columnIndex) {\r
+ case 0: return (String)io.getInput(String.class);\r
+ case 1: return (String)io.getOutput(String.class);\r
+ }\r
+ }\r
+ return "";\r
+ }\r
+ }\r
+\r
+ public void addLocation(Point2D location) {\r
+ tableRows.add(new InputOutput(location.getX(), location.getY()));\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ refresh();\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ public void removeLocation(Point2D location) {\r
+ for(InputOutput io : tableRows) {\r
+ if((Double)io.getInput(Double.class) == location.getX()) {\r
+ tableRows.remove(io);\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ refresh();\r
+ }\r
+ });\r
+ break;\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ \r
+ class InputOutput {\r
+ private double input, output;\r
+\r
+ public InputOutput(double input, double output) {\r
+ this.input = input;\r
+ this.output = output;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param clazz String.class or Double.class\r
+ * @return input as string or double or null if asked for something else\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public Object getInput(Class clazz) {\r
+ if(clazz == String.class) {\r
+ return "" + input;\r
+ } else if (clazz == Double.class) {\r
+ return input;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public Double setInput(String input) {\r
+ try {\r
+ this.input = Double.parseDouble(input);\r
+ return this.input;\r
+ } catch (NumberFormatException e) {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public void setInput(double input) {\r
+ this.input = input;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param clazz String.class or Double.class\r
+ * @return output as string or double or null if asked for something else\r
+ */\r
+ @SuppressWarnings("unchecked")\r
+ public Object getOutput(Class clazz) {\r
+ if(clazz == String.class) {\r
+ return "" + output;\r
+ } else if (clazz == Double.class) {\r
+ return output;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public void setOutput(String output) {\r
+ try {\r
+ this.output = Double.parseDouble(output);\r
+ } catch (NumberFormatException e) {\r
+\r
+ }\r
+ }\r
+\r
+ public void setOutput(double output) {\r
+ this.output = output;\r
+ }\r
+\r
+ }\r
+\r
+ class InputOutputComparator extends ViewerComparator {\r
+ @Override\r
+ public int compare(Viewer viewer, Object e1, Object e2) {\r
+ if ((e1 instanceof InputOutput) &&\r
+ (e2 instanceof InputOutput)) {\r
+ InputOutput io1 = (InputOutput)e1;\r
+ InputOutput io2 = (InputOutput)e2;\r
+ Double d1 = (Double)io1.getInput((Double.class));\r
+ Double d2 = (Double)io2.getInput((Double.class));\r
+ return d1.compareTo(d2);\r
+ }\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ public TableViewer getTableViewer() {\r
+ return this.tableViewer;\r
+ }\r
+ \r
+ public void refresh() {\r
+ tableViewer.setComparator(new InputOutputComparator());\r
+ tableViewer.refresh();\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.equation.expressions;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.GridLayout;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.geom.Ellipse2D;\r
+import java.awt.geom.Point2D;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import javax.swing.JComponent;\r
+import javax.swing.JPanel;\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.dialogs.IDialogConstants;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ICellModifier;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.swt.widgets.Item;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.jfree.chart.ChartFactory;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.axis.ValueAxis;\r
+import org.jfree.chart.plot.PlotOrientation;\r
+import org.jfree.chart.plot.XYPlot;\r
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
+import org.jfree.data.xy.XYDataItem;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
+import org.simantics.g2d.chassis.SWTAWTComponent;\r
+import org.simantics.sysdyn.tableParser.ParseException;\r
+import org.simantics.sysdyn.tableParser.Token;\r
+import org.simantics.sysdyn.tableParser.TableParser;\r
+import org.simantics.sysdyn.ui.equation.expressions.LookupInputOutputTable.InputOutput;\r
+\r
+public class LookupPopup extends Dialog {\r
+\r
+ JFreeChart chart;\r
+ LookupInputOutputTable table;\r
+ ArrayList<Point2D> dataPoints;\r
+ Text input, output;\r
+ Text minX, maxX, minY, maxY;\r
+ Label unit;\r
+ LookupChartInfo chartInfo;\r
+\r
+ protected LookupPopup(Shell parentShell, LookupChartInfo chartInfo) {\r
+ super(parentShell);\r
+ this.chartInfo = chartInfo;\r
+ this.dataPoints = new ArrayList<Point2D>();\r
+ TableParser parser = new TableParser(new StringReader(""));\r
+ parser.ReInit(new StringReader(chartInfo.lookupTable));\r
+ try {\r
+ parser.table();\r
+ ArrayList<Token> xTokens = parser.getXTokens();\r
+ for(Token token : xTokens) {\r
+ dataPoints.add(new Point2D.Double(\r
+ Double.parseDouble(token.image), \r
+ Double.parseDouble(token.next.next.image)));\r
+ }\r
+ } catch (ParseException e1) {\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ protected Control createDialogArea(Composite parent) {\r
+ KeyListener enterListener = new KeyListener() {\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) {}\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if(e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR)\r
+ getButton(IDialogConstants.OK_ID).forceFocus();\r
+ }\r
+ };\r
+\r
+ final LookupChartPanel chartPanel = new LookupChartPanel(createChart());\r
+ chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));\r
+ chartPanel.setMouseZoomable(true, false);\r
+ chartPanel.setDomainZoomable(false);\r
+ chartPanel.setRangeZoomable(false);\r
+\r
+ XYPlot plot = (XYPlot) chart.getPlot();\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+\r
+ Composite container = new Composite(parent, SWT.None);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(container);\r
+\r
+ Composite yAxis = new Composite(container, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().applyTo(yAxis);\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(yAxis);\r
+ maxY = new Text(yAxis, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(maxY);\r
+ maxY.addKeyListener(enterListener);\r
+ maxY.addModifyListener(getAxisBoundModifyListener());\r
+ maxY.setText("" + rangeAxis.getUpperBound());\r
+ Composite fillY = new Composite(yAxis, SWT.NONE);\r
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(false, true).applyTo(fillY);\r
+ GridLayoutFactory.fillDefaults().applyTo(fillY);\r
+ unit = new Label(fillY, SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(unit);\r
+ unit.setText(""); //TODO: how to get and update units?\r
+ unit.addKeyListener(enterListener);\r
+ minY = new Text(yAxis, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(minY);\r
+ minY.addKeyListener(enterListener);\r
+ minY.addModifyListener(getAxisBoundModifyListener());\r
+ minY.setText("" + rangeAxis.getLowerBound());\r
+\r
+ SWTAWTComponent c = new SWTAWTComponent(container, SWT.BORDER) {\r
+ @Override\r
+ protected JComponent createSwingComponent() {\r
+ JPanel panel = new JPanel();\r
+ panel.setLayout(new GridLayout(1, 1));\r
+ panel.setPreferredSize(new java.awt.Dimension(500, 270));\r
+ panel.add(chartPanel);\r
+ panel.doLayout();\r
+ return panel;\r
+ }\r
+ };\r
+ GridDataFactory.fillDefaults().hint(500, 300).applyTo(c);\r
+ c.populate();\r
+\r
+\r
+ Composite valueTableComposite = new Composite(container, SWT.NONE);\r
+ GridDataFactory.fillDefaults().span(1, 2).grab(true, true).applyTo(valueTableComposite);\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(valueTableComposite);\r
+\r
+\r
+ table = new LookupInputOutputTable(valueTableComposite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().span(3, 1).grab(true, true).applyTo(table);\r
+ chartPanel.setTable(table);\r
+ table.getTableViewer().setCellModifier(new InputOutputCellModifier());\r
+ table.getTableViewer().getTable().addMouseListener(new MouseListener() {\r
+\r
+ @Override\r
+ public void mouseUp(org.eclipse.swt.events.MouseEvent e) {\r
+ if(e.button == MouseEvent.BUTTON3) {\r
+ Table table = (Table)e.widget;\r
+ TableItem item = (TableItem)table.getItem(new org.eclipse.swt.graphics.Point(e.x, e.y));\r
+ chartPanel.removeItemFromSeries(table.indexOf(item));\r
+ }\r
+ }\r
+ @Override\r
+ public void mouseDown(org.eclipse.swt.events.MouseEvent e) { }\r
+ @Override\r
+ public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { }\r
+ });\r
+ for(Point2D location : this.dataPoints) {\r
+ chartPanel.addLocationToSeries(location);\r
+ }\r
+\r
+ input = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(60, SWT.DEFAULT).applyTo(input);\r
+ input.setText("");\r
+ output = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(60, SWT.DEFAULT).applyTo(output);\r
+ output.setText("");\r
+\r
+ Button add = new Button(valueTableComposite, SWT.None);\r
+ add.setText("Add");\r
+ add.addSelectionListener(new SelectionListener() {\r
+\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ try {\r
+ Double in = Double.parseDouble(input.getText());\r
+ Double out = Double.parseDouble(output.getText());\r
+ chartPanel.addLocationToSeries(new Point2D.Double(in, out));\r
+ } catch (NumberFormatException e1) {\r
+ input.setText("");\r
+ output.setText("");\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void widgetDefaultSelected(SelectionEvent e) {}\r
+ });\r
+\r
+ FocusListener flistener = new FocusListener() {\r
+ @Override\r
+ public void focusGained(FocusEvent e) {\r
+ Text text = (Text)e.widget;\r
+ text.setSelection(0, text.getCharCount());\r
+ }\r
+ @Override\r
+ public void focusLost(FocusEvent e) { }\r
+ };\r
+\r
+\r
+ KeyListener listener = new KeyListener() {\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+ try {\r
+ Double in = Double.parseDouble(input.getText());\r
+ Double out = Double.parseDouble(output.getText());\r
+ chartPanel.addLocationToSeries(new Point2D.Double(in, out));\r
+ } catch (NumberFormatException e1) {\r
+ if(input.getText().isEmpty() && output.getText().isEmpty()) {\r
+ getButton(IDialogConstants.OK_ID).forceFocus();\r
+ return;\r
+ }\r
+ }\r
+ input.setText("");\r
+ output.setText("");\r
+ input.setFocus();\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) { }\r
+\r
+ };\r
+\r
+ input.addFocusListener(flistener);\r
+ input.addKeyListener(listener);\r
+ output.addFocusListener(flistener);\r
+ output.addKeyListener(listener);\r
+\r
+ Label l = new Label(container, SWT.NONE);\r
+ l.setText("");\r
+\r
+ Composite xAxis = new Composite(container, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(xAxis);\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(xAxis);\r
+ minX = new Text(xAxis, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(minX); \r
+ minX.addKeyListener(enterListener);\r
+ minX.addModifyListener(getAxisBoundModifyListener());\r
+ minX.setText("" + domainAxis.getLowerBound());\r
+ Composite fillX = new Composite(xAxis, SWT.CENTER);\r
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, false).applyTo(fillX);\r
+ GridLayoutFactory.fillDefaults().applyTo(fillX);\r
+ l = new Label(fillX, SWT.NONE);\r
+ l.setText(chartInfo.expression);\r
+ maxX = new Text(xAxis, SWT.BORDER | SWT.RIGHT);\r
+ GridDataFactory.fillDefaults().hint(40, SWT.DEFAULT).applyTo(maxX);\r
+ maxX.addKeyListener(enterListener);\r
+ maxX.addModifyListener(getAxisBoundModifyListener());\r
+ maxX.setText("" + domainAxis.getUpperBound());\r
+\r
+ return null;\r
+ }\r
+\r
+ protected void createButtonsForButtonBar(Composite parent) {\r
+ // create OK and Cancel buttons by default\r
+ createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,\r
+ false);\r
+ createButton(parent, IDialogConstants.CANCEL_ID,\r
+ IDialogConstants.CANCEL_LABEL, false);\r
+ }\r
+\r
+ public LookupChartInfo open(Boolean bool) {\r
+ Shell shell = this.getShell();\r
+ if (shell == null || shell.isDisposed()) {\r
+ shell = null;\r
+ create();\r
+ shell = this.getShell();\r
+ }\r
+ constrainShellSize();\r
+ shell.open();\r
+ getButton(IDialogConstants.OK_ID).setFocus();\r
+ Display display = getParentShell().getDisplay();\r
+ while (!shell.isDisposed()) {\r
+ if (!display.readAndDispatch()) {\r
+ display.sleep();\r
+ }\r
+ }\r
+ return chartInfo;\r
+ }\r
+ \r
+ @Override\r
+ public void okPressed() {\r
+ chartInfo.lookupTable = graphToModelicaTable();\r
+ chartInfo.minX = Double.parseDouble(minX.getText());\r
+ chartInfo.maxX = Double.parseDouble(maxX.getText());\r
+ chartInfo.minY = Double.parseDouble(minY.getText());\r
+ chartInfo.maxY = Double.parseDouble(maxY.getText());\r
+ super.okPressed();\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ private String graphToModelicaTable() {\r
+ StringBuilder b = new StringBuilder();\r
+ b.append("{");\r
+ XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
+ XYSeries series = collection.getSeries(0);\r
+ if(series.isEmpty())\r
+ return "";\r
+ Iterator iterator = series.getItems().iterator();\r
+ while(iterator.hasNext()){\r
+ XYDataItem item = (XYDataItem)iterator.next();\r
+ b.append("{" + item.getX() + "," + item.getY() + "}");\r
+ if(iterator.hasNext())\r
+ b.append(",");\r
+ }\r
+ b.append("}");\r
+ return b.toString();\r
+ }\r
+\r
+ private JFreeChart createChart() {\r
+ XYDataset dataset = createDataset();\r
+ chart = ChartFactory.createXYLineChart(null, null, null,\r
+ dataset, PlotOrientation.VERTICAL, false, true, false);\r
+ XYPlot plot = (XYPlot) chart.getPlot();\r
+ XYLineAndShapeRenderer renderer\r
+ = (XYLineAndShapeRenderer) plot.getRenderer();\r
+ renderer.setBaseShapesVisible(true);\r
+ renderer.setDrawOutlines(true);\r
+ renderer.setUseFillPaint(true);\r
+ renderer.setBaseFillPaint(Color.white);\r
+ renderer.setSeriesStroke(0, new BasicStroke(3.0f));\r
+ renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0f));\r
+ renderer.setSeriesShape(0, new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0));\r
+\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ rangeAxis.setAutoRange(false);\r
+ rangeAxis.setRange(chartInfo.minY, chartInfo.maxY);\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+ domainAxis.setAutoRange(false);\r
+ domainAxis.setRange(chartInfo.minX, chartInfo.maxX);\r
+ return chart;\r
+ }\r
+\r
+ public XYDataset createDataset() {\r
+ XYSeries series = new XYSeries("Series");\r
+ XYSeriesCollection dataset = new XYSeriesCollection();\r
+ dataset.addSeries(series);\r
+ return dataset;\r
+ }\r
+\r
+ private ModifyListener getAxisBoundModifyListener() {\r
+ return new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ Widget widget = e.widget;\r
+ if(widget instanceof Text) {\r
+ Text text = (Text)widget;\r
+ Double value;\r
+ try {\r
+ value = Double.parseDouble(text.getText());\r
+ } catch (NumberFormatException e1 ) {\r
+ return;\r
+ }\r
+ XYPlot plot = (XYPlot) chart.getPlot();\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+ if(text == minX) {\r
+ domainAxis.setLowerBound(value);\r
+ } else if (text == maxX) {\r
+ domainAxis.setUpperBound(value);\r
+ } else if (text == minY) {\r
+ rangeAxis.setLowerBound(value);\r
+ } else if (text == maxY) {\r
+ rangeAxis.setUpperBound(value);\r
+ }\r
+ }\r
+ }\r
+ };\r
+ }\r
+\r
+ private class InputOutputCellModifier implements ICellModifier {\r
+\r
+ XYSeries series;\r
+\r
+ public InputOutputCellModifier() {\r
+ XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
+ series = collection.getSeries(0); \r
+ }\r
+\r
+ public boolean canModify(Object element, String property) {\r
+ return true;\r
+ }\r
+\r
+ public Object getValue(Object element, String property) {\r
+ InputOutput io = (InputOutput)element;\r
+ if (LookupInputOutputTable.INPUT.equals(property))\r
+ return (String)io.getInput(String.class);\r
+ else if (LookupInputOutputTable.OUTPUT.equals(property))\r
+ return (String)io.getOutput(String.class);\r
+ else\r
+ return null;\r
+ }\r
+\r
+ public void modify(Object element, String property, Object value) {\r
+ if (element instanceof Item) element = ((Item) element).getData();\r
+\r
+ InputOutput io = (InputOutput)element;\r
+ Double x = (Double)io.getInput(Double.class);\r
+ int item = series.indexOf(x);\r
+ series.remove(item);\r
+\r
+ if (LookupInputOutputTable.INPUT.equals(property)) {\r
+ Double newX = io.setInput((String)value);\r
+ // if has the same x-value, revert back\r
+ if(newX != null && series.indexOf(newX) >= 0) {\r
+ io.setInput(x);\r
+ }\r
+ } else if (LookupInputOutputTable.OUTPUT.equals(property)) {\r
+ io.setOutput((String)value);\r
+ }\r
+\r
+ series.add((Double)io.getInput(Double.class), (Double)io.getOutput(Double.class));\r
+\r
+ table.refresh();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ParameterExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ private Label equationLabel;\r
+ private ExpressionField expression;\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+\r
+ final String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
+ equationLabel = new Label(parent, SWT.NONE);\r
+ equationLabel.setFont(FONT);\r
+ equationLabel.setText("=");\r
+ GridDataFactory.fillDefaults().applyTo(equationLabel);\r
+\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setFont(FONT);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.expression != null) this.expression.focus();\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String equation = null;\r
+ if (variable != null && data.get("equation") == null) {\r
+ try {\r
+ equation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.ParameterExpression)) {\r
+ return graph.getRelatedValue(expression, sr.HasEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", equation);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void writeData(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ if(currentText != null) {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null) {\r
+ g.deny(variable, sr.HasExpression);\r
+ }\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.ParameterExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasEquation, currentText);\r
+ }\r
+\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression());\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class StockExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+ private Label integralLabel;\r
+ private Text integral;\r
+ private Label equationLabel;\r
+ private ExpressionField expression;\r
+\r
+ @Override\r
+ public void createView(Composite parent, Map<String, Object> data) {\r
+\r
+ final String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
+ final String integralEquation = data.get("integral") != null ? (String)data.get("integral") : "";\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
+\r
+ integralLabel = new Label(parent, SWT.NONE);\r
+ integralLabel.setFont(FONT);\r
+ integralLabel.setText("Integral");\r
+ GridDataFactory.fillDefaults().applyTo(integralLabel);\r
+\r
+ integral = new Text(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);\r
+ integral.setEditable(false);\r
+ integral.setFont(FONT);\r
+ integral.setText(integralEquation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(integral);\r
+\r
+ equationLabel = new Label(parent, SWT.NONE);\r
+ equationLabel.setFont(FONT);\r
+ equationLabel.setText("Initial\nValue");\r
+ GridDataFactory.fillDefaults().applyTo(equationLabel);\r
+\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setFont(FONT);\r
+ expression.setExpression(initialEquation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String initialEquation = null;\r
+\r
+ if (variable != null && data.get("initialEquation") == null) {\r
+ try {\r
+ initialEquation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.StockExpression)) {\r
+ return graph.getRelatedValue(expression, sr.HasInitialEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("initialEquation", initialEquation);\r
+ }\r
+\r
+ data.put("integral", getIntegral(variable));\r
+ }\r
+\r
+ @Override\r
+ public void writeData(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ if(currentText != null) {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null) {\r
+ g.deny(variable, sr.HasExpression);\r
+ }\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.StockExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasInitialEquation, currentText);\r
+ }\r
+\r
+ });\r
+ }\r
+ }\r
+\r
+ private String getIntegral(final Resource variable) {\r
+ String integral = "";\r
+ try {\r
+ integral = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+ Collection<Resource> heads = graph.getObjects(variable, sr.IsHeadOf);\r
+ Collection<Resource> tails = graph.getObjects(variable, sr.IsTailOf);\r
+\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("");\r
+ for (Resource r : heads) {\r
+ if(graph.isInstanceOf(r, sr.Flow)) {\r
+ Resource tail = graph.getPossibleObject(r, sr.HasTail);\r
+ if(tail != null) {\r
+ Object name = graph.getPossibleRelatedValue(tail, b.HasName);\r
+ if (name != null)\r
+ builder.append(" + " + name);\r
+ }\r
+ }\r
+ }\r
+ for (Resource r : tails) {\r
+ if(graph.isInstanceOf(r, sr.Flow)) {\r
+ Resource head = graph.getPossibleObject(r, sr.HasHead);\r
+ if(head != null) {\r
+ Object name = graph.getPossibleRelatedValue(head, b.HasName);\r
+ if (name != null)\r
+ builder.append(" - " + name);\r
+ }\r
+ }\r
+ }\r
+ if (builder.indexOf(" + ") == 0)\r
+ builder.delete(0, 3);\r
+ return builder.toString().trim();\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return integral;\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.expression != null) this.expression.focus();\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("initialEquation", this.expression.getExpression());\r
+ if(this.integral != null && this.integral.getText() != null)\r
+ data.put("integral", this.integral.getText());\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.equation.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class WithLookupExpressionViewFactor implements IExpressionViewFactor {\r
+\r
+\r
+ private Label expressionLabel;\r
+ private ExpressionField expression;\r
+ private Label lookupLabel;\r
+ private ExpressionField lookup;\r
+ private Button asGraph;\r
+ private ExpressionField lastSelectedText = expression;\r
+ private Resource variable;\r
+ private LookupChartInfo chartInfo;\r
+\r
+ public WithLookupExpressionViewFactor(Resource variable) {\r
+ super();\r
+ this.variable = variable;\r
+ }\r
+ \r
+ @Override\r
+ public void createView(Composite parent, final Map<String, Object> data) {\r
+ String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+ String lookupTable = data.get("lookup") != null ? (String)data.get("lookup") : "";\r
+\r
+ GridLayoutFactory.fillDefaults().numColumns(2).spacing(3, 3).applyTo(parent);\r
+\r
+ expressionLabel = new Label(parent, SWT.NONE);\r
+ expressionLabel.setFont(FONT);\r
+ expressionLabel.setText("With\nLookup");\r
+ GridDataFactory.fillDefaults().applyTo(expressionLabel);\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setFont(FONT);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ lastSelectedText = expression;\r
+ }\r
+ });\r
+\r
+ lookupLabel = new Label(parent, SWT.NONE);\r
+ lookupLabel.setFont(FONT);\r
+ lookupLabel.setText("Lookup\ntable");\r
+ GridDataFactory.fillDefaults().applyTo(lookupLabel);\r
+\r
+ lookup = new ExpressionField(parent, SWT.BORDER);\r
+ lookup.setFont(FONT);\r
+ lookup.setExpression(lookupTable);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(lookup);\r
+\r
+ lookup.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ lastSelectedText = lookup;\r
+ }\r
+ });\r
+\r
+ asGraph = new Button(parent, SWT.None);\r
+ asGraph.setText("As graph");\r
+ asGraph.setFont(FONT);\r
+ asGraph.addSelectionListener(new SelectionAdapter() {\r
+ public void widgetSelected(SelectionEvent e) {\r
+ if(e.widget == asGraph) {\r
+ if(chartInfo == null) chartInfo = new LookupChartInfo(expression.getExpression(), lookup.getExpression(), variable, data);\r
+ LookupPopup pud = new LookupPopup(asGraph.getParent().getShell(), chartInfo);\r
+ LookupChartInfo newInfo = pud.open(false);\r
+ if(pud.getReturnCode() == org.eclipse.jface.window.Window.OK) {\r
+ chartInfo = newInfo;\r
+ lookup.setExpression(chartInfo.lookupTable);\r
+ }\r
+ }\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String[] results = null;\r
+ if (variable != null && data.get("equation") == null) {\r
+ try {\r
+ results = SimanticsUI.getSession().syncRequest(new Read<String[]>() {\r
+\r
+ @Override\r
+ public String[] perform(ReadGraph graph) throws DatabaseException {\r
+ String[] results = new String[2];\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ results[0] = graph.getRelatedValue(expression, sr.HasEquation);\r
+ results[1] = graph.getRelatedValue(expression, sr.HasLookup);\r
+ } else {\r
+ results[0] = "";\r
+ results[1] = "";\r
+ }\r
+ return results;\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", results[0]);\r
+ data.put("lookup", results[1]);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void writeData(final Resource variable, Map<String, Object> data) {\r
+ final String currentExpression = expression.getExpression();\r
+ final String currentLookupTable = lookup.getExpression();\r
+\r
+ if(currentExpression != null && currentLookupTable != null) {\r
+ data.putAll(data);\r
+ data.put("equation", currentExpression);\r
+ data.put("lookup", currentLookupTable);\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null) {\r
+ g.deny(variable, sr.HasExpression);\r
+ }\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.WithLookupExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasEquation, currentExpression);\r
+ g.claimValue(expression, sr.HasLookup, currentLookupTable);\r
+ g.claimValue(expression, sr.HasMinX, chartInfo.minX);\r
+ g.claimValue(expression, sr.HasMaxX, chartInfo.maxX);\r
+ g.claimValue(expression, sr.HasMinY, chartInfo.minY);\r
+ g.claimValue(expression, sr.HasMaxY, chartInfo.maxY);\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.lastSelectedText != null) this.lastSelectedText.focus();\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(lastSelectedText != null) {\r
+ IDocument doc = lastSelectedText.getDocument();\r
+ try {\r
+ Point selection = lastSelectedText.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ lastSelectedText.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression());\r
+ if(this.lookup != null && this.lookup.getExpression() != null)\r
+ data.put("lookup", this.lookup.getExpression());\r
+ if(this.chartInfo != null) {\r
+ data.put("minX", chartInfo.minX);\r
+ data.put("maxX", chartInfo.maxX);\r
+ data.put("minY", chartInfo.minY);\r
+ data.put("maxY", chartInfo.maxY);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression, this.lookup);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.sysdyn.ui.actions.CreateAuxiliary;\r
+\r
+public class CreateAuxiliaryHandler extends DiagramContextMenuActionHandler {\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ CreateAuxiliary ca = new CreateAuxiliary();\r
+ ca.handle(editor, event);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.sysdyn.ui.actions.CreateCloud;\r
+\r
+public class CreateCloudHandler extends DiagramContextMenuActionHandler {\r
+\r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ CreateCloud cc = new CreateCloud();\r
+ cc.handle(editor, event);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.sysdyn.ui.actions.CreateStock;\r
+\r
+public class CreateStockHandler extends DiagramContextMenuActionHandler {\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ CreateStock cs = new CreateStock();\r
+ cs.handle(editor, event);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.sysdyn.ui.actions.CreateValve;\r
+\r
+public class CreateValveHandler extends DiagramContextMenuActionHandler {\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ CreateValve cv = new CreateValve();\r
+ cv.handle(editor, event);\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.swt.widgets.MenuItem;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.sysdyn.ui.actions.DiagramContextMenuData;\r
+import org.simantics.sysdyn.ui.editor.SysdynDiagramEditor;\r
+\r
+public abstract class DiagramContextMenuActionHandler extends AbstractHandler {\r
+ \r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ IWorkbenchPart ap = HandlerUtil.getActivePart(event);\r
+ if(ap instanceof SysdynDiagramEditor) {\r
+ Event ci = (Event)event.getTrigger();\r
+ MenuItem mi = (MenuItem) ci.widget;\r
+ Menu m = mi.getParent();\r
+ while(m.getParentMenu() != null)\r
+ m = m.getParentMenu();\r
+ DiagramContextMenuData cmd = (DiagramContextMenuData) m.getData();\r
+ IDiagramEditor de = cmd.diagramEditor;\r
+ IEvent evnt = cmd.event;\r
+ handleEvent(de, evnt);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ // Implement in another class\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.simantics.project.IExperimentDescriptor;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class DisposeExperiment extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ IProject project = SimanticsUI.getProject();\r
+ IExperimentManager manager = \r
+ project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if (experiment != null)\r
+ experiment.shutdown();\r
+\r
+ /*\r
+ // Keep the UI happy.\r
+ IExperimentDescriptor ed = project.getHint(ProjectKeys.KEY_SELECTED_UI_EXPERIMENT);\r
+ if (ed != null) {\r
+ ed.getParent().removeHint(ProjectKeys.KEY_SELECTED_EXPERIMENT);\r
+ project.removeHint(ProjectKeys.KEY_SELECTED_UI_EXPERIMENT);\r
+ }\r
+ */\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class NewExperimentNodeHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ System.out.println("New Experiment");\r
+ \r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+ if (resources.length != 1)\r
+ return null;\r
+ \r
+ final Resource model = resources[0];\r
+ \r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph g) throws DatabaseException {\r
+ Builtins b = g.getBuiltins();\r
+ Resource report = GraphUtils.create2(g, b.Report, b.HasDocumentation, "===Report===");\r
+ @SuppressWarnings("unused")\r
+ Resource experiment = GraphUtils.create2(g, b.Experiment,\r
+ b.HasName, "Experiment",\r
+ b.HasLabel, "Experiment",\r
+ b.HasReportFactory, report,\r
+ b.PartOf, model);\r
+ }\r
+ });\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException; \r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.DiagramConstants;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayer;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayerUtil;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class NewModelHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph g) throws DatabaseException {\r
+ // Same as in SysdynProject.java. Should use the same code, not copy.\r
+ Builtins b = g.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ ModelingResources mr = ModelingResources.getInstance(g);\r
+ ModelingUtils mu = new ModelingUtils(g);\r
+ \r
+ Resource model = g.newResource();\r
+ g.claimValue(model, b.HasName, "Model1");\r
+ g.claimValue(model, b.HasLabel, "Model1");\r
+ g.claim(model, b.InstanceOf, sr.SysdynModel);\r
+ g.claim(model, b.PartOf, SimanticsUI.getProject().get());\r
+ \r
+ \r
+ Resource diagram = OrderedSetUtils.create(g, sr.ConfigurationDiagram);\r
+ GraphLayer l = new GraphLayerUtil(g).createLayer(DiagramConstants.DEFAULT_LAYER_NAME, true);\r
+ g.claim(diagram, mu.dr.HasLayer, l.getLayer());\r
+ g.claimValue(diagram, b.HasName, "Diagrammi", StringBindingDefault.INSTANCE);\r
+ \r
+ Resource conf = GraphUtils.create2(g, \r
+ sr.Configuration,\r
+ b.PartOf, model,\r
+ b.HasName, "Configuration",\r
+ sr.HasStartTime, 0.0,\r
+ sr.HasStopTime, 10.0);\r
+\r
+ g.claim(conf, mr.CompositeToDiagram, diagram);\r
+ g.claim(model, b.HasConfiguration, conf);\r
+ \r
+ Resource mapping = g.newResource();\r
+ g.claim(mapping, b.InstanceOf, null, sr.DiagramToCompositeMapping);\r
+ g.claim(diagram, b.HasTrigger, mapping);\r
+ \r
+ Resource report = GraphUtils.create2(g, mu.b.Report, mu.b.HasDocumentation, "===Report===");\r
+\r
+ Resource experiment = GraphUtils.create2(g, mu.b.Experiment,\r
+ mu.b.HasName, "Experiment",\r
+ mu.b.HasLabel, "Experiment",\r
+ mu.b.HasReportFactory, report,\r
+ mu.b.PartOf, model);\r
+ }\r
+ });\r
+ return null;\r
+ }\r
+\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.DiagramConstants;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayer;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayerUtil;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class NewModuleNodeHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ \r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+ if (resources.length != 1)\r
+ return null;\r
+ \r
+ final Resource model = resources[0];\r
+ \r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph g) throws DatabaseException {\r
+ // Same as in SysdynProject.java. Should use the same code, not copy.\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ ModelingUtils mu = new ModelingUtils(g);\r
+ \r
+ Resource moduleType = g.newResource();\r
+ g.claimValue(moduleType, mu.b.HasName, "New Module Type");\r
+ g.claim(moduleType, mu.b.Inherits, sr.Module);\r
+ g.claim(moduleType, mu.b.PartOf, model);\r
+ \r
+ Resource diagram = OrderedSetUtils.create(g, sr.ConfigurationDiagram);\r
+ GraphLayer l = new GraphLayerUtil(g).createLayer(DiagramConstants.DEFAULT_LAYER_NAME, true);\r
+ g.claim(diagram, mu.dr.HasLayer, l.getLayer());\r
+ Resource mapping = g.newResource();\r
+ g.claim(mapping, mu.b.InstanceOf, null, sr.DiagramToCompositeMapping);\r
+ g.claim(diagram, mu.b.HasTrigger, mapping);\r
+\r
+ \r
+ Resource configuration = GraphUtils.create2(g, \r
+ sr.Configuration,\r
+ mu.b.HasName, "ModuuliConffi",\r
+ mu.mr.CompositeToDiagram, diagram);\r
+ \r
+ g.claim(moduleType, mu.sr.IsDefinedBy , configuration);\r
+ \r
+ \r
+ Resource moduleSymbol = g.newResource();\r
+ g.claimValue(moduleSymbol, mu.b.HasName, "ModuuliSymboli");\r
+ g.claimValue(moduleSymbol, mu.b.HasLabel, "ModuuliSymboliLabel");\r
+ g.claim(moduleSymbol, mu.b.Inherits, sr.ModuleSymbol);\r
+ g.claim(moduleSymbol, mu.mr.SymbolToComponentType, moduleType);\r
+ \r
+ Resource terminal = g.newResource();\r
+ g.claim(terminal, mu.b.InstanceOf, sr.SysdynTerminal);\r
+ Resource connectionVariable = g.newResource();\r
+ g.claim(connectionVariable, mu.b.InstanceOf, mu.sr.ConnectionVariable);\r
+ g.claim(connectionVariable, mu.sr.Binds, sr.IsHeadOfTerminal);\r
+ g.claim(connectionVariable, mu.sr.IsParameterOf, sr.ModuleSymbol);\r
+ g.claim(terminal, mu.dr.HasConnectionVariable, connectionVariable);\r
+ \r
+ \r
+ Resource terminal2 = g.newResource();\r
+ g.claim(terminal2, mu.b.InstanceOf, sr.SysdynTerminal);\r
+ Resource connectionVariable2 = g.newResource();\r
+ g.claim(connectionVariable2, mu.b.InstanceOf, mu.sr.ConnectionVariable);\r
+ g.claim(connectionVariable2, mu.sr.Binds, sr.IsTailOfTerminal);\r
+ g.claim(connectionVariable2, mu.sr.IsParameterOf, sr.ModuleSymbol);\r
+ g.claim(terminal2, mu.dr.HasConnectionVariable, connectionVariable2);\r
+ \r
+ g.claim(moduleSymbol, mu.sr.IsDefinedBy, OrderedSetUtils.create(g, mu.sr.Composite, terminal, terminal2));\r
+ \r
+ \r
+ }\r
+ });\r
+ return null;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.handler.Delete;\r
+\r
+public class RemoveHandler extends DiagramContextMenuActionHandler {\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ Delete d = new Delete();\r
+ d.handle(editor, event);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.RemoverUtil;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class RemoveNodeHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+ if (resources.length == 0)\r
+ return null;\r
+\r
+ MessageDialog dialog = new MessageDialog(shell, "Remove Item", null, "Are you sure?", 0,\r
+ new String[] { "OK", "Cancel" }, 0);\r
+ dialog.create();\r
+ if (dialog.open() == 0)\r
+ deleteItem(resources);\r
+\r
+ return null;\r
+ }\r
+\r
+ private void deleteItem(final Resource[] resources) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+ for (Resource r : resources)\r
+ RemoverUtil.remove(graph, r);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ ExceptionUtils.logAndShowError(e);\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.simantics.h2d.editor.IDiagramEditor;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.h2d.event.IEvent;\r
+import org.simantics.h2d.event.ILocatableEvent;\r
+import org.simantics.sysdyn.ui.elements.TextElement;\r
+\r
+public class RenameHandler extends DiagramContextMenuActionHandler {\r
+ \r
+ protected void handleEvent(IDiagramEditor editor, IEvent event) {\r
+ ILocatableEvent e = (ILocatableEvent)event;\r
+ if(e.getPickedElements().size() <= 0) return;\r
+ IElement element = e.getPickedElements().get(0);\r
+ if(element instanceof TextElement) {\r
+ TextElement te = (TextElement)element;\r
+ te.beginRenameAction(editor);\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class RenameNodeHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ NodeContext ctx = ISelectionUtils.filterSingleSelection(sel, NodeContext.class);\r
+ if (ctx == null)\r
+ return null;\r
+\r
+ IWorkbenchPart part = HandlerUtil.getActivePart(event);\r
+ if (part == null)\r
+ return null;\r
+\r
+ GraphExplorer graphExplorer = (GraphExplorer) part.getAdapter(GraphExplorer.class);\r
+ if (graphExplorer != null)\r
+ graphExplorer.startEditing(ctx, ColumnKeys.SINGLE);\r
+\r
+ return null;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.Command;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.commands.ICommandService;\r
+import org.eclipse.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.ui.actions.ToggleSimulation;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class RunBasicExperiment extends AbstractHandler implements IElementUpdater {\r
+ \r
+ public static final String COMMAND = "org.simantics.sysdyn.ui.run";\r
+ \r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ IExperimentManager manager = \r
+ SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulate(true);\r
+ return null;\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ @Override\r
+ public void updateElement(UIElement element, Map parameters) {\r
+ ICommandService commandService =\r
+ (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = commandService.getCommand(ToggleSimulation.COMMAND);\r
+ boolean checked = (Boolean) command.getState(ToggleSimulation.STATE).getValue();\r
+ if(checked)\r
+ this.setBaseEnabled(false);\r
+ else\r
+ this.setBaseEnabled(true);\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class SaveResultsHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ IExperimentManager manager = \r
+ SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment instanceof IDynamicExperiment) {\r
+ ((IDynamicExperiment)experiment).saveState();\r
+ }\r
+ return null;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.ResourceArray;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ComponentUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.StructuralVariables;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.ui.workbench.ResourceEditorInput2;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * Style Edit\r
+ * \r
+ * TODO : should we have extension point for expanding styles?\r
+ * TODO : default ColorChooser is not suitable for this task\r
+ * TODO : how to store MetricsFormat template list\r
+ * \r
+ * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
+ *\r
+ */\r
+public class ShowModuleHandler extends AbstractHandler {\r
+\r
+ private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ \r
+ ISelection s = HandlerUtil.getCurrentSelectionChecked(event);\r
+ final Resource resources[] = ResourceAdaptionUtils.toResources(s);\r
+ final DiagramViewer viewer = (DiagramViewer)HandlerUtil.getActiveEditor(event);\r
+ \r
+ SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+\r
+ DiagramResource dr = DiagramResource.getInstance(graph);\r
+ Resource runtime = viewer.getRuntime();\r
+ String uri = graph.getPossibleRelatedValue(runtime, dr.HasVariable, StringBindingDefault.INSTANCE);\r
+ String currentRVI = graph.getPossibleRelatedValue(runtime, dr.HasRVI, StringBindingDefault.INSTANCE);\r
+ Variable variable = Variables.getVariable(graph, uri);\r
+ Resource model = Variables.getModel(graph, variable);\r
+ final String modelURI = graph.getURI(model);\r
+ \r
+ for(Resource element : resources) {\r
+\r
+ Builtins b = graph.getBuiltins();\r
+ ModelingResources mr = ModelingResources.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+ \r
+ final Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+ final Resource componentType = graph.getPossibleType(component, sr.Module);\r
+ final Resource configuration = graph.getPossibleObject(componentType, st.IsDefinedBy);\r
+ final Resource diagram = ComponentUtils.getPossibleCompositeDiagram(graph, configuration);\r
+ \r
+ if(diagram == null) return;\r
+ \r
+ final String rvi = currentRVI + "/" + graph.getPossibleRelatedValue(component, b.HasName, StringBindingDefault.INSTANCE);\r
+ if(rvi == null) return;\r
+\r
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ // for (Triple<Resource, String, String> in : ins) {\r
+ try {\r
+ String editorId = EDITOR_ID;\r
+ System.out.println("Activating diagram: model=" + modelURI + " rvi='" + rvi + "'");\r
+ WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, diagram, modelURI, rvi));\r
+ } catch (PartInitException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ // }\r
+ }\r
+ });\r
+ \r
+ }\r
+ \r
+ }\r
+ });\r
+ \r
+ return null;\r
+ }\r
+ \r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.concurrent.Semaphore;\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.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.AdaptionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.message.MessageService;\r
+import org.simantics.project.IExperimentDescriptor;\r
+import org.simantics.project.IModelDescriptor;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.IProjectElement;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.project.exception.ProjectException;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.model.ExperimentLoadingFailed;\r
+import org.simantics.simulation.project.IExperimentActivationListener;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.ui.listeners.SysdynExperimentManagerListener;\r
+import org.simantics.utils.DataContainer;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+import org.simantics.utils.ui.dialogs.ShowMessage;\r
+\r
+public class SysdynExperimentActivator {\r
+ /**\r
+ * @param project\r
+ * @param experimentManager\r
+ * @param experiment\r
+ */\r
+ public static void scheduleActivation(RequestProcessor processor, final IProject project, final IExperimentManager experimentManager, final Resource experiment) {\r
+ String jobName = "Activate Experiment";\r
+ String experimentName = getName(processor, experiment);\r
+ if (experimentName != null)\r
+ jobName += " '" + experimentName + "'";\r
+ /*\r
+ // Shut down the previous active experiment\r
+ IExperiment activeExperiment = experimentManager.getActiveExperiment();\r
+ if (experiment != null)\r
+ activeExperiment.shutdown();\r
+ */\r
+ // Activate a new experiment\r
+ scheduleActivation(jobName, project, experimentManager, experiment);\r
+ }\r
+\r
+ /**\r
+ * @param project\r
+ * @param experimentManager\r
+ * @param experiment\r
+ */\r
+ public static void scheduleActivation(String jobName, final IProject project, final IExperimentManager experimentManager, final Resource experiment) {\r
+ new Job(jobName) {\r
+ @Override\r
+ protected IStatus run(final IProgressMonitor monitor) {\r
+ return SysdynExperimentActivator.activate(monitor, project, experimentManager, experiment);\r
+ }\r
+ }.schedule();\r
+ }\r
+\r
+ public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
+ return new SysdynExperimentActivator().activateExperiment(monitor, project, experimentManager, experiment);\r
+ }\r
+\r
+ private static String getName(RequestProcessor processor, final Resource resource) {\r
+ try {\r
+ return processor.syncRequest(new Read<String>() {\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ try {\r
+ return graph.adapt(resource, String.class);\r
+ } catch (AdaptionException e) {\r
+ return GraphUtils.getReadableName(graph, resource);\r
+ }\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ ErrorLogger.defaultLogWarning(e);\r
+ return null;\r
+ }\r
+ }\r
+\r
+ private IStatus activateExperiment(final IProgressMonitor monitor, final IProject project, final IExperimentManager manager, final Resource experimentResource) {\r
+ monitor.beginTask("Activating experiment", IProgressMonitor.UNKNOWN);\r
+ try {\r
+ SysdynExperimentManagerListener.listenManager(manager);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment != null) {\r
+ experiment.shutdown();\r
+ }\r
+ final Semaphore activated = new Semaphore(0);\r
+ final DataContainer<Throwable> problem = new DataContainer<Throwable>();\r
+ manager.startExperiment(experimentResource, new IExperimentActivationListener() {\r
+ \r
+ @Override\r
+ public void onExperimentActivated(final IExperiment experiment) {\r
+\r
+ MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
+ \r
+ \r
+ activated.release();\r
+ // Set the selected experiment into the the model descriptor.\r
+ new Thread("Set Selected Experiment") {\r
+ @Override\r
+ public void run() {\r
+ setSelectedExperiment(project, experimentResource);\r
+ }\r
+ }.start();\r
+ }\r
+ @Override\r
+ public void onFailure(Throwable e) {\r
+ problem.set(e);\r
+ activated.release();\r
+ }\r
+ @Override\r
+ public void onMessage(IStatus message) {\r
+ MessageService.getDefault().log(message);\r
+ /*ILogger logger = MessageService.getDefault();\r
+ MultiStatus init = new MultiStatus(Activator.PLUGIN_ID, 0, "Activating experiment", null);\r
+ for (String msg : messages) {\r
+ init.add(new Status(IStatus.INFO, Activator.PLUGIN_ID, msg));\r
+ }\r
+ logger.log(init);*/\r
+ }\r
+ }, true);\r
+ try {\r
+ activated.acquire();\r
+ Throwable t = problem.get();\r
+ if (t != null) {\r
+ if (t instanceof ExperimentLoadingFailed) {\r
+ ErrorLogger.defaultLogError(t);\r
+ ShowMessage.showError("Experiment Activation Failed", t.getMessage());\r
+ } else {\r
+ ExceptionUtils.logAndShowError(t);\r
+ }\r
+ }\r
+ \r
+ return Status.OK_STATUS;\r
+ //return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Experiment activation failed, see exception for details.", problem.get());\r
+ } catch (InterruptedException e) {\r
+ return Status.CANCEL_STATUS;\r
+ }\r
+ } finally {\r
+ monitor.done();\r
+ }\r
+ }\r
+\r
+ private void setSelectedExperiment(IProject project, Resource experiment) {\r
+ try {\r
+ for (IProjectElement model : project.members()) {\r
+ if (model instanceof IModelDescriptor) {\r
+ for (IProjectElement member : ((IModelDescriptor) model).members()) {\r
+ if (member instanceof IExperimentDescriptor && experiment.equals(member.get())) {\r
+ model.setHint(ProjectKeys.KEY_SELECTED_EXPERIMENT, member);\r
+ project.setHint(ProjectKeys.KEY_SELECTED_UI_EXPERIMENT, member);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } catch (ProjectException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class ToggleResultActivation extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+ if (resources.length == 0)\r
+ return null;\r
+ \r
+ toggleActivation(resources);\r
+ \r
+ return null;\r
+ }\r
+\r
+ private void toggleActivation(final Resource[] resources) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+ for(Resource r : resources) {\r
+ if(graph.isInstanceOf(r, sr.Result)) {\r
+ if (graph.hasStatement(r, b.IsActive)) {\r
+ graph.denyStatement(r, b.IsActive, r);\r
+ } else {\r
+ graph.claim(r, b.IsActive, r);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ });\r
+ } catch (DatabaseException e) {\r
+ \r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.handlers;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.IEditorReference;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.editor.SysdynDiagramEditor;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class UnlinkNodeHandler extends AbstractHandler {\r
+\r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+ ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+ Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+ if (resources.length == 0)\r
+ return null;\r
+\r
+ MessageDialog dialog = new MessageDialog(shell, "Remove Item", null, "Are you sure?", 0,\r
+ new String[] { "OK", "Cancel" }, 0);\r
+ dialog.create();\r
+ if (dialog.open() == 0)\r
+ deleteItem(resources);\r
+\r
+ return null;\r
+ }\r
+\r
+ private void deleteItem(final Resource[] resources) {\r
+ final ArrayList<Resource> configurations = new ArrayList<Resource>();\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ for (Resource r : resources) {\r
+ if (graph.isInstanceOf(r, sr.SysdynModel)) {\r
+ unlinkModel(graph, r);\r
+ configurations.add(graph.getSingleObject(r, graph.getBuiltins().HasConfiguration));\r
+ }\r
+ else if (graph.isInstanceOf(r, graph.getBuiltins().Experiment))\r
+ unlinkExperiment(graph, r);\r
+ else if (graph.isInstanceOf(r, sr.Result))\r
+ unlinkResult(graph, r);\r
+ }\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ ExceptionUtils.logAndShowError(e);\r
+ }\r
+\r
+ for (Resource r : configurations) {\r
+ IEditorReference[] editorReferences = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getEditorReferences();\r
+ for(IEditorReference er : editorReferences) {\r
+ if(er.getEditor(false) instanceof SysdynDiagramEditor) {\r
+ SysdynDiagramEditor editor = (SysdynDiagramEditor)er.getEditor(false);\r
+ if(editor.getResourceInput().getResource().equals(r)) {\r
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeEditor(editor, false);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ private void unlinkModel(WriteGraph graph, Resource model) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+\r
+ for(Resource r : graph.getObjects(model, b.ConsistsOf))\r
+ if(graph.isInstanceOf(r, SysdynResource.getInstance(graph).Result))\r
+ deleteResultFiles(graph, r);\r
+\r
+ graph.deny(model, b.PartOf);\r
+ }\r
+\r
+ private void unlinkExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ Collection<Resource> results = graph.getObjects(experiment, SysdynResource.getInstance(graph).HasResult);\r
+ if(results != null)\r
+ for(Resource result : results) \r
+ unlinkResult(graph, result);\r
+ graph.deny(experiment, b.PartOf);\r
+\r
+ }\r
+\r
+ private void unlinkResult(WriteGraph graph, Resource result) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ deleteResultFiles(graph, result);\r
+ graph.deny(result, b.PartOf);\r
+ graph.deny(result, graph.getInverse(SysdynResource.getInstance(graph).HasResult));\r
+\r
+ }\r
+\r
+ private void deleteResultFiles(WriteGraph graph, Resource result) throws DatabaseException {\r
+ String path;\r
+ path = graph.getPossibleRelatedValue(result, SysdynResource.getInstance(graph).HasResultFile);\r
+ if(path != null) {\r
+ File file = new File(path);\r
+ file.delete();\r
+ File parent = file.getParentFile();\r
+ if(parent.listFiles().length == 0)\r
+ parent.delete();\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.sysdyn.ui.listeners;\r
+\r
+import org.eclipse.core.commands.Command;\r
+import org.eclipse.core.commands.State;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.commands.ICommandService;\r
+import org.eclipse.ui.contexts.IContextActivation;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperimentListener;\r
+import org.simantics.sysdyn.ui.actions.ToggleSimulation;\r
+import org.simantics.sysdyn.ui.handlers.RunBasicExperiment;\r
+\r
+public class SysdynExperimentListener implements IExperimentListener {\r
+\r
+ IContextActivation contextActivation;\r
+\r
+ @Override\r
+ public void stateChanged(final ExperimentState state) {\r
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ ICommandService commandService =\r
+ (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = commandService.getCommand(ToggleSimulation.COMMAND);\r
+ State buttonState = command.getState(ToggleSimulation.STATE);\r
+ \r
+ switch(state) {\r
+ case DISPOSED:\r
+ buttonState.setValue(false); \r
+ break;\r
+ }\r
+ commandService.refreshElements(command.getId(), null); \r
+ commandService.refreshElements(RunBasicExperiment.COMMAND, null);\r
+ }\r
+ \r
+ });\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.listeners;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.contexts.IContextActivation;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.simulation.project.IExperimentManagerListener;\r
+\r
+public class SysdynExperimentManagerListener implements IExperimentManagerListener{\r
+\r
+ public static final String BASIC_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.basicExperiment";\r
+ \r
+ static Set<IExperimentManager> managers = \r
+ new HashSet<IExperimentManager>();\r
+ \r
+ IExperimentManager manager;\r
+ \r
+ Collection<IContextActivation> contextActivations = \r
+ new ArrayList<IContextActivation>();\r
+ \r
+ public SysdynExperimentManagerListener(IExperimentManager manager) {\r
+ this.manager = manager;\r
+ }\r
+\r
+ public static void listenManager(IExperimentManager manager) {\r
+ synchronized(managers) {\r
+ if(managers.contains(manager))\r
+ return;\r
+ SysdynExperimentManagerListener listener = \r
+ new SysdynExperimentManagerListener(manager);\r
+ manager.addListener(listener);\r
+ managers.add(manager);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void activeExperimentLoaded(final IExperiment experiment) { \r
+ experiment.addListener(new SysdynExperimentListener());\r
+\r
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ IContextService contextService =\r
+ (IContextService)PlatformUI.getWorkbench()\r
+ .getActiveWorkbenchWindow().getService(IContextService.class);\r
+ synchronized(contextActivations) {\r
+ contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT));\r
+ }\r
+ }\r
+ \r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void activeExperimentUnloaded() {\r
+ \r
+ synchronized(contextActivations) {\r
+ final Collection<IContextActivation> oldContextActivations = \r
+ contextActivations;\r
+ \r
+ contextActivations = new ArrayList<IContextActivation>();\r
+ \r
+ final IWorkbench workbench = PlatformUI.getWorkbench();\r
+ workbench.getDisplay().asyncExec(new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ if (workbench.isClosing())\r
+ return;\r
+ \r
+ IContextService contextService =\r
+ (IContextService)workbench.getActiveWorkbenchWindow().getService(IContextService.class);\r
+ contextService.deactivateContexts(oldContextActivations); \r
+ }\r
+ \r
+ });\r
+ }\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void managerDisposed() {\r
+ synchronized(managers) {\r
+ managers.remove(manager);\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.modelica;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.presentation.IPresentationReconciler;\r
+import org.eclipse.jface.text.presentation.PresentationReconciler;\r
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;\r
+import org.eclipse.jface.text.rules.ICharacterScanner;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.IToken;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+\r
+public class ModelicaSourceViewerConfiguration extends SourceViewerConfiguration {\r
+\r
+ public IPresentationReconciler getPresentationReconciler(\r
+ ISourceViewer sourceViewer) {\r
+ PresentationReconciler pr = new PresentationReconciler();\r
+ DefaultDamagerRepairer ddr = new DefaultDamagerRepairer(\r
+ new RuleBasedScanner() { \r
+ {\r
+ setRules(new IRule[] {new IRule() {\r
+\r
+ @Override\r
+ public IToken evaluate(ICharacterScanner scanner) {\r
+ int ch;\r
+ try {\r
+ scanner.unread();\r
+ ch = scanner.read();\r
+ } catch (Throwable t) {\r
+ ch = -1;\r
+ }\r
+ if (ch <= 0 || !isIdentifierChar((char) ch)) {\r
+ ch = scanner.read();\r
+ if(isIdentifierChar((char)ch)) {\r
+ StringBuilder b = new StringBuilder();\r
+ do {\r
+ b.append((char)ch);\r
+ ch = scanner.read();\r
+ } while(isIdentifierChar((char) ch));\r
+ String str = b.toString();\r
+ if(keywords.contains(str))\r
+ return getModelicaKeywordToken();\r
+ }\r
+ scanner.unread();\r
+ }\r
+ return Token.UNDEFINED;\r
+ } \r
+ \r
+ }});\r
+ } \r
+ }\r
+ );\r
+ pr.setRepairer(ddr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ pr.setDamager(ddr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ return pr;\r
+ }\r
+ \r
+ static boolean isIdentifierChar(char c) {\r
+ return \r
+ (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') \r
+ || (c >= '0' && c <= '9') || c == '_';\r
+ }\r
+ \r
+ static final Set<String> keywords = new HashSet<String>();\r
+ \r
+ static {\r
+ keywords.add("within");\r
+ keywords.add("final");\r
+ keywords.add("public");\r
+ keywords.add("protected");\r
+ keywords.add("connect");\r
+ keywords.add("when");\r
+ keywords.add("then");\r
+ keywords.add("elsewhen");\r
+ keywords.add("if");\r
+ keywords.add("end");\r
+ keywords.add("elseif");\r
+ keywords.add("else");\r
+ keywords.add("for");\r
+ keywords.add("while");\r
+ keywords.add("loop");\r
+ keywords.add("der");\r
+ keywords.add("enumeration");\r
+ keywords.add("extends");\r
+ keywords.add("class");\r
+ keywords.add("partial");\r
+ keywords.add("encapsulated");\r
+ keywords.add("model");\r
+ keywords.add("record");\r
+ keywords.add("block");\r
+ keywords.add("expandable");\r
+ keywords.add("connector");\r
+ keywords.add("type");\r
+ keywords.add("package");\r
+ keywords.add("function");\r
+ keywords.add("import");\r
+ keywords.add("external");\r
+ keywords.add("constrainedby");\r
+ keywords.add("redeclare");\r
+ keywords.add("replaceable");\r
+ keywords.add("flow");\r
+ keywords.add("discrete");\r
+ keywords.add("parameter");\r
+ keywords.add("constant");\r
+ keywords.add("input");\r
+ keywords.add("output");\r
+ keywords.add("annotation");\r
+ keywords.add("false");\r
+ keywords.add("true");\r
+ keywords.add("each");\r
+ keywords.add("initial");\r
+ keywords.add("algorithm");\r
+ keywords.add("equation");\r
+ keywords.add("or");\r
+ keywords.add("and");\r
+ keywords.add("not");\r
+ keywords.add("break");\r
+ keywords.add("return"); \r
+ }\r
+\r
+ static IToken modelicaKeywordToken = null;\r
+ public IToken getModelicaKeywordToken() {\r
+ if(modelicaKeywordToken == null) {\r
+ modelicaKeywordToken = \r
+ new Token(\r
+ new TextAttribute(\r
+ new Color(null, 127, 0, 85),\r
+ new Color(null, 255, 255, 255),\r
+ SWT.BOLD\r
+ ));\r
+ }\r
+ return modelicaKeywordToken;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.modelica;\r
+\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.jface.operation.IRunnableContext;\r
+import org.eclipse.jface.text.Document;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.PaintManager;\r
+import org.eclipse.jface.text.source.AnnotationModel;\r
+import org.eclipse.jface.text.source.AnnotationPainter;\r
+import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;\r
+import org.eclipse.jface.text.source.IAnnotationModel;\r
+import org.eclipse.jface.text.source.MatchingCharacterPainter;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.editors.text.TextEditor;\r
+import org.eclipse.ui.texteditor.AbstractDocumentProvider;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.modelica.ModelicaWriter;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.LoadRepresentation;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorInput;\r
+\r
+\r
+public class SysdynModelicaEditor extends TextEditor {\r
+\r
+ AnnotationModel annotationModel = new AnnotationModel();\r
+ AnnotationPainter apainter;\r
+ \r
+ public SysdynModelicaEditor() {\r
+ super();\r
+ showOverviewRuler();\r
+ setDocumentProvider(new AbstractDocumentProvider() {\r
+\r
+ @Override\r
+ protected IAnnotationModel createAnnotationModel(Object element)\r
+ throws CoreException {\r
+ return annotationModel;\r
+ }\r
+\r
+ @Override\r
+ protected IDocument createDocument(Object element)\r
+ throws CoreException {\r
+ try {\r
+ Configuration configuration =\r
+ LoadRepresentation.loadConfiguration(SimanticsUI.getSession(), ((ResourceEditorInput)element).getResource());\r
+ ModelicaWriter writer = new ModelicaWriter();\r
+ writer.write(configuration);\r
+ \r
+ return new Document(writer.toString());\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ throw new CoreException(STATUS_ERROR);\r
+ } \r
+ }\r
+\r
+ @Override\r
+ protected void doSaveDocument(IProgressMonitor monitor,\r
+ Object element, IDocument document, boolean overwrite)\r
+ throws CoreException {\r
+ }\r
+\r
+ @Override\r
+ protected IRunnableContext getOperationRunner(\r
+ IProgressMonitor monitor) {\r
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow();\r
+ }\r
+ \r
+ @Override\r
+ public boolean isModifiable(Object element) {\r
+ return false;\r
+ }\r
+ \r
+ @Override\r
+ public boolean isReadOnly(Object element) {\r
+ return true;\r
+ }\r
+ \r
+ }); \r
+ \r
+ setSourceViewerConfiguration(new ModelicaSourceViewerConfiguration());\r
+ \r
+ }\r
+ \r
+ @Override\r
+ protected void createActions() {\r
+ super.createActions();\r
+ \r
+ PaintManager paintManager = new PaintManager(getSourceViewer());\r
+ MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(getSourceViewer(),\r
+ new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} ));\r
+ matchingCharacterPainter.setColor(new Color(Display.getCurrent(), new RGB(160, 160, 160)));\r
+ paintManager.addPainter(matchingCharacterPainter);\r
+ }\r
+ \r
+ \r
+}\r
+\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.modelica;\r
+\r
+import org.eclipse.ui.part.EditorActionBarContributor;\r
+\r
+public class TextEditorActionBarContributor extends EditorActionBarContributor {\r
+\r
+ public TextEditorActionBarContributor() {\r
+ // TODO Auto-generated constructor stub\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.VirtualGraphContext;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.RealizationVirtualGraph;\r
+import org.simantics.db.layer0.adapter.ResourceData;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class DefaultRealizationVirtualGraph extends RealizationVirtualGraph {\r
+\r
+ public DefaultRealizationVirtualGraph(Session session, Resource model) throws DatabaseException {\r
+ super(session, model, SysdynResource.getInstance(session).DefaultRealization);\r
+ }\r
+ \r
+ @Override\r
+ public void initialize(final VirtualGraphContext context, WriteGraph graph) throws DatabaseException {\r
+ \r
+ Resource configuration = graph.getPossibleObject(model, b.HasConfiguration);\r
+\r
+ Resource defaultsResource = graph.newResource();\r
+ int modelNode = context.getIndex(model);\r
+ int defaultsNode = context.getIndex(defaultsResource);\r
+ graph.claim(model, b.ConsistsOf, null, defaultsResource);\r
+ graph.claim(model, b.HasBaseRealization, null, defaultsResource);\r
+ \r
+ undiscovered.put(defaultsNode, new ResourceData(modelNode, configuration, b.Realization, "BaseRealization", null, null));\r
+ \r
+ }\r
+ \r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.java.DoubleBindingDefault;\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.ResourceVariable;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class DefaultVariable extends ResourceVariable {\r
+\r
+ public DefaultVariable(Resource resource) {\r
+ super(resource);\r
+ }\r
+\r
+ @Override\r
+ public <T> T getValue(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource represents = graph.getPossibleObject(resource, b.Represents);\r
+ if(represents == null) return null;\r
+ Resource expression = graph.getPossibleObject(represents, sr.HasExpression);\r
+ if(expression == null) return null;\r
+ if(!graph.isInstanceOf(expression, sr.ParameterExpression)) return null;\r
+ String text = graph.getPossibleRelatedValue(expression, sr.HasEquation);\r
+ if(text == null) return null;\r
+ Double value = Double.parseDouble(text); \r
+ return (T)value;\r
+ }\r
+\r
+ @Override\r
+ public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {\r
+ if(!DoubleBindingDefault.INSTANCE.equals(binding)) return null;\r
+ return getValue(graph);\r
+ }\r
+ \r
+ @Override\r
+ public void setValue(WriteGraph graph, Object object, Binding binding) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ if(!DoubleBindingDefault.INSTANCE.equals(binding)) return;\r
+ Resource represents = graph.getPossibleObject(resource, b.Represents);\r
+ if(represents == null) return;\r
+ Resource expression = graph.getPossibleObject(represents, sr.HasExpression);\r
+ if(expression == null) return;\r
+ if(!graph.isInstanceOf(expression, sr.ParameterExpression)) return;\r
+ Double value = (Double)object;\r
+ graph.claimValue(expression, sr.HasEquation, value.toString(), StringBindingDefault.INSTANCE);\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.project;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.VirtualGraphContext;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.procedure.single.SingleSetSyncListener;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.RealizationVirtualGraph;\r
+import org.simantics.db.layer0.adapter.ResourceData;\r
+import org.simantics.db.layer0.adapter.RuntimeValuations;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class HistoryRealizationVirtualGraph extends RealizationVirtualGraph {\r
+\r
+ public HistoryRealizationVirtualGraph(Session session, Resource model) throws DatabaseException {\r
+ super(session, model, SysdynResource.getInstance(session).HistoryRealization);\r
+ }\r
+ \r
+ @Override\r
+ public void initialize(final VirtualGraphContext context, WriteGraph graph) throws DatabaseException {\r
+ \r
+ graph.asyncRequest(new Read<Collection<Resource>>() {\r
+\r
+ @Override\r
+ public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+// System.out.println("Compute runs starts");\r
+ HashSet<Resource> result = new HashSet<Resource>();\r
+ Builtins b = graph.getBuiltins();\r
+ for(Resource config : graph.getObjects(model, b.ConsistsOf)) {\r
+ if(graph.isInstanceOf(config, b.Experiment)) {\r
+ for(Resource run : graph.getObjects(config, b.ConsistsOf)) {\r
+ if(graph.isInstanceOf(run, b.Run)) {\r
+// System.out.println("found run " + run);\r
+ result.add(run);\r
+ }\r
+ }\r
+ }\r
+ }\r
+// System.out.println("Compute runs ends");\r
+ return result;\r
+ }\r
+ \r
+ }, new SingleSetSyncListener<Resource>() {\r
+\r
+ @Override\r
+ public void add(ReadGraph graph, final Resource run) throws DatabaseException {\r
+\r
+ final String experimentName = graph.getPossibleRelatedValue(run, b.HasName, StringBindingDefault.INSTANCE);\r
+ \r
+// System.out.println("RealizationVirtualGraph new experiment " + experimentName);\r
+\r
+ RuntimeValuations vs = graph.getService(RuntimeValuations.class);\r
+ if(vs.supports(experimentName)) {\r
+\r
+// System.out.println("RealizationVirtualGraph scheduling " + experimentName);\r
+\r
+ graph.getSession().asyncRequest(new WriteRequest(graph.getService(VirtualGraph.class)) {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ \r
+// System.out.println("RealizationVirtualGraph about to serve " + experimentName);\r
+\r
+ int runNode = context.getIndex(run);\r
+\r
+ Resource configuration = graph.getPossibleObject(model, b.HasConfiguration);\r
+ for(Resource part : graph.getObjects(configuration, b.ConsistsOf)) {\r
+ String partName = graph.getPossibleRelatedValue(part, b.HasName, StringBindingDefault.INSTANCE);\r
+ if(partName != null) {\r
+ Resource partResource = graph.newResource();\r
+ int partNode = context.getIndex(partResource);\r
+ graph.claim(run, b.ConsistsOf, null, partResource);\r
+ undiscovered.put(partNode, new ResourceData(runNode, part, valuation, partName, experimentName, null));\r
+ }\r
+ }\r
+ \r
+ }\r
+ });\r
+ \r
+ }\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public void exception(ReadGraph graph, Throwable throwable) {\r
+ throwable.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return false;\r
+ }\r
+ \r
+ });\r
+ \r
+ \r
+ }\r
+ \r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.simantics.databoard.Accessors;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.Accessor;\r
+import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.ResourceVariable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.manager.SysdynResult;\r
+\r
+public class HistoryVariable extends ResourceVariable {\r
+\r
+ public HistoryVariable(Resource resource) {\r
+ super(resource);\r
+ }\r
+ \r
+ @Override\r
+ public <T> T getInterface(ReadGraph graph, Class<T> clazz) throws DatabaseException {\r
+ if(Accessor.class.equals(clazz)) {\r
+\r
+ Builtins b = graph.getBuiltins();\r
+ Resource model = Variables.getModel(graph, this);\r
+ Resource configuration = graph.getPossibleObject(model, b.HasConfiguration);\r
+ SysdynModel sm = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration);\r
+ SysdynResult sr = sm.getSysdynResult();\r
+ String rvi = Variables.getRVI(graph, this);\r
+ System.out.println("HistoryVariable rvi='" + rvi + "'");\r
+ rvi = rvi.substring(1).replace("/", ".");\r
+ SysdynDataSet ds = sr.getDataSet(rvi);\r
+ \r
+ try {\r
+ return (T)Accessors.getAccessor(Bindings.getBindingUnchecked(SysdynDataSet.class), ds);\r
+ } catch (RuntimeBindingConstructionException e) {\r
+ e.printStackTrace();\r
+ } catch (AccessorConstructionException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return null;\r
+ \r
+ }\r
+ return super.getInterface(graph, clazz);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.project;\r
+\r
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.ui.IFolderLayout;\r
+import org.eclipse.ui.IPageLayout;\r
+import org.eclipse.ui.IPerspectiveFactory;\r
+import org.eclipse.ui.cheatsheets.OpenCheatSheetAction;\r
+import org.eclipse.ui.console.IConsoleConstants;\r
+import org.osgi.service.prefs.BackingStoreException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+public class SysdynPerspectiveFactory implements IPerspectiveFactory {\r
+\r
+ private static final String CHEATSHEET_ID = "org.simantics.sysdyn.ui.cheatsheet1";\r
+\r
+ private static final String FIRST_SYSDYN_PROJECT = "firstSysdynProject";\r
+\r
+ @Override\r
+ public void createInitialLayout(IPageLayout layout) {\r
+ layout.setEditorAreaVisible(true);\r
+ String editorArea = layout.getEditorArea();\r
+\r
+ IFolderLayout bottom1 = layout.createFolder("bottom1", IPageLayout.BOTTOM, 0.75f, editorArea);\r
+ IFolderLayout bottom2 = layout.createFolder("bottom2", IPageLayout.LEFT, 0.4f, "bottom1");\r
+ bottom1.addView("org.simantics.browsing.ui.graph.propertyView");\r
+ bottom1.addView(IConsoleConstants.ID_CONSOLE_VIEW);\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
+ \r
+ IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, 0.7f, editorArea);\r
+ right.addView("org.simantics.diagram.symbollibrary");\r
+\r
+ // Open cheatsheets view on the first time the user creates a sysdyn project\r
+ // for a particular workspace.\r
+ IEclipsePreferences prefs = new InstanceScope().getNode(Activator.PLUGIN_ID);\r
+ boolean firstSysdynProject = prefs.getBoolean(FIRST_SYSDYN_PROJECT, true);\r
+ if (firstSysdynProject) {\r
+ new OpenCheatSheetAction(CHEATSHEET_ID).run();\r
+\r
+ // Make a note that the user has created a sysdyn project.\r
+ try {\r
+ prefs.putBoolean(FIRST_SYSDYN_PROJECT, false);\r
+ prefs.flush();\r
+ } catch (BackingStoreException e) {\r
+ ErrorLogger.defaultLogError(e);\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.project;\r
+\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PartInitException;\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.Queries;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.service.GraphChangeListenerSupport;\r
+import org.simantics.db.service.LifecycleSupport;\r
+import org.simantics.diagram.DiagramConstants;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayer;\r
+import org.simantics.diagram.synchronization.graph.layer.GraphLayerUtil;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.modeling.services.CaseInsensitiveComponentNamingStrategy2;\r
+import org.simantics.modeling.services.ComponentNamingStrategy;\r
+import org.simantics.modeling.ui.features.EditorNamingService2;\r
+import org.simantics.project.ProjectElementType;\r
+import org.simantics.project.ProjectElements;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.project.exception.ProjectException;\r
+import org.simantics.project.features.AbstractProjectFeature;\r
+import org.simantics.project.features.UIModelManager;\r
+import org.simantics.project.features.UIModelManagerBase;\r
+import org.simantics.project.features.UIModelManagerBase.WriteRunnable;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.workbench.IEditorNamingService;\r
+import org.simantics.ui.workbench.action.ChooseActionRequest;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+public class SysdynProject extends AbstractProjectFeature {\r
+ private static final String DEFAULT_PERSPECTIVE = "org.simantics.sysdyn.ui.perspective";\r
+\r
+ class ModelManager extends UIModelManagerBase {\r
+ @Override\r
+ public void create(ProjectElementType kind, Shell parentShell, Session session, Resource container,\r
+ Callback<Resource> callback, Callback<Throwable> errorCallback) {\r
+\r
+ if (ProjectElements.MODEL.equals(kind)) {\r
+ request(session, container, callback, errorCallback, CREATE_MODEL);\r
+ return;\r
+ }\r
+\r
+ super.create(kind, parentShell, session, container, callback, errorCallback);\r
+ }\r
+\r
+ /**\r
+ * \r
+ * \r
+ * @see org.simantics.project.features.UIModelManager#openEditor(org.simantics.db.Session, java.lang.String)\r
+ */\r
+ @Override\r
+ public void openEditor(Session session, String uri) throws PartInitException {\r
+ try {\r
+ Resource resource = session.syncRequest(Queries.resource(uri));\r
+ session.syncRequest(new ChooseActionRequest(null, resource, WorkbenchUtils.getCurrentPerspectiveId()));\r
+ } catch (DatabaseException e) {\r
+ LifecycleSupport ls = session.getService(LifecycleSupport.class);\r
+ throw new PartInitException("Failed to open editor for URI '" + uri + "' with session '" + ls.getSessionReference() + "', see exception for details.", e);\r
+ }\r
+ }\r
+ }\r
+\r
+ private final WriteRunnable CREATE_MODEL = new WriteRunnable() {\r
+ @Override\r
+ public void run(WriteGraph g, Resource library, Callback<Resource> callback, Callback<Throwable> errorCallback) {\r
+ try {\r
+ Builtins b = g.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ ModelingResources mr = ModelingResources.getInstance(g);\r
+ ModelingUtils mu = new ModelingUtils(g);\r
+\r
+ Resource model = g.newResource();\r
+\r
+ String modelName = GraphUtils.findFreshName(g, "Model", library, b.ConsistsOf, "%s%d");\r
+\r
+ g.claimValue(model, b.HasName, modelName);\r
+ g.claimValue(model, b.HasLabel, modelName);\r
+ g.claim(model, b.InstanceOf, sr.SysdynModel);\r
+ g.claim(model, b.PartOf, library);\r
+\r
+ Resource diagram = OrderedSetUtils.create(g, sr.ConfigurationDiagram);\r
+ GraphLayer l = new GraphLayerUtil(g).createLayer(DiagramConstants.DEFAULT_LAYER_NAME, true);\r
+ g.claim(diagram, mu.dr.HasLayer, l.getLayer());\r
+ g.claimValue(diagram, b.HasName, "Diagrammi", StringBindingDefault.INSTANCE);\r
+\r
+\r
+ Resource conf = g.newResource();\r
+ g.claimValue(conf, b.HasName, "Configuration");\r
+ g.claim(conf, b.InstanceOf, sr.Configuration);\r
+ g.claimValue(conf, sr.HasStartTime, 0.0);\r
+ g.claimValue(conf, sr.HasStopTime, 10.0);\r
+\r
+ g.claim(conf, mr.CompositeToDiagram, diagram);\r
+ g.claim(model, b.HasConfiguration, conf);\r
+\r
+ Resource mapping = g.newResource();\r
+ g.claim(mapping, b.InstanceOf, null, mr.DiagramToCompositeMapping);\r
+ g.claim(diagram, b.HasTrigger, mapping);\r
+\r
+ Resource report = GraphUtils.create2(g, mu.b.Report, mu.b.HasDocumentation, "===Report===");\r
+\r
+ GraphUtils.create2(g, mu.b.Experiment,\r
+ mu.b.HasName, "Experiment",\r
+ mu.b.HasLabel, "Experiment",\r
+ mu.b.HasReportFactory, report,\r
+ mu.b.PartOf, model);\r
+\r
+ callback.run(model);\r
+ } catch(Exception e) {\r
+ errorCallback.run(e);\r
+ }\r
+ }\r
+ };\r
+\r
+ ModelManager mm;\r
+\r
+ @Override\r
+ public void configure() throws ProjectException {\r
+ addToCollectionHint(ProjectKeys.PERSPECTIVES, DEFAULT_PERSPECTIVE);\r
+ addToCollectionHint(ProjectKeys.OPEN_PERSPECTIVES, DEFAULT_PERSPECTIVE);\r
+ getProjectElement().setHint(ProjectKeys.DEFAULT_PERSPECTIVE, DEFAULT_PERSPECTIVE);\r
+ \r
+ getProjectElement().setHint(IEditorNamingService.KEY_EDITOR_NAMING_SERVICE, new EditorNamingService2());\r
+\r
+ mm = new ModelManager();\r
+ getProjectElement().setHint(UIModelManager.KEY_MODEL_MANAGER, mm);\r
+\r
+ // Install naming strategy for model components.\r
+ Session session = getProject().getSession();\r
+ GraphChangeListenerSupport changeSupport = session.peekService(GraphChangeListenerSupport.class);\r
+ if (changeSupport != null) {\r
+ getProjectElement().setHint(ComponentNamingStrategy.PROJECT_KEY, new CaseInsensitiveComponentNamingStrategy2(changeSupport, "%s%d"));\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void deconfigure() throws ProjectException {\r
+ if (getProjectElement().getHint(UIModelManager.KEY_MODEL_MANAGER) == mm)\r
+ getProjectElement().removeHint(UIModelManager.KEY_MODEL_MANAGER);\r
+ mm = null;\r
+\r
+ getProjectElement().removeHint(ComponentNamingStrategy.PROJECT_KEY);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.project;\r
+\r
+import java.io.File;\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.core.runtime.Platform;\r
+import org.simantics.databoard.accessor.Accessor;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.procedure.single.SingleSetListener;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.exception.ValidationException;\r
+import org.simantics.db.layer0.adapter.ActivationManager;\r
+import org.simantics.db.layer0.adapter.RuntimeValuations;\r
+import org.simantics.db.layer0.adapter.TrendVariable;\r
+import org.simantics.db.layer0.util.Simantics;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.IProjectLifeCycle;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+public class SysdynProjectLifeCycle implements IProjectLifeCycle{\r
+\r
+ public static final Key INITIALIZED = new KeyOf(Boolean.class, "SYSDYN_LIFECYCLE_INITIALIZED");\r
+\r
+ @Override\r
+ public void onCreate(WriteGraph g, Resource project) {\r
+// System.out.println("onCreate Sysdyn Project: " + GraphUtils.getReadableName(g, project));\r
+ }\r
+\r
+ @Override\r
+ public void onDestroy(WriteGraph g, Resource project) {\r
+ try {\r
+ System.out.println("onDestroy Sysdyn Project: " + GraphUtils.getReadableName(g, project));\r
+ } catch (ValidationException e) {\r
+ e.printStackTrace();\r
+ } catch (ServiceException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void onActivated(RequestProcessor processor, final IProject project) {\r
+\r
+ System.out.println("onActivated Sysdyn Project");\r
+\r
+ ISessionContext context = SimanticsUI.getSessionContext();\r
+ if (context.getHint(INITIALIZED) == null) {\r
+\r
+ try {\r
+\r
+ Resource projectResource = project.get();\r
+\r
+ final Session session = context.getSession();\r
+\r
+ session.registerService(RuntimeValuations.class, new RuntimeValuations() {\r
+\r
+ @Override\r
+ public boolean supports(String valuation) {\r
+\r
+ IExperimentManager expMan = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = expMan.getExperiment(valuation);\r
+\r
+ return experiment != null;\r
+\r
+ }\r
+\r
+ @Override\r
+ public Accessor getAccessor(String variableIdentityPrefix, String valuation, String suffix) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public TrendVariable getVariable(String variableIdentityPrefix, String valuation, String suffix) {\r
+\r
+ return null;\r
+\r
+ }\r
+\r
+ });\r
+\r
+\r
+// System.out.println("A1");\r
+\r
+ final Builtins b = session.getBuiltins();\r
+ ActivationManager activationManager = session.getService(ActivationManager.class);\r
+ if (activationManager != null) {\r
+ activationManager.activate(processor, projectResource);\r
+ }\r
+\r
+// System.out.println("A2");\r
+\r
+ VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);\r
+ final VirtualGraph graph = session.getService(VirtualGraph.class);\r
+\r
+// System.out.println("A3");\r
+\r
+ session.asyncRequest(new ObjectsWithType(projectResource, b.ConsistsOf, b.Model), new SingleSetListener<Resource>() {\r
+\r
+ @Override\r
+ public void add(final Resource model) {\r
+ // FIXME:\r
+ Simantics.async(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ try {\r
+ // This creates experiment realizations\r
+ graph.register(new HistoryRealizationVirtualGraph(session, model));\r
+ // This creates the BaseRealization\r
+ graph.register(new DefaultRealizationVirtualGraph(session, model));\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return false;\r
+ }\r
+\r
+ });\r
+\r
+ support.getWorkspacePersistent("experiments");\r
+\r
+ } catch (DatabaseException e) {\r
+\r
+ e.printStackTrace();\r
+\r
+ }\r
+\r
+\r
+ cleanProjectFolder(project.get());\r
+ context.setHint(INITIALIZED, Boolean.TRUE);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void onDeactivated(IProject project) {\r
+// System.out.println("onDeactivated Sysdyn Project: " + project.getName());\r
+ }\r
+\r
+ public void cleanProjectFolder(final Resource projectResource) {\r
+ System.out.println("cleaning up project folder");\r
+ ISessionContext context = SimanticsUI.getSessionContext();\r
+ final Session session = context.getSession();\r
+ String projectName = null;\r
+ final HashMap<String, Resource> resultPaths = new HashMap<String, Resource>();\r
+ try {\r
+ projectName = session.syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ for(Resource model : graph.getObjects(projectResource, b.ConsistsOf)) {\r
+ if(graph.isInstanceOf(model, sr.SysdynModel)){\r
+ for(Resource experiment : graph.getObjects(model, b.ConsistsOf)) {\r
+ if(graph.isInstanceOf(experiment, b.Experiment)) {\r
+ for(Resource result : graph.getObjects(experiment, sr.HasResult)) {\r
+ String resultFile = (String)graph.getPossibleRelatedValue(result, sr.HasResultFile);\r
+ if(result != null) resultPaths.put(resultFile, result);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return graph.getPossibleRelatedValue(projectResource, b.HasName);\r
+\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ if(projectName != null) {\r
+ File root = new File(Platform.getLocation().toOSString(), "www.simantics.org");\r
+ if(!root.isDirectory()) return;\r
+ File projectRoot = new File(root, projectName);\r
+ if(!projectRoot.isDirectory()) return;\r
+ File[] files = projectRoot.listFiles();\r
+\r
+ for(File file : files) {\r
+ if(resultPaths.get(file.getAbsolutePath()) == null) {\r
+ file.delete();\r
+ } else {\r
+ resultPaths.remove(file.getAbsolutePath());\r
+ }\r
+ }\r
+\r
+ if (!resultPaths.keySet().isEmpty()) {\r
+ session.asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ for(String key : resultPaths.keySet()) {\r
+ Resource result = resultPaths.get(key);\r
+ graph.deny(result, b.PartOf);\r
+ graph.deny(result, graph.getInverse(SysdynResource.getInstance(graph).HasResult));\r
+ }\r
+ }\r
+ }) ;\r
+\r
+\r
+ }\r
+\r
+\r
+\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class ConfigurationTab extends PropertyTabContributorImpl {\r
+\r
+ \r
+ \r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+\r
+ Label label = new Label(composite, SWT.NONE);\r
+ label.setText("Name");\r
+ \r
+ TrackedText name = new TrackedText(composite, support, SWT.BORDER);\r
+ name.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ name.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ name.setInputValidator(new IInputValidator() {\r
+ \r
+ @Override\r
+ public String isValid(String newText) {\r
+ if (newText.contains(" "))\r
+ return "Sorry but spaces are not allowed for names right now";\r
+ return null;\r
+ }\r
+ });\r
+\r
+ GridDataFactory.fillDefaults().hint(200, SWT.DEFAULT).applyTo(name.getWidget());\r
+\r
+ label = new Label(composite, SWT.NONE);\r
+ label.setText("Start time");\r
+\r
+ TrackedText startTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+ startTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasStartTime));\r
+ startTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasStartTime));\r
+ startTime.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().hint(200, SWT.DEFAULT).applyTo(startTime.getWidget());\r
+\r
+ label = new Label(composite, SWT.NONE);\r
+ label.setText("Stop time");\r
+\r
+ TrackedText stopTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+ stopTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasStopTime));\r
+ stopTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasStopTime));\r
+ stopTime.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().hint(200, SWT.DEFAULT).applyTo(stopTime.getWidget());\r
+\r
+ \r
+ }\r
+\r
+ private class DoubleValidator implements IInputValidator {\r
+\r
+ @Override\r
+ public String isValid(String newText) {\r
+ for(int i = 0; i < newText.length(); i++){\r
+ if(!Character.isDigit(newText.charAt(i))){\r
+ if(newText.charAt(i) != '.') {\r
+ return "Invalid character '" + newText.charAt(i) + "'";\r
+ } else if(newText.indexOf('.') != newText.lastIndexOf('.')) {\r
+ return "There can be only one '.'";\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ } \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class DependencyTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite);\r
+ TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+ nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.MouseEvent;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListener;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
+\r
+public class EquationTab extends PropertyTabContributorImpl {\r
+\r
+ TrackedCombo expressionTypeCombo, unitCombo;\r
+ ShortcutTabWidget shortcutTabWidget;\r
+ ExpressionWidget expressionWidget;\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite);\r
+ TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+ nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+\r
+\r
+ Label label = new Label(composite, SWT.SINGLE );\r
+ label.setText("Type:");\r
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+ expressionTypeCombo = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+\r
+ \r
+ label = new Label(composite, SWT.SINGLE );\r
+ label.setText("Unit:");\r
+ GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+\r
+ unitCombo = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER);\r
+ \r
+ shortcutTabWidget = new ShortcutTabWidget(composite, support, SWT.NONE);\r
+\r
+\r
+ Composite expressionComposite = new Composite(composite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).span(5, 1).applyTo(expressionComposite);\r
+ expressionWidget = new ExpressionWidget(expressionComposite, support, SWT.NONE);\r
+ expressionWidget.setVariableTable(shortcutTabWidget.getVariableTable());\r
+\r
+ addListeners();\r
+ }\r
+\r
+ private void addListeners() {\r
+ \r
+ expressionTypeCombo.setItemFactory(new ReadFactoryImpl<Resource, Map<String,Object>>() {\r
+\r
+ @Override\r
+ public Map<String, Object> perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+\r
+ Map<String, Object> map = new HashMap<String, Object>();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ final ExpressionType[] expressionTypes;\r
+ if(graph.isInstanceOf(input, sr.Auxiliary))\r
+ expressionTypes = ExpressionTypes.auxiliaryExpressions;\r
+ else if(graph.isInstanceOf(input, sr.Stock))\r
+ expressionTypes = ExpressionTypes.stockExpressions;\r
+ else if(graph.isInstanceOf(input, sr.Valve))\r
+ expressionTypes = ExpressionTypes.valveExpressions;\r
+ else\r
+ expressionTypes = new ExpressionType[] {};\r
+ \r
+ for(ExpressionType et : expressionTypes) {\r
+ map.put(et.toString(), et);\r
+ }\r
+ return map;\r
+ }\r
+ });\r
+\r
+ expressionTypeCombo.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+ return ExpressionTypes.getExpressionTypeForVariable(graph, input).toString();\r
+ }\r
+ });\r
+ \r
+ expressionTypeCombo.addModifyListener(new TextModifyListener() {\r
+ \r
+ @Override\r
+ public void modifyText(TrackedModifyEvent e) {\r
+ System.out.println(e.getText());\r
+ expressionWidget.displayExpression(e.getText(), false);\r
+ expressionWidget.save(); \r
+ }\r
+ });\r
+\r
+ \r
+ unitCombo.setItemFactory(new ReadFactoryImpl<Resource, Map<String,Object>>() {\r
+\r
+ @Override\r
+ public Map<String, Object> perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+ Map<String, Object> map = new HashMap<String, Object>();\r
+\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+ Resource model = graph.getPossibleObject(input, b.PartOf);\r
+ if (model != null) {\r
+ Collection<Resource> variables = graph.getObjects(model, b.ConsistsOf);\r
+ for(Resource v : variables) {\r
+ Object unit = graph.getPossibleRelatedValue(v, sr.HasUnit);\r
+ if (unit != null && !map.keySet().contains((String) unit)) {\r
+ map.put((String)unit, (String)unit);\r
+\r
+ }\r
+ }\r
+ }\r
+ return map;\r
+ }\r
+ });\r
+ unitCombo.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+ String unit = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HasUnit);\r
+ if(unit == null)\r
+ return "";\r
+ else \r
+ return unit;\r
+ }\r
+ });\r
+\r
+ unitCombo.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+ @Override\r
+ public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
+ graph.claimValue(input, SysdynResource.getInstance(graph).HasUnit, text);\r
+ }\r
+ });\r
+\r
+\r
+ shortcutTabWidget.addMouseListener(new MouseListener(){\r
+\r
+ @Override\r
+ public void mouseDoubleClick(MouseEvent e) {\r
+ Table table = (Table)e.widget;\r
+ TableItem item = table.getItem(new Point(e.x, e.y));\r
+ if(item != null) {\r
+ final String var = (String)item.getData();\r
+ table.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ if(expressionWidget!= null) {\r
+ expressionWidget.getExpression().replaceSelection(var);\r
+ expressionWidget.getExpression().focus();\r
+ }\r
+ }\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void mouseDown(MouseEvent e) {\r
+ expressionWidget.getExpression().focus();\r
+ }\r
+\r
+ @Override\r
+ public void mouseUp(MouseEvent e) {\r
+ }\r
+\r
+ });\r
+ shortcutTabWidget.addFocusListener(new FocusListener() {\r
+\r
+ @Override\r
+ public void focusGained(FocusEvent e) { \r
+ }\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ ((Table)e.widget).deselectAll();\r
+ }\r
+\r
+ });\r
+\r
+ expressionWidget.addModifyListener(new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ expressionWidget.validateFields();\r
+ }\r
+ });\r
+\r
+ expressionWidget.addFocusListener(new FocusListener() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ expressionWidget.save();\r
+ }\r
+\r
+ @Override\r
+ public void focusGained(FocusEvent e) {\r
+ expressionWidget.validateFields();\r
+ }\r
+ }); \r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ExperimentTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class InputVariableTab extends PropertyTabContributorImpl {\r
+\r
+ TrackedCombo expressionTypeCombo;\r
+ IsOutputWidget isOutput;\r
+ \r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+\r
+ TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+ nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+\r
+ isOutput = new IsOutputWidget(composite, support, SWT.NULL);\r
+\r
+ Label label = new Label(composite, SWT.NULL);\r
+ label.setText("Default Value");\r
+ \r
+ TrackedText defaultValue = new TrackedText(composite, support, SWT.RIGHT | SWT.BORDER);\r
+ defaultValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasDefaultInputValue));\r
+ defaultValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasDefaultInputValue));\r
+ defaultValue.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(defaultValue.getWidget());\r
+\r
+\r
+ }\r
+\r
+ private class DoubleValidator implements IInputValidator {\r
+\r
+ @Override\r
+ public String isValid(String newText) {\r
+ for(int i = 0; i < newText.length(); i++){\r
+ if(!Character.isDigit(newText.charAt(i))){\r
+ if(newText.charAt(i) != '.') {\r
+ return "Invalid character '" + newText.charAt(i) + "'";\r
+ } else if(newText.indexOf('.') != newText.lastIndexOf('.')) {\r
+ return "There can be only one '.'";\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ChartTableWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.ChartWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class LookupTableTab extends PropertyTabContributorImpl {\r
+ \r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+\r
+ \r
+ Composite baseContainer = new Composite(body, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(3).applyTo(baseContainer);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(baseContainer);\r
+\r
+ Composite Ycontainer = new Composite(baseContainer, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().applyTo(Ycontainer);\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(Ycontainer);\r
+\r
+ TrackedText maxYText = new TrackedText(Ycontainer, support, SWT.BORDER);\r
+ maxYText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasMaxY));\r
+ maxYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasMaxY));\r
+\r
+ Label l = new Label(Ycontainer, SWT.NONE);\r
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(false, true).applyTo(l);\r
+\r
+ TrackedText minYText = new TrackedText(Ycontainer, support, SWT.BORDER);\r
+ minYText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasMinY));\r
+ minYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasMinY));\r
+\r
+\r
+ Composite chartContainer = new Composite(baseContainer, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(chartContainer);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(chartContainer);\r
+\r
+ @SuppressWarnings("unused")\r
+ ChartWidget chartWidget = new ChartWidget(chartContainer, support, SWT.NONE);\r
+ \r
+ Composite chartTableContainer = new Composite(baseContainer, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().applyTo(chartTableContainer);\r
+ GridDataFactory.fillDefaults().grab(false, true).span(1, 2).applyTo(chartTableContainer); \r
+ \r
+ @SuppressWarnings("unused")\r
+ ChartTableWidget chartTableWidget = new ChartTableWidget(chartTableContainer, support, SWT.NONE);\r
+ \r
+ l = new Label(baseContainer, SWT.NONE);\r
+\r
+ Composite Xcontainer = new Composite(baseContainer, SWT.NONE);\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(Xcontainer);\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(Xcontainer);\r
+\r
+ TrackedText minXText = new TrackedText(Xcontainer, support, SWT.BORDER);\r
+ minXText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasMinX));\r
+ minXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasMinX));\r
+\r
+ l = new Label(Xcontainer, SWT.NONE);\r
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, false).applyTo(l);\r
+\r
+ TrackedText maxXText = new TrackedText(Xcontainer, support, SWT.BORDER);\r
+ maxXText.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasMaxX));\r
+ maxXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasMaxX));\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ModelTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ \r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.TableViewerColumn;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ModuleInputEditingSupport;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceTable;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceRow;\r
+import org.simantics.sysdyn.ui.properties.widgets.RowProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceRowLabelProvider;\r
+\r
+public class ModuleInputTab extends PropertyTabContributorImpl {\r
+\r
+ public static final String FIRSTCOLUMN = "Input in Module";\r
+ public static final String SECONDCOLUMN = "Refers to output";\r
+ \r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ ReferenceTable referenceTable = new ReferenceTable(body, support, SWT.NONE);\r
+ \r
+ String[] titles = { FIRSTCOLUMN, SECONDCOLUMN};\r
+ int[] bounds = { 100, 100, 100, 100 };\r
+ for (int i = 0; i < titles.length; i++) {\r
+ TableViewerColumn column = new TableViewerColumn(referenceTable.getTableViewer(), SWT.NONE);\r
+ column.getColumn().setText(titles[i]);\r
+ column.getColumn().setWidth(bounds[i]);\r
+ column.getColumn().setResizable(true);\r
+ column.getColumn().setMoveable(false);\r
+ // enable editing support\r
+ column.setEditingSupport(new ModuleInputEditingSupport(referenceTable.getTableViewer(), i));\r
+ }\r
+ referenceTable.setContentProvider (new ArrayContentProvider());\r
+ referenceTable.setLabelProvider (new ReferenceRowLabelProvider());\r
+ \r
+ RowProvider rp = new RowProvider() {\r
+ \r
+ @Override\r
+ public ArrayList<ReferenceRow> getRows(ReadGraph graph, Resource module) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+ ArrayList<ReferenceRow> result = new ArrayList<ReferenceRow>();\r
+ Resource instanceOf = graph.getPossibleObject(module, b.InstanceOf);\r
+ if(instanceOf == null) return result;\r
+ Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+ for(Resource input : graph.syncRequest(new ObjectsWithType(configuration, b.ConsistsOf, sr.Input))) {\r
+ Resource dependency = null;\r
+ for(Resource dep : graph.getObjects(module, sr.IsHeadOf)) {\r
+ Resource refersTo = graph.getPossibleObject(dep, sr.RefersTo);\r
+ if(refersTo != null && refersTo.equals(input)) {\r
+ dependency = dep;\r
+ break;\r
+ }\r
+ }\r
+ ReferenceRow rr = new ReferenceRow(module, dependency, input); \r
+ result.add(rr);\r
+ }\r
+ return result;\r
+ }\r
+ };\r
+ referenceTable.setRowProvider(rp);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.TableViewerColumn;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ModuleOutputEditingSupport;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceRow;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceRowLabelProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.ReferenceTable;\r
+import org.simantics.sysdyn.ui.properties.widgets.RowProvider;\r
+\r
+public class ModuleOutputTab extends PropertyTabContributorImpl {\r
+\r
+ public static final String FIRSTCOLUMN = "Output in module";\r
+ public static final String SECONDCOLUMN = "Referes to input";\r
+ \r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ ReferenceTable referenceTable = new ReferenceTable(body, support, SWT.NONE);\r
+ \r
+ String[] titles = { FIRSTCOLUMN, SECONDCOLUMN};\r
+ int[] bounds = { 100, 100, 100, 100 };\r
+ for (int i = 0; i < titles.length; i++) {\r
+ TableViewerColumn column = new TableViewerColumn(referenceTable.getTableViewer(), SWT.NONE);\r
+ column.getColumn().setText(titles[i]);\r
+ column.getColumn().setWidth(bounds[i]);\r
+ column.getColumn().setResizable(true);\r
+ column.getColumn().setMoveable(false);\r
+ // enable editing support\r
+ column.setEditingSupport(new ModuleOutputEditingSupport(referenceTable.getTableViewer(), i));\r
+ }\r
+ referenceTable.setContentProvider (new ArrayContentProvider());\r
+ referenceTable.setLabelProvider (new ReferenceRowLabelProvider());\r
+ \r
+ RowProvider rp = new RowProvider() {\r
+ \r
+ @Override\r
+ public ArrayList<ReferenceRow> getRows(ReadGraph graph, Resource module) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+ ArrayList<ReferenceRow> result = new ArrayList<ReferenceRow>();\r
+ Resource instanceOf = graph.getPossibleObject(module, b.InstanceOf);\r
+ if(instanceOf == null) return result;\r
+ Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+ for(Resource variable : graph.syncRequest(new ObjectsWithType(configuration, b.ConsistsOf, sr.Variable))) {\r
+ if(!graph.hasStatement(variable, sr.IsOutput)) continue;\r
+ \r
+ Resource dependency = null;\r
+ for(Resource dep : graph.getObjects(module, sr.IsTailOf)) {\r
+ Resource refersTo = graph.getPossibleObject(dep, sr.RefersTo);\r
+ if(refersTo != null && refersTo.equals(variable)) {\r
+ dependency = dep;\r
+ break;\r
+ }\r
+ }\r
+ ReferenceRow rr = new ReferenceRow(module, dependency, variable); \r
+ result.add(rr);\r
+ }\r
+ return result;\r
+ }\r
+ };\r
+ referenceTable.setRowProvider(rp);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ModuleTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite);\r
+ TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+ nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ModuleTypeTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(composite);\r
+ TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+ nameText.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasName));\r
+ nameText.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasName));\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ReferenceDependencyTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.browsing.ui.SelectionProcessor;\r
+import org.simantics.browsing.ui.swt.ComparableTabContributor;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.utils.AdaptionUtils;\r
+\r
+public class ResourceSelectionProcessor implements SelectionProcessor<Object, ReadGraph> {\r
+\r
+ @Override\r
+ public Collection<?> process(Object selection, ReadGraph backend) {\r
+ Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
+ if(r == null)\r
+ return Collections.emptyList();\r
+\r
+ try {\r
+ SysdynResource sr = SysdynResource.getInstance(backend);\r
+ DiagramResource dr = DiagramResource.getInstance(backend);\r
+ ModelingResources mr = ModelingResources.getInstance(backend);\r
+ Collection<ComparableTabContributor> tabs = new ArrayList<ComparableTabContributor>();\r
+ if (backend.isInstanceOf(r, dr.Element)) {\r
+ Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
+ if (component != null) {\r
+ r = component;\r
+ } else {\r
+ Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
+ if(connection != null)\r
+ r = connection;\r
+ }\r
+ }\r
+ if (backend.isInstanceOf(r, sr.IndependentVariable)) {\r
+ Resource expression = backend.getPossibleObject(r, sr.HasExpression);\r
+ tabs.add(new ComparableTabContributor(\r
+ new EquationTab(),\r
+ 2,\r
+ r,\r
+ "Equation"));\r
+ if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ tabs.add(new ComparableTabContributor(\r
+ new LookupTableTab(),\r
+ 1,\r
+ expression,\r
+ "Lookup Table"));\r
+ }\r
+ tabs.add(new ComparableTabContributor(\r
+ new VariableInformationTab(),\r
+ 0,\r
+ r,\r
+ "Additional Information"));\r
+ return tabs;\r
+ }\r
+ if (backend.isInstanceOf(r, sr.Input)) {\r
+ return Collections.singleton(new ComparableTabContributor(\r
+ new InputVariableTab(),\r
+ 2,\r
+ r,\r
+ "Input"));\r
+ }\r
+ if (backend.isInstanceOf(r, sr.Configuration))\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ConfigurationTab(),\r
+ 0,\r
+ r,\r
+ "Configuration Properties"));\r
+ if (backend.isInstanceOf(r, sr.Module)){\r
+ tabs.add(new ComparableTabContributor(\r
+ new ModuleTab(),\r
+ 3,\r
+ r,\r
+ "Module Properties"));\r
+ tabs.add(new ComparableTabContributor(\r
+ new ModuleInputTab(),\r
+ 2,\r
+ r,\r
+ "Inputs"));\r
+ tabs.add(new ComparableTabContributor(\r
+ new ModuleOutputTab(),\r
+ 1,\r
+ r,\r
+ "Outputs"));\r
+ return tabs;\r
+ }\r
+ if (backend.isInstanceOf(r, sr.Experiment))\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ExperimentTab(),\r
+ 0,\r
+ r,\r
+ "Experiment Properties"));\r
+ if (backend.isInstanceOf(r, sr.SysdynModel))\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ModelTab(),\r
+ 0,\r
+ r,\r
+ "Model Properties"));\r
+ if (backend.isInstanceOf(r, sr.Result))\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ResultTab(),\r
+ 0,\r
+ r,\r
+ "Result Properties"));\r
+ if (backend.isInstanceOf(r, sr.Dependency))\r
+ if (backend.hasStatement(r, sr.RefersTo))\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ReferenceDependencyTab(),\r
+ 0,\r
+ r,\r
+ "Reference Properties"));\r
+ else\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new DependencyTab(),\r
+ 0,\r
+ r,\r
+ "Dependency Properties"));\r
+ if (backend.isInheritedFrom(r, sr.ModuleSymbol)) {\r
+ r = backend.getPossibleObject(r, mr.SymbolToComponentType);\r
+ if(r != null)\r
+ return Collections.singleton(\r
+ new ComparableTabContributor(\r
+ new ModuleTypeTab(),\r
+ 0,\r
+ r,\r
+ "Module Type Properties"));\r
+ }\r
+ } catch (ServiceException e) {\r
+ e.printStackTrace();\r
+ } catch (ManyObjectsForFunctionalRelationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return Collections.emptyList();\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class ResultTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ \r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.simantics.browsing.ui.swt.StandardPropertyPage;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.modeling.ModelingUtils;\r
+\r
+public class SysdynPropertyPage extends StandardPropertyPage {\r
+\r
+ public SysdynPropertyPage(IWorkbenchPartSite site, Set<String> set) {\r
+ super(site, set);\r
+ }\r
+\r
+ @Override\r
+ protected String computeTitle(ReadGraph graph, ISelection selection) throws DatabaseException {\r
+ return ModelingUtils.computeTitle(graph, selection, MAX_SELECTION_LENGTH_TO_SHOW, true);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.PropertyTabContributorImpl;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class VariableInformationTab extends PropertyTabContributorImpl {\r
+\r
+ @Override\r
+ public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+ Composite composite = new Composite(body, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+\r
+ Group informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+ informationGroup.setText("Information");\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(informationGroup);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);\r
+\r
+ TrackedText information = new TrackedText(informationGroup, support, SWT.MULTI | SWT.BORDER);\r
+ information.setTextFactory(new StringPropertyFactory(Builtins.URIs.HasDescription));\r
+ information.addModifyListener(new StringPropertyModifier(context, Builtins.URIs.HasDescription));\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+\r
+ Group rangeGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+ rangeGroup.setText("Range");\r
+ GridDataFactory.fillDefaults().applyTo(rangeGroup);\r
+ GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(rangeGroup);\r
+\r
+ Label label = new Label(rangeGroup, SWT.NONE);\r
+ label.setText("Start");\r
+\r
+ TrackedText rangeStart = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);\r
+ rangeStart.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStart));\r
+ rangeStart.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStart));\r
+ rangeStart.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());\r
+\r
+\r
+ label = new Label(rangeGroup, SWT.NONE);\r
+ label.setText("End");\r
+\r
+\r
+ TrackedText rangeEnd = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);\r
+ rangeEnd.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeEnd));\r
+ rangeEnd.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeEnd));\r
+ rangeEnd.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());\r
+\r
+ label = new Label(rangeGroup, SWT.NONE);\r
+ label.setText("Step");\r
+\r
+ TrackedText rangeStep = new TrackedText(rangeGroup, support, SWT.RIGHT | SWT.BORDER);\r
+ rangeStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.HasRangeStep));\r
+ rangeStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.HasRangeStep));\r
+ rangeStep.setInputValidator(new DoubleValidator());\r
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
+\r
+ new IsOutputWidget(composite, support, SWT.NULL);\r
+\r
+ }\r
+\r
+ private class DoubleValidator implements IInputValidator {\r
+\r
+ @Override\r
+ public String isValid(String newText) {\r
+ for(int i = 0; i < newText.length(); i++){\r
+ if(!Character.isDigit(newText.charAt(i))){\r
+ if(newText.charAt(i) != '.') {\r
+ return "Invalid character '" + newText.charAt(i) + "'";\r
+ } else if(newText.indexOf('.') != newText.lastIndexOf('.')) {\r
+ return "There can be only one '.'";\r
+ }\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.event.MouseEvent;\r
+import java.awt.geom.Point2D;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+\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.swt.SWT;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.tableParser.ParseException;\r
+import org.simantics.sysdyn.tableParser.TableParser;\r
+import org.simantics.sysdyn.tableParser.Token;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupInputOutputTable;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupInputOutputTable.InputOutput;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ChartTableWidget implements Widget {\r
+\r
+ Text input, output;\r
+ Button add;\r
+ LookupInputOutputTable table;\r
+ Resource expression;\r
+\r
+ public ChartTableWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+ Composite valueTableComposite = new Composite(parent, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(valueTableComposite);\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(valueTableComposite);\r
+\r
+ table = new LookupInputOutputTable(valueTableComposite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().span(3, 1).grab(false, true).applyTo(table);\r
+ table.getTableViewer().getTable().addMouseListener(new MouseListener() {\r
+\r
+ @Override\r
+ public void mouseUp(org.eclipse.swt.events.MouseEvent e) {\r
+ if(e.button == MouseEvent.BUTTON3) {\r
+ Table t = (Table)e.widget;\r
+ TableItem item = (TableItem)t.getItem(new org.eclipse.swt.graphics.Point(e.x, e.y));\r
+ table.removeItem(t.indexOf(item));\r
+ tableModified();\r
+ }\r
+ }\r
+ @Override\r
+ public void mouseDown(org.eclipse.swt.events.MouseEvent e) { }\r
+ @Override\r
+ public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { }\r
+ });\r
+\r
+ input = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT);\r
+ input.setText("");\r
+ output = new Text(valueTableComposite, SWT.BORDER | SWT.RIGHT);\r
+ output.setText("");\r
+\r
+ add = new Button(valueTableComposite, SWT.None);\r
+ add.setText("Add");\r
+ add.addSelectionListener(new SelectionListener() {\r
+\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ try {\r
+ Double in = Double.parseDouble(input.getText());\r
+ Double out = Double.parseDouble(output.getText());\r
+ table.addLocation(new Point2D.Double(in, out));\r
+ tableModified();\r
+ } catch (NumberFormatException e1) {\r
+ }\r
+ input.setText("");\r
+ output.setText("");\r
+ }\r
+\r
+ @Override\r
+ public void widgetDefaultSelected(SelectionEvent e) {}\r
+ });\r
+\r
+ FocusListener flistener = new FocusListener() {\r
+ @Override\r
+ public void focusGained(FocusEvent e) {\r
+ Text text = (Text)e.widget;\r
+ text.setSelection(0, text.getCharCount());\r
+ }\r
+ @Override\r
+ public void focusLost(FocusEvent e) { }\r
+ };\r
+\r
+\r
+ KeyListener listener = new KeyListener() {\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {\r
+ try {\r
+ Double in = Double.parseDouble(input.getText());\r
+ Double out = Double.parseDouble(output.getText());\r
+ table.addLocation(new Point2D.Double(in, out));\r
+ tableModified();\r
+ } catch (NumberFormatException e1) {\r
+ if(input.getText().isEmpty() && output.getText().isEmpty()) {\r
+ add.forceFocus();\r
+ return;\r
+ }\r
+ }\r
+ input.setText("");\r
+ output.setText("");\r
+ input.setFocus();\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) { }\r
+\r
+ };\r
+\r
+ input.addFocusListener(flistener);\r
+ input.addKeyListener(listener);\r
+ output.addFocusListener(flistener);\r
+ output.addKeyListener(listener);\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+\r
+ expression = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
+\r
+\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ String lookup = graph.getRelatedValue(expression, sr.HasLookup);\r
+ return lookup;\r
+ }\r
+ }, new Listener<String>() {\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(String lookup) {\r
+ TableParser parser = new TableParser(new StringReader(""));\r
+ parser.ReInit(new StringReader(lookup));\r
+ table.clearTable();\r
+ try {\r
+ parser.table();\r
+ ArrayList<Token> xTokens = parser.getXTokens();\r
+ ArrayList<Token> yTokens = parser.getYTokens();\r
+ for(int i = 0; i < xTokens.size(); i++) {\r
+ table.addLocation(new Point2D.Double(\r
+ Double.parseDouble(xTokens.get(i).image), \r
+ Double.parseDouble(yTokens.get(i).image)));\r
+ }\r
+ } catch (ParseException e1) {\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return table.isDisposed();\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ table.addListener(SWT.Modify, new org.eclipse.swt.widgets.Listener() {\r
+\r
+ @Override\r
+ public void handleEvent(Event event) {\r
+ tableModified();\r
+ }\r
+ });\r
+ }\r
+ \r
+ \r
+ @SuppressWarnings("unchecked")\r
+ private void tableModified() {\r
+ StringBuilder b = new StringBuilder();\r
+ b.append("{");\r
+ Iterator<InputOutput> iterator = ((ArrayList<InputOutput>)table.getTableViewer().getInput()).iterator();\r
+ while(iterator.hasNext()){\r
+ InputOutput io = iterator.next();\r
+ b.append("{" + io.getInput(String.class) + "," + io.getOutput(String.class) + "}");\r
+ if(iterator.hasNext())\r
+ b.append(",");\r
+ }\r
+ b.append("}");\r
+ final String table = b.toString();\r
+\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ graph.claimValue(expression, sr.HasLookup, table);\r
+ }\r
+ });\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.GridLayout;\r
+import java.awt.geom.Ellipse2D;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import javax.swing.JComponent;\r
+import javax.swing.JPanel;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.jfree.chart.ChartFactory;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.axis.ValueAxis;\r
+import org.jfree.chart.plot.PlotOrientation;\r
+import org.jfree.chart.plot.XYPlot;\r
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
+import org.jfree.data.general.SeriesChangeEvent;\r
+import org.jfree.data.general.SeriesChangeListener;\r
+import org.jfree.data.xy.XYDataItem;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.g2d.chassis.SWTAWTComponent;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.tableParser.ParseException;\r
+import org.simantics.sysdyn.tableParser.TableParser;\r
+import org.simantics.sysdyn.tableParser.Token;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupChartPanel;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ChartWidget implements Widget {\r
+\r
+ JFreeChart chart;\r
+ LookupChartPanel chartPanel;\r
+ SWTAWTComponent swtawtcomponent;\r
+\r
+ public ChartWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+ chartPanel = new LookupChartPanel(createChart());\r
+ chartPanel.setMouseZoomable(true, false);\r
+ chartPanel.setDomainZoomable(false);\r
+ chartPanel.setRangeZoomable(false);\r
+\r
+ swtawtcomponent = new SWTAWTComponent(parent, SWT.BORDER) {\r
+ @Override\r
+ protected JComponent createSwingComponent() {\r
+ JPanel panel = new JPanel();\r
+ panel.setLayout(new GridLayout(1, 1));\r
+ panel.add(chartPanel);\r
+ panel.doLayout();\r
+ return panel;\r
+ }\r
+ };\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(swtawtcomponent);\r
+ swtawtcomponent.populate();\r
+\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+\r
+ final Resource expression = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
+\r
+ class Auxiliary {\r
+ Double minX, minY, maxX, maxY;\r
+ String table;\r
+ }\r
+\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new Read<Auxiliary>() {\r
+\r
+ @Override\r
+ public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
+ Auxiliary auxiliary = new Auxiliary();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ auxiliary.minX = graph.getRelatedValue(expression, sr.HasMinX);\r
+ auxiliary.maxX = graph.getRelatedValue(expression, sr.HasMaxX);\r
+ auxiliary.minY = graph.getRelatedValue(expression, sr.HasMinY);\r
+ auxiliary.maxY = graph.getRelatedValue(expression, sr.HasMaxY);\r
+ auxiliary.table = graph.getRelatedValue(expression, sr.HasLookup);\r
+ return auxiliary;\r
+ }\r
+ }, new Listener<Auxiliary>() {\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(Auxiliary result) {\r
+\r
+ XYDataset dataset = createDataset(result.table);\r
+ chartPanel.resetChart(dataset);\r
+ chartPanel.addSeriesChangeListener(new _SeriesChangeListener(expression));\r
+ \r
+ XYPlot plot = (XYPlot) chart.getPlot();\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ rangeAxis.setAutoRange(false);\r
+ rangeAxis.setRange(result.minY, result.maxY);\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+ domainAxis.setAutoRange(false);\r
+ domainAxis.setRange(result.minX, result.maxX);\r
+\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return swtawtcomponent.isDisposed();\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ private JFreeChart createChart() {\r
+ XYDataset dataset = createDataset(null);\r
+ chart = ChartFactory.createXYLineChart(null, null, null,\r
+ dataset, PlotOrientation.VERTICAL, false, true, false);\r
+ XYPlot plot = (XYPlot) chart.getPlot();\r
+ XYLineAndShapeRenderer renderer\r
+ = (XYLineAndShapeRenderer) plot.getRenderer();\r
+ renderer.setBaseShapesVisible(true);\r
+ renderer.setDrawOutlines(true);\r
+ renderer.setUseFillPaint(true);\r
+ renderer.setBaseFillPaint(Color.white);\r
+ renderer.setSeriesStroke(0, new BasicStroke(3.0f));\r
+ renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0f));\r
+ renderer.setSeriesShape(0, new Ellipse2D.Double(-5.0, -5.0, 10.0, 10.0));\r
+ return chart;\r
+ }\r
+\r
+ public XYDataset createDataset(String table) {\r
+ XYSeries series = new XYSeries("Series");\r
+ \r
+ if(table != null) {\r
+ TableParser parser = new TableParser(new StringReader(""));\r
+ parser.ReInit(new StringReader(table));\r
+ try {\r
+ parser.table();\r
+ ArrayList<Token> xTokens = parser.getXTokens();\r
+ ArrayList<Token> yTokens = parser.getYTokens();\r
+ for(int i = 0; i < xTokens.size(); i++) {\r
+ series.add(\r
+ Double.parseDouble(xTokens.get(i).image), \r
+ Double.parseDouble(yTokens.get(i).image));\r
+ }\r
+ } catch (ParseException e1) {\r
+ }\r
+ }\r
+ \r
+ XYSeriesCollection dataset = new XYSeriesCollection();\r
+ dataset.addSeries(series);\r
+ return dataset;\r
+ }\r
+\r
+ public LookupChartPanel getChartPanel() {\r
+ return this.chartPanel;\r
+ }\r
+\r
+ public JFreeChart getChart() {\r
+ return this.chart;\r
+ }\r
+\r
+ private class _SeriesChangeListener implements SeriesChangeListener {\r
+\r
+ Resource expression;\r
+ \r
+ public _SeriesChangeListener(Resource expression) {\r
+ this.expression = expression;\r
+ }\r
+ @Override\r
+ public void seriesChanged(SeriesChangeEvent event) {\r
+ if(chartPanel.isDragging()) return;\r
+\r
+ StringBuilder b = new StringBuilder();\r
+ b.append("{");\r
+ XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
+ XYSeries series = collection.getSeries(0);\r
+ if(series.isEmpty())\r
+ return;\r
+ Iterator<?> iterator = series.getItems().iterator();\r
+ while(iterator.hasNext()){\r
+ XYDataItem item = (XYDataItem)iterator.next();\r
+ b.append("{" + item.getX() + "," + item.getY() + "}");\r
+ if(iterator.hasNext())\r
+ b.append(",");\r
+ }\r
+ b.append("}");\r
+ final String table = b.toString();\r
+\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ graph.claimValue(expression, sr.HasLookup, table);\r
+ }\r
+ });\r
+\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ExpressionTypes {\r
+\r
+ public static enum ExpressionType {Auxiliary, Parameter, Constant, Lookup, WithLookup, Stock, Delay, Empty};\r
+\r
+ public static ExpressionType[] auxiliaryExpressions = new ExpressionType[] {\r
+ ExpressionType.Parameter, \r
+ ExpressionType.Auxiliary, \r
+ ExpressionType.Constant, \r
+ ExpressionType.Lookup, \r
+ ExpressionType.WithLookup};\r
+\r
+ public static ExpressionType[] valveExpressions = new ExpressionType[] {\r
+ ExpressionType.Auxiliary, \r
+ ExpressionType.Parameter, \r
+ ExpressionType.Constant, \r
+ ExpressionType.WithLookup};\r
+\r
+ public static ExpressionType[] stockExpressions = new ExpressionType[] {\r
+ ExpressionType.Stock};\r
+\r
+ public static ExpressionType getExpressionTypeForVariable(final Resource variable) {\r
+ try {\r
+ return SimanticsUI.getSession().syncRequest(new Read<ExpressionType>() {\r
+\r
+ @Override\r
+ public ExpressionType perform(ReadGraph graph) throws DatabaseException {\r
+ return getExpressionTypeForVariable(graph, variable);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ return null;\r
+ }\r
+\r
+ }\r
+\r
+ public static ExpressionType getExpressionTypeForVariable(ReadGraph graph, final Resource variable) {\r
+ ExpressionType et = null;\r
+ try {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if(expression == null) {\r
+ if(graph.isInstanceOf(variable, sr.Auxiliary)) {\r
+ et = ExpressionType.Auxiliary;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Valve)) {\r
+ et = ExpressionType.Auxiliary;\r
+ }\r
+ else if(graph.isInstanceOf(variable, sr.Stock)) {\r
+ et = ExpressionType.Stock;\r
+ } else\r
+ et = ExpressionType.Empty;\r
+ } else {\r
+ if(graph.isInstanceOf(expression, sr.NormalExpression)) {\r
+ et = ExpressionType.Auxiliary;\r
+ } else if (graph.isInstanceOf(expression, sr.StockExpression)) {\r
+ et = ExpressionType.Stock;\r
+ } else if (graph.isInstanceOf(expression, sr.ParameterExpression)) {\r
+ et = ExpressionType.Parameter;\r
+ } else if (graph.isInstanceOf(expression, sr.ConstantExpression)) {\r
+ et = ExpressionType.Constant;\r
+ } else if (graph.isInstanceOf(expression, sr.DelayExpression)) {\r
+ et = ExpressionType.Delay;\r
+ } else if (graph.isInstanceOf(expression, sr.LookupExpression)) {\r
+ et = ExpressionType.Lookup;\r
+ } else if (graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ et = ExpressionType.WithLookup;\r
+ } else {\r
+ et = ExpressionType.Empty;\r
+ }\r
+ }\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return et;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.AuxiliaryExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ConstantExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.DelayExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.EmptyExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionValidation;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.LookupExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ParameterExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.StockExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.WithLookupExpression;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ExpressionWidget implements Widget {\r
+ \r
+ private Resource variable;\r
+ private Composite parent;\r
+ private Map<String, Object> data;\r
+ private IExpression expression;\r
+ private ModifyListener modifyListener;\r
+ private FocusListener focusListener;\r
+ private Table variableTable;\r
+ \r
+ \r
+ public ExpressionWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+ this.parent = parent;\r
+ this.data = new HashMap<String, Object>();\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ if(input instanceof ISelection) {\r
+ ISelection selection = (ISelection)input;\r
+ if(selection instanceof IStructuredSelection) {\r
+ Resource resource = ISelectionUtils.filterSingleSelection(selection, Resource.class);\r
+ if(resource != null) {\r
+ variable = resource;\r
+ }\r
+ }\r
+ }\r
+ \r
+ ExpressionType et = ExpressionTypes.getExpressionTypeForVariable(variable);\r
+ \r
+ displayExpression(et.toString(), true);\r
+ }\r
+ \r
+ \r
+ public void displayExpression(String expressionType, boolean original) {\r
+ if(expressionType == null)\r
+ return;\r
+\r
+ if(this.expression != null) expression.updateData(data);\r
+ ExpressionType et = ExpressionType.valueOf(expressionType);\r
+ IExpression exp = null;\r
+ switch (et) {\r
+ case Auxiliary: \r
+ exp = new AuxiliaryExpression(); break;\r
+ case Parameter: \r
+ exp = new ParameterExpression(); break;\r
+ case Constant: \r
+ exp = new ConstantExpression(); break;\r
+ case Lookup: \r
+ exp = new LookupExpression(); break;\r
+ case WithLookup: \r
+ exp = new WithLookupExpression(variable); break;\r
+ case Stock: \r
+ exp = new StockExpression(); break;\r
+ case Delay: \r
+ exp = new DelayExpression(); break;\r
+ default: \r
+ exp = new EmptyExpression();\r
+ }\r
+\r
+ if (exp != null) {\r
+ for(Control c : parent.getChildren()) {\r
+ c.dispose();\r
+ } \r
+\r
+ if(original) \r
+ exp.readData(variable, data);\r
+ \r
+ exp.createExpressionFields(parent, data);\r
+ exp.addModifyListener(modifyListener);\r
+ exp.addFocusListener(focusListener);\r
+ this.expression = exp;\r
+ this.parent.layout();\r
+ validateFields();\r
+ } \r
+ }\r
+ \r
+ public IExpression getExpression() {\r
+ return expression;\r
+ }\r
+ \r
+ public void setVariableTable(Table table) {\r
+ this.variableTable = table;\r
+ }\r
+ \r
+ public void validateFields() {\r
+ if(this.variableTable == null) return;\r
+ TableItem[] connectedVariables = this.variableTable.getItems();\r
+ try {\r
+ final Resource configuration = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource configuration = variable;\r
+ \r
+ do {\r
+ configuration = graph.getSingleObject(configuration, graph.getBuiltins().PartOf);\r
+ if(graph.isInstanceOf(configuration, sr.Configuration))\r
+ return configuration;\r
+ } while (configuration != null);\r
+ \r
+ return null;\r
+ }\r
+ });\r
+ ExpressionValidation.validateExpressionFields(expression, connectedVariables, configuration);\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ public void addModifyListener(ModifyListener listener) {\r
+ this.modifyListener = listener;\r
+ }\r
+ \r
+ public void addFocusListener(FocusListener listener) {\r
+ this.focusListener = listener;\r
+ }\r
+ \r
+ public void save() {\r
+ this.expression.save(variable, data);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\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.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class IsOutputWidget implements Widget{\r
+ \r
+ Resource variable = null; \r
+ org.simantics.browsing.ui.swt.widgets.Button isOutputButton;\r
+ \r
+ public IsOutputWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+ isOutputButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK);\r
+ isOutputButton.setText("Is Output");\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ if(input instanceof ISelection) {\r
+ ISelection selection = (ISelection)input;\r
+ if(selection instanceof IStructuredSelection) {\r
+ Resource resource = ISelectionUtils.filterSingleSelection(selection, Resource.class);\r
+ if(resource != null) {\r
+ variable = resource;\r
+ }\r
+ }\r
+ }\r
+ \r
+ if(variable == null) return;\r
+ \r
+ try {\r
+ context.getSession().syncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ final boolean isOutput = graph.hasStatement(variable, sr.IsOutput);\r
+ final Button button = getWidget();\r
+ button.getDisplay().asyncExec(new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ if(button.isDisposed()) return;\r
+ \r
+ if(isOutput)\r
+ button.setSelection(true);\r
+ else\r
+ button.setSelection(false);\r
+ }\r
+ });\r
+\r
+ \r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ isOutputButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+ @Override\r
+ public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ if(graph.hasStatement(input, sr.IsOutput)) {\r
+ graph.deny(input, sr.IsOutput);\r
+ } else {\r
+ graph.claim(input, SysdynResource.getInstance(graph).IsOutput, null, input);\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ public Button getWidget() {\r
+ return isOutputButton.getWidget();\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ComboBoxCellEditor;\r
+import org.eclipse.jface.viewers.EditingSupport;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.swt.SWT;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModuleInputEditingSupport extends EditingSupport {\r
+ private CellEditor editor;\r
+ private int column;\r
+ private HashMap<String, Resource> optionResources;\r
+ private String[] options;\r
+ private TableViewer tableViewer;\r
+\r
+ public ModuleInputEditingSupport(TableViewer viewer, int column) {\r
+ super(viewer);\r
+ this.tableViewer = (TableViewer)viewer;\r
+ this.column = column;\r
+ }\r
+\r
+ @Override\r
+ protected boolean canEdit(Object element) {\r
+ switch (this.column) {\r
+ case 0: return false;\r
+ default: return true;\r
+ }\r
+ }\r
+\r
+ \r
+ @Override\r
+ protected CellEditor getCellEditor(Object element) {\r
+ // Create the correct editor based on the column index\r
+ switch (column) {\r
+ case 0: \r
+ editor = new TextCellEditor(this.tableViewer.getTable());\r
+ case 1:\r
+ ReferenceRow row = (ReferenceRow)element;\r
+ final Resource module = row.getModule();\r
+ final Resource inputVariable = row.getVariable();\r
+\r
+ optionResources = new HashMap<String, Resource>();\r
+ try {\r
+ optionResources = SimanticsUI.getSession().syncRequest(new Read<HashMap<String, Resource>>() {\r
+\r
+ @Override\r
+ public HashMap<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ HashMap<String, Resource> result = new HashMap<String, Resource>();\r
+ for(Resource dependency : graph.syncRequest(new ObjectsWithType(module, sr.IsHeadOf, sr.Dependency))) {\r
+ if(graph.getPossibleObject(dependency, sr.RefersTo) == null ||\r
+ graph.getPossibleObject(dependency, sr.RefersTo).equals(inputVariable)) {\r
+ Resource output = graph.getSingleObject(dependency, sr.HasTail);\r
+ result.put((String)graph.getRelatedValue(output, b.HasName), dependency);\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ options = optionResources.keySet().toArray(new String[optionResources.keySet().size() + 1]);\r
+ options[optionResources.keySet().size()] = "";\r
+ ComboBoxCellEditor ceditor = new ComboBoxCellEditor(this.tableViewer.getTable(), options, SWT.READ_ONLY);\r
+ ceditor.setActivationStyle(1);\r
+ editor = ceditor;\r
+ break;\r
+ default:\r
+ editor = null;\r
+ }\r
+\r
+ return editor;\r
+ }\r
+\r
+ @Override\r
+ protected Object getValue(Object element) {\r
+ ReferenceRow referenceRow = (ReferenceRow) element;\r
+\r
+ switch (this.column) {\r
+ case 0:\r
+ return referenceRow.getName();\r
+ case 1:\r
+ String refersToName = referenceRow.getValue();\r
+ if (refersToName == null) return options.length - 1;\r
+ for(int i = 0; i < options.length ; i++) {\r
+ if(refersToName.equals(options[i])) return i;\r
+ }\r
+ return options[options.length - 1];\r
+ default:\r
+ break;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ protected void setValue(Object element, Object value) {\r
+ ReferenceRow referenceRow = (ReferenceRow) element;\r
+ String valueString = String.valueOf(value);\r
+ switch (this.column) {\r
+ case 0:\r
+ break;\r
+ case 1:\r
+ referenceRow.setRefersTo(optionResources.get(options[Integer.parseInt(valueString)]));\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ getViewer().update(element, null);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ComboBoxCellEditor;\r
+import org.eclipse.jface.viewers.EditingSupport;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.swt.SWT;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModuleOutputEditingSupport extends EditingSupport {\r
+ private CellEditor editor;\r
+ private int column;\r
+ private HashMap<String, Resource> optionResources;\r
+ private String[] options;\r
+ private TableViewer tableViewer;\r
+\r
+ public ModuleOutputEditingSupport(TableViewer viewer, int column) {\r
+ super(viewer);\r
+ this.tableViewer = (TableViewer)viewer;\r
+ this.column = column;\r
+ }\r
+\r
+ @Override\r
+ protected boolean canEdit(Object element) {\r
+ switch (this.column) {\r
+ case 0: return false;\r
+ default: return true;\r
+ }\r
+ }\r
+\r
+ \r
+ @Override\r
+ protected CellEditor getCellEditor(Object element) {\r
+ // Create the correct editor based on the column index\r
+ switch (column) {\r
+ case 0: \r
+ editor = new TextCellEditor(this.tableViewer.getTable());\r
+ case 1:\r
+ ReferenceRow row = (ReferenceRow)element;\r
+ final Resource module = row.getModule();\r
+ final Resource outputVariable = row.getVariable();\r
+\r
+ optionResources = new HashMap<String, Resource>();\r
+ try {\r
+ optionResources = SimanticsUI.getSession().syncRequest(new Read<HashMap<String, Resource>>() {\r
+\r
+ @Override\r
+ public HashMap<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ HashMap<String, Resource> result = new HashMap<String, Resource>();\r
+ for(Resource dependency : graph.syncRequest(new ObjectsWithType(module, sr.IsTailOf, sr.Dependency))) {\r
+ if(graph.getPossibleObject(dependency, sr.RefersTo) == null ||\r
+ graph.getPossibleObject(dependency, sr.RefersTo).equals(outputVariable)) {\r
+ Resource input = graph.getSingleObject(dependency, sr.HasHead);\r
+ result.put((String)graph.getRelatedValue(input, b.HasName), dependency);\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ options = optionResources.keySet().toArray(new String[optionResources.keySet().size() + 1]);\r
+ options[optionResources.keySet().size()] = "";\r
+ ComboBoxCellEditor ceditor = new ComboBoxCellEditor(this.tableViewer.getTable(), options, SWT.READ_ONLY);\r
+ ceditor.setActivationStyle(1);\r
+ editor = ceditor;\r
+ break;\r
+ default:\r
+ editor = null;\r
+ }\r
+\r
+ return editor;\r
+ }\r
+\r
+ @Override\r
+ protected Object getValue(Object element) {\r
+ ReferenceRow referenceRow = (ReferenceRow) element;\r
+\r
+ switch (this.column) {\r
+ case 0:\r
+ return referenceRow.getName();\r
+ case 1:\r
+ String refersToName = referenceRow.getValue();\r
+ if (refersToName == null) return options.length - 1;\r
+ for(int i = 0; i < options.length ; i++) {\r
+ if(refersToName.equals(options[i])) return i;\r
+ }\r
+ return options[options.length - 1];\r
+ default:\r
+ break;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ protected void setValue(Object element, Object value) {\r
+ ReferenceRow referenceRow = (ReferenceRow) element;\r
+ String valueString = String.valueOf(value);\r
+ switch (this.column) {\r
+ case 0:\r
+ break;\r
+ case 1:\r
+ referenceRow.setRefersTo(optionResources.get(options[Integer.parseInt(valueString)]));\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ getViewer().update(element, null);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import org.simantics.databoard.binding.java.StringBindingDefault;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ReferenceRow {\r
+\r
+ Resource variable, module, dependency;\r
+ String name;\r
+\r
+ public ReferenceRow(Resource module, Resource dependency, Resource variable) {\r
+ this.module = module;\r
+ this.variable = variable;\r
+ this.dependency = dependency;\r
+ }\r
+\r
+\r
+ public Resource getModule() {\r
+ return this.module;\r
+ }\r
+\r
+ public Resource getVariable() {\r
+ return this.variable;\r
+ }\r
+\r
+ public Resource getDependency() {\r
+ return this.dependency;\r
+ }\r
+\r
+ public String getName() {\r
+ String name = null;\r
+ try {\r
+ name = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ return (String)graph.getRelatedValue(getVariable(), graph.getBuiltins().HasName);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return name;\r
+ }\r
+\r
+ public String getValue() {\r
+ if(dependency == null) return "";\r
+\r
+ String value = null;\r
+ try {\r
+ value = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ Builtins b = graph.getBuiltins();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource valueResource = graph.getPossibleObject(dependency, sr.HasTail);\r
+ if(!graph.isInstanceOf(valueResource, sr.Variable))\r
+ valueResource = graph.getPossibleObject(dependency, sr.HasHead);\r
+ if(!graph.isInstanceOf(valueResource, sr.Variable))\r
+ return "";\r
+ return (String)graph.getRelatedValue(valueResource, b.HasName, StringBindingDefault.INSTANCE);\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return value;\r
+ }\r
+\r
+ public void setRefersTo(final Resource dependency) {\r
+ if(dependency != null && dependency.equals(this.dependency)) return;\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ if(getDependency() != null && graph.hasStatement(getDependency(), sr.RefersTo))\r
+ graph.deny(getDependency(), sr.RefersTo);\r
+ setDependency(null);\r
+ if(dependency != null) {\r
+ setDependency(dependency);\r
+ graph.claim(getDependency(), SysdynResource.getInstance(graph).RefersTo, getVariable());\r
+ }\r
+ }\r
+ });\r
+ }\r
+\r
+ private void setDependency(Resource dependency) {\r
+ this.dependency = dependency;\r
+ }\r
+}\r
+\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import org.eclipse.jface.viewers.ITableLabelProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.swt.graphics.Image;\r
+\r
+public class ReferenceRowLabelProvider extends LabelProvider implements ITableLabelProvider {\r
+\r
+ @Override\r
+ public Image getColumnImage(Object element, int columnIndex) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public String getColumnText(Object element, int columnIndex) {\r
+ ReferenceRow referenceRow = (ReferenceRow) element;\r
+ switch (columnIndex) {\r
+ case 0:\r
+ return referenceRow.getName();\r
+ case 1:\r
+ return referenceRow.getValue();\r
+ default:\r
+ throw new RuntimeException("Should not happen");\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.ArrayList;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.IBaseLabelProvider;\r
+import org.eclipse.jface.viewers.IContentProvider;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerComparator;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ReferenceTable implements Widget{\r
+\r
+ private TableViewer tableViewer;\r
+ private RowProvider rowProvider;\r
+\r
+ public static final String FIRSTCOLUMN = "Inputs";\r
+ public static final String SECONDCOLUMN = "Outputs";\r
+ \r
+ public ReferenceTable(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+\r
+ Composite base = new Composite(parent, style);\r
+ GridLayoutFactory.fillDefaults().applyTo(base);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(base);\r
+\r
+ Table table = new Table(base, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(table);\r
+ table.setHeaderVisible (true);\r
+ table.setLinesVisible(true);\r
+ table.getVerticalBar().setVisible(true);\r
+\r
+ tableViewer = new TableViewer (table);\r
+ tableViewer.setComparator(new ReferenceRowComparator());\r
+ }\r
+\r
+ public TableViewer getTableViewer() {\r
+ return this.tableViewer;\r
+ }\r
+\r
+ public void setRowProvider(RowProvider rowProvider) {\r
+ this.rowProvider = rowProvider;\r
+ }\r
+ \r
+ public void setContentProvider(IContentProvider provider) {\r
+ tableViewer.setContentProvider(provider);\r
+ }\r
+ \r
+ public void setLabelProvider(IBaseLabelProvider labelProvider) {\r
+ tableViewer.setLabelProvider(labelProvider);\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ final Resource module = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
+ if(this.rowProvider != null) {\r
+ try {\r
+ SimanticsUI.getSession().syncRequest(new Read<ArrayList<ReferenceRow>>() {\r
+\r
+ @Override\r
+ public ArrayList<ReferenceRow> perform(ReadGraph graph) throws DatabaseException {\r
+ return rowProvider.getRows(graph, module);\r
+ }\r
+ } , new Listener<ArrayList<ReferenceRow>>() {\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ if(tableViewer != null && tableViewer.getTable() != null)\r
+ return getTableViewer().getTable().isDisposed();\r
+ else\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public void execute(final ArrayList<ReferenceRow> result) {\r
+ if(!isDisposed())\r
+ getTableViewer().getTable().getDisplay().asyncExec(new Runnable() {\r
+ \r
+ @Override\r
+ public void run() {\r
+ if(!isDisposed())\r
+ getTableViewer().setInput(result);\r
+ }\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ }\r
+ }\r
+ );\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ private class ReferenceRowComparator extends ViewerComparator {\r
+ @Override\r
+ public int compare(Viewer viewer, Object e1, Object e2) {\r
+ ReferenceRow rr1 = (ReferenceRow)e1;\r
+ ReferenceRow rr2 = (ReferenceRow)e2;\r
+ return rr1.getName().compareTo(rr2.getName());\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public abstract class RowProvider { \r
+ public abstract ArrayList<ReferenceRow> getRows(ReadGraph graph, Resource module) throws DatabaseException;\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.MouseListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.TabFolder;\r
+import org.eclipse.swt.widgets.TabItem;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ShortcutTabWidget implements Widget {\r
+\r
+ TabFolder tabFolder;\r
+ TabItem variables;\r
+ TabItem functions;\r
+ Table variableTable;\r
+ Table functionTable;\r
+\r
+ public ShortcutTabWidget(Composite parent, WidgetSupport support, int style) {\r
+ support.register(this);\r
+\r
+ Composite composite = new Composite(parent, style);\r
+ GridDataFactory.fillDefaults().span(1, 2).grab(false, true).applyTo(composite);\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
+\r
+ tabFolder = new TabFolder (composite, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(false, true).applyTo(tabFolder);\r
+ GridLayoutFactory.fillDefaults().applyTo(tabFolder);\r
+ variables = new TabItem(tabFolder, SWT.NULL);\r
+ variables.setText("Variables");\r
+ variableTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);\r
+\r
+ variables.setControl(variableTable);\r
+\r
+ functions = new TabItem(tabFolder, SWT.NULL);\r
+ functions.setText("Functions"); \r
+ functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);\r
+ TableItem item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("min()");\r
+ item.setData("min({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("max()");\r
+ item.setData("max({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("abs()");\r
+ item.setData("abs({ })");\r
+ item = new TableItem(functionTable, SWT.NONE);\r
+ item.setText("if then else");\r
+ item.setData("if then else");\r
+ functions.setControl(functionTable);\r
+ }\r
+\r
+ @Override\r
+ public void setInput(ISessionContext context, Object input) {\r
+ if(input instanceof IStructuredSelection) {\r
+ final Resource variable = ISelectionUtils.filterSingleSelection((IStructuredSelection)input, Resource.class);\r
+ if(variable != null) {\r
+ HashSet<String> dependencies = getDependencies(variable);\r
+ TableItem item;\r
+ for(String d : dependencies) {\r
+ item = new TableItem(variableTable, SWT.NONE);\r
+ item.setText(d);\r
+ item.setData(d);\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // Returns the names of the related variables (dependencies)\r
+ private HashSet<String> getDependencies(final Resource r){\r
+ HashSet<String> variables = null;\r
+ if(r != null)\r
+ try {\r
+ variables = SimanticsUI.getSession().syncRequest(new Read<HashSet<String>>() {\r
+\r
+ @Override\r
+ public HashSet<String> perform(ReadGraph graph)\r
+ throws DatabaseException {\r
+ HashSet<String> variables = new HashSet<String>();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+\r
+ Collection<Resource> dependencies = graph.getObjects(r, sr.IsHeadOf);\r
+\r
+ for(Resource d : dependencies) {\r
+ if(graph.isInstanceOf(d, sr.Dependency)) {\r
+ Resource tail = graph.getPossibleObject(d, sr.HasTail);\r
+ if(tail != null) {\r
+ Object name = graph.getPossibleRelatedValue(tail, b.HasName);\r
+ if(name != null)\r
+ variables.add((String)name);\r
+ }\r
+ }\r
+ }\r
+\r
+ return variables;\r
+\r
+ }\r
+\r
+\r
+ });\r
+ } catch (DatabaseException ee) {\r
+ ExceptionUtils.logAndShowError(ee);\r
+ }\r
+\r
+ return variables;\r
+ }\r
+ \r
+ public void addFocusListener(FocusListener listener) {\r
+ this.functionTable.addFocusListener(listener);\r
+ this.variableTable.addFocusListener(listener);\r
+ }\r
+ \r
+ public void addMouseListener(MouseListener listener) {\r
+ this.functionTable.addMouseListener(listener);\r
+ this.variableTable.addMouseListener(listener);\r
+ }\r
+ \r
+ public Table getVariableTable() {\r
+ return variableTable;\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class AuxiliaryExpression extends BasicExpression {\r
+\r
+ public AuxiliaryExpression() {\r
+ try {\r
+ this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ return SysdynResource.getInstance(graph).NormalExpression;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class BasicExpression implements IExpression {\r
+\r
+ private ExpressionField expression;\r
+ protected Resource expressionType;\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
+ String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+\r
+ Label l = new Label(parent, SWT.NONE);\r
+ l.setText("=");\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ this.expression.focus();\r
+\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String equation = null;\r
+ if (variable != null && data.get("equation") == null && expressionType != null) {\r
+ try {\r
+ equation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, expressionType)) {\r
+ return graph.getRelatedValue(expression, sr.HasEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", equation);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void save(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ String oldEquation = (String)data.get("equation");\r
+ if(oldEquation == null || \r
+ (currentText != null && expressionType != null && !currentText.equals(oldEquation))) {\r
+ data.put("equation", currentText);\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null && !g.isInstanceOf(expression, expressionType)) {\r
+ g.deny(variable, sr.HasExpression);\r
+ expression = null;\r
+ }\r
+ if(expression == null) {\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, expressionType);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ }\r
+ g.claimValue(expression, sr.HasEquation, currentText);\r
+ }\r
+\r
+ });\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression());\r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.properties.widgets.expressions;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.text.source.ISharedTextColors;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+public class ColorManager implements ISharedTextColors {\r
+\r
+ protected HashMap<RGB, Color> colorTable = new HashMap<RGB, Color>();\r
+\r
+ @Override\r
+ public void dispose() {\r
+ for(Color c : colorTable.values())\r
+ c.dispose();\r
+ colorTable.clear();\r
+ }\r
+\r
+ @Override\r
+ public Color getColor(RGB rgb) {\r
+ Color color = colorTable.get(rgb);\r
+ if (color == null) {\r
+ color = new Color(Display.getCurrent(), rgb);\r
+ colorTable.put(rgb, color);\r
+ }\r
+ return color;\r
+\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ConstantExpression extends BasicExpression {\r
+\r
+ public ConstantExpression() {\r
+ try {\r
+ this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ return SysdynResource.getInstance(graph).ConstantExpression;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class DelayExpression implements IExpression {\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void readData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void save(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class EmptyExpression implements IExpression {\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void readData(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void save(Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.Document;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.PaintManager;\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.jface.text.source.Annotation;\r
+import org.eclipse.jface.text.source.AnnotationModel;\r
+import org.eclipse.jface.text.source.AnnotationPainter;\r
+import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;\r
+import org.eclipse.jface.text.source.IAnnotationAccess;\r
+import org.eclipse.jface.text.source.MatchingCharacterPainter;\r
+import org.eclipse.jface.text.source.SourceViewer;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+\r
+public class ExpressionField extends Composite {\r
+\r
+ protected SourceViewer _sourceViewer;\r
+ protected IDocument _document;\r
+ protected AnnotationModel _annotationModel;\r
+ \r
+ String oldExpression;\r
+\r
+ ColorManager cManager = new ColorManager();\r
+\r
+ IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();\r
+\r
+ public ExpressionField(Composite parent, int style) {\r
+ super(parent, style);\r
+ \r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+ \r
+ int styles = SWT.V_SCROLL\r
+ | SWT.MULTI\r
+ | SWT.FULL_SELECTION\r
+ | SWT.WRAP;\r
+\r
+ _document = new Document();\r
+ _document.set("");\r
+\r
+ _annotationModel = new AnnotationModel();\r
+ _annotationModel.connect(_document);\r
+\r
+ _sourceViewer = new SourceViewer(this,\r
+\r
+ null,\r
+ null,\r
+ true,\r
+ styles);\r
+ _sourceViewer.configure(new ExpressionFieldConfiguration(cManager));\r
+\r
+ AnnotationPainter painter = new AnnotationPainter(_sourceViewer, annotationAccess);\r
+ _sourceViewer.addPainter(painter);\r
+\r
+ painter.addAnnotationType("MissingLink");\r
+ painter.setAnnotationTypeColor("MissingLink", new Color(this.getDisplay(), 255,0,0));\r
+ painter.addAnnotationType("NoSuchVariable");\r
+ painter.setAnnotationTypeColor("NoSuchVariable", new Color(this.getDisplay(), 255,0,0));\r
+ \r
+ _sourceViewer.setDocument(_document, _annotationModel);\r
+\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(_sourceViewer.getControl());\r
+// _sourceViewer.getControl().setLayoutData(new GridData(SWT.FILL,\r
+// SWT.FILL,\r
+// true,\r
+// true)); \r
+\r
+ PaintManager paintManager = new PaintManager(_sourceViewer);\r
+ MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(_sourceViewer,\r
+ new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} ));\r
+ matchingCharacterPainter.setColor(new Color(Display.getCurrent(), new RGB(160, 160, 160)));\r
+ paintManager.addPainter(matchingCharacterPainter);\r
+ \r
+ \r
+ _sourceViewer.getTextWidget().addKeyListener(new KeyListener() {\r
+\r
+ @Override\r
+ public void keyReleased(KeyEvent e) {\r
+ }\r
+\r
+ @Override\r
+ public void keyPressed(KeyEvent e) {\r
+ if(e.keyCode == SWT.ESC && getExpression() != null) {\r
+ ((StyledText)e.widget).setText(oldExpression);\r
+ ((StyledText)e.widget).setSelection(getExpression().length());\r
+ } \r
+ }\r
+ });\r
+ \r
+ }\r
+\r
+ public SourceViewer getSourceViewer() {\r
+ return this._sourceViewer;\r
+ }\r
+\r
+ public void setMissingLinkAnnotations(List<Position> positions){\r
+ for(Position p : positions) {\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("MissingLink");\r
+ annotation.setText("No link to this variable");\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+ }\r
+ \r
+ public void setNoSuchVariableAnnotations(List<Position> positions){\r
+ for(Position p : positions) {\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("NoSuchVariable");\r
+ annotation.setText("No such variable in model");\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+ }\r
+\r
+ public void setSyntaxError(Token token){\r
+ int start = 0;\r
+ int offset = this._document.getLength();\r
+ if(token.image != null && this._document.getLength() > 0) {\r
+ try {\r
+ start = this._document.getLineOffset(token.beginLine - 1) + token.beginColumn - 1;\r
+ offset = this._document.getLineOffset(token.endLine - 1) + token.endColumn - start;\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ Annotation annotation = new Annotation(false);\r
+ annotation.setType("MissingLink");\r
+ annotation.setText("Syntax error");\r
+ Position p = new Position(start, offset);\r
+ _annotationModel.addAnnotation(annotation, p); \r
+ }\r
+\r
+ public void resetAnnotations() {\r
+ _annotationModel.removeAllAnnotations();\r
+ }\r
+ public void setExpression(String expression) {\r
+ _document.set(expression);\r
+ this.oldExpression = expression;\r
+ }\r
+\r
+ public String getExpression() {\r
+ return this._document.get();\r
+ }\r
+\r
+ public Point getSelection() {\r
+ return _sourceViewer.getSelectedRange();\r
+ }\r
+\r
+ public void setSelection(int selection) {\r
+ this._sourceViewer.setSelectedRange(selection, 0);\r
+ }\r
+\r
+ public IDocument getDocument() {\r
+ return _document;\r
+ }\r
+\r
+ public void focus() {\r
+ this._sourceViewer.getTextWidget().forceFocus();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.properties.widgets.expressions;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.text.DefaultTextHover;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.ITextHover;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.presentation.IPresentationReconciler;\r
+import org.eclipse.jface.text.presentation.PresentationReconciler;\r
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;\r
+import org.eclipse.jface.text.rules.IRule;\r
+import org.eclipse.jface.text.rules.ITokenScanner;\r
+import org.eclipse.jface.text.rules.IWordDetector;\r
+import org.eclipse.jface.text.rules.RuleBasedScanner;\r
+import org.eclipse.jface.text.rules.Token;\r
+import org.eclipse.jface.text.rules.WordRule;\r
+import org.eclipse.jface.text.source.DefaultAnnotationHover;\r
+import org.eclipse.jface.text.source.IAnnotationHover;\r
+import org.eclipse.jface.text.source.ISourceViewer;\r
+import org.eclipse.jface.text.source.SourceViewerConfiguration;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.RGB;\r
+\r
+public class ExpressionFieldConfiguration extends SourceViewerConfiguration {\r
+\r
+\r
+ ColorManager colorManager;\r
+\r
+ public ExpressionFieldConfiguration(ColorManager colorManager) {\r
+ super();\r
+ this.colorManager = colorManager;\r
+ }\r
+\r
+ public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {\r
+ return new String[] {\r
+ IDocument.DEFAULT_CONTENT_TYPE\r
+ };\r
+ }\r
+\r
+ /*\r
+ @Override\r
+ public IAutoEditStrategy[] getAutoEditStrategies(\r
+ ISourceViewer sourceViewer, String contentType) {\r
+ return new IAutoEditStrategy[] {\r
+ new ReplaceTabsBySpaces(),\r
+ new IndentLineEditStrategy(),\r
+ new MatchingBracketsEditStrategy()\r
+ };\r
+ }\r
+ */\r
+\r
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {\r
+ PresentationReconciler reconciler = new PresentationReconciler();\r
+\r
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getSclTokenScanner());\r
+\r
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);\r
+\r
+ return reconciler;\r
+ }\r
+\r
+ /*\r
+ * \r
+ */\r
+ ITokenScanner getSclTokenScanner() {\r
+ RuleBasedScanner scanner = new RuleBasedScanner();\r
+\r
+ final Token reserved = new Token(\r
+ new TextAttribute(\r
+ colorManager.getColor(new RGB(127, 0, 85)),\r
+ null,\r
+ SWT.BOLD\r
+ ));\r
+ \r
+\r
+ WordRule reservedWord = new WordRule(new IWordDetector() { \r
+ @Override\r
+ public boolean isWordStart(char c) {\r
+ return Character.isLetter(c);\r
+ }\r
+\r
+ @Override\r
+ public boolean isWordPart(char c) {\r
+ return Character.isLetter(c);\r
+ }\r
+ });\r
+\r
+ for(String s : keywords) {\r
+ reservedWord.addWord(s, reserved);\r
+ }\r
+\r
+ IRule[] rules = new IRule[] {\r
+ reservedWord\r
+ };\r
+ scanner.setRules(rules);\r
+\r
+ return scanner; \r
+ }\r
+\r
+ @Override\r
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {\r
+ return new DefaultTextHover(sourceViewer);\r
+ }\r
+\r
+ @Override\r
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {\r
+ return new DefaultAnnotationHover();\r
+ }\r
+\r
+ static final Set<String> keywords = new HashSet<String>();\r
+ \r
+ static {\r
+ keywords.add("within");\r
+ keywords.add("final");\r
+ keywords.add("public");\r
+ keywords.add("protected");\r
+ keywords.add("connect");\r
+ keywords.add("when");\r
+ keywords.add("then");\r
+ keywords.add("elsewhen");\r
+ keywords.add("if");\r
+ keywords.add("end");\r
+ keywords.add("elseif");\r
+ keywords.add("else");\r
+ keywords.add("for");\r
+ keywords.add("while");\r
+ keywords.add("loop");\r
+ keywords.add("der");\r
+ keywords.add("enumeration");\r
+ keywords.add("extends");\r
+ keywords.add("class");\r
+ keywords.add("partial");\r
+ keywords.add("encapsulated");\r
+ keywords.add("model");\r
+ keywords.add("record");\r
+ keywords.add("block");\r
+ keywords.add("expandable");\r
+ keywords.add("connector");\r
+ keywords.add("type");\r
+ keywords.add("package");\r
+ keywords.add("function");\r
+ keywords.add("import");\r
+ keywords.add("external");\r
+ keywords.add("constrainedby");\r
+ keywords.add("redeclare");\r
+ keywords.add("replaceable");\r
+ keywords.add("flow");\r
+ keywords.add("discrete");\r
+ keywords.add("parameter");\r
+ keywords.add("constant");\r
+ keywords.add("input");\r
+ keywords.add("output");\r
+ keywords.add("annotation");\r
+ keywords.add("false");\r
+ keywords.add("true");\r
+ keywords.add("each");\r
+ keywords.add("initial");\r
+ keywords.add("algorithm");\r
+ keywords.add("equation");\r
+ keywords.add("or");\r
+ keywords.add("and");\r
+ keywords.add("not");\r
+ keywords.add("break");\r
+ keywords.add("return"); \r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.text.Position;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.expressionParser.ParseException;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ExpressionValidation {\r
+\r
+ static public void validateExpressionFields(IExpression expression, TableItem[] connectedVariables, Resource configuration) {\r
+ ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
+ Set<String> variables = new HashSet<String>();\r
+ HashMap<ExpressionField, HashMap<String, List<Token>>> references = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
+\r
+\r
+ // Build references and variable array\r
+ for(ExpressionField ef : expression.getExpressionFields()) {\r
+ ef.resetAnnotations();\r
+ String textString = ef.getExpression();\r
+ parser.ReInit(new StringReader(textString));\r
+ try {\r
+ parser.expr();\r
+ HashMap<String, List<Token>> cr = parser.getReferences();\r
+ references.put(ef, cr);\r
+ for(String t : cr.keySet())\r
+ variables.add(t);\r
+ } catch (ParseException e1) {\r
+ ef.setSyntaxError(e1.currentToken);\r
+ }\r
+ }\r
+\r
+ // Remove variables from variable array that don't exist in the model. Create annotations\r
+ if(!variables.isEmpty()) {\r
+ ArrayList<String> modelVariables = new ArrayList<String>();\r
+ Set<String> noSuchVariables = new HashSet<String>();\r
+ SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+ SysdynModel model = sdm.getModel(configuration);\r
+ Configuration conf = model.getConfiguration();\r
+ ArrayList<IElement> elements = conf.getElements();\r
+ for(IElement e : elements) {\r
+ if(e instanceof Variable) {\r
+ Variable v = (Variable) e;\r
+ modelVariables.add(v.getName());\r
+ }\r
+ }\r
+\r
+\r
+ for(String v : variables) {\r
+ if(!modelVariables.contains(v)) {\r
+ noSuchVariables.add(v);\r
+ }\r
+ }\r
+\r
+ if(!noSuchVariables.isEmpty()) {\r
+ // remove no such variables from variable list\r
+ for(String s : noSuchVariables)\r
+ variables.remove(s);\r
+ // create annotations\r
+ HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, noSuchVariables);\r
+ for(ExpressionField ef : positions.keySet()) {\r
+ ef.setNoSuchVariableAnnotations(positions.get(ef));\r
+ }\r
+ } \r
+ }\r
+\r
+ // Check that the variables that exist have connections and the connected variables have references in the expressions\r
+ if(!(expression instanceof StockExpression)) { \r
+ for(TableItem ti : connectedVariables) {\r
+ if(!variables.contains(ti.getText())) {\r
+ ti.setForeground(new Color(ti.getDisplay(), 255, 0, 0));\r
+ } else {\r
+ ti.setForeground(new Color(ti.getDisplay(), 0, 0, 0));\r
+ variables.remove(ti.getText());\r
+ }\r
+ }\r
+\r
+ if(!variables.isEmpty()) {\r
+ HashMap<ExpressionField ,ArrayList<Position>> positions = getPositionsForVariables(references, variables);\r
+ for(ExpressionField ef : positions.keySet()) {\r
+ ef.setMissingLinkAnnotations(positions.get(ef));\r
+ }\r
+\r
+ }\r
+ } \r
+\r
+ }\r
+\r
+ @SuppressWarnings("unchecked")\r
+ static private HashMap<ExpressionField ,ArrayList<Position>> getPositionsForVariables(HashMap<ExpressionField, HashMap<String, List<Token>>> references, Set<String> variables) {\r
+ HashMap<ExpressionField ,ArrayList<Position>> result = new HashMap<ExpressionField ,ArrayList<Position>>();\r
+ for(String s : variables) {\r
+ List<Token> tlist = new ArrayList<Token>();\r
+ for(ExpressionField ef : references.keySet()) {\r
+ ArrayList<Position> positions = new ArrayList<Position>();\r
+ tlist = references.get(ef).get(s);\r
+ if(tlist != null)\r
+ for(Token t : tlist) {\r
+ StyledText st = ef.getSourceViewer().getTextWidget();\r
+ int start = st.getOffsetAtLine(t.beginLine - 1) + t.beginColumn - 1;\r
+ int offset = st.getOffsetAtLine(t.endLine - 1) + t.endColumn - start;\r
+ positions.add(new Position(\r
+ start,\r
+ offset));\r
+ }\r
+ if(result.keySet().contains(ef)) {\r
+ result.get(ef).addAll((ArrayList<Position>)positions.clone());\r
+ } else {\r
+ result.put(ef, (ArrayList<Position>)positions.clone());\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public interface IExpression {\r
+\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data);\r
+\r
+ public void readData(final Resource variable, Map<String, Object> data);\r
+\r
+ public void save(final Resource variable, Map<String, Object> data);\r
+\r
+ public void focus();\r
+\r
+ public void replaceSelection(String var);\r
+\r
+ public void updateData(Map<String, Object> data);\r
+\r
+ public List<ExpressionField> getExpressionFields();\r
+ \r
+ public void addModifyListener(ModifyListener listener);\r
+ \r
+ public void addKeyListener(KeyListener listener);\r
+\r
+ public void addFocusListener(FocusListener listener);\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.awt.Point;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.ChartRenderingInfo;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.axis.ValueAxis;\r
+import org.jfree.chart.entity.ChartEntity;\r
+import org.jfree.chart.entity.PlotEntity;\r
+import org.jfree.chart.entity.XYItemEntity;\r
+import org.jfree.chart.plot.XYPlot;\r
+import org.jfree.data.general.SeriesChangeListener;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
+\r
+@SuppressWarnings("serial")\r
+public class LookupChartPanel extends ChartPanel {\r
+\r
+ private XYItemEntity dragPrevEntity;\r
+ private boolean drawing;\r
+ private XYSeries series; \r
+ private JFreeChart chart;\r
+ private SeriesChangeListener changeListener;\r
+\r
+ public LookupChartPanel(JFreeChart chart) {\r
+ super(chart);\r
+ this.chart = chart;\r
+ XYSeriesCollection collection = (XYSeriesCollection) ((XYPlot)chart.getPlot()).getDataset();\r
+ series = collection.getSeries(0); \r
+ }\r
+\r
+ public void mouseDragged(MouseEvent e)\r
+ {\r
+ if(dragPrevEntity != null) {\r
+\r
+ int item = dragPrevEntity.getItem();\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ValueAxis rangeAxis = plot.getRangeAxis();\r
+ ValueAxis domainAxis = plot.getDomainAxis();\r
+ Point2D location = getLocationOnChart(getMouseLocation(e));\r
+ Number prevX = item == 0 ? null : series.getX(item - 1);\r
+ Number nextX = item == series.getItemCount() - 1 ? null : series.getX(item + 1);\r
+\r
+\r
+ if(series.indexOf(location.getX()) >= 0 && series.indexOf(location.getX()) != item)\r
+ return;\r
+ else if (prevX != null && location.getX() < prevX.doubleValue())\r
+ location.setLocation(series.getX(item).doubleValue(), location.getY());\r
+ else if (nextX != null && location.getX() > nextX.doubleValue())\r
+ location.setLocation(series.getX(item).doubleValue(), location.getY());\r
+ else if (location.getX() > domainAxis.getUpperBound())\r
+ location.setLocation(domainAxis.getUpperBound(), location.getY());\r
+ else if (location.getX() < domainAxis.getLowerBound()) \r
+ location.setLocation(domainAxis.getLowerBound(), location.getY()); \r
+\r
+ if (location.getY() > rangeAxis.getUpperBound())\r
+ location.setLocation(location.getX(), rangeAxis.getUpperBound());\r
+ else if (location.getY() < rangeAxis.getLowerBound()) \r
+ location.setLocation(location.getX(), rangeAxis.getLowerBound()); \r
+\r
+ removeItemFromSeries(dragPrevEntity.getItem());\r
+ addLocationToSeries(location);\r
+ } else {\r
+ ChartEntity currEntity = this.getEntityForPoint(e.getX(),e.getY());\r
+ if(!drawing && currEntity instanceof XYItemEntity) {\r
+ dragPrevEntity = ((XYItemEntity)currEntity);\r
+ } else if (currEntity instanceof PlotEntity){\r
+ drawing = true;\r
+ Point2D locationOnChart = getLocationOnChart(getMouseLocation(e));\r
+ int item = series.indexOf(locationOnChart.getX());\r
+ if (item >= 0) {\r
+ Point2D location = new Point2D.Double(series.getX(item).doubleValue(), series.getY(item).doubleValue());\r
+ Point2D javaLocation = getLocationOnJava2D(location);\r
+ removeItemFromSeries(item);\r
+ addLocationToSeries(getLocationOnChart(new Point2D.Double(javaLocation.getX(), e.getY())));\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ public void mouseReleased(MouseEvent e) {\r
+ if(isDragging()) {\r
+ dragPrevEntity = null;\r
+ if(changeListener != null)\r
+ changeListener.seriesChanged(null);\r
+ }\r
+ drawing = false;\r
+\r
+ }\r
+\r
+ public void mouseClicked(MouseEvent e)\r
+ {\r
+ if(e.getButton() == MouseEvent.BUTTON1) {\r
+ addLocationToSeries(getLocationOnChart(getMouseLocation(e)));\r
+ } else if (e.getButton() == MouseEvent.BUTTON3) {\r
+ ChartEntity entity = this.getEntityForPoint(e.getX(),e.getY());\r
+ if(entity instanceof XYItemEntity) {\r
+ XYItemEntity xyentity = ((XYItemEntity)entity);\r
+ removeItemFromSeries(xyentity.getItem());\r
+ }\r
+ }\r
+ } \r
+\r
+ private Point2D getLocationOnChart(Point2D coordinates) {\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ChartRenderingInfo info = getChartRenderingInfo();\r
+ Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
+ double chartX = plot.getDomainAxis().java2DToValue(coordinates.getX(), dataArea,\r
+ plot.getDomainAxisEdge());\r
+ double chartY = plot.getRangeAxis().java2DToValue(coordinates.getY(), dataArea,\r
+ plot.getRangeAxisEdge());\r
+ return new Point2D.Double(chartX, chartY);\r
+ }\r
+\r
+ private Point2D getLocationOnJava2D(Point2D location) {\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ ChartRenderingInfo info = getChartRenderingInfo();\r
+ Rectangle2D dataArea = info.getPlotInfo().getDataArea();\r
+ double javaX = plot.getDomainAxis().valueToJava2D(location.getX(), dataArea,\r
+ plot.getDomainAxisEdge());\r
+ double javaY = plot.getRangeAxis().valueToJava2D(location.getY(), dataArea,\r
+ plot.getRangeAxisEdge());\r
+ return new Point2D.Double(javaX, javaY);\r
+ }\r
+\r
+ public void addLocationToSeries(Point2D location) {\r
+ if(series.indexOf(location.getX()) < 0) {\r
+ series.add(location.getX(), location.getY());\r
+ }\r
+ }\r
+\r
+ public void removeItemFromSeries(int item){\r
+ series.remove(item);\r
+ }\r
+ \r
+ public void resetChart(XYDataset dataset) {\r
+ XYPlot plot = (XYPlot)chart.getPlot();\r
+ plot.setDataset(dataset);\r
+ XYSeriesCollection collection = (XYSeriesCollection) plot.getDataset();\r
+ series = collection.getSeries(0); \r
+ }\r
+\r
+ private Point2D getMouseLocation(MouseEvent e) {\r
+ int mouseX = e.getX();\r
+ int mouseY = e.getY();\r
+ Point2D p = translateScreenToJava2D(\r
+ new Point(mouseX, mouseY));\r
+ return p;\r
+ }\r
+\r
+ public void addSeriesChangeListener(SeriesChangeListener listener) {\r
+ this.changeListener = listener;\r
+ this.series.addChangeListener(changeListener);\r
+ }\r
+\r
+ public boolean isDragging() {\r
+ return dragPrevEntity != null;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+\r
+public class LookupExpression implements IExpression {\r
+\r
+ @Override\r
+ public void focus() {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ // TODO Auto-generated method stub\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void save(final Resource variable, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ // TODO Auto-generated method stub\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ArrayContentProvider;\r
+import org.eclipse.jface.viewers.CellEditor;\r
+import org.eclipse.jface.viewers.ICellModifier;\r
+import org.eclipse.jface.viewers.ITableLabelProvider;\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.jface.viewers.TableViewer;\r
+import org.eclipse.jface.viewers.TextCellEditor;\r
+import org.eclipse.jface.viewers.Viewer;\r
+import org.eclipse.jface.viewers.ViewerComparator;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Item;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+\r
+public class LookupInputOutputTable extends Composite {\r
+\r
+ public static final String INPUT = "Input";\r
+ public static final String OUTPUT = "Output";\r
+ public static final String[] PROPS = { INPUT, OUTPUT };\r
+\r
+ private Table table;\r
+ private TableViewer tableViewer;\r
+ private List<InputOutput> tableRows;\r
+\r
+ public LookupInputOutputTable(Composite parent, int style) {\r
+ super(parent, style);\r
+\r
+ GridLayoutFactory.fillDefaults().applyTo(this);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(this);\r
+ table = new Table(this, SWT.BORDER|SWT.SINGLE|SWT.FULL_SELECTION);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(table);\r
+ table.setHeaderVisible (true);\r
+ table.setLinesVisible(true);\r
+ table.getVerticalBar().setVisible(true);\r
+ TableColumn column1 = new TableColumn (table, SWT.LEFT);\r
+ column1.setText (INPUT);\r
+ column1.setWidth (85);\r
+\r
+ TableColumn column2 = new TableColumn (table, SWT.LEFT);\r
+ column2.setText (OUTPUT);\r
+ column2.setWidth (85);\r
+\r
+ // Create the viewer and connect it to the view\r
+ tableViewer = new TableViewer (table);\r
+\r
+ tableViewer.setContentProvider (new ArrayContentProvider());\r
+ tableViewer.setLabelProvider (new InputOutputLabelProvider());\r
+ tableViewer.setCellModifier(new InputOutputCellModifier());\r
+\r
+ tableRows = new ArrayList<InputOutput>(); \r
+ tableViewer.setInput(tableRows);\r
+\r
+ CellEditor[] editors = new CellEditor[2];\r
+ editors[0] = new TextCellEditor(table);\r
+ editors[1] = new TextCellEditor(table);\r
+ tableViewer.setCellEditors(editors);\r
+ tableViewer.setColumnProperties(PROPS);\r
+\r
+ }\r
+\r
+ private class InputOutputLabelProvider extends LabelProvider implements ITableLabelProvider {\r
+ public Image getColumnImage (Object element, int columnIndex) {\r
+ return null;\r
+ }\r
+ public String getColumnText (Object element, int columnIndex) {\r
+ if(element instanceof InputOutput) {\r
+ InputOutput io = (InputOutput)element;\r
+ switch (columnIndex) {\r
+ case 0: return (String)io.getInput(String.class);\r
+ case 1: return (String)io.getOutput(String.class);\r
+ }\r
+ }\r
+ return "";\r
+ }\r
+ }\r
+\r
+ public void addLocation(Point2D location) {\r
+ tableRows.add(new InputOutput(location.getX(), location.getY()));\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ refresh();\r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ public void removeItem(int index) {\r
+ tableRows.remove(index);\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ refresh();\r
+ }\r
+ });\r
+ }\r
+\r
+ public void clearTable() {\r
+ this.tableRows.clear();\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ refresh();\r
+ }\r
+ });\r
+ }\r
+\r
+\r
+ public class InputOutput {\r
+ private double input, output;\r
+\r
+ public InputOutput(double input, double output) {\r
+ this.input = input;\r
+ this.output = output;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param clazz String.class or Double.class\r
+ * @return input as string or double or null if asked for something else\r
+ */\r
+ public Object getInput(Class clazz) {\r
+ if(clazz == String.class) {\r
+ return "" + input;\r
+ } else if (clazz == Double.class) {\r
+ return input;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public Double setInput(String input) {\r
+ try {\r
+ this.input = Double.parseDouble(input);\r
+ return this.input;\r
+ } catch (NumberFormatException e) {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public void setInput(double input) {\r
+ this.input = input;\r
+ }\r
+\r
+ /**\r
+ * \r
+ * @param clazz String.class or Double.class\r
+ * @return output as string or double or null if asked for something else\r
+ */\r
+ public Object getOutput(Class clazz) {\r
+ if(clazz == String.class) {\r
+ return "" + output;\r
+ } else if (clazz == Double.class) {\r
+ return output;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public void setOutput(String output) {\r
+ try {\r
+ this.output = Double.parseDouble(output);\r
+ } catch (NumberFormatException e) {\r
+\r
+ }\r
+ }\r
+\r
+ public void setOutput(double output) {\r
+ this.output = output;\r
+ }\r
+\r
+ }\r
+\r
+ class InputOutputComparator extends ViewerComparator {\r
+ @Override\r
+ public int compare(Viewer viewer, Object e1, Object e2) {\r
+ if ((e1 instanceof InputOutput) &&\r
+ (e2 instanceof InputOutput)) {\r
+ InputOutput io1 = (InputOutput)e1;\r
+ InputOutput io2 = (InputOutput)e2;\r
+ Double d1 = (Double)io1.getInput((Double.class));\r
+ Double d2 = (Double)io2.getInput((Double.class));\r
+ return d1.compareTo(d2);\r
+ }\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ public TableViewer getTableViewer() {\r
+ return this.tableViewer;\r
+ }\r
+\r
+ public void refresh() {\r
+ if(!tableViewer.getTable().isDisposed()) {\r
+ tableViewer.setComparator(new InputOutputComparator());\r
+ tableViewer.refresh();\r
+ }\r
+ }\r
+\r
+ class InputOutputCellModifier implements ICellModifier {\r
+\r
+ public InputOutputCellModifier() {}\r
+\r
+ public boolean canModify(Object element, String property) {\r
+ return true;\r
+ }\r
+\r
+ public Object getValue(Object element, String property) {\r
+ InputOutput io = (InputOutput)element;\r
+ if (LookupInputOutputTable.INPUT.equals(property))\r
+ return (String)io.getInput(String.class);\r
+ else if (LookupInputOutputTable.OUTPUT.equals(property))\r
+ return (String)io.getOutput(String.class);\r
+ else\r
+ return null;\r
+ }\r
+\r
+ public void modify(Object element, String property, Object value) {\r
+ if (element instanceof Item) element = ((Item) element).getData();\r
+\r
+ InputOutput io = (InputOutput)element;\r
+\r
+ if (LookupInputOutputTable.INPUT.equals(property)) {\r
+ io.setInput((String)value);\r
+ } else if (LookupInputOutputTable.OUTPUT.equals(property)) {\r
+ io.setOutput((String)value);\r
+ }\r
+ tableModified();\r
+ refresh();\r
+ }\r
+ }\r
+\r
+ private void tableModified() {\r
+ tableViewer.getTable().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ for (Listener listener : getListeners(SWT.Modify)) {\r
+ Event e = new Event();\r
+ listener.handleEvent(e);\r
+ }\r
+ }\r
+ });\r
+\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ParameterExpression extends BasicExpression {\r
+ \r
+\r
+ public ParameterExpression() {\r
+ try {\r
+ this.expressionType = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+ @Override\r
+ public Resource perform(ReadGraph graph) throws DatabaseException {\r
+ return SysdynResource.getInstance(graph).ParameterExpression;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class StockExpression implements IExpression {\r
+\r
+ private Text integral;\r
+ private ExpressionField expression;\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(2).applyTo(parent);\r
+ String initialEquation = data.get("initialEquation") != null ? (String)data.get("initialEquation") : "";\r
+ String integralEquation = data.get("integral") != null ? (String)data.get("integral") : "";\r
+\r
+\r
+ Label label = new Label(parent, SWT.NONE);\r
+ label.setText("Integral");\r
+\r
+ integral = new Text(parent, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);\r
+ integral.setEditable(false);\r
+ integral.setText(integralEquation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(integral);\r
+\r
+\r
+ label = new Label(parent, SWT.NONE);\r
+ label.setText("Initial\nValue");\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setExpression(initialEquation);\r
+\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ this.expression.focus();\r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression);\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+ String initialEquation = null;\r
+\r
+ if (variable != null && data.get("initialEquation") == null) {\r
+ try {\r
+ initialEquation = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.StockExpression)) {\r
+ return graph.getRelatedValue(expression, sr.HasInitialEquation);\r
+ } else {\r
+ return "";\r
+ }\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("initialEquation", initialEquation);\r
+ }\r
+\r
+ data.put("integral", getIntegral(variable));\r
+\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(expression != null) {\r
+ IDocument doc = expression.getDocument();\r
+ try {\r
+ Point selection = expression.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ expression.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void save(final Resource variable, Map<String, Object> data) {\r
+ final String currentText = expression.getExpression();\r
+ if(currentText != null) {\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null && !g.isInstanceOf(expression, sr.StockExpression)) {\r
+ g.deny(variable, sr.HasExpression);\r
+ expression = null;\r
+ }\r
+ if(expression == null) {\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.StockExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ } \r
+ g.claimValue(expression, sr.HasInitialEquation, currentText);\r
+ }\r
+\r
+ });\r
+ }\r
+ expression.setExpression(currentText);\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("initialEquation", this.expression.getExpression());\r
+ if(this.integral != null && this.integral.getText() != null)\r
+ data.put("integral", this.integral.getText());\r
+ }\r
+\r
+\r
+ private String getIntegral(final Resource variable) {\r
+ String integral = "";\r
+ try {\r
+ integral = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Builtins b = graph.getBuiltins();\r
+ Collection<Resource> heads = graph.getObjects(variable, sr.IsHeadOf);\r
+ Collection<Resource> tails = graph.getObjects(variable, sr.IsTailOf);\r
+\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("");\r
+ for (Resource r : heads) {\r
+ if(graph.isInstanceOf(r, sr.Flow)) {\r
+ Resource tail = graph.getPossibleObject(r, sr.HasTail);\r
+ if(tail != null) {\r
+ Object name = graph.getPossibleRelatedValue(tail, b.HasName);\r
+ if (name != null) \r
+ builder.append(" + " + name);\r
+\r
+ }\r
+ }\r
+ }\r
+ for (Resource r : tails) {\r
+ if(graph.isInstanceOf(r, sr.Flow)) {\r
+ Resource head = graph.getPossibleObject(r, sr.HasHead);\r
+ if(head != null) {\r
+ Object name = graph.getPossibleRelatedValue(head, b.HasName);\r
+ if (name != null)\r
+ builder.append(" - " + name);\r
+ }\r
+ }\r
+ }\r
+ if (builder.indexOf(" + ") == 0)\r
+ builder.delete(0, 3);\r
+ return builder.toString().trim();\r
+ }\r
+\r
+ });\r
+ } catch (DatabaseException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return integral;\r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Frame;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.awt.geom.Point2D;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import javax.swing.Timer;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.awt.SWT_AWT;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\r
+import org.eclipse.swt.events.FocusListener;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.jfree.chart.ChartFactory;\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.plot.PlotOrientation;\r
+import org.jfree.data.xy.XYDataset;\r
+import org.jfree.data.xy.XYSeries;\r
+import org.jfree.data.xy.XYSeriesCollection;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.Auxiliary;\r
+import org.simantics.sysdyn.tableParser.ParseException;\r
+import org.simantics.sysdyn.tableParser.TableParser;\r
+import org.simantics.sysdyn.tableParser.Token;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class WithLookupExpression implements IExpression {\r
+\r
+ private ExpressionField expression;\r
+ private ExpressionField lookup;\r
+ private ExpressionField lastSelectedText = expression;\r
+ private Timer updateChartTimer;\r
+\r
+ private ChartPanel smallPanel;\r
+ private Frame smallFrame;\r
+\r
+ private Resource variable;\r
+\r
+ public WithLookupExpression(Resource variable) {\r
+ this.variable = variable;\r
+ }\r
+\r
+ @Override\r
+ public void createExpressionFields(Composite parent, final Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parent);\r
+\r
+ updateChartTimer = new Timer(1000, new ActionListener() {\r
+\r
+ @Override\r
+ public void actionPerformed(ActionEvent e) {\r
+ updateChart();\r
+ }\r
+ });\r
+ updateChartTimer.setRepeats(false);\r
+\r
+ String equation = data.get("equation") != null ? (String)data.get("equation") : "";\r
+ String lookupTable = data.get("lookup") != null ? (String)data.get("lookup") : "";\r
+\r
+ Label l = new Label(parent, SWT.NONE);\r
+ l.setText("With\nLookup");\r
+\r
+ expression = new ExpressionField(parent, SWT.BORDER);\r
+ expression.setExpression(equation);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+ expression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ lastSelectedText = expression;\r
+ }\r
+ });\r
+\r
+ Composite chartContainer = new Composite(parent, SWT.NONE);\r
+ createChart(chartContainer, data);\r
+\r
+\r
+ l = new Label(parent, SWT.NONE);\r
+ l.setText("Lookup\ntable");\r
+\r
+ lookup = new ExpressionField(parent, SWT.BORDER);\r
+ lookup.setExpression(lookupTable);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(lookup);\r
+\r
+ lookup.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+ @Override\r
+ public void focusLost(FocusEvent e) {\r
+ lastSelectedText = lookup;\r
+ }\r
+ });\r
+\r
+ lookup.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
+\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ if(!updateChartTimer.isRunning())\r
+ updateChartTimer.start();\r
+ else\r
+ updateChartTimer.restart();\r
+ }\r
+ });\r
+\r
+\r
+ SimanticsUI.getSession().asyncRequest(new Read<String>() {\r
+\r
+ @Override\r
+ public String perform(ReadGraph graph) throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ String result = "";\r
+ if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ result = graph.getRelatedValue(expression, sr.HasLookup);\r
+ }\r
+ return result;\r
+ }\r
+ }, new Listener<String>() {\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void execute(final String result) {\r
+ if(lookup != null)\r
+ lookup.getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ lookup.setExpression(result); \r
+ }\r
+ });\r
+ updateChart();\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ if(lookup != null && !lookup.isDisposed()) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+ });\r
+\r
+ updateChart();\r
+ }\r
+\r
+ @Override\r
+ public void focus() {\r
+ if(this.lastSelectedText != null) this.lastSelectedText.focus(); \r
+ }\r
+\r
+ @Override\r
+ public List<ExpressionField> getExpressionFields() {\r
+ return Arrays.asList(this.expression, this.lookup);\r
+ }\r
+\r
+ @Override\r
+ public void readData(final Resource variable, Map<String, Object> data) {\r
+\r
+ class Auxiliary {\r
+ String equation, lookup;\r
+ }\r
+\r
+ Auxiliary results = null;\r
+\r
+ if (variable != null && data.get("equation") == null) {\r
+ try {\r
+ results = SimanticsUI.getSession().syncRequest(new Read<Auxiliary>() {\r
+\r
+ @Override\r
+ public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
+ Auxiliary results = new Auxiliary();\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ Resource expression = graph.getPossibleObject(variable, sr.HasExpression);\r
+ if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ results.equation = graph.getRelatedValue(expression, sr.HasEquation);\r
+ results.lookup = graph.getRelatedValue(expression, sr.HasLookup);\r
+ } else {\r
+ results.equation = "";\r
+ results.lookup = "";\r
+ }\r
+ return results;\r
+ }\r
+ });\r
+ } catch (DatabaseException e1) {\r
+ e1.printStackTrace();\r
+ }\r
+ data.put("equation", results.equation);\r
+ data.put("lookup", results.lookup);\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void replaceSelection(String var) {\r
+ if(lastSelectedText != null) {\r
+ IDocument doc = lastSelectedText.getDocument();\r
+ try {\r
+ Point selection = lastSelectedText.getSelection();\r
+ doc.replace(selection.x, selection.y, var);\r
+ lastSelectedText.setSelection(selection.x + var.length());\r
+ } catch (BadLocationException e) {\r
+ e.printStackTrace();\r
+ }\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void save(final Resource variable, Map<String, Object> data) {\r
+ final String currentExpression = expression.getExpression();\r
+ final String currentLookupTable = lookup.getExpression();\r
+ String oldExpression = (String)data.get("equation");\r
+ String oldLookupTable = (String)data.get("lookup");\r
+\r
+ if(oldExpression == null || oldLookupTable == null ||\r
+ (currentExpression != null && currentLookupTable != null\r
+ && (!currentExpression.equals(oldExpression) || \r
+ !currentLookupTable.equals(oldLookupTable)))) {\r
+ data.putAll(data);\r
+ data.put("equation", currentExpression);\r
+ data.put("lookup", currentLookupTable);\r
+ SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+ @Override\r
+ public void perform(WriteGraph g)\r
+ throws DatabaseException {\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+ Resource expression = g.getPossibleObject(variable, sr.HasExpression);\r
+ Builtins b = g.getBuiltins();\r
+ if(expression != null && !g.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+ g.deny(variable, sr.HasExpression);\r
+ expression = null;\r
+ }\r
+ if(expression == null) {\r
+ expression = g.newResource();\r
+ g.claim(expression, b.InstanceOf, null, sr.WithLookupExpression);\r
+ g.claim(variable, sr.HasExpression, expression);\r
+ g.claimValue(expression, sr.HasMinX, 0.0);\r
+ g.claimValue(expression, sr.HasMaxX, 10.0);\r
+ g.claimValue(expression, sr.HasMinY, 0.0);\r
+ g.claimValue(expression, sr.HasMaxY, 10.0);\r
+\r
+ } \r
+ g.claimValue(expression, sr.HasEquation, currentExpression);\r
+ g.claimValue(expression, sr.HasLookup, currentLookupTable);\r
+ }\r
+ });\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void updateData(Map<String, Object> data) {\r
+ if(this.expression != null && this.expression.getExpression() != null)\r
+ data.put("equation", this.expression.getExpression());\r
+ if(this.lookup != null && this.lookup.getExpression() != null)\r
+ data.put("lookup", this.lookup.getExpression()); \r
+ }\r
+\r
+ @Override\r
+ public void addKeyListener(KeyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+ this.lookup.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+ }\r
+\r
+ @Override\r
+ public void addModifyListener(ModifyListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+ this.lookup.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+ }\r
+\r
+ @Override\r
+ public void addFocusListener(FocusListener listener) {\r
+ this.expression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+ this.lookup.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+ }\r
+\r
+ private void createChart(Composite composite, final Map<String, Object> data) {\r
+ GridLayoutFactory.fillDefaults().applyTo(composite);\r
+ GridDataFactory.fillDefaults().span(1, 2).hint(150, SWT.DEFAULT).applyTo(composite);\r
+ final Composite chartComposite = new Composite(composite, \r
+ SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(chartComposite);\r
+ smallFrame = SWT_AWT.new_Frame(chartComposite);\r
+\r
+ XYDataset dataset = new XYSeriesCollection(new XYSeries("Lookup Table"));\r
+ JFreeChart chart = createChart(dataset);\r
+ smallPanel = new ChartPanel(chart);\r
+ smallFrame.add(smallPanel);\r
+\r
+ }\r
+\r
+ private static JFreeChart createChart(XYDataset dataset) {\r
+ JFreeChart chart = ChartFactory.createXYLineChart(\r
+ null,\r
+ null,\r
+ null,\r
+ dataset,\r
+ PlotOrientation.VERTICAL,\r
+ true,\r
+ true,\r
+ false\r
+ );\r
+ chart.removeLegend();\r
+ chart.getXYPlot().getDomainAxis().setTickLabelsVisible(true);\r
+ chart.getXYPlot().getDomainAxis().setAxisLineVisible(false);\r
+ chart.getXYPlot().getDomainAxis().setTickMarksVisible(true);\r
+ chart.getXYPlot().getRangeAxis().setTickLabelsVisible(true);\r
+ chart.getXYPlot().getRangeAxis().setAxisLineVisible(false);\r
+ chart.getXYPlot().getRangeAxis().setTickMarksVisible(true);\r
+ chart.getXYPlot().getRenderer().setSeriesStroke(0, new BasicStroke(3.0f));\r
+ return chart;\r
+ }\r
+\r
+ private void updateChart() {\r
+ ArrayList<Point2D> dataPoints = new ArrayList<Point2D>();\r
+ TableParser parser = new TableParser(new StringReader(""));\r
+ parser.ReInit(new StringReader(lookup.getExpression()));\r
+ try {\r
+ parser.table();\r
+ ArrayList<Token> xTokens = parser.getXTokens();\r
+ ArrayList<Token> yTokens = parser.getYTokens();\r
+ for(int i = 0; i < xTokens.size(); i++) {\r
+ dataPoints.add(new Point2D.Double(\r
+ Double.parseDouble(xTokens.get(i).image), \r
+ Double.parseDouble(yTokens.get(i).image)));\r
+ }\r
+ } catch (ParseException e1) {\r
+// e1.printStackTrace();\r
+ return;\r
+ }\r
+\r
+ XYSeries series = new XYSeries("Lookup Table");\r
+ for(Point2D point : dataPoints) {\r
+ series.add(point.getX(), point.getY());\r
+ }\r
+ XYSeriesCollection dataset = new XYSeriesCollection(series);\r
+ smallPanel.getChart().getXYPlot().setDataset(dataset);\r
+ }\r
+\r
+\r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+public class DoublePropertyFactory extends ReadFactoryImpl<Resource, String> {\r
+\r
+ final private String propertyURI;\r
+ \r
+ public DoublePropertyFactory(String propertyURI) {\r
+ this.propertyURI = propertyURI;\r
+ }\r
+\r
+ @Override\r
+ public Object getIdentity(Object inputContents) {\r
+ return new Triple<Resource, String, Object>((Resource)inputContents, propertyURI, getClass());\r
+ }\r
+ \r
+ @Override\r
+ public String perform(ReadGraph graph, Resource issue) throws DatabaseException {\r
+ \r
+ Double value = graph.getPossibleRelatedValue(issue, graph.getResource(propertyURI));\r
+ if (value != null)\r
+ return value.toString();\r
+ else\r
+ return "";\r
+ }\r
+ \r
+}\r
--- /dev/null
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.databoard.binding.java.DoubleBindingDefault;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public class DoublePropertyModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+ final private String propertyURI;\r
+ \r
+ public DoublePropertyModifier(ISessionContext context, String propertyURI) {\r
+ this.propertyURI = propertyURI;\r
+ }\r
+\r
+ @Override\r
+ public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
+ graph.claimValue(input, graph.getResource(propertyURI), Double.parseDouble(text), DoubleBindingDefault.INSTANCE);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.sg;\r
+\r
+import java.awt.AWTEvent;\r
+import java.awt.event.AWTEventListener;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.h2d.diagram.IDiagram;\r
+import org.simantics.h2d.diagram.IDiagramListener;\r
+import org.simantics.h2d.element.IElement;\r
+import org.simantics.objmap.IMapping;\r
+import org.simantics.objmap.IMappingListener;\r
+import org.simantics.objmap.MappingException;\r
+import org.simantics.objmap.Mappings;\r
+import org.simantics.scenegraph.adapters.ISceneGraphProvider;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.G2DSceneGraph;\r
+import org.simantics.scenegraph.g2d.nodes.NavigationNode;\r
+import org.simantics.scenegraph.g2d.nodes.PageBorderNode;\r
+import org.simantics.scenegraph.g2d.nodes.TransformNode;\r
+import org.simantics.sysdyn.ui.editor.SysdynDiagramSchema;\r
+\r
+public class SysdynSceneGraphProvider implements ISceneGraphProvider, AWTEventListener {\r
+\r
+ protected Resource resource;\r
+\r
+ IDiagram diagram;\r
+ IMapping mapping;\r
+\r
+ public SysdynSceneGraphProvider(ReadGraph g, final Resource resource) {\r
+ this.resource = resource;\r
+ \r
+ SysdynDiagramSchema schema;\r
+ try {\r
+ schema = new SysdynDiagramSchema(g);\r
+ } catch (DatabaseException e1) {\r
+ // TODO Auto-generated catch block\r
+ e1.printStackTrace();\r
+ return;\r
+ }\r
+ \r
+ mapping = Mappings.createWithListening(schema);\r
+ \r
+ try {\r
+ diagram = (IDiagram)mapping.map(g, resource);\r
+ } catch (MappingException e) {\r
+ // TODO Auto-generated catch block\r
+ e.printStackTrace();\r
+ }\r
+ \r
+ final Session session = g.getSession();\r
+ mapping.addMappingListener(new IMappingListener() {\r
+ \r
+ @Override\r
+ public void rangeModified() { \r
+ session.asyncRequest(new WriteRequest() {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph)\r
+ throws DatabaseException {\r
+ try {\r
+ mapping.updateDomain(graph);\r
+ } catch(Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ });\r
+ }\r
+ \r
+ @Override\r
+ public void domainModified() {\r
+ session.asyncRequest(new ReadRequest() {\r
+ \r
+ @Override\r
+ public void run(ReadGraph graph) throws DatabaseException {\r
+ try {\r
+ mapping.updateRange(graph);\r
+ } catch(Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ });\r
+ }\r
+ });\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public AWTEventListener getEventListener() {\r
+ return this;\r
+ }\r
+\r
+ @Override\r
+ public G2DSceneGraph initializeSceneGraph(G2DSceneGraph sg) {\r
+ return initializeSceneGraph(sg, null);\r
+ }\r
+\r
+ G2DSceneGraph sceneGraph;\r
+ TransformNode diagramCoordinatesNode;\r
+ G2DParentNode elementsNode;\r
+ G2DParentNode selectionNode;\r
+ G2DParentNode actionNode;\r
+\r
+ @Override\r
+ public G2DSceneGraph initializeSceneGraph(G2DSceneGraph sg, String view) {\r
+ sceneGraph = sg;\r
+ diagramCoordinatesNode = sceneGraph.addNode(NavigationNode.class);\r
+\r
+ PageBorderNode border = diagramCoordinatesNode.addNode(PageBorderNode.class);\r
+ border.init(new Rectangle2D.Double(0.0, 0.0, 297.0, 210.0), new Rectangle2D.Double(10.0, 10.0, 277.0, 190.0), Boolean.TRUE);\r
+\r
+ elementsNode = diagramCoordinatesNode.addNode(G2DParentNode.class);\r
+ elementsNode.setZIndex(0);\r
+\r
+ selectionNode = diagramCoordinatesNode.addNode(G2DParentNode.class);\r
+ selectionNode.setZIndex(1);\r
+\r
+ actionNode = diagramCoordinatesNode.addNode(G2DParentNode.class);\r
+ actionNode.setZIndex(2);\r
+ \r
+ for(IElement element : diagram.getElements())\r
+ element.init(elementsNode);\r
+ diagram.addDiagramListener(new IDiagramListener() {\r
+ \r
+ @Override\r
+ public void elementAdded(IElement element) {\r
+ element.init(elementsNode);\r
+ }\r
+\r
+ @Override\r
+ public void elementRemoved(IElement element) {\r
+ element.remove();\r
+ }\r
+ });\r
+ \r
+ return sg;\r
+ }\r
+\r
+ @Override\r
+ public void setHint(Object key, Object value) {\r
+ // TODO Auto-generated method stub\r
+\r
+ }\r
+\r
+ @Override\r
+ public void eventDispatched(AWTEvent event) {\r
+ \r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.trend;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.core.commands.Command;\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.core.commands.State;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.commands.ICommandService;\r
+\r
+\r
+public class PinTrend extends AbstractHandler {\r
+\r
+ public static final String COMMAND = "org.simantics.sysdyn.ui.trend.view.pin";\r
+ public static final String STATE = "org.simantics.sysdyn.ui.trend.view.pin.state";\r
+ \r
+ @Override\r
+ public Object execute(ExecutionEvent event) throws ExecutionException {\r
+ ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = service.getCommand(COMMAND);\r
+ State state = command.getState(STATE);\r
+ Boolean value = (Boolean) state.getValue();\r
+ value = !value;\r
+ state.setValue(value);\r
+\r
+ return null;\r
+ }\r
+ \r
+ public static Boolean getState() {\r
+ ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+ Command command = service.getCommand(COMMAND);\r
+ State state = command.getState(STATE);\r
+ return (Boolean)state.getValue();\r
+ }\r
+\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in 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.trend;\r
+\r
+import java.awt.Frame;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import javax.swing.SwingUtilities;\r
+\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.awt.SWT_AWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.jfree.chart.ChartPanel;\r
+import org.jfree.chart.JFreeChart;\r
+import org.jfree.chart.axis.NumberAxis;\r
+import org.jfree.chart.plot.XYPlot;\r
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
+import org.jfree.data.xy.AbstractXYDataset;\r
+import org.simantics.db.Builtins;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.manager.SysdynResult;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+import org.simantics.utils.ui.jface.ActiveSelectionProvider;\r
+\r
+public class TrendView extends ViewPart {\r
+\r
+ Frame frame;\r
+ ChartPanel panel;\r
+ SysdynDatasets sysdynDatasets = new SysdynDatasets();\r
+\r
+\r
+ @SuppressWarnings("serial")\r
+ class SysdynDatasets extends AbstractXYDataset {\r
+\r
+ SysdynDataSet[] sets = new SysdynDataSet[0];\r
+\r
+ public void setDatasets(SysdynDataSet[] sets) {\r
+ this.sets = sets;\r
+ fireDatasetChanged();\r
+ }\r
+\r
+ @Override\r
+ public Number getY(int series, int item) {\r
+ return sets[series].values[item];\r
+ }\r
+\r
+ @Override\r
+ public Number getX(int series, int item) {\r
+ return sets[series].times[item];\r
+ }\r
+\r
+ @Override\r
+ public int getItemCount(int series) {\r
+ return sets[series].times.length;\r
+ }\r
+\r
+ @Override\r
+ public Comparable<String> getSeriesKey(int series) { \r
+ SysdynDataSet sds = sets[series];\r
+ if(sds.result == null)\r
+ return sds.name;\r
+ else\r
+ return sds.name + " : " + sds.result;\r
+ }\r
+\r
+ @Override\r
+ public int getSeriesCount() { \r
+ return sets.length;\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void createPartControl(Composite parent) { \r
+ final ActiveSelectionProvider selectionProvider = new ActiveSelectionProvider();\r
+ getSite().setSelectionProvider(selectionProvider);\r
+\r
+ final Composite composite = new Composite(parent, \r
+ SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+ frame = SWT_AWT.new_Frame(composite);\r
+\r
+ SwingUtilities.invokeLater(new Runnable() {\r
+\r
+ @Override\r
+ public void run() { \r
+ XYPlot plot = new XYPlot(\r
+ sysdynDatasets,\r
+ new NumberAxis("time"),\r
+ new NumberAxis("x"),\r
+ new XYLineAndShapeRenderer(true, false)\r
+ );\r
+\r
+ JFreeChart chart = new JFreeChart(plot);\r
+ panel = new ChartPanel(chart);\r
+ frame.add(panel);\r
+\r
+ panel.requestFocus();\r
+ }\r
+\r
+ });\r
+\r
+ getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(new ISelectionListener() {\r
+\r
+ @Override\r
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {\r
+ if(selection.isEmpty() || Boolean.TRUE.equals(PinTrend.getState()))\r
+ return;\r
+ if(selection instanceof IStructuredSelection) {\r
+ Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
+ List<Resource> runtimes = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_VARIABLE_RESOURCE, Resource.class);\r
+ if(runtimes.isEmpty())\r
+ return;\r
+ Resource runtime = runtimes.get(0);\r
+ setSelection(ress.toArray(Resource.NONE), runtime);\r
+ } \r
+ }\r
+ });\r
+\r
+ }\r
+\r
+ Resource[] resources;\r
+ Resource runtime;\r
+\r
+ protected void setSelection(Resource[] resources, Resource runtime) {\r
+ this.resources = resources;\r
+ this.runtime = runtime;\r
+ updateView();\r
+ }\r
+\r
+ public void updateView() {\r
+\r
+ Session session = SimanticsUI.peekSession();\r
+ if (session == null)\r
+ return;\r
+\r
+ session.asyncRequest(new ReadRequest() {\r
+ @Override\r
+ public void run(ReadGraph g) throws DatabaseException {\r
+\r
+ final ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+ for(Resource resource : resources) {\r
+// SysdynDataSet set = load(g, resource, runtime);\r
+// if(set == null) {\r
+// return;\r
+// }\r
+// datasets.add(set);\r
+ Collection<SysdynDataSet> activeDataSets = loadAllActive(g, resource, runtime);\r
+ if(activeDataSets != null && !activeDataSets.isEmpty())\r
+ datasets.addAll(activeDataSets);\r
+ }
+\r
+ SwingUtilities.invokeLater(new Runnable() {\r
+\r
+ @Override\r
+ public void run() { \r
+ sysdynDatasets.setDatasets(datasets.toArray(new SysdynDataSet[datasets.size()]));\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+ });\r
+ }\r
+\r
+ /*\r
+ protected SysdynDataSet load(ReadGraph g, Resource element, Resource runtime) throws DatabaseException {\r
+\r
+ Builtins b = g.getBuiltins();\r
+\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+ DiagramResource dr = DiagramResource.getInstance(g);\r
+\r
+ if(runtime == null) return null;\r
+ Resource resource = ModelingUtils.getPossibleElementCorrespondendence(g, element);\r
+ if(resource == null || !g.isInstanceOf(resource, sr.Variable)) return null;\r
+\r
+ String variableURI = g.getPossibleRelatedValue(runtime, dr.HasVariable);\r
+\r
+ System.out.println("load dataset for '"+ g.getPossibleRelatedValue(resource, b.HasName) + "'in composite '" + variableURI + "'");\r
+ Variable compositeVariable = Variables.getVariable(g, variableURI);\r
+ Variable item = compositeVariable.browsePossible(g, resource);\r
+ if(item == null) return null;\r
+\r
+ System.out.println("load dataset for '" + item.getURI(g) + "'");\r
+\r
+ Accessor accessor = item.getInterface(g, Accessor.class);\r
+ if(accessor == null) return null;\r
+ try {\r
+ return (SysdynDataSet)accessor.getValue(Bindings.getBindingUnchecked(SysdynDataSet.class));\r
+ } catch (RuntimeBindingConstructionException e) {\r
+ e.printStackTrace();\r
+ } catch (AccessorException e) {\r
+ e.printStackTrace();\r
+ }\r
+ return null;\r
+\r
+ }\r
+ */\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ if(panel != null)\r
+ panel.requestFocus(); \r
+ }\r
+\r
+ protected Collection<SysdynDataSet> loadAllActive(ReadGraph g, Resource element, Resource runtime) throws DatabaseException {\r
+\r
+ ArrayList<SysdynDataSet> dataSets = new ArrayList<SysdynDataSet>();\r
+ Builtins b = g.getBuiltins();\r
+\r
+ SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+ DiagramResource dr = DiagramResource.getInstance(g);\r
+\r
+ if(runtime == null) return null;\r
+ Resource resource = ModelingUtils.getPossibleElementCorrespondendence(g, element);\r
+ if(resource == null || !g.isInstanceOf(resource, sr.Variable)) return null;\r
+\r
+ String variableURI = g.getPossibleRelatedValue(runtime, dr.HasVariable);\r
+\r
+ System.out.println("load dataset for '"+ g.getPossibleRelatedValue(resource, b.HasName) + "'in composite '" + variableURI + "'");\r
+ Variable compositeVariable = Variables.getVariable(g, variableURI);\r
+ Variable item = compositeVariable.browsePossible(g, resource);\r
+ if(item == null) return null;\r
+\r
+ String rvi = Variables.getRVI(g, item);\r
+ System.out.println("HistoryVariable rvi='" + rvi + "'");\r
+\r
+ System.out.println("load dataset for '" + item.getURI(g) + "'");\r
+\r
+ Resource model = Variables.getModel(g, item);\r
+ Resource configuration = g.getPossibleObject(model, b.HasConfiguration);\r
+ SysdynModel sm = SysdynModelManager.getInstance(g.getSession()).getModel(g, configuration);\r
+\r
+ Collection<SysdynResult> activeResults = sm.getActiveResults(g);\r
+ for(SysdynResult sysdynResult : activeResults) {\r
+ SysdynDataSet sds = sysdynResult.getDataSet(rvi.substring(1).replace("/", "."));\r
+ if(sds != null)\r
+ dataSets.add(sds);\r
+ }\r
+ return dataSets;\r
+\r
+ }\r
+\r
+}\r