]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Hopefully undoing the little "upsista"
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 11 Aug 2010 07:02:56 +0000 (07:02 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 11 Aug 2010 07:02:56 +0000 (07:02 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@17080 ac1ea38d-2e2b-0410-8846-a27921b304fc

208 files changed:
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/TestDiagramEditor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/Connect.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectBase.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectDependency.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectFlow.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateAuxiliary.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateCloud.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateStock.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateValve.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/DiagramContextMenuData.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/OpenContextMenu.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ToggleSimulation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Module.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramEditor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramSchema.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Arcs.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/DependencyElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Flows.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangularElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/TextElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElement.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElementOld.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/AuxiliaryFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/BorderSceneGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/CloudFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ComponentNameSynchronizer.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConfigurationDiagramClassAdapter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/GraphPropertyNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverShapeNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementNoBounds.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Input.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/InputFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/StockFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementHints.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/WholeElementTerminals.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Arcs.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/ConnectionClasses.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Dependencies.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowStroke.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Flows.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionTypeSelector.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/NameComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ShortcutTabs.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/UnitSelector.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/AuxiliaryExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ColorManager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ConstantExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/DelayExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/EmptyExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionField.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionFieldConfiguration.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/IExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartInfo.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ParameterExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/StockExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateAuxiliaryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateCloudHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateStockHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateValveHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramContextMenuActionHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModuleNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultRealizationVirtualGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryRealizationVirtualGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProjectLifeCycle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleInputEditingSupport.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleOutputEditingSupport.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRow.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRowLabelProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceTable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/RowProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionValidation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/sg/SysdynSceneGraphProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java [new file with mode: 0644]

diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/Activator.java
new file mode 100644 (file)
index 0000000..988e479
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/TestDiagramEditor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/TestDiagramEditor.java
new file mode 100644 (file)
index 0000000..b85a32c
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/Connect.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/Connect.java
new file mode 100644 (file)
index 0000000..fb37933
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectBase.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectBase.java
new file mode 100644 (file)
index 0000000..d1cde77
--- /dev/null
@@ -0,0 +1,117 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectDependency.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectDependency.java
new file mode 100644 (file)
index 0000000..1392fc4
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectFlow.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConnectFlow.java
new file mode 100644 (file)
index 0000000..4885f7a
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateAuxiliary.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateAuxiliary.java
new file mode 100644 (file)
index 0000000..4bde7cc
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateCloud.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateCloud.java
new file mode 100644 (file)
index 0000000..ec03cca
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateStock.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateStock.java
new file mode 100644 (file)
index 0000000..104852e
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateValve.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/CreateValve.java
new file mode 100644 (file)
index 0000000..20a8c85
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/DiagramContextMenuData.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/DiagramContextMenuData.java
new file mode 100644 (file)
index 0000000..c5c45d9
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/OpenContextMenu.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/OpenContextMenu.java
new file mode 100644 (file)
index 0000000..53f89ff
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ToggleSimulation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ToggleSimulation.java
new file mode 100644 (file)
index 0000000..d92a2de
--- /dev/null
@@ -0,0 +1,79 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynBrowser.java
new file mode 100644 (file)
index 0000000..3fae63c
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeImager.java
new file mode 100644 (file)
index 0000000..21ae321
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AbstractNodeLabeler.java
new file mode 100644 (file)
index 0000000..813365c
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Configuration.java
new file mode 100644 (file)
index 0000000..086ccde
--- /dev/null
@@ -0,0 +1,51 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ConfigurationLabeler.java
new file mode 100644 (file)
index 0000000..2161aae
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Experiment.java
new file mode 100644 (file)
index 0000000..34bc6ad
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabelDecorator.java
new file mode 100644 (file)
index 0000000..b38c9f6
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentLabeler.java
new file mode 100644 (file)
index 0000000..7779cc8
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ExperimentsLabeler.java
new file mode 100644 (file)
index 0000000..f301ce2
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InputLabeler.java
new file mode 100644 (file)
index 0000000..3e042c6
--- /dev/null
@@ -0,0 +1,27 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryViewpointContributor.java
new file mode 100644 (file)
index 0000000..7eea121
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Model.java
new file mode 100644 (file)
index 0000000..eb2d5a0
--- /dev/null
@@ -0,0 +1,36 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModelLabeler.java
new file mode 100644 (file)
index 0000000..bb53b59
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Module.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Module.java
new file mode 100644 (file)
index 0000000..59945da
--- /dev/null
@@ -0,0 +1,57 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java
new file mode 100644 (file)
index 0000000..78e02ff
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java
new file mode 100644 (file)
index 0000000..74adf59
--- /dev/null
@@ -0,0 +1,20 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Modules.java
new file mode 100644 (file)
index 0000000..4399de9
--- /dev/null
@@ -0,0 +1,40 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java
new file mode 100644 (file)
index 0000000..9bc154c
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/OperatingInterfacesLabeler.java
new file mode 100644 (file)
index 0000000..13cc2d3
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Project.java
new file mode 100644 (file)
index 0000000..83ef90d
--- /dev/null
@@ -0,0 +1,40 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResult.java
new file mode 100644 (file)
index 0000000..cf5bfb1
--- /dev/null
@@ -0,0 +1,53 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultDecorator.java
new file mode 100644 (file)
index 0000000..6946962
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultImager.java
new file mode 100644 (file)
index 0000000..1bc9430
--- /dev/null
@@ -0,0 +1,20 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultLabeler.java
new file mode 100644 (file)
index 0000000..c74bb40
--- /dev/null
@@ -0,0 +1,16 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/VariableLabeler.java
new file mode 100644 (file)
index 0000000..14b675a
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractNode.java
new file mode 100644 (file)
index 0000000..bf56020
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ConfigurationNode.java
new file mode 100644 (file)
index 0000000..1f44cfd
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentNode.java
new file mode 100644 (file)
index 0000000..a04e596
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExperimentsFolder.java
new file mode 100644 (file)
index 0000000..b68b539
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InputNode.java
new file mode 100644 (file)
index 0000000..b0efeb7
--- /dev/null
@@ -0,0 +1,10 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModelNode.java
new file mode 100644 (file)
index 0000000..b79582c
--- /dev/null
@@ -0,0 +1,31 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleNode.java
new file mode 100644 (file)
index 0000000..1689c07
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModuleTypeNode.java
new file mode 100644 (file)
index 0000000..fdbad70
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ModulesNode.java
new file mode 100644 (file)
index 0000000..1536a4c
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/OperatingInterfacesFolder.java
new file mode 100644 (file)
index 0000000..94ecb3f
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultNode.java
new file mode 100644 (file)
index 0000000..ef28f83
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SymbolNode.java
new file mode 100644 (file)
index 0000000..90fb533
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/VariableNode.java
new file mode 100644 (file)
index 0000000..1480bb6
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/CreateDependencyGraph.java
new file mode 100644 (file)
index 0000000..4a287d5
--- /dev/null
@@ -0,0 +1,116 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/dependencies/DependencyView.java
new file mode 100644 (file)
index 0000000..280f997
--- /dev/null
@@ -0,0 +1,191 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java
new file mode 100644 (file)
index 0000000..cf7fbc5
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java
new file mode 100644 (file)
index 0000000..fa54697
--- /dev/null
@@ -0,0 +1,151 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java
new file mode 100644 (file)
index 0000000..c2fcda8
--- /dev/null
@@ -0,0 +1,17 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynConnectionAdvisor.java
new file mode 100644 (file)
index 0000000..e289edd
--- /dev/null
@@ -0,0 +1,129 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java
new file mode 100644 (file)
index 0000000..ac3a25b
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramEditor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramEditor.java
new file mode 100644 (file)
index 0000000..d57867f
--- /dev/null
@@ -0,0 +1,331 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramSchema.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynDiagramSchema.java
new file mode 100644 (file)
index 0000000..d0d2b3e
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java
new file mode 100644 (file)
index 0000000..d36ba47
--- /dev/null
@@ -0,0 +1,533 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/PointerInteractor.java
new file mode 100644 (file)
index 0000000..f799426
--- /dev/null
@@ -0,0 +1,193 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Arcs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Arcs.java
new file mode 100644 (file)
index 0000000..7651fcd
--- /dev/null
@@ -0,0 +1,165 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryElement.java
new file mode 100644 (file)
index 0000000..068f65f
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudElement.java
new file mode 100644 (file)
index 0000000..f7cd27f
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/DependencyElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/DependencyElement.java
new file mode 100644 (file)
index 0000000..4a4b641
--- /dev/null
@@ -0,0 +1,217 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/FlowElement.java
new file mode 100644 (file)
index 0000000..9371a6d
--- /dev/null
@@ -0,0 +1,249 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Flows.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Flows.java
new file mode 100644 (file)
index 0000000..59e7def
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangularElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangularElement.java
new file mode 100644 (file)
index 0000000..a83f747
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockElement.java
new file mode 100644 (file)
index 0000000..97d2872
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/TextElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/TextElement.java
new file mode 100644 (file)
index 0000000..4cbde64
--- /dev/null
@@ -0,0 +1,244 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElement.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElement.java
new file mode 100644 (file)
index 0000000..81f1493
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElementOld.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveElementOld.java
new file mode 100644 (file)
index 0000000..d63c7d4
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/AuxiliaryFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/AuxiliaryFactory.java
new file mode 100644 (file)
index 0000000..1620323
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/BorderSceneGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/BorderSceneGraph.java
new file mode 100644 (file)
index 0000000..96a3cd5
--- /dev/null
@@ -0,0 +1,43 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/CloudFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/CloudFactory.java
new file mode 100644 (file)
index 0000000..20da281
--- /dev/null
@@ -0,0 +1,174 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ComponentNameSynchronizer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ComponentNameSynchronizer.java
new file mode 100644 (file)
index 0000000..a1f14b3
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConfigurationDiagramClassAdapter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ConfigurationDiagramClassAdapter.java
new file mode 100644 (file)
index 0000000..6e4a945
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/GraphPropertyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/GraphPropertyNode.java
new file mode 100644 (file)
index 0000000..04d0674
--- /dev/null
@@ -0,0 +1,101 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverShapeNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverShapeNode.java
new file mode 100644 (file)
index 0000000..1db4490
--- /dev/null
@@ -0,0 +1,46 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementHandler.java
new file mode 100644 (file)
index 0000000..479a688
--- /dev/null
@@ -0,0 +1,43 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementNoBounds.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextElementNoBounds.java
new file mode 100644 (file)
index 0000000..e5b502d
--- /dev/null
@@ -0,0 +1,139 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/HoverTextNode.java
new file mode 100644 (file)
index 0000000..a55f754
--- /dev/null
@@ -0,0 +1,52 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Input.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Input.java
new file mode 100644 (file)
index 0000000..60f9a4c
--- /dev/null
@@ -0,0 +1,25 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/InputFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/InputFactory.java
new file mode 100644 (file)
index 0000000..43936fd
--- /dev/null
@@ -0,0 +1,210 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java
new file mode 100644 (file)
index 0000000..c542c1a
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/StockFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/StockFactory.java
new file mode 100644 (file)
index 0000000..44476a8
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementFactory.java
new file mode 100644 (file)
index 0000000..989380f
--- /dev/null
@@ -0,0 +1,128 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementHints.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementHints.java
new file mode 100644 (file)
index 0000000..ef69bf4
--- /dev/null
@@ -0,0 +1,10 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynElementUtils.java
new file mode 100644 (file)
index 0000000..dd82a3c
--- /dev/null
@@ -0,0 +1,20 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java
new file mode 100644 (file)
index 0000000..6c9123a
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/WholeElementTerminals.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/WholeElementTerminals.java
new file mode 100644 (file)
index 0000000..46296ae
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Arcs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Arcs.java
new file mode 100644 (file)
index 0000000..70092ac
--- /dev/null
@@ -0,0 +1,211 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/ConnectionClasses.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/ConnectionClasses.java
new file mode 100644 (file)
index 0000000..4d09067
--- /dev/null
@@ -0,0 +1,20 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Dependencies.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Dependencies.java
new file mode 100644 (file)
index 0000000..2fba130
--- /dev/null
@@ -0,0 +1,227 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyConnectionFactory.java
new file mode 100644 (file)
index 0000000..403aa41
--- /dev/null
@@ -0,0 +1,157 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeClass.java
new file mode 100644 (file)
index 0000000..140bd0d
--- /dev/null
@@ -0,0 +1,205 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyEdgeFactory.java
new file mode 100644 (file)
index 0000000..7713bdf
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/DependencyNode.java
new file mode 100644 (file)
index 0000000..a2a24a9
--- /dev/null
@@ -0,0 +1,97 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowConnectionFactory.java
new file mode 100644 (file)
index 0000000..57cc1fc
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeClass.java
new file mode 100644 (file)
index 0000000..6687459
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowEdgeFactory.java
new file mode 100644 (file)
index 0000000..e2926c7
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowNode.java
new file mode 100644 (file)
index 0000000..4b307b4
--- /dev/null
@@ -0,0 +1,76 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowStroke.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/FlowStroke.java
new file mode 100644 (file)
index 0000000..137d9c5
--- /dev/null
@@ -0,0 +1,18 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Flows.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/Flows.java
new file mode 100644 (file)
index 0000000..fc00fa7
--- /dev/null
@@ -0,0 +1,175 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/connections/SysdynConnectionClass.java
new file mode 100644 (file)
index 0000000..aad41db
--- /dev/null
@@ -0,0 +1,561 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java
new file mode 100644 (file)
index 0000000..ae407a9
--- /dev/null
@@ -0,0 +1,482 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionComposite.java
new file mode 100644 (file)
index 0000000..33ccb1e
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionTypeSelector.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ExpressionTypeSelector.java
new file mode 100644 (file)
index 0000000..383fff3
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/NameComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/NameComposite.java
new file mode 100644 (file)
index 0000000..bc95925
--- /dev/null
@@ -0,0 +1,149 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ShortcutTabs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/ShortcutTabs.java
new file mode 100644 (file)
index 0000000..8cba344
--- /dev/null
@@ -0,0 +1,136 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/UnitSelector.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/UnitSelector.java
new file mode 100644 (file)
index 0000000..b78edbd
--- /dev/null
@@ -0,0 +1,183 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/AuxiliaryExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/AuxiliaryExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..9a74a19
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ColorManager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ColorManager.java
new file mode 100644 (file)
index 0000000..5bbb339
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ConstantExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ConstantExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..1994fd0
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/DelayExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/DelayExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..debac67
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/EmptyExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/EmptyExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..0b0c170
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionField.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionField.java
new file mode 100644 (file)
index 0000000..f210154
--- /dev/null
@@ -0,0 +1,165 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionFieldConfiguration.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ExpressionFieldConfiguration.java
new file mode 100644 (file)
index 0000000..018028b
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/IExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/IExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..f7ac03b
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartInfo.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartInfo.java
new file mode 100644 (file)
index 0000000..237eff3
--- /dev/null
@@ -0,0 +1,63 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupChartPanel.java
new file mode 100644 (file)
index 0000000..c08fbf9
--- /dev/null
@@ -0,0 +1,152 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..97841d9
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupInputOutputTable.java
new file mode 100644 (file)
index 0000000..585ac91
--- /dev/null
@@ -0,0 +1,202 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/LookupPopup.java
new file mode 100644 (file)
index 0000000..57b2904
--- /dev/null
@@ -0,0 +1,435 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ParameterExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/ParameterExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..fe23484
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/StockExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/StockExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..ac8b745
--- /dev/null
@@ -0,0 +1,208 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/expressions/WithLookupExpressionViewFactor.java
new file mode 100644 (file)
index 0000000..43218e0
--- /dev/null
@@ -0,0 +1,221 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateAuxiliaryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateAuxiliaryHandler.java
new file mode 100644 (file)
index 0000000..cc32ba4
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateCloudHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateCloudHandler.java
new file mode 100644 (file)
index 0000000..2beded5
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateStockHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateStockHandler.java
new file mode 100644 (file)
index 0000000..2716596
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateValveHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/CreateValveHandler.java
new file mode 100644 (file)
index 0000000..e4fe83b
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramContextMenuActionHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramContextMenuActionHandler.java
new file mode 100644 (file)
index 0000000..b13abfa
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DisposeExperiment.java
new file mode 100644 (file)
index 0000000..13bc387
--- /dev/null
@@ -0,0 +1,35 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..3b101a2
--- /dev/null
@@ -0,0 +1,47 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java
new file mode 100644 (file)
index 0000000..b4c6265
--- /dev/null
@@ -0,0 +1,76 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModuleNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModuleNodeHandler.java
new file mode 100644 (file)
index 0000000..cd1484e
--- /dev/null
@@ -0,0 +1,95 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveHandler.java
new file mode 100644 (file)
index 0000000..b5edcc2
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RemoveNodeHandler.java
new file mode 100644 (file)
index 0000000..2ac9756
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameHandler.java
new file mode 100644 (file)
index 0000000..a187806
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java
new file mode 100644 (file)
index 0000000..7e836b5
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RunBasicExperiment.java
new file mode 100644 (file)
index 0000000..8b81ffc
--- /dev/null
@@ -0,0 +1,47 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveResultsHandler.java
new file mode 100644 (file)
index 0000000..9d7beed
--- /dev/null
@@ -0,0 +1,24 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ShowModuleHandler.java
new file mode 100644 (file)
index 0000000..eff51ec
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java
new file mode 100644 (file)
index 0000000..85823f8
--- /dev/null
@@ -0,0 +1,172 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultActivation.java
new file mode 100644 (file)
index 0000000..3a470de
--- /dev/null
@@ -0,0 +1,55 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler.java
new file mode 100644 (file)
index 0000000..171007a
--- /dev/null
@@ -0,0 +1,138 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java
new file mode 100644 (file)
index 0000000..bd81f37
--- /dev/null
@@ -0,0 +1,40 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java
new file mode 100644 (file)
index 0000000..5c385fd
--- /dev/null
@@ -0,0 +1,96 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/ModelicaSourceViewerConfiguration.java
new file mode 100644 (file)
index 0000000..c27ebaa
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/SysdynModelicaEditor.java
new file mode 100644 (file)
index 0000000..6547280
--- /dev/null
@@ -0,0 +1,112 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/modelica/TextEditorActionBarContributor.java
new file mode 100644 (file)
index 0000000..9c090cf
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultRealizationVirtualGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultRealizationVirtualGraph.java
new file mode 100644 (file)
index 0000000..7a07c88
--- /dev/null
@@ -0,0 +1,34 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/DefaultVariable.java
new file mode 100644 (file)
index 0000000..909cab6
--- /dev/null
@@ -0,0 +1,55 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryRealizationVirtualGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryRealizationVirtualGraph.java
new file mode 100644 (file)
index 0000000..aa398ee
--- /dev/null
@@ -0,0 +1,110 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/HistoryVariable.java
new file mode 100644 (file)
index 0000000..b686274
--- /dev/null
@@ -0,0 +1,52 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynPerspectiveFactory.java
new file mode 100644 (file)
index 0000000..15371b0
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProject.java
new file mode 100644 (file)
index 0000000..2b18c8d
--- /dev/null
@@ -0,0 +1,164 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProjectLifeCycle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynProjectLifeCycle.java
new file mode 100644 (file)
index 0000000..7b26b65
--- /dev/null
@@ -0,0 +1,238 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ConfigurationTab.java
new file mode 100644 (file)
index 0000000..cc061e9
--- /dev/null
@@ -0,0 +1,86 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java
new file mode 100644 (file)
index 0000000..30eebee
--- /dev/null
@@ -0,0 +1,30 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EquationTab.java
new file mode 100644 (file)
index 0000000..8e43dd3
--- /dev/null
@@ -0,0 +1,240 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExperimentTab.java
new file mode 100644 (file)
index 0000000..1db9ef9
--- /dev/null
@@ -0,0 +1,16 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/InputVariableTab.java
new file mode 100644 (file)
index 0000000..4cba9ab
--- /dev/null
@@ -0,0 +1,70 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LookupTableTab.java
new file mode 100644 (file)
index 0000000..0fb17cf
--- /dev/null
@@ -0,0 +1,77 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModelTab.java
new file mode 100644 (file)
index 0000000..235c34c
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleInputTab.java
new file mode 100644 (file)
index 0000000..f8fccc7
--- /dev/null
@@ -0,0 +1,78 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleOutputTab.java
new file mode 100644 (file)
index 0000000..a12623a
--- /dev/null
@@ -0,0 +1,79 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTab.java
new file mode 100644 (file)
index 0000000..bcf9047
--- /dev/null
@@ -0,0 +1,28 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleTypeTab.java
new file mode 100644 (file)
index 0000000..ef01992
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ReferenceDependencyTab.java
new file mode 100644 (file)
index 0000000..56fa104
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResourceSelectionProcessor.java
new file mode 100644 (file)
index 0000000..267cae3
--- /dev/null
@@ -0,0 +1,147 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ResultTab.java
new file mode 100644 (file)
index 0000000..fc25355
--- /dev/null
@@ -0,0 +1,15 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynPropertyPage.java
new file mode 100644 (file)
index 0000000..9f3e56f
--- /dev/null
@@ -0,0 +1,23 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/VariableInformationTab.java
new file mode 100644 (file)
index 0000000..8a3e3fa
--- /dev/null
@@ -0,0 +1,96 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartTableWidget.java
new file mode 100644 (file)
index 0000000..b0e6e63
--- /dev/null
@@ -0,0 +1,231 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ChartWidget.java
new file mode 100644 (file)
index 0000000..2f3aa63
--- /dev/null
@@ -0,0 +1,221 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionTypes.java
new file mode 100644 (file)
index 0000000..3741a34
--- /dev/null
@@ -0,0 +1,88 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ExpressionWidget.java
new file mode 100644 (file)
index 0000000..94643af
--- /dev/null
@@ -0,0 +1,160 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/IsOutputWidget.java
new file mode 100644 (file)
index 0000000..2c90f66
--- /dev/null
@@ -0,0 +1,91 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleInputEditingSupport.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleInputEditingSupport.java
new file mode 100644 (file)
index 0000000..1031a79
--- /dev/null
@@ -0,0 +1,126 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleOutputEditingSupport.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ModuleOutputEditingSupport.java
new file mode 100644 (file)
index 0000000..50da2db
--- /dev/null
@@ -0,0 +1,126 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRow.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRow.java
new file mode 100644 (file)
index 0000000..d3e4f8a
--- /dev/null
@@ -0,0 +1,100 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRowLabelProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceRowLabelProvider.java
new file mode 100644 (file)
index 0000000..93668d2
--- /dev/null
@@ -0,0 +1,26 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceTable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ReferenceTable.java
new file mode 100644 (file)
index 0000000..32bb833
--- /dev/null
@@ -0,0 +1,121 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/RowProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/RowProvider.java
new file mode 100644 (file)
index 0000000..4c1bce7
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java
new file mode 100644 (file)
index 0000000..b43486c
--- /dev/null
@@ -0,0 +1,143 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/AuxiliaryExpression.java
new file mode 100644 (file)
index 0000000..2f4c190
--- /dev/null
@@ -0,0 +1,26 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/BasicExpression.java
new file mode 100644 (file)
index 0000000..fe27bb3
--- /dev/null
@@ -0,0 +1,150 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ColorManager.java
new file mode 100644 (file)
index 0000000..9a733b9
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ConstantExpression.java
new file mode 100644 (file)
index 0000000..a0b5254
--- /dev/null
@@ -0,0 +1,25 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/DelayExpression.java
new file mode 100644 (file)
index 0000000..8c9eb5d
--- /dev/null
@@ -0,0 +1,74 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/EmptyExpression.java
new file mode 100644 (file)
index 0000000..f2a99fd
--- /dev/null
@@ -0,0 +1,74 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionField.java
new file mode 100644 (file)
index 0000000..d564d06
--- /dev/null
@@ -0,0 +1,187 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionFieldConfiguration.java
new file mode 100644 (file)
index 0000000..68d46d8
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionValidation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionValidation.java
new file mode 100644 (file)
index 0000000..5c8a2cd
--- /dev/null
@@ -0,0 +1,132 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/IExpression.java
new file mode 100644 (file)
index 0000000..6c8c152
--- /dev/null
@@ -0,0 +1,33 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupChartPanel.java
new file mode 100644 (file)
index 0000000..6258aea
--- /dev/null
@@ -0,0 +1,165 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupExpression.java
new file mode 100644 (file)
index 0000000..4bb7fb3
--- /dev/null
@@ -0,0 +1,74 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/LookupInputOutputTable.java
new file mode 100644 (file)
index 0000000..6010421
--- /dev/null
@@ -0,0 +1,259 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java
new file mode 100644 (file)
index 0000000..7cc116d
--- /dev/null
@@ -0,0 +1,29 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java
new file mode 100644 (file)
index 0000000..6d357d7
--- /dev/null
@@ -0,0 +1,217 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/WithLookupExpression.java
new file mode 100644 (file)
index 0000000..8d9afd0
--- /dev/null
@@ -0,0 +1,369 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyFactory.java
new file mode 100644 (file)
index 0000000..7727d14
--- /dev/null
@@ -0,0 +1,32 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/DoublePropertyModifier.java
new file mode 100644 (file)
index 0000000..5a2f5a7
--- /dev/null
@@ -0,0 +1,23 @@
+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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/sg/SysdynSceneGraphProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/sg/SysdynSceneGraphProvider.java
new file mode 100644 (file)
index 0000000..be4a507
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PinTrend.java
new file mode 100644 (file)
index 0000000..ee6b75e
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java
new file mode 100644 (file)
index 0000000..b9179b9
--- /dev/null
@@ -0,0 +1,277 @@
+/*******************************************************************************\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