]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Create a new branch for BPMN import prototype
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 4 Sep 2014 11:03:32 +0000 (11:03 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 4 Sep 2014 11:03:32 +0000 (11:03 +0000)
refs #5197

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches/bpmn-import@30210 ac1ea38d-2e2b-0410-8846-a27921b304fc

606 files changed:
org.simantics.sysdyn.ui/.classpath [new file with mode: 0644]
org.simantics.sysdyn.ui/.hgignore [new file with mode: 0644]
org.simantics.sysdyn.ui/.project [new file with mode: 0644]
org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.simantics.sysdyn.ui/META-INF/MANIFEST.MF [new file with mode: 0644]
org.simantics.sysdyn.ui/adapters.xml [new file with mode: 0644]
org.simantics.sysdyn.ui/build.properties [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/box.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/brick.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/brick_link.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/bricks.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/bullet_gray.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/bullet_green.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_bar.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_bar_3.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_bar_light.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_line.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_line_light.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_organisation.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_pie.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/chart_pie_light.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/close.gif [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_fastforward.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_fastforward_blue.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_pause.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_pause_blue.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_play.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_play_blue.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_step.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/control_step_blue.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/cursor.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/dependency.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/dependency_old.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/equalizer.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/error.svg [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/error_decoration.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/fatal.svg [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/fatal_decoration.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/flow.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/flow_old.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/folder.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/folder_link.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/function.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/functionLink.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/maximize.gif [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/minimize.gif [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/modelicaFunction.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/page_white_text.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/page_white_text_width.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/rainbow.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/save_as.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn128.xcf [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn16.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn32.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn48.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/simantics_sysdyn64.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/sysdyn.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/sysdyn32.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/sysdynFunction.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/table.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/table_multiple.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/table_multiple_pinned.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/time.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/time_go.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/time_rainbow.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/timeline_marker.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/variable.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/variableGray.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/vensimFunction.png [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/warning.svg [new file with mode: 0644]
org.simantics.sysdyn.ui/icons/warning_decoration.png [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/Simantics_sysdyn_logo2.blend [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/Simantics_sysdyn_text.png [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/Splash.xcf [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/sysdyn.png [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.png [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.xcf [new file with mode: 0644]
org.simantics.sysdyn.ui/logo/sysdyn_with_arrows_and_orange_bg.xcf [new file with mode: 0644]
org.simantics.sysdyn.ui/plugin.properties [new file with mode: 0644]
org.simantics.sysdyn.ui/plugin.xml [new file with mode: 0644]
org.simantics.sysdyn.ui/plugin_customization.ini [new file with mode: 0644]
org.simantics.sysdyn.ui/splash.bmp [new file with mode: 0644]
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/PropertyViewUndoHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.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/SysdynModelBrowser.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.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/AnnotationContribution.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationContribution2.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationTypeImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationTypeLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.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/FunctionLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditionLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditions.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditionsLabeler.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/LibraryContribution.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryFunctions.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryLabeler.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/ModuleLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleType.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/SCLModuleLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModulesLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.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/SimulationResultSet.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetDecorator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SysdynProject.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/imagerules/ChartImageRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationType.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationValue.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.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/EnumerationNode.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/ExportTester.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialCondition.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialConditionsFolder.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/Library.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.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/PieChartNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedOntologyNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.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/SimulationResultSetNode.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/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/OpenDiagramFromComponentAdapter.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/SysdynEditorInput.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/BorderSceneGraph.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ComponentNameSynchronizer.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverShapeNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Input.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopClockwise.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyConnectionFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowConnectionFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/IssueDecorationStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/AssignIC.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.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/EnumerationIndexRenameNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExportSharedOntologyHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewAnnotationTypeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewAnnotationValueHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewLibraryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewSCLModuleHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialDialog.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.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/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/SaveHistoryDialog.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveHistoryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveICHandler.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/SynthesisSimulation.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/ToggleResultSetActivation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleSimulation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler2.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/ReloadGameExperimentHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportBPMNHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportSharedLibraryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/ToggleSimulation.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.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/listeners/SysdynPlaybackExperimentListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.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/preferences/ModelicaPreferencePage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.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/SysdynTrendPerspectiveFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/CommentTab.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/EnumerationTab.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/ExternalFilesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.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/LoopTab.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/ModuleParameterTab.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/PlaybackExperimentTab.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/RemoveFocusBeforeExperimentComposite.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/SensitivityAnalysisExperimentTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.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/ArrayExpressionCombo.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.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/ColumnKeys.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.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/FontModifyListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.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/ShortcutTabWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexes.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.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/CompletionProcessor.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/ExpressionComposite.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/ExpressionWidgetInput.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/externalFiles/ExternalFileImager.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.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/properties/widgets/factories/FunctionLibraryNameInputValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyModifier.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleOutputEditingSupport.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRowLabelProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceTable.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/RowProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/DistributionPropertyWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.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/SensitivityChartAxisAndVariablesTab.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SharedFunctionLibraryNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SheetNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SyntaxError.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModelLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraryLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ImportWizardFunction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModulesLabeler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java [new file with mode: 0644]
org.simantics.sysdyn.ui/sysdyn.product [new file with mode: 0644]

diff --git a/org.simantics.sysdyn.ui/.classpath b/org.simantics.sysdyn.ui/.classpath
new file mode 100644 (file)
index 0000000..8a8f166
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.simantics.sysdyn.ui/.hgignore b/org.simantics.sysdyn.ui/.hgignore
new file mode 100644 (file)
index 0000000..73df90f
--- /dev/null
@@ -0,0 +1,5 @@
+syntax: regexp\r
+^bin/\r
+\r
+syntax: glob\r
+*.svn/*
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/.project b/org.simantics.sysdyn.ui/.project
new file mode 100644 (file)
index 0000000..2ebd569
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.sysdyn.ui</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs b/org.simantics.sysdyn.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..f287d53
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6\r
+org.eclipse.jdt.core.compiler.compliance=1.6\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.6\r
diff --git a/org.simantics.sysdyn.ui/META-INF/MANIFEST.MF b/org.simantics.sysdyn.ui/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..790eeb2
--- /dev/null
@@ -0,0 +1,72 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics System Dynamics UI
+Bundle-SymbolicName: org.simantics.sysdyn.ui;singleton:=true
+Bundle-Version: 1.8.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.simantics.layer0.utils;bundle-version="0.6.2",
+ org.simantics.scenegraph;bundle-version="0.9.0",
+ org.junit4;bundle-version="4.5.0";resolution:=optional,
+ org.simantics.ui;bundle-version="1.0.0",
+ org.eclipse.ui;bundle-version="3.5.0",
+ org.eclipse.core.runtime;bundle-version="3.5.0",
+ org.simantics.objmap;bundle-version="0.1.0",
+ org.simantics.sysdyn;bundle-version="1.0.0",
+ org.simantics.project;bundle-version="1.0.0",
+ org.eclipse.jface.text;bundle-version="3.5.0",
+ org.eclipse.ui.editors;bundle-version="3.5.0",
+ org.jfree.jcommon;bundle-version="1.0.16",
+ org.jfree.jchart;bundle-version="1.0.13",
+ org.simantics.modelica;bundle-version="1.0.0",
+ org.apache.log4j;bundle-version="1.2.15",
+ org.eclipse.ui.console;bundle-version="3.4.0",
+ org.simantics.browsing.ui.graph;bundle-version="1.1.0",
+ org.simantics.browsing.ui.swt;bundle-version="1.1.0",
+ org.simantics.modeling.ui;bundle-version="1.0.0",
+ org.eclipse.ui.cheatsheets,
+ org.simantics.graphviz.ui;bundle-version="1.0.0",
+ org.simantics.graphviz;bundle-version="1.0.0",
+ org.simantics.diagram;bundle-version="0.9.4",
+ org.simantics.modeling;bundle-version="1.0.0",
+ org.simantics.mapping;bundle-version="1.0.0",
+ org.simantics.structural.ontology;bundle-version="1.0.0",
+ gnu.trove2;bundle-version="2.0.4",
+ org.simantics.simulation;bundle-version="1.0.0",
+ org.simantics.message;bundle-version="0.9.0",
+ org.simantics.structural2;bundle-version="1.0.0",
+ org.simantics.layer0;bundle-version="1.0.0",
+ org.simantics.diagram.ontology;bundle-version="1.0.0",
+ org.simantics.graph;bundle-version="1.0.2",
+ org.simantics.graph.db;bundle-version="1.0.0",
+ org.simantics.structural.ui;bundle-version="1.1.1",
+ org.simantics.browsing.ui.model;bundle-version="1.0.0",
+ org.simantics.spreadsheet.ui;bundle-version="1.1.0",
+ org.simantics.views.swt;bundle-version="1.0.0",
+ org.simantics.selectionview;bundle-version="1.0.0",
+ org.simantics.issues;bundle-version="1.1.0",
+ org.simantics.issues.ui;bundle-version="1.1.0",
+ org.simantics.issues.common;bundle-version="1.1.0",
+ org.simantics.scenegraph.profile;bundle-version="1.0.0",
+ org.simantics.trend;bundle-version="1.0.0",
+ org.simantics.history;bundle-version="1.0.0",
+ org.simantics.utils.thread.swt;bundle-version="1.1.0",
+ org.simantics.jfreechart.ontology;bundle-version="0.1.0",
+ org.eclipse.ui.forms;bundle-version="3.5.2",
+ org.simantics.scenegraph.swing;bundle-version="1.0.0",
+ org.eclipse.nebula.widgets.tablecombo;bundle-version="1.0.0",
+ org.simantics.fmu;bundle-version="1.0.0",
+ org.simantics.jfreechart;bundle-version="1.0.0",
+ org.simantics.db.indexing;bundle-version="1.1.0",
+ org.simantics.workbench,
+ org.simantics.annotation.ui;bundle-version="1.0.0",
+ org.simantics.annotation.ontology;bundle-version="1.0.0",
+ org.simantics.spreadsheet.common;bundle-version="1.1.0"
+Bundle-Activator: org.simantics.sysdyn.ui.Activator
+Bundle-ActivationPolicy: lazy
+Export-Package: org.simantics.sysdyn.ui.browser.nodes
+Bundle-Vendor: VTT Technical Reserarch Centre of Finland
+Bundle-Localization: plugin
+Import-Package: freemarker.template,
+ org.simantics.workbench,
+ org.simantics.workbench.ontology,
+ org.simantics.workbench.search
diff --git a/org.simantics.sysdyn.ui/adapters.xml b/org.simantics.sysdyn.ui/adapters.xml
new file mode 100644 (file)
index 0000000..517bc7e
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>\r<!--\r
+    Copyright (c) 2010 Association for Decentralized Information Management in\r
+    Industry THTH ry.\r
+    All rights reserved. This program and the accompanying materials\r
+    are made available under the terms of the Eclipse Public License v1.0\r
+    which accompanies this distribution, and is available at\r
+    http://www.eclipse.org/legal/epl-v10.html\r
+   \r
+    Contributors:\r
+        VTT Technical Research Centre of Finland - initial API and implementation\r
+ -->\r
+
+<adapters>\r\r   <target interface="org.simantics.db.layer0.adapter.Realization">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/Module"\r                 class="org.simantics.structural2.realization.StructuralRealization">\r                   <this />\r               </type>\r        </target>\r\r     <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-0.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r      \r       <target interface="org.simantics.structural.ui.modelBrowser.nodes.AbstractNode">\r               <type uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                    class="org.simantics.structural.ui.modelBrowser.nodes.ModelNode">\r                      <this />\r               </type>\r        </target>               \r               \r\r      <target\r                interface="org.simantics.browsing.ui.common.node.AbstractNode">\r                <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/SysdynModel"\r                  class="org.simantics.sysdyn.ui.browser.nodes.ModelNode">\r                       <this />\r               </type>\r\r               <resource\r                      uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                 class="org.simantics.sysdyn.ui.browser.nodes.SymbolNode">\r                      <this />\r               </resource>\r\r           <type\r                  uri="http://www.simantics.org/Simulation-0.0/Experiment"\r                       class="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode">\r                  <this />\r               </type>\r                \r               <type\r                  uri="http://www.simantics.org/Sysdyn-0.0/Result"\r                       class="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode">\r                    <this />\r               </type>\r                \r       </target>\r\r     <!-- Inject default connection routing algorithm for sysdyn diagrams -->\r       <target interface="org.simantics.g2d.diagram.DiagramClass">\r            <adapter uri="http://www.simantics.org/Sysdyn-0.0/ConfigurationDiagram"\r                        adapterClass="org.simantics.sysdyn.ui.elements.ConfigurationDiagramClassAdapter" />\r    </target>\r\r     <!-- Sysdyn symbols -->\r        <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                        class="org.simantics.sysdyn.ui.elements.StockFactory" />\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                       class="org.simantics.sysdyn.ui.elements.ModuleFactory" />\r              <resource uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                        class="org.simantics.sysdyn.ui.elements.ValveFactory" />\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                    class="org.simantics.sysdyn.ui.elements.AuxiliaryFactory" />\r           <resource uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                        class="org.simantics.sysdyn.ui.elements.CloudFactory" />\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                        class="org.simantics.sysdyn.ui.elements.InputFactory" />\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/ShadowSymbol"\r                       class="org.simantics.sysdyn.ui.elements.ShadowFactory" />                       \r               <resource uri="http://www.simantics.org/Sysdyn-0.0/LoopSymbol"\r                 class="org.simantics.sysdyn.ui.elements.LoopFactory" />                 \r\r              <type uri="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r                    class="org.simantics.sysdyn.ui.elements.StockFactory" />\r               <type uri="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r                   class="org.simantics.sysdyn.ui.elements.ModuleFactory" />\r              <type uri="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r                    class="org.simantics.sysdyn.ui.elements.ValveFactory" />\r               <type uri="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r                        class="org.simantics.sysdyn.ui.elements.AuxiliaryFactory" />\r           <type uri="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r                    class="org.simantics.sysdyn.ui.elements.CloudFactory" />\r               <type uri="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r                    class="org.simantics.sysdyn.ui.elements.InputFactory" />        \r               <type uri="http://www.simantics.org/Sysdyn-0.0/ShadowSymbol"\r                   class="org.simantics.sysdyn.ui.elements.ShadowFactory" />       \r               <type uri="http://www.simantics.org/Sysdyn-0.0/LoopSymbol"\r                     class="org.simantics.sysdyn.ui.elements.LoopFactory" /> \r       </target>\r      \r       <!-- Additional symbols -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r          <resource uri="http://www.simantics.org/Sysdyn-0.0/AdditionalSymbols/MultilineText"\r            class="org.simantics.sysdyn.ui.elements.MultilineTextElementFactory" />\r        <type uri="http://www.simantics.org/Sysdyn-0.0/AdditionalSymbols/MultilineText"\r            class="org.simantics.sysdyn.ui.elements.MultilineTextElementFactory" />         \r    </target>                  \r       \r       <!-- Sysdyn connections -->\r    <target interface="org.simantics.diagram.adapter.ElementFactory">\r              <!-- Edges -->       \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements.connections.RouteFlowEdgeFactory" />\r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements.connections.RouteFlowEdgeFactory" />            \r        <type uri="http://www.simantics.org/Sysdyn-0.0/FlowConnection"\r            class="org.simantics.sysdyn.ui.elements.connections.RouteFlowConnectionFactory">\r            <graph/>\r        </type>                          \r                       \r               <resource uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                       class="org.simantics.sysdyn.ui.elements.connections.DependencyEdgeFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements.connections.DependencyEdgeFactory" />\r          <type uri="http://www.simantics.org/Sysdyn-0.0/DependencyConnection"\r                   class="org.simantics.sysdyn.ui.elements.connections.DependencyConnectionFactory" />\r    </target>\r      \r       <target interface="org.simantics.g2d.connection.EdgeVisualsConfigurer">\r          <baseType uri="http://www.simantics.org/Diagram-0.0/HasConnector" />\r   <resource uri="http://www.simantics.org/Diagram-0.0/HasPlainConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>none 0</string>\r       </resource>\r    <resource uri="http://www.simantics.org/Diagram-0.0/HasArrowConnector"\r          class="org.simantics.diagram.content.ArrowConfigurer">\r         <string>fill 1</string>\r       </resource>\r  </target>\r      \r       <!-- ModelBrowser2 -->\r \r       <target interface="org.simantics.browsing.ui.model.children.ChildRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ModuleTypeChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleTypeChildRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ModuleContentChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.ModuleContentChildRule"/>              \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/VariableChildRule"\r            class="org.simantics.sysdyn.ui.browser.childrules.VariableChildRule"/>                  \r                  \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/HistoryDataset/HistoryDatasetVariablesBrowseContext/VariableChildRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.historyDataset.VariableChildRule"/>     \r        <resource uri=" http://www.simantics.org/Sysdyn-0.0/Module/ParameterOverrideBrowseContext/ParameterChildRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.modules.ParameterChildRule"/>              \r            \r            \r       <!-- Sensitivity analysis -->\r      <resource uri="http://www.simantics.org/Sysdyn-0.0/SensitivityAnalysisExperiment/ParameterBrowseContext/ParameterChildRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.ParameterChildRule"/>         \r    </target>\r    \r    <target interface="org.simantics.browsing.ui.model.visuals.VisualsRule">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ModuleTypeLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.ModuleTypeLabelRule"/>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/VariableNameLabelRule"\r            class="org.simantics.sysdyn.ui.browser.labelrules.VariableNameLabelRule"/>\r\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/VariableImageRule"\r            class="org.simantics.sysdyn.ui.browser.imagerules.VariableImageRule"/>   \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ChartImageRule"\r            class="org.simantics.sysdyn.ui.browser.imagerules.ChartImageRule"/>      \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ResultImageRule"\r            class="org.simantics.sysdyn.ui.browser.imagerules.ResultImageRule"/>                        \r            \r  \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/HistoryDataset/HistoryDatasetVariablesBrowseContext/VariableLabelRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.historyDataset.VariableLabelRule"/>                \r\r            \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/Module/ParameterOverrideBrowseContext/ParameterLabelRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.modules.ParameterLabelRule"/>    \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/Module/ParameterOverrideBrowseContext/ParameterLabelDecorationRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.modules.ParameterLabelDecorationRule"/>               \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/Module/ParameterOverrideBrowseContext/ParameterModifierRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.modules.ParameterModifierRule"/>    \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/Module/ParameterOverrideBrowseContext/ParameterSorterRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.modules.ParameterSorterRule"/>      \r            \r    <!-- Sensitivity analysis -->\r      <resource uri="http://www.simantics.org/Sysdyn-0.0/SensitivityAnalysisExperiment/ParameterBrowseContext/ParameterLabelRule"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.ParameterLabelRule"/>\r\r    </target>    \r    \r    <target interface="org.simantics.db.layer0.adapter.ActionFactory">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewModuleType"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewModuleTypeAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewEnumeration"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewEnumerationAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewFunction"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewFunctionAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewFunctionLibraryAction" />\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewSharedFunctionLibrary"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewSharedFunctionLibraryAction" />   \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewExperiment"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewExperimentAction" />   \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewSimulationPlaybackExperiment"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewSimulationPlaybackExperimentAction" />    \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewLineChart"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewLineChartAction" /> \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewBarChart"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewBarChartAction" /> \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewPieChart"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewPieChartAction" />        \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewSheet"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewSheetAction" />       \r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/NewHistoryData"\r            class="org.simantics.sysdyn.ui.browser.actions.newActions.NewHistoryDataAction" />                                                                                              \r    </target>         \r    \r   <target interface="org.simantics.db.layer0.adapter.DropActionFactory">\r        <resource\r            uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/FunctionDropAction"\r            class="org.simantics.sysdyn.ui.browser.actions.drop.FunctionDropAction" />\r        <resource\r            uri="http://www.simantics.org/Sysdyn-0.0/ModelingActionContext/Actions/ChartDropAction"\r            class="org.simantics.sysdyn.ui.browser.actions.drop.ChartDropAction" />            \r   \r                    \r    </target>     \r  \r    <target interface="org.simantics.db.layer0.adapter.Remover">\r        <type uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ModuleSymbol"\r            class="org.simantics.sysdyn.ui.browser.actions.remove.ModuleTypeRemover">\r            <graph />\r            <this />\r        </type>\r        <type uri="http://www.simantics.org/Sysdyn-0.0/Variable"\r            class="org.simantics.sysdyn.ui.actions.SysdynVariableRemover">\r            <this />\r        </type>\r    </target>\r    \r    \r    <target interface="org.simantics.browsing.ui.model.nodetypes.NodeType">\r        <baseType uri="http://www.simantics.org/Layer0-0.0/Entity" />\r        <type\r            uri="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext/ModuleSymbolNodeType"\r            class="org.simantics.sysdyn.ui.browser.nodeTypes.ModuleSymbolNodeType"\r            constructor="create">\r            <this/>\r        </type>        \r     </target>\r    \r  <!-- PROFILES -->\r    <target interface="org.simantics.scenegraph.profile.Style">\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/SimulationPlaybackStyle"\r            class="org.simantics.sysdyn.ui.elements.profiles.SimulationPlaybackStyle">\r        </resource>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/IssueStyle"\r            class="org.simantics.sysdyn.ui.elements.profiles.IssueDecorationStyle">\r        </resource>\r        <resource uri="http://www.simantics.org/Sysdyn-0.0/ShadowStyle"\r            class="org.simantics.sysdyn.ui.elements.profiles.ShadowStyle">\r        </resource>        \r    </target>\r    \r \r    <!--  TODO: currently maps jfree concepts directly to Sysdyn implementations. Sysdyn needs tool specific types for the datasets. -->\r    <!--  TODO: AllVariablesOfModel query is run on random Resources; listing all possible types explicitly is cumbersome, we need a better implementation. -->\r    <target interface="org.simantics.jfreechart.chart.properties.IAllVariablesOfModel">  \r        <type uri="http://www.simantics.org/Sysdyn-1.1/SysdynModel"\r            class="org.simantics.sysdyn.ui.trend.AllVariablesOfModel">\r            <this />\r        </type>  \r        <type uri="http://www.simantics.org/JFreeChart-1.0/NumberAxis"\r            class="org.simantics.sysdyn.ui.trend.AllVariablesOfModel">\r            <this />\r        </type>   \r        <type uri="http://www.simantics.org/JFreeChart-1.0/Series"\r            class="org.simantics.sysdyn.ui.trend.AllVariablesOfModel">\r            <this />\r        </type>      \r        <type uri="http://www.simantics.org/Sysdyn-0.0/SensitivityAnalysisExperiment/Parameter"\r            class="org.simantics.sysdyn.ui.trend.AllParametersOfModel">\r            <this />\r        </type>\r    </target> \r       \r    <target interface="org.simantics.jfreechart.chart.properties.RangeHandlerFactory">  \r        <type uri="http://www.simantics.org/JFreeChart-1.0/Series"\r            class="org.simantics.sysdyn.ui.trend.SysdynRangeHandlerFactory">\r        </type>    \r        <type uri="http://www.simantics.org/Sysdyn-0.0/SensitivityAnalysisExperiment/Parameter"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.SensitivityRangeHandlerFactory">\r        </type>\r    </target> \r    \r    <!--  TODO: currently maps jfree concepts directly to Sysdyn implementations. Sysdyn needs tool specific types for the datasets. -->\r     <target interface="org.simantics.jfreechart.chart.IDataset">\r        <type uri="http://www.simantics.org/JFreeChart-0.0/XYDataset"\r            class="org.simantics.sysdyn.ui.trend.XYDataset">\r            <graph />\r            <this />\r        </type>\r        <type uri="http://www.simantics.org/JFreeChart-0.0/CategoryDataset"\r            class="org.simantics.sysdyn.ui.trend.CategoryDataset">\r            <graph />\r            <this />\r        </type>        \r        <type uri="http://www.simantics.org/JFreeChart-0.0/PieDataset"\r            class="org.simantics.sysdyn.ui.trend.PieDataset">\r            <graph />\r            <this />\r        </type>   \r        <type uri="http://www.simantics.org/Sysdyn-0.0/Charts/SensitivityDataset"\r            class="org.simantics.sysdyn.ui.trend.SensitivityDataset">\r            <graph />\r            <this />\r        </type>\r    </target>\r    \r       <!-- Sensitivity analysis -->\r   <target\r        interface="org.simantics.sysdyn.ui.properties.widgets.sensitivity.IDistributionProperties">\r        <type\r            uri="http://www.simantics.org/Sysdyn-0.0/NormalDistribution"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.NormalDistributionProperties">\r            <this />\r        </type>       \r        <type\r            uri="http://www.simantics.org/Sysdyn-0.0/UniformDistribution"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.UniformDistributionProperties">\r            <this />\r        </type> \r        <type\r            uri="http://www.simantics.org/Sysdyn-0.0/Interval"\r            class="org.simantics.sysdyn.ui.properties.widgets.sensitivity.IntervalProperties">\r            <this />\r        </type>\r    </target>\r    \r    <!-- Search -->\r       <target interface="org.simantics.scl.runtime.function.Function">\r               <resource uri="http://www.simantics.org/Sysdyn-0.0/ModulesSearchFunction"\r                      class="org.simantics.sysdyn.ui.function.ModulesSearchFunction">\r                </resource>\r    </target>\r    \r
+</adapters>
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/build.properties b/org.simantics.sysdyn.ui/build.properties
new file mode 100644 (file)
index 0000000..258de40
--- /dev/null
@@ -0,0 +1,21 @@
+###############################################################################\r
+# Copyright (c) 2010 Association for Decentralized Information Management in\r
+# Industry THTH ry.\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Eclipse Public License v1.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.eclipse.org/legal/epl-v10.html\r
+#\r
+# Contributors:\r
+#     VTT Technical Research Centre of Finland - initial API and implementation\r
+###############################################################################\r
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               plugin.xml,\\r
+               adapters.xml,\\r
+               icons/,\\r
+               splash.bmp,\\r
+               plugin.properties,\\r
+               plugin_customization.ini\r
diff --git a/org.simantics.sysdyn.ui/icons/box.png b/org.simantics.sysdyn.ui/icons/box.png
new file mode 100644 (file)
index 0000000..8443c23
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/box.png differ
diff --git a/org.simantics.sysdyn.ui/icons/brick.png b/org.simantics.sysdyn.ui/icons/brick.png
new file mode 100644 (file)
index 0000000..7851cf3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/brick.png differ
diff --git a/org.simantics.sysdyn.ui/icons/brick_link.png b/org.simantics.sysdyn.ui/icons/brick_link.png
new file mode 100644 (file)
index 0000000..9ebf013
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/brick_link.png differ
diff --git a/org.simantics.sysdyn.ui/icons/bricks.png b/org.simantics.sysdyn.ui/icons/bricks.png
new file mode 100644 (file)
index 0000000..0905f93
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/bricks.png differ
diff --git a/org.simantics.sysdyn.ui/icons/bullet_gray.png b/org.simantics.sysdyn.ui/icons/bullet_gray.png
new file mode 100644 (file)
index 0000000..6f58b93
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/bullet_gray.png differ
diff --git a/org.simantics.sysdyn.ui/icons/bullet_green.png b/org.simantics.sysdyn.ui/icons/bullet_green.png
new file mode 100644 (file)
index 0000000..1b5409f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/bullet_green.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_bar.png b/org.simantics.sysdyn.ui/icons/chart_bar.png
new file mode 100644 (file)
index 0000000..9051fbc
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_bar.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_bar_3.png b/org.simantics.sysdyn.ui/icons/chart_bar_3.png
new file mode 100644 (file)
index 0000000..15b7cae
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_bar_3.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png b/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png
new file mode 100644 (file)
index 0000000..0e23ab3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_bar_3_blackAndWhite.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png b/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png
new file mode 100644 (file)
index 0000000..087f88c
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_bar_blackAndWhite.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_bar_light.png b/org.simantics.sysdyn.ui/icons/chart_bar_light.png
new file mode 100644 (file)
index 0000000..6069b5c
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_bar_light.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_line.png b/org.simantics.sysdyn.ui/icons/chart_line.png
new file mode 100644 (file)
index 0000000..85020f3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_line.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_line_light.png b/org.simantics.sysdyn.ui/icons/chart_line_light.png
new file mode 100644 (file)
index 0000000..2a77b24
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_line_light.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_organisation.png b/org.simantics.sysdyn.ui/icons/chart_organisation.png
new file mode 100644 (file)
index 0000000..c32d25c
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_organisation.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_pie.png b/org.simantics.sysdyn.ui/icons/chart_pie.png
new file mode 100644 (file)
index 0000000..fe00fa0
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_pie.png differ
diff --git a/org.simantics.sysdyn.ui/icons/chart_pie_light.png b/org.simantics.sysdyn.ui/icons/chart_pie_light.png
new file mode 100644 (file)
index 0000000..fa553c2
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/chart_pie_light.png differ
diff --git a/org.simantics.sysdyn.ui/icons/close.gif b/org.simantics.sysdyn.ui/icons/close.gif
new file mode 100644 (file)
index 0000000..1aca259
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/close.gif differ
diff --git a/org.simantics.sysdyn.ui/icons/control_fastforward.png b/org.simantics.sysdyn.ui/icons/control_fastforward.png
new file mode 100644 (file)
index 0000000..31f7fd3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_fastforward.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png b/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png
new file mode 100644 (file)
index 0000000..4a2f9d4
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_pause.png b/org.simantics.sysdyn.ui/icons/control_pause.png
new file mode 100644 (file)
index 0000000..2d9ce9c
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_pause.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_pause_blue.png b/org.simantics.sysdyn.ui/icons/control_pause_blue.png
new file mode 100644 (file)
index 0000000..ec61099
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_pause_blue.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_play.png b/org.simantics.sysdyn.ui/icons/control_play.png
new file mode 100644 (file)
index 0000000..0846555
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_play.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_play_blue.png b/org.simantics.sysdyn.ui/icons/control_play_blue.png
new file mode 100644 (file)
index 0000000..f8c8ec6
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_play_blue.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_step.png b/org.simantics.sysdyn.ui/icons/control_step.png
new file mode 100644 (file)
index 0000000..820b020
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_step.png differ
diff --git a/org.simantics.sysdyn.ui/icons/control_step_blue.png b/org.simantics.sysdyn.ui/icons/control_step_blue.png
new file mode 100644 (file)
index 0000000..98071cc
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_step_blue.png differ
diff --git a/org.simantics.sysdyn.ui/icons/cursor.png b/org.simantics.sysdyn.ui/icons/cursor.png
new file mode 100644 (file)
index 0000000..532f532
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/cursor.png differ
diff --git a/org.simantics.sysdyn.ui/icons/dependency.png b/org.simantics.sysdyn.ui/icons/dependency.png
new file mode 100644 (file)
index 0000000..768b55f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/dependency.png differ
diff --git a/org.simantics.sysdyn.ui/icons/dependency_old.png b/org.simantics.sysdyn.ui/icons/dependency_old.png
new file mode 100644 (file)
index 0000000..6a604a3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/dependency_old.png differ
diff --git a/org.simantics.sysdyn.ui/icons/equalizer.png b/org.simantics.sysdyn.ui/icons/equalizer.png
new file mode 100644 (file)
index 0000000..e496cf4
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/equalizer.png differ
diff --git a/org.simantics.sysdyn.ui/icons/error.svg b/org.simantics.sysdyn.ui/icons/error.svg
new file mode 100644 (file)
index 0000000..e4eb0ab
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="744.09448"
+   height="1052.3622"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="error.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata29">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="841"
+     inkscape:window-width="1212"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="7.0241977"
+     inkscape:cx="-17.826432"
+     inkscape:cy="1037.7942"
+     inkscape:window-x="270"
+     inkscape:window-y="71"
+     inkscape:current-layer="svg2"
+     inkscape:window-maximized="0" />
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective31" />
+    <linearGradient
+       id="linearGradient3488">
+      <stop
+         id="stop3490"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3492"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3420">
+      <stop
+         id="stop3422"
+         style="stop-color:#ff1e1e;stop-opacity:1;"
+         offset="0" />
+      <stop
+         id="stop3424"
+         style="stop-color:#dc2828;stop-opacity:1;"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       id="linearGradient3426"
+       xlink:href="#linearGradient3420"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       id="linearGradient3494"
+       xlink:href="#linearGradient3488"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3420"
+       id="linearGradient2411"
+       gradientUnits="userSpaceOnUse"
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       gradientTransform="matrix(0,-2.7617189e-2,2.7612784e-2,0,-11.701736,14.171172)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3488"
+       id="linearGradient2413"
+       gradientUnits="userSpaceOnUse"
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       gradientTransform="matrix(0,-2.7617189e-2,2.7612784e-2,0,-11.701736,14.171172)" />
+  </defs>
+  <path
+     style="fill:url(#linearGradient2411);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2413);stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="path2383"
+     d="M 2.1698824,1.1121873 C 3.3682412,1.1119962 4.3398041,2.0835591 4.3398041,3.2821091 C 4.3398041,4.4806589 3.3682412,5.4522219 2.1698824,5.4520308 C 0.97152351,5.4522219 -3.9437272e-05,4.4806589 -3.9437272e-05,3.2821091 C -3.9437272e-05,2.0835591 0.97152351,1.1119962 2.1698824,1.1121873 L 2.1698824,1.1121873 z" />
+  <g
+     style="fill:#ffffff;fill-opacity:1;stroke:none"
+     id="g3164"
+     transform="matrix(9.4934061e-2,0,0,1.3562015e-2,-34.990031,-2.4459735)">
+    <rect
+       style="opacity:0.8;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3166"
+       y="472.36218"
+       x="388.57144"
+       height="40"
+       width="5.7142859" />
+  </g>
+  <path
+     style="opacity:0.8;fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.35824198;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     id="path2385"
+     d="M 3.8894553,3.2821081 C 3.8894553,4.2317955 3.1195813,5.0016695 2.1698938,5.0016695 C 1.2202064,5.0016695 0.45033238,4.2317955 0.45033238,3.2821081 C 0.45033238,2.3324207 1.2202064,1.5625466 2.1698938,1.5625466 C 3.1195813,1.5625466 3.8894553,2.3324207 3.8894553,3.2821081 z" />
+  <g
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-opacity:1"
+     id="g3159"
+     transform="matrix(9.4934061e-2,0,0,4.0686044e-2,-34.990031,-17.157021)">
+    <rect
+       style="opacity:0.8;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:12.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect3157"
+       y="472.36218"
+       x="388.57144"
+       height="40"
+       width="5.7142859" />
+  </g>
+</svg>
diff --git a/org.simantics.sysdyn.ui/icons/error_decoration.png b/org.simantics.sysdyn.ui/icons/error_decoration.png
new file mode 100644 (file)
index 0000000..688ad22
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/error_decoration.png differ
diff --git a/org.simantics.sysdyn.ui/icons/fatal.svg b/org.simantics.sysdyn.ui/icons/fatal.svg
new file mode 100644 (file)
index 0000000..5ee4816
--- /dev/null
@@ -0,0 +1,612 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   version="1.0"
+   width="744.09448"
+   height="1052.3622"
+   id="svg2">
+  <metadata
+     id="metadata29">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3488">
+      <stop
+         id="stop3490"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3492"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3420">
+      <stop
+         id="stop3422"
+         style="stop-color:#ff1e1e;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3424"
+         style="stop-color:#dc2828;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       id="linearGradient3426"
+       xlink:href="#linearGradient3420"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       x1="315.71429"
+       y1="502.36218"
+       x2="472.85712"
+       y2="502.36218"
+       id="linearGradient3494"
+       xlink:href="#linearGradient3488"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       x1="111.7876"
+       y1="230.2852"
+       x2="111.7876"
+       y2="142.84979"
+       id="linearGradient3407"
+       xlink:href="#XMLID_3_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="111.7876"
+       y1="230.2852"
+       x2="111.7876"
+       y2="142.84979"
+       id="XMLID_3_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3166"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3167"
+         style="stop-color:#fafafa;stop-opacity:1"
+         offset="0.1019" />
+      <stop
+         id="stop3168"
+         style="stop-color:#ebebeb;stop-opacity:1"
+         offset="0.2256" />
+      <stop
+         id="stop3169"
+         style="stop-color:#d2d2d2;stop-opacity:1"
+         offset="0.36059999" />
+      <stop
+         id="stop3170"
+         style="stop-color:#b0b0b0;stop-opacity:1"
+         offset="0.50370002" />
+      <stop
+         id="stop3171"
+         style="stop-color:#848484;stop-opacity:1"
+         offset="0.65319997" />
+      <stop
+         id="stop3172"
+         style="stop-color:#4e4e4e;stop-opacity:1"
+         offset="0.80809999" />
+      <stop
+         id="stop3173"
+         style="stop-color:#0f0f0f;stop-opacity:1"
+         offset="0.96460003" />
+      <stop
+         id="stop3174"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3175"
+         style="stop-color:#FFFFFF"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3176"
+         style="stop-color:#FFFFFF"
+         offset="0.6667" />
+      <a:midPointStop
+         id="midPointStop3177"
+         style="stop-color:#000000"
+         offset="1" />
+    </linearGradient>
+    <radialGradient
+       cx="223.2383"
+       cy="994.02441"
+       r="45.424"
+       fx="223.2383"
+       fy="994.02441"
+       id="radialGradient3409"
+       xlink:href="#XMLID_4_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.273125,-0.583125,0.4891875,1.0680937,-219.67181,-763.6707)" />
+    <radialGradient
+       cx="223.2383"
+       cy="994.02441"
+       r="45.424"
+       fx="223.2383"
+       fy="994.02441"
+       id="XMLID_4_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.358,-0.622,0.5218,1.1393,-739.9166,-885.3684)">
+      <stop
+         id="stop3180"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3181"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3182"
+         style="stop-color:#FFFFFF"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3183"
+         style="stop-color:#FFFFFF"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3184"
+         style="stop-color:#000000"
+         offset="1" />
+    </radialGradient>
+    <linearGradient
+       x1="131.50101"
+       y1="96.0942"
+       x2="141.1622"
+       y2="105.7555"
+       id="linearGradient3411"
+       xlink:href="#XMLID_5_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="131.50101"
+       y1="96.0942"
+       x2="141.1622"
+       y2="105.7555"
+       id="XMLID_5_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3188"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3189"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3190"
+         style="stop-color:#FFFFFF"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3191"
+         style="stop-color:#FFFFFF"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3192"
+         style="stop-color:#000000"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="139.91209"
+       y1="98.640602"
+       x2="154.45309"
+       y2="98.640602"
+       id="linearGradient3413"
+       xlink:href="#XMLID_6_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="139.91209"
+       y1="98.640602"
+       x2="154.45309"
+       y2="98.640602"
+       id="XMLID_6_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3196"
+         style="stop-color:#bbbbbb;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3197"
+         style="stop-color:#888888;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3198"
+         style="stop-color:#BBBBBB"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3199"
+         style="stop-color:#BBBBBB"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3200"
+         style="stop-color:#888888"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="145.959"
+       y1="93.064499"
+       x2="166.4863"
+       y2="93.064499"
+       id="linearGradient3415"
+       xlink:href="#XMLID_7_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="145.959"
+       y1="93.064499"
+       x2="166.4863"
+       y2="93.064499"
+       id="XMLID_7_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3203"
+         style="stop-color:#ff9200;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3204"
+         style="stop-color:#ff0000;stop-opacity:1"
+         offset="0.264" />
+      <stop
+         id="stop3205"
+         style="stop-color:#fa0000;stop-opacity:1"
+         offset="0.37470001" />
+      <stop
+         id="stop3206"
+         style="stop-color:#eb0000;stop-opacity:1"
+         offset="0.50889999" />
+      <stop
+         id="stop3207"
+         style="stop-color:#d20000;stop-opacity:1"
+         offset="0.65539998" />
+      <stop
+         id="stop3208"
+         style="stop-color:#b00000;stop-opacity:1"
+         offset="0.81059998" />
+      <stop
+         id="stop3209"
+         style="stop-color:#850000;stop-opacity:1"
+         offset="0.97109997" />
+      <stop
+         id="stop3210"
+         style="stop-color:#7c0000;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3211"
+         style="stop-color:#FF9200"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3212"
+         style="stop-color:#FF9200"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3213"
+         style="stop-color:#FF0000"
+         offset="0.264" />
+      <a:midPointStop
+         id="midPointStop3214"
+         style="stop-color:#FF0000"
+         offset="0.6667" />
+      <a:midPointStop
+         id="midPointStop3215"
+         style="stop-color:#7C0000"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="158.666"
+       y1="69.667"
+       x2="171.85741"
+       y2="69.667"
+       id="linearGradient3417"
+       xlink:href="#XMLID_8_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="158.666"
+       y1="69.667"
+       x2="171.85741"
+       y2="69.667"
+       id="XMLID_8_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3218"
+         style="stop-color:#ff6d00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3219"
+         style="stop-color:#ff3300;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3220"
+         style="stop-color:#FF6D00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3221"
+         style="stop-color:#FF6D00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3222"
+         style="stop-color:#FF3300"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="160.666"
+       y1="69.8423"
+       x2="168.79691"
+       y2="69.8423"
+       id="linearGradient3419"
+       xlink:href="#XMLID_9_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="160.666"
+       y1="69.8423"
+       x2="168.79691"
+       y2="69.8423"
+       id="XMLID_9_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3225"
+         style="stop-color:#ffae00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3226"
+         style="stop-color:#fff030;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3227"
+         style="stop-color:#FFAE00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3228"
+         style="stop-color:#FFAE00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3229"
+         style="stop-color:#FFF030"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="169.2207"
+       y1="81.175797"
+       x2="193.29491"
+       y2="81.175797"
+       id="linearGradient3421"
+       xlink:href="#XMLID_10_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="169.2207"
+       y1="81.175797"
+       x2="193.29491"
+       y2="81.175797"
+       id="XMLID_10_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3232"
+         style="stop-color:#ff6d00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3233"
+         style="stop-color:#ff3300;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3234"
+         style="stop-color:#FF6D00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3235"
+         style="stop-color:#FF6D00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3236"
+         style="stop-color:#FF3300"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="171.38091"
+       y1="80.176804"
+       x2="189.1348"
+       y2="80.176804"
+       id="linearGradient3423"
+       xlink:href="#XMLID_11_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="171.38091"
+       y1="80.176804"
+       x2="189.1348"
+       y2="80.176804"
+       id="XMLID_11_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3239"
+         style="stop-color:#ffae00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3240"
+         style="stop-color:#fff030;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3241"
+         style="stop-color:#FFAE00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3242"
+         style="stop-color:#FFAE00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3243"
+         style="stop-color:#FFF030"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="170.4492"
+       y1="100.71"
+       x2="194.9375"
+       y2="100.71"
+       id="linearGradient3425"
+       xlink:href="#XMLID_12_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="170.4492"
+       y1="100.71"
+       x2="194.9375"
+       y2="100.71"
+       id="XMLID_12_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3246"
+         style="stop-color:#ff6d00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3247"
+         style="stop-color:#ff3300;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3248"
+         style="stop-color:#FF6D00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3249"
+         style="stop-color:#FF6D00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3250"
+         style="stop-color:#FF3300"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="172.3457"
+       y1="99.710899"
+       x2="191.03909"
+       y2="99.710899"
+       id="linearGradient3427"
+       xlink:href="#XMLID_13_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+    <linearGradient
+       x1="172.3457"
+       y1="99.710899"
+       x2="191.03909"
+       y2="99.710899"
+       id="XMLID_13_"
+       gradientUnits="userSpaceOnUse">
+      <stop
+         id="stop3253"
+         style="stop-color:#ffae00;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3254"
+         style="stop-color:#fff030;stop-opacity:1"
+         offset="1" />
+      <a:midPointStop
+         id="midPointStop3255"
+         style="stop-color:#FFAE00"
+         offset="0" />
+      <a:midPointStop
+         id="midPointStop3256"
+         style="stop-color:#FFAE00"
+         offset="0.5" />
+      <a:midPointStop
+         id="midPointStop3257"
+         style="stop-color:#FFF030"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="172.3457"
+       y1="99.710899"
+       x2="191.03909"
+       y2="99.710899"
+       id="linearGradient3175"
+       xlink:href="#XMLID_13_"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.9375,0,0,0.9375,474,66.36218)" />
+  </defs>
+  <g
+     transform="matrix(0.0330998,0,0,0.0330998,-17.583388,-2.9032996)"
+     id="g3390">
+    <path
+       d="m 616.36125,173.18655 c 1.50375,-1.15031 3.06188,-2.51625 4.66781,-4.12125 -0.007,-0.0553 -0.0131,-0.10593 -0.0197,-0.15937 0.21751,-0.11344 0.42657,-0.24938 0.60938,-0.43406 2.15906,-2.15719 -0.615,-6.8625 -4.32281,-10.56844 -3.70406,-3.70406 -8.41219,-6.47813 -10.56657,-4.32281 -0.18656,0.18656 -0.32249,0.3975 -0.43781,0.61875 -0.0534,-0.009 -0.10218,-0.0187 -0.15562,-0.0272 -2.56125,2.56125 -4.515,5.00437 -5.94938,7.28531 -5.8725,-2.595 -12.36281,-4.04625 -19.19437,-4.04625 -26.26313,0 -47.55563,21.29344 -47.55563,47.55469 0,26.26687 21.2925,47.55469 47.55563,47.55469 26.26406,0 47.55375,-21.28782 47.55375,-47.55469 -9.4e-4,-12.2175 -4.61156,-23.35594 -12.18469,-31.77938 z"
+       id="path3163"
+       style="opacity:0.2;stroke:none" />
+    <path
+       d="m 531.24656,202.77499 c 0,26.26688 21.29157,47.55469 47.55469,47.55469 26.26406,0 47.55375,-21.28781 47.55375,-47.55469 0,-26.26125 -21.28969,-47.55281 -47.55375,-47.55281 -26.26312,0 -47.55469,21.29156 -47.55469,47.55281 z"
+       id="path3164"
+       style="stroke:none" />
+    <path
+       d="m 533.96344,202.77499 c 0,24.72469 20.11594,44.83875 44.83687,44.83875 24.72469,0 44.83688,-20.11406 44.83688,-44.83875 0,-24.72281 -20.11219,-44.835 -44.83688,-44.835 -24.72093,0 -44.83687,20.11219 -44.83687,44.835 z"
+       id="path3178"
+       style="opacity:0.6;fill:url(#linearGradient3407);stroke:none" />
+    <path
+       d="m 541.89094,197.46687 c 5.15437,11.25937 20.20875,15.39937 33.62719,9.25406 13.41937,-6.14531 20.11593,-20.25188 14.96062,-31.50656 -5.15719,-11.25563 -20.21062,-15.40313 -33.63,-9.25594 -13.41844,6.14437 -20.115,20.25094 -14.95781,31.50844 z"
+       id="path3185"
+       style="fill:url(#radialGradient3409);stroke:none" />
+    <path
+       d="m 603.94594,151.98124 c -10.05,10.05094 -10.80657,18.28875 -7.10063,21.99469 3.70406,3.70406 11.94375,2.94937 21.99281,-7.09875 -1.03031,-8.7675 -2.1975,-12.69656 -14.89218,-14.89594 z"
+       id="path3186"
+       style="stroke:none" />
+    <path
+       d="m 596.1825,168.56937 c 0,1.90406 0.59156,3.41812 1.62375,4.44562 3.06844,3.07031 10.47937,2.23594 19.59563,-6.65062 -0.97032,-7.86657 -2.22282,-10.90969 -12.98626,-12.89625 -5.87625,6.04031 -8.23312,11.33437 -8.23312,15.10125 z"
+       id="path3193"
+       style="fill:url(#linearGradient3411);stroke:none" />
+    <path
+       d="m 604.5375,151.39155 c -2.15531,2.15532 0.61875,6.86063 4.32469,10.56844 3.70406,3.70594 8.41218,6.48 10.56562,4.32281 2.16094,-2.15906 -0.615,-6.8625 -4.32281,-10.56843 -3.70406,-3.70407 -8.41031,-6.48 -10.5675,-4.32282 z"
+       id="path3194"
+       style="stroke:none" />
+    <path
+       d="m 605.49937,152.35343 c -1.19343,1.19156 0.74344,5.06437 4.32282,8.64656 3.58125,3.58125 7.45218,5.51719 8.64468,4.32281 1.19532,-1.19531 -0.73781,-5.06437 -4.32281,-8.64656 -3.58031,-3.57937 -7.44937,-5.51719 -8.64469,-4.32281 z"
+       id="path3201"
+       style="fill:url(#linearGradient3413);stroke:none" />
+    <path
+       d="m 630.08062,149.90843 c -0.0234,-0.49031 -0.0422,-0.99094 -0.0572,-1.48875 -13.10344,1.08 -17.64,6.04031 -19.18782,8.95406 0.29157,0.46313 0.56626,0.94125 0.83719,1.42594 l 0.63938,-0.28406 c 1.59281,-2.83407 5.97281,-7.34719 17.76843,-8.60719 z"
+       id="path3216"
+       style="fill:url(#linearGradient3415);stroke:none" />
+    <path
+       d="m 628.42219,120.20562 6.69469,1.79625 -5.67282,21.14343 -6.69469,-1.79625 5.67282,-21.14343 z"
+       id="path3223"
+       style="fill:url(#linearGradient3417);stroke:none" />
+    <path
+       d="m 624.62437,140.67968 c 1.15969,0.31125 1.52438,0.41062 2.68313,0.72187 0.89062,-3.31312 4.05,-15.09187 4.93969,-18.405 -1.15875,-0.31125 -1.52438,-0.40875 -2.68313,-0.71906 -0.88969,3.31125 -4.05093,15.09188 -4.93969,18.40219 z"
+       id="path3230"
+       style="fill:url(#linearGradient3419);stroke:none" />
+    <path
+       d="m 651.94031,134.23999 3.27375,6.11063 -19.29562,10.33781 -3.27375,-6.11063 19.29562,-10.33781 z"
+       id="path3237"
+       style="fill:url(#linearGradient3421);stroke:none" />
+    <path
+       d="m 634.66969,144.53655 c 0.52218,0.97407 0.68437,1.27969 1.20656,2.25188 2.77781,-1.48875 12.65813,-6.78188 15.43781,-8.27063 -0.52219,-0.97218 -0.68437,-1.27781 -1.20656,-2.25 -2.77969,1.48782 -12.65812,6.78 -15.43781,8.26875 z"
+       id="path3244"
+       style="fill:url(#linearGradient3423);stroke:none" />
+    <path
+       d="m 656.75437,160.52843 -1.95,6.6525 -21.0075,-6.15281 1.94813,-6.65438 21.00937,6.15469 z"
+       id="path3251"
+       style="fill:url(#linearGradient3425);stroke:none" />
+    <path
+       d="m 635.57438,158.60468 c 3.02718,0.88594 13.78218,4.03781 16.8075,4.92375 0.31124,-1.06031 0.40874,-1.39125 0.71812,-2.44969 -3.02531,-0.88781 -13.78031,-4.03781 -16.8075,-4.92375 -0.31031,1.0575 -0.40688,1.39125 -0.71812,2.44969 z"
+       id="path3258"
+       style="fill:url(#linearGradient3175);stroke:none" />
+  </g>
+</svg>
diff --git a/org.simantics.sysdyn.ui/icons/fatal_decoration.png b/org.simantics.sysdyn.ui/icons/fatal_decoration.png
new file mode 100644 (file)
index 0000000..f2e1f4c
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/fatal_decoration.png differ
diff --git a/org.simantics.sysdyn.ui/icons/flow.png b/org.simantics.sysdyn.ui/icons/flow.png
new file mode 100644 (file)
index 0000000..e90b3d2
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/flow.png differ
diff --git a/org.simantics.sysdyn.ui/icons/flow_old.png b/org.simantics.sysdyn.ui/icons/flow_old.png
new file mode 100644 (file)
index 0000000..b1a1819
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/flow_old.png differ
diff --git a/org.simantics.sysdyn.ui/icons/folder.png b/org.simantics.sysdyn.ui/icons/folder.png
new file mode 100644 (file)
index 0000000..784e8fa
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/folder.png differ
diff --git a/org.simantics.sysdyn.ui/icons/folder_link.png b/org.simantics.sysdyn.ui/icons/folder_link.png
new file mode 100644 (file)
index 0000000..b9b75f6
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/folder_link.png differ
diff --git a/org.simantics.sysdyn.ui/icons/function.png b/org.simantics.sysdyn.ui/icons/function.png
new file mode 100644 (file)
index 0000000..d677847
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/function.png differ
diff --git a/org.simantics.sysdyn.ui/icons/functionLink.png b/org.simantics.sysdyn.ui/icons/functionLink.png
new file mode 100644 (file)
index 0000000..70ae679
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/functionLink.png differ
diff --git a/org.simantics.sysdyn.ui/icons/maximize.gif b/org.simantics.sysdyn.ui/icons/maximize.gif
new file mode 100644 (file)
index 0000000..5e5999b
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/maximize.gif differ
diff --git a/org.simantics.sysdyn.ui/icons/minimize.gif b/org.simantics.sysdyn.ui/icons/minimize.gif
new file mode 100644 (file)
index 0000000..7402dc9
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/minimize.gif differ
diff --git a/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png b/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png
new file mode 100644 (file)
index 0000000..878469f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/modelicaArrayFunction.png differ
diff --git a/org.simantics.sysdyn.ui/icons/modelicaFunction.png b/org.simantics.sysdyn.ui/icons/modelicaFunction.png
new file mode 100644 (file)
index 0000000..30ee96f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/modelicaFunction.png differ
diff --git a/org.simantics.sysdyn.ui/icons/page_white_text.png b/org.simantics.sysdyn.ui/icons/page_white_text.png
new file mode 100644 (file)
index 0000000..813f712
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/page_white_text.png differ
diff --git a/org.simantics.sysdyn.ui/icons/page_white_text_width.png b/org.simantics.sysdyn.ui/icons/page_white_text_width.png
new file mode 100644 (file)
index 0000000..d9cf132
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/page_white_text_width.png differ
diff --git a/org.simantics.sysdyn.ui/icons/rainbow.png b/org.simantics.sysdyn.ui/icons/rainbow.png
new file mode 100644 (file)
index 0000000..5ede989
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/rainbow.png differ
diff --git a/org.simantics.sysdyn.ui/icons/save_as.png b/org.simantics.sysdyn.ui/icons/save_as.png
new file mode 100644 (file)
index 0000000..033bd35
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/save_as.png differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png b/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png
new file mode 100644 (file)
index 0000000..e65f010
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.xcf b/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.xcf
new file mode 100644 (file)
index 0000000..49879df
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.xcf differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn16.png b/org.simantics.sysdyn.ui/icons/simantics_sysdyn16.png
new file mode 100644 (file)
index 0000000..138465f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn16.png differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn32.png b/org.simantics.sysdyn.ui/icons/simantics_sysdyn32.png
new file mode 100644 (file)
index 0000000..b77a76a
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn32.png differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn48.png b/org.simantics.sysdyn.ui/icons/simantics_sysdyn48.png
new file mode 100644 (file)
index 0000000..142afd3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn48.png differ
diff --git a/org.simantics.sysdyn.ui/icons/simantics_sysdyn64.png b/org.simantics.sysdyn.ui/icons/simantics_sysdyn64.png
new file mode 100644 (file)
index 0000000..1d4d73f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/simantics_sysdyn64.png differ
diff --git a/org.simantics.sysdyn.ui/icons/sysdyn.png b/org.simantics.sysdyn.ui/icons/sysdyn.png
new file mode 100644 (file)
index 0000000..2c801ef
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/sysdyn.png differ
diff --git a/org.simantics.sysdyn.ui/icons/sysdyn32.png b/org.simantics.sysdyn.ui/icons/sysdyn32.png
new file mode 100644 (file)
index 0000000..01398b2
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/sysdyn32.png differ
diff --git a/org.simantics.sysdyn.ui/icons/sysdynFunction.png b/org.simantics.sysdyn.ui/icons/sysdynFunction.png
new file mode 100644 (file)
index 0000000..ddc929d
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/sysdynFunction.png differ
diff --git a/org.simantics.sysdyn.ui/icons/table.png b/org.simantics.sysdyn.ui/icons/table.png
new file mode 100644 (file)
index 0000000..abcd936
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/table.png differ
diff --git a/org.simantics.sysdyn.ui/icons/table_multiple.png b/org.simantics.sysdyn.ui/icons/table_multiple.png
new file mode 100644 (file)
index 0000000..d76448e
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/table_multiple.png differ
diff --git a/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png b/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png
new file mode 100644 (file)
index 0000000..5f4e487
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/table_multiple_pinned.png differ
diff --git a/org.simantics.sysdyn.ui/icons/time.png b/org.simantics.sysdyn.ui/icons/time.png
new file mode 100644 (file)
index 0000000..911da3f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/time.png differ
diff --git a/org.simantics.sysdyn.ui/icons/time_go.png b/org.simantics.sysdyn.ui/icons/time_go.png
new file mode 100644 (file)
index 0000000..d451ee0
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/time_go.png differ
diff --git a/org.simantics.sysdyn.ui/icons/time_rainbow.png b/org.simantics.sysdyn.ui/icons/time_rainbow.png
new file mode 100644 (file)
index 0000000..579887f
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/time_rainbow.png differ
diff --git a/org.simantics.sysdyn.ui/icons/timeline_marker.png b/org.simantics.sysdyn.ui/icons/timeline_marker.png
new file mode 100644 (file)
index 0000000..a3fbddf
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/timeline_marker.png differ
diff --git a/org.simantics.sysdyn.ui/icons/variable.png b/org.simantics.sysdyn.ui/icons/variable.png
new file mode 100644 (file)
index 0000000..0299de3
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/variable.png differ
diff --git a/org.simantics.sysdyn.ui/icons/variableGray.png b/org.simantics.sysdyn.ui/icons/variableGray.png
new file mode 100644 (file)
index 0000000..a3ed59b
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/variableGray.png differ
diff --git a/org.simantics.sysdyn.ui/icons/vensimFunction.png b/org.simantics.sysdyn.ui/icons/vensimFunction.png
new file mode 100644 (file)
index 0000000..f007096
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/vensimFunction.png differ
diff --git a/org.simantics.sysdyn.ui/icons/warning.svg b/org.simantics.sysdyn.ui/icons/warning.svg
new file mode 100644 (file)
index 0000000..1dd13ec
--- /dev/null
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="600"
+   height="500"
+   id="svg2904"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="Nuvola_apps_important_yellow.svg">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1356"
+     inkscape:window-height="874"
+     id="namedview28"
+     showgrid="false"
+     inkscape:zoom="64"
+     inkscape:cx="1.4002934"
+     inkscape:cy="497.30748"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2904" />
+  <metadata
+     id="metadata2950">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs2906">
+    <linearGradient
+       id="Grad1"
+       x1="41.1948738"
+       y1="616.477173"
+       x2="118.931351"
+       y2="527.555115"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.03733917,0,0,-0.03535839,0.20475678,22.530063)">
+      <stop
+         offset="0"
+         id="stop2909"
+         style="stop-color:#f2b600;stop-opacity:1;" />
+      <stop
+         offset="1"
+         id="stop2911"
+         style="stop-color:#f29600;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="Grad2"
+       x1="530.809509"
+       y1="486.631012"
+       x2="174.805481"
+       y2="211.22995"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.00786651,0,0,0.00786651,-0.00679244,0.00631797)">
+      <stop
+         offset="0"
+         id="stop2914"
+         style="stop-color:#d88500;stop-opacity:1;" />
+      <stop
+         offset="1"
+         id="stop2916"
+         style="stop-color:#fc3;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="Grad3"
+       x1="187.873566"
+       y1="224.598923"
+       x2="581.837463"
+       y2="483.100006"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.00786651,0,0,0.00786651,-0.00679244,0.00631791)">
+      <stop
+         offset="0"
+         id="stop2919"
+         style="stop-color:#ffd657;stop-opacity:1;" />
+      <stop
+         offset="1"
+         id="stop2921"
+         style="stop-color:#f2b600;stop-opacity:1;" />
+    </linearGradient>
+    <linearGradient
+       id="Grad4"
+       x1="250.398453"
+       y1="101.536331"
+       x2="412.094299"
+       y2="264.54187"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.00786651,0,0,0.00786651,-0.00679244,0.00631797)">
+      <stop
+         offset="0"
+         id="stop2924"
+         style="stop-color:#fff1c5;stop-opacity:1;" />
+      <stop
+         offset="1"
+         id="stop2926"
+         style="stop-color:#fc3;stop-opacity:1;" />
+    </linearGradient>
+    <radialGradient
+       id="Grad5"
+       cx="295.471252"
+       cy="186.096344"
+       r="179.550003"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,0.01254747,-0.00718228,-1.7748438e-7,3.6893627,-2.0814894)">
+      <stop
+         offset="0"
+         stop-color="#ffffff"
+         id="stop2929" />
+      <stop
+         offset="0.5"
+         stop-color="#ffffff"
+         id="stop2931" />
+      <stop
+         offset="1"
+         stop-color="#d5d5d5"
+         id="stop2933" />
+    </radialGradient>
+  </defs>
+  <path
+     d="m 2.2495975,0.17755318 c 0,0 -2.13182401,3.50059672 -2.13182401,3.50059672 -0.04090583,0.066865 -0.04090583,0.1494635 0,0.2163294 0.0401193,0.066078 0.11563773,0.1077713 0.19744941,0.1077713 l 4.2636484,0 c 0.081025,0 0.1565435,-0.041693 0.197449,-0.1077713 0.040119,-0.066866 0.040119,-0.1494637 0,-0.2163294 L 2.6444965,0.17755318 C 2.6035909,0.11068789 2.528072,0.06899551 2.4470466,0.06899551 c -0.081025,0 -0.1565435,0.04169235 -0.1974491,0.10855767 z"
+     style="fill-opacity:0.17857098"
+     id="path2935"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 2.1557113,0.11487581 c 0,0 -2.13182443,3.50059629 -2.13182443,3.50059629 -0.04090583,0.066865 -0.04090583,0.1494646 0,0.2163294 0.04011931,0.066079 0.11563774,0.1077714 0.1974494,0.1077714 l 4.26364803,0 c 0.081026,0 0.1565435,-0.041692 0.1974498,-0.1077714 0.040119,-0.066864 0.040119,-0.1494636 0,-0.2163294 L 2.5506094,0.11487581 C 2.5097038,0.04801053 2.4341857,0.006318 2.3531605,0.006318 c -0.081026,0 -0.1565436,0.04169253 -0.1974492,0.10855781 z"
+     style="fill:url(#Grad1)"
+     id="path2937"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 2.3531605,0.1864611 c -0.013374,0 -0.025959,0.007079 -0.033039,0.018093 L 1.2542088,1.9548528 0.1882969,3.7051507 c -0.007081,0.011014 -0.007081,0.025173 0,0.036186 0.007081,0.011014 0.0196662,0.018093 0.0330394,0.018093 l 4.26364802,0 c 0.013374,0 0.025959,-0.00708 0.03304,-0.018093 0.00708,-0.011014 0.00708,-0.025173 0,-0.036186 L 2.3861996,0.20455409 c -0.00708,-0.0110133 -0.019666,-0.018093 -0.033039,-0.018093 z"
+     style="fill:url(#Grad2)"
+     id="path2939"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 2.3528655,0.1864611 c -0.013374,0 -0.02596,0.007079 -0.03304,0.018093 L 1.2539138,1.9548528 0.18800176,3.7051507 c -0.007081,0.011014 -0.007081,0.025173 0,0.036186 0.007081,0.011014 0.0196662,0.018093 0.0330394,0.018093 l 4.26364814,0 c 0.013374,0 0.025959,-0.00708 0.033039,-0.018093 0.00708,-0.011014 0.00708,-0.025173 0,-0.036186 L 2.3859045,0.20455409 c -0.00708,-0.0110133 -0.019666,-0.018093 -0.033039,-0.018093 z"
+     style="fill:none;stroke:url(#Grad3);stroke-width:0.09439755;stroke-linejoin:round"
+     id="path2941"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 2.3537257,0.24950271 c -0.012666,6.1991e-4 -0.024472,0.007694 -0.03122,0.0181914 L 1.2565934,2.0179925 1.1081131,2.2618546 c 0.3616458,0.2170897 0.7847846,0.3421927 1.2370087,0.3421927 0.458646,0 0.8874945,-0.128465 1.2524958,-0.3512883 L 2.3886332,0.26769413 c -0.00708,-0.0110133 -0.019568,-0.0181914 -0.032941,-0.0181914 -6.199e-4,0 -0.00135,-3.07e-5 -0.00197,0 z"
+     style="fill:url(#Grad4);stroke-width:10;stroke-linejoin:round"
+     id="path2943"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 2.2446032,1.1202159 -1.28774827,2.113732 c -0.0220263,0.036973 -0.0220263,0.082598 0,0.1187843 0.0220272,0.036972 0.0637188,0.059786 0.10855797,0.059786 l 2.57471,0 c 0.044839,0 0.086531,-0.022814 0.1085579,-0.059786 0.022026,-0.036972 0.022026,-0.081811 0,-0.1187843 L 2.4617192,1.1202159 c -0.022026,-0.036972 -0.063719,-0.059785 -0.108558,-0.059785 -0.044839,0 -0.086532,0.022813 -0.108558,0.059785 z"
+     style="fill:url(#Grad5)"
+     id="path2945"
+     inkscape:connector-curvature="0" />
+  <path
+     d="M 2.2852663,3.337518 C 2.2114878,3.3021821 2.1553008,3.2172169 2.1553008,3.1409868 c 0,-0.1419381 0.148319,-0.248858 0.2886484,-0.2080803 0.094669,0.027511 0.1590123,0.1129419 0.1582241,0.2100805 -6.804e-4,0.082516 -0.036387,0.1433023 -0.1092874,0.1860081 -0.055802,0.032689 -0.1491636,0.03652 -0.2076196,0.00852 z M 2.3020353,2.7770489 C 2.2928126,2.7719848 2.2710912,2.7543341 2.2537687,2.737834 2.1932418,2.6801841 2.1933171,2.6806913 2.1538627,2.0638401 2.1187897,1.5155034 2.1184996,1.506983 2.1335493,1.4675949 2.1674053,1.3789769 2.2428431,1.3401722 2.3684515,1.346762 c 0.079842,0.00419 0.1413326,0.032228 0.1813017,0.082674 0.03414,0.043088 0.041563,0.067446 0.041532,0.1362832 -3.36e-5,0.074803 -0.047818,0.9921396 -0.054611,1.0483554 -0.00889,0.073626 -0.05188,0.133375 -0.1148864,0.1596827 -0.036004,0.015035 -0.095413,0.016668 -0.119753,0.00329 z"
+     id="path2947"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/org.simantics.sysdyn.ui/icons/warning_decoration.png b/org.simantics.sysdyn.ui/icons/warning_decoration.png
new file mode 100644 (file)
index 0000000..c80f14d
Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/warning_decoration.png differ
diff --git a/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_logo2.blend b/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_logo2.blend
new file mode 100644 (file)
index 0000000..8307229
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_logo2.blend differ
diff --git a/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_text.png b/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_text.png
new file mode 100644 (file)
index 0000000..98035c2
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/Simantics_sysdyn_text.png differ
diff --git a/org.simantics.sysdyn.ui/logo/Splash.xcf b/org.simantics.sysdyn.ui/logo/Splash.xcf
new file mode 100644 (file)
index 0000000..110af1a
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/Splash.xcf differ
diff --git a/org.simantics.sysdyn.ui/logo/sysdyn.png b/org.simantics.sysdyn.ui/logo/sysdyn.png
new file mode 100644 (file)
index 0000000..30e09cf
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/sysdyn.png differ
diff --git a/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.png b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.png
new file mode 100644 (file)
index 0000000..7a52a5a
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.png differ
diff --git a/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.xcf b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.xcf
new file mode 100644 (file)
index 0000000..d4d4cdb
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows.xcf differ
diff --git a/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows_and_orange_bg.xcf b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows_and_orange_bg.xcf
new file mode 100644 (file)
index 0000000..dae6145
Binary files /dev/null and b/org.simantics.sysdyn.ui/logo/sysdyn_with_arrows_and_orange_bg.xcf differ
diff --git a/org.simantics.sysdyn.ui/plugin.properties b/org.simantics.sysdyn.ui/plugin.properties
new file mode 100644 (file)
index 0000000..bac5b93
--- /dev/null
@@ -0,0 +1,9 @@
+about.text = Simantics System Dynamics\n\\r
+\n\\r
+Version 1.8.1\n\\r
+\n\\r
+Copyright (c) 2014 Association for Decentralized Information Management in Industry THTH ry.\n\\r
+\n\\r
+Contributors:\n\\r
+VTT Technical Research Centre of Finland\n\\r
+Semantum Oy
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/plugin.xml b/org.simantics.sysdyn.ui/plugin.xml
new file mode 100644 (file)
index 0000000..f66bf39
--- /dev/null
@@ -0,0 +1,3390 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?eclipse version="3.4"?>\r
+<!--\r
+    Copyright (c) 2010 Association for Decentralized Information Management in\r
+    Industry THTH ry.\r
+    All rights reserved. This program and the accompanying materials\r
+    are made available under the terms of the Eclipse Public License v1.0\r
+    which accompanies this distribution, and is available at\r
+    http://www.eclipse.org/legal/epl-v10.html\r
+   \r
+    Contributors:\r
+        VTT Technical Research Centre of Finland - initial API and implementation\r
+ -->\r
+\r
+<plugin>\r
+   <extension\r
+         point="org.eclipse.ui.editors">\r
+      <editor\r
+            class="org.simantics.modeling.ui.diagramEditor.DiagramEditor:viewer=org.simantics.sysdyn.ui.editor.DiagramViewer"\r
+            contributorClass="org.simantics.ui.toolbar.ToolbarContributor:toolbar=org.simantics.sysdyn.ui.diagramToolbar"\r
+            default="false"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/plugin.png"\r
+            id="org.simantics.sysdyn.ui.diagramViewer"\r
+            matchingStrategy="org.simantics.ui.workbench.editor.input.ResourceEditorInputMatchingStrategy"\r
+            name="System Dynamic Diagram Viewer">\r
+      </editor>\r
+      <editor\r
+            class="org.simantics.sysdyn.ui.modelica.SysdynModelicaEditor"\r
+            contributorClass="org.simantics.sysdyn.ui.modelica.TextEditorActionBarContributor"\r
+            default="false"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/page_white_text.png"\r
+            id="org.simantics.sysdyn.ui.modelicaEditor"\r
+            name="Modelica Code Viewer">\r
+      </editor>\r
+      <editor\r
+            class="org.simantics.sysdyn.ui.trend.TrendEditor"\r
+            default="false"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_line.png"\r
+            id="org.simantics.sysdyn.ui.jfreeChartEditor"\r
+            name="Chart Viewer">\r
+      </editor>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.views">\r
+      <category\r
+            id="org.simantics.sysdyn.ui.category"\r
+            name="System Dynamics">\r
+      </category>\r
+      <view\r
+            allowMultiple="true"\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.trend.TrendView"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_line.png"\r
+            id="org.simantics.sysdyn.ui.trend.view"\r
+            name="Trend"\r
+            restorable="true">\r
+      </view>\r
+      <view\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.browser.SysdynBrowser"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.ui.browser"\r
+            name="Model Browser"\r
+            restorable="true">\r
+      </view>\r
+      <view\r
+            allowMultiple="false"\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.structure.StructureView"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/arrow_switch.png"\r
+            id="org.simantics.sysdyn.ui.structure.view"\r
+            name="Structure"\r
+            restorable="true">\r
+      </view>\r
+      <view\r
+            allowMultiple="false"\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.values.ValueView"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/page_white_database.png"\r
+            id="org.simantics.sysdyn.ui.values.view"\r
+            name="Values"\r
+            restorable="true">\r
+      </view>\r
+      <view\r
+            category="org.simantics.sysdyn.ui.category"\r
+            class="org.simantics.sysdyn.ui.browser.SysdynModelBrowser"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.ui.modelBrowser"\r
+            name="Model Browser"\r
+            restorable="true">\r
+         <description>\r
+            Structural model browser view for Sysdyn.\r
+         </description>\r
+      </view>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.perspectives">\r
+      <perspective\r
+            class="org.simantics.sysdyn.ui.project.SysdynPerspectiveFactory"\r
+            icon="icons/sysdyn.png"\r
+            id="org.simantics.sysdyn.ui.perspective"\r
+            name="System Dynamics">\r
+      </perspective>\r
+      <perspective\r
+            class="org.simantics.sysdyn.ui.project.SysdynEquationPerspectiveFactory"\r
+            icon="icons/function.png"\r
+            id="org.simantics.sysdyn.ui.perspective.equation"\r
+            name="Equation">\r
+      </perspective>\r
+      <perspective\r
+            class="org.simantics.sysdyn.ui.project.SysdynTrendPerspectiveFactory"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_curve.png"\r
+            id="org.simantics.sysdyn.ui.perspective.trend"\r
+            name="Trend">\r
+      </perspective>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.perspectiveExtensions">\r
+      <perspectiveExtension\r
+            targetID="org.simantics.sysdyn.ui.perspective">\r
+         <view\r
+               id="org.simantics.browsing.ui.graph.propertyView"\r
+               ratio="0.65f"\r
+               relationship="bottom"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.eclipse.ui.console.ConsoleView"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.trend.view"\r
+               ratio="0.4f"\r
+               relationship="left"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.structure.view"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.browser"\r
+               ratio="0.25f"\r
+               relationship="left"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.symbollibrary"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.values.view"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.issues.ui.issueview2"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.profile"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.jfreechart.chartPanel"\r
+               minimized="true"\r
+               ratio="0.5"\r
+               relationship="right"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.workbench.search.browser"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+         <!--\r
+         <view\r
+               id="org.simantics.document.workbench.documentViewer"\r
+               minimized="true"\r
+               relationship="stack"\r
+               relative="org.simantics.jfreechart.chartPanel">\r
+         </view>\r
+         -->\r
+      </perspectiveExtension>\r
+      <perspectiveExtension\r
+            targetID="org.simantics.sysdyn.ui.perspective.equation">\r
+         <view\r
+               id="org.simantics.browsing.ui.graph.propertyView"\r
+               minimized="false"\r
+               ratio="0.65f"\r
+               relationship="right"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.eclipse.ui.console.ConsoleView"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.trend.view"\r
+               minimized="true"\r
+               ratio="0.4f"\r
+               relationship="left"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.structure.view"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.browser"\r
+               minimized="true"\r
+               ratio="0.25f"\r
+               relationship="left"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.symbollibrary"\r
+               minimized="true"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.values.view"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.issues.ui.issueview2"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.profile"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.jfreechart.chartPanel"\r
+               minimized="true"\r
+               ratio="0.5"\r
+               relationship="right"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.workbench.search.browser"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+      </perspectiveExtension>\r
+      <perspectiveExtension\r
+            targetID="org.simantics.sysdyn.ui.perspective.trend">\r
+         <view\r
+               id="org.simantics.browsing.ui.graph.propertyView"\r
+               minimized="true"\r
+               ratio="0.6f"\r
+               relationship="bottom"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.eclipse.ui.console.ConsoleView"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.trend.view"\r
+               ratio="0.4f"\r
+               relationship="bottom"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.structure.view"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.browser"\r
+               minimized="true"\r
+               ratio="0.25f"\r
+               relationship="left"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.symbollibrary"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+         <view\r
+               id="org.simantics.sysdyn.ui.values.view"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.trend.view">\r
+         </view>\r
+         <view\r
+               id="org.simantics.issues.ui.issueview2"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.diagram.profile"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.browsing.ui.graph.propertyView">\r
+         </view>\r
+         <view\r
+               id="org.simantics.jfreechart.chartPanel"\r
+               minimized="false"\r
+               ratio="0.4"\r
+               relationship="right"\r
+               relative="org.eclipse.ui.editorss">\r
+         </view>\r
+         <view\r
+               id="org.simantics.workbench.search.browser"\r
+               minimized="false"\r
+               relationship="stack"\r
+               relative="org.simantics.sysdyn.ui.browser">\r
+         </view>\r
+      </perspectiveExtension>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.contexts">\r
+      <context\r
+            id="org.simantics.sysdyn.ui.basicExperiment"\r
+            name="Basic Experiment">\r
+      </context>\r
+      <context\r
+            id="org.simantics.sysdyn.ui.playbackExperiment"\r
+            name="Playback Experiment">\r
+      </context>\r
+      <context\r
+            id="org.simantics.sysdyn.ui.gameExperiment"\r
+            name="Game Experiment">\r
+      </context>\r
+      <context\r
+            id="org.simantics.sysdyn.ui.sensitivityAnalysisExperiment"\r
+            name="Sensitivity Analysis Experiment">\r
+      </context>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.menus">\r
+      <menuContribution\r
+            locationURI="menu:sFile?after=import.ext">\r
+         <command commandId="org.eclipse.ui.file.import" />\r
+         <command commandId="org.eclipse.ui.file.export" />\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="toolbar:org.eclipse.ui.main.toolbar">\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.modelToolbar">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportModelButton"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/disk.png"\r
+                  id="org.simantics.sysdyn.ui.export.button"\r
+                  tooltip="Save model">\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportModelAsButton"\r
+                  icon="icons/save_as.png"\r
+                  id="org.simantics.sysdyn.ui.exportAs.button"\r
+                  tooltip="Save model as...">\r
+            </command>\r
+         </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.diagramToolbar">\r
+         </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.experimentControlToolbar">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.run"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png"\r
+                  id="org.simantics.sysdyn.ui.run.button"\r
+                  label="Simulate"\r
+                  style="push">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.basicExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.toggleSimulation"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_repeat_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_repeat.png"\r
+                  label="Simulate On Change"\r
+                  style="toggle"\r
+                  tooltip="Simulate On Change">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.basicExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.dispose"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_eject_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_eject.png"\r
+                  id="org.simantics.sysdyn.ui.dispose.button"\r
+                  label="Quit Experiment"\r
+                  tooltip="Quit Experiment">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.basicExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.saveResults"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/table_save.png"\r
+                  id="org.simantics.sysdyn.ui.save.button"\r
+                  label="Save Results">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.basicExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.saveIC"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/table_save.png"\r
+                  id="org.simantics.sysdyn.ui.saveic.button"\r
+                  label="Save Initial Condition">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.saveHistory"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/table_save.png"\r
+                  id="org.simantics.sysdyn.ui.savehistory.button"\r
+                  label="Save History">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.synthesisSimulation"\r
+                  hoverIcon="icons/equalizer.png"\r
+                  icon="icons/equalizer.png"\r
+                  label="Sliders and Trends"\r
+                  style="toggle"\r
+                  tooltip="Sliders and Trends">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.basicExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                     <and>\r
+                        <count\r
+                              value="0">\r
+                        </count>\r
+                     </and>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+         </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.playbackControlToolbar">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.playbackReset"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_start_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_start.png"\r
+                  id="org.simantics.sysdyn.ui.playbackReset.button"\r
+                  label="Reset"\r
+                  style="push"\r
+                  tooltip="Reset">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.playback"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png"\r
+                  id="org.simantics.sysdyn.ui.playback.button"\r
+                  label="Start Playback"\r
+                  style="pulldown"\r
+                  tooltip="Start playback">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <dynamic\r
+                  class="org.simantics.sysdyn.ui.menu.PlaybackSliderContribution"\r
+                  id="org.simantics.sysdyn.ui.playbackSlider">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </dynamic>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.playbackReload"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_repeat_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_repeat.png"\r
+                  label="Reload"\r
+                  style="push"\r
+                  tooltip="Reload">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.dispose"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_eject_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_eject.png"\r
+                  id="org.simantics.sysdyn.ui.dispose.button"\r
+                  label="Quit Experiment"\r
+                  tooltip="Quit Experiment">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+         </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.gameControlToolbar">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.reloadGame"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png"\r
+                  id="org.simantics.sysdyn.ui.reload.game.button"\r
+                  label="Reload Game"\r
+                  style="push">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <dynamic\r
+                  class="org.simantics.sysdyn.ui.menu.GameStepDurationContribution"\r
+                  id="org.simantics.sysdyn.ui.gameStepDuration">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </dynamic>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.step"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_end_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_end.png"\r
+                  id="org.simantics.sysdyn.ui.step.button"\r
+                  label="Step"\r
+                  style="push">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.dispose"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_eject_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_eject.png"\r
+                  id="org.simantics.sysdyn.ui.dispose.button"\r
+                  label="Quit Experiment"\r
+                  tooltip="Quit Experiment">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.gameExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+         </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.sensitivityAnalysisControlToolbar">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.runSensitivityAnalysis"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png"\r
+                  id="org.simantics.sysdyn.ui.runSensitivityAnalysis.button"\r
+                  label="Simulate"\r
+                  style="push">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.sensitivityAnalysisExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_repeat_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_repeat.png"\r
+                  label="Simulate On Change"\r
+                  style="toggle"\r
+                  tooltip="Simulate On Change">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.sensitivityAnalysisExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.dispose"\r
+                  hoverIcon="platform:/plugin/com.famfamfam.silk/icons/control_eject_blue.png"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/control_eject.png"\r
+                  id="org.simantics.sysdyn.ui.dispose.button"\r
+                  label="Quit Experiment"\r
+                  tooltip="Quit Experiment">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.sensitivityAnalysisExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.saveSensitivityAnalysisResults"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/table_save.png"\r
+                  id="org.simantics.sysdyn.ui.saveSensitivityAnalysis.button"\r
+                  label="Save Sensitivity Analysis Results">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.sensitivityAnalysisExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+         </toolbar>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="toolbar:org.simantics.sysdyn.ui.trend.view">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.trend.view.pin"\r
+               icon="icons/table_multiple_pinned.png"\r
+               label="Pin Trend"\r
+               style="toggle"\r
+               tooltip="Pins the trend so that it does not react to selection changes">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.trend.view.png"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/images.png"\r
+               label="Export to PNG"\r
+               style="push"\r
+               tooltip="Exports the trend to PNG file">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.trend.view.svg"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/map.png"\r
+               label="Export to SVG"\r
+               style="push"\r
+               tooltip="Exports the trend to SVG file">\r
+         </command>\r
+      </menuContribution>\r
+      \r
+      <menuContribution\r
+            locationURI="popup:#EnumerationTabPopup?after=wbStart">\r
+            \r
+            <command\r
+               commandId="org.simantics.sysdyn.ui.renameNode1"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/textfield_rename.png"\r
+               id="org.simantics.sysdyn.ui.browser.rename"\r
+               label="Rename"\r
+               style="push">\r
+            <visibleWhen checkEnabled="true">\r
+            </visibleWhen>\r
+         </command>\r
+            \r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="popup:#SysdynBrowserPopup?after=wbStart">\r
+         <menu id="org.simantics.new"\r
+               label="New">\r
+               <!--\r
+            <command\r
+                  commandId="org.simantics.modeling.ui.newModel"\r
+                  id="org.simantics.sysdyn.ui.browser.newModel"\r
+                  label="Model"\r
+                  style="push">\r
+            </command>\r
+            -->\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newSCLModule"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/script.png"\r
+                  id="org.simantics.sysdyn.ui.newSCLModule"\r
+                  label="SCL Module"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newAnnotationType"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/note.png"\r
+                  id="org.simantics.sysdyn.ui.newAnnotationType"\r
+                  label="Annotation Type"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                        <test\r
+                              args="http://www.simantics.org/Layer0-0.0/Library"\r
+                              property="org.simantics.graph.resourceType"\r
+                              value="true">\r
+                        </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newAnnotationValue"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/note.png"\r
+                  id="org.simantics.sysdyn.ui.newAnnotationValue"\r
+                  label="Annotation Value"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                        <test\r
+                              args="http://www.simantics.org/Layer0-0.0/Entity"\r
+                              property="org.simantics.graph.resourceType"\r
+                              value="true">\r
+                        </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newLibrary"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/folder.png"\r
+                  id="org.simantics.sysdyn.ui.newLibrary"\r
+                  label="Library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <or>\r
+                        <test\r
+                              args="http://www.simantics.org/Layer0-0.0/Library"\r
+                              property="org.simantics.graph.resourceType"\r
+                              value="true">\r
+                        </test>\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ModelNode"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                     </or>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newModuleNode"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/bricks.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newModule"\r
+                  label="Module type"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ModulesNode"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newExperiment"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/time.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newExperiment"\r
+                  label="Experiment"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newPlaybackExperiment"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/timeline_marker.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newPlaybackExperiment"\r
+                  label="Playback Experiment"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newGameExperiment"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/time_go.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newGameExperiment"\r
+                  label="Game Experiment"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newSensitivityAnalysisExperiment"\r
+                  icon="icons/time_rainbow.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newSensitivityAnalysisExperiment"\r
+                  label="Sensitivity Analysis Experiment"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newEnumeration"\r
+                  id="org.simantics.sysdyn.ui.browser.newEnumeration"\r
+                  label="Enumeration"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newFunction"\r
+                  id="org.simantics.sysdyn.ui.browser.newFunction"\r
+                  label="Function"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <or>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.FunctionNode"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                     </or>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newFunctionLibrary"\r
+                  label="Function Library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <or>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                     </or>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newSharedFunctionLibrary"\r
+                  label="Shared Function Library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newSpreadSheet"\r
+                  label="Sheet"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.BookNode"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newXYLineChart"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/chart_line.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newXYLineChart"\r
+                  label="Line Chart"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ChartsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newSensitivityChart"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/rainbow.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newSensitivityChart"\r
+                  label="Sensitivity Chart"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ChartsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newBarChart"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/chart_bar.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newBarChart"\r
+                  label="Bar Chart"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ChartsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newPieChart"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/chart_pie.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newPieChart"\r
+                  label="Pie Chart"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ChartsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newHistoryData"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/table.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newHistoryData"\r
+                  label="History Data"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newModel"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newModel"\r
+                  label="Model"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <!--\r
+            <command\r
+                  commandId="org.simantics.documentation.workbench.newDocumentation"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/script.png"\r
+                  id="org.simantics.sysdyn.ui.browser.newDocumentation"\r
+                  label="Document"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.document.workbench.browser_old.DocumentationFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            -->\r
+         </menu>\r
+         <dynamic\r
+               class="org.simantics.ui.contribution.OpenWithMenuContribution"\r
+               id="org.simantics.sysdyn.ui.browser.openWithMenu">\r
+         </dynamic>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.activateResult"\r
+               id="org.simantics.sysdyn.ui.browser.activateResult"\r
+               label="Show in charts"\r
+               style="push">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.activateResultSet"\r
+               id="org.simantics.sysdyn.ui.browser.activateResultSet"\r
+               label="Show in charts"\r
+               style="push">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.renameNode"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/textfield_rename.png"\r
+               id="org.simantics.sysdyn.ui.browser.rename"\r
+               label="Rename"\r
+               style="push">\r
+            <visibleWhen checkEnabled="true">\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.removeNode"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/cross.png"\r
+               id="org.simantics.sysdyn.ui.browser.remove"\r
+               label="Remove"\r
+               style="push">\r
+            <visibleWhen checkEnabled="true">\r
+            </visibleWhen>\r
+         </command>\r
+         <menu\r
+               id="org.simantics.import"\r
+               label="Import">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importModel"\r
+                  label="Model"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importSharedLibrary"\r
+                  label="Shared Library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <!--\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importMdl"\r
+                  label="Vensim model"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            -->\r
+            <command\r
+                  commandId="org.simantics.image.ui.importImage"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/image_add.png"\r
+                  label="Image"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.image.ui.modelBrowser.ImagesNode"\r
+                           property="org.simantics.modeling.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importFunctionLibrary"\r
+                  label="Function library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importModule"\r
+                  label="Module"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importMdl"\r
+                  label="Vensim Model (.mdl)"\r
+                  style="push">\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.importBPMN"\r
+                  label="BPMN (prototype)"\r
+                  style="push">\r
+            </command>\r
+         </menu>\r
+         <menu\r
+               id="org.simantics.export"\r
+               label="Export">\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportSharedOntology"\r
+                  icon="platform:/plugin/com.famfamfam.silk/icons/folder.png"\r
+                  id="org.simantics.sysdyn.ui.exportSharedOntology"\r
+                  label="Shared Library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <or>\r
+                        <test\r
+                              args="org.simantics.sysdyn.ui.browser.nodes.SharedOntologyNode"\r
+                              property="org.simantics.sysdyn.ui.nodeClass">\r
+                        </test>\r
+                     </or>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportModel"\r
+                  label="Model"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportFunctionLibrary"\r
+                  label="Function library"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.exportModule"\r
+                  label="Module"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+               </visibleWhen>\r
+            </command>\r
+         </menu>\r
+         <command\r
+               commandId="org.eclipse.ui.edit.findReplace"\r
+               label="Find"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.activateExperiment"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+               id="org.simantics.sysdyn.ui.browser.activateExperiment"\r
+               label="Activate Experiment"\r
+               style="push">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.assignIC"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/control_play_blue.png"\r
+               id="org.simantics.sysdyn.ui.browser.assignIC"\r
+               label="Assign IC"\r
+               style="push">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="popup:#SysdynDiagramPopup?after=wbStart">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.showModule"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/palette.png"\r
+               label="Show Module"\r
+               style="push">\r
+            <visibleWhen>\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r
+                        property="org.simantics.graph.resourceType">\r
+                  </test>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <dynamic\r
+               class="org.simantics.sysdyn.ui.menu.FontContextMenuContribution"\r
+               id="org.simantics.sysdyn.ui.fontContextMenu">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <or>\r
+                     <test\r
+                           args="http://www.simantics.org/Diagram-0.0/FontProvider"\r
+                           property="org.simantics.graph.resourceTypes"\r
+                           value="true">\r
+                     </test>\r
+                  </or>\r
+               </with>\r
+            </visibleWhen>\r
+         </dynamic>\r
+         <command\r
+               commandId="org.eclipse.ui.edit.copy"\r
+               label="Copy"\r
+               style="push">\r
+            <visibleWhen\r
+                  checkEnabled="true">\r
+               <with\r
+                     variable="selection">\r
+                  <or>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                  </or>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.eclipse.ui.edit.paste"\r
+               label="Paste"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.eclipse.ui.edit.findReplace"\r
+               label="Find"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.pasteSpecial"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/paste_plain.png"\r
+               label="Paste special"\r
+               style="push">\r
+         </command>         \r
+         <command\r
+               commandId="org.eclipse.ui.edit.cut"\r
+               label="Cut"\r
+               style="push">\r
+            <visibleWhen>\r
+               <with\r
+                     variable="selection">\r
+                  <or>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Layer0-0.0/SCLModule"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                  </or>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+         <command\r
+               commandId="org.eclipse.ui.edit.rename"\r
+               label="Rename"\r
+               style="push">\r
+            <visibleWhen>\r
+               <with\r
+                     variable="selection">\r
+                  <or>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ValveSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/StockSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/AuxiliarySymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/CloudSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/InputSymbol"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                     <test\r
+                           args="http://www.simantics.org/Layer0-0.0/SCLModule"\r
+                           property="org.simantics.graph.resourceType"\r
+                           value="true">\r
+                     </test>\r
+                  </or>\r
+               </with>\r
+            </visibleWhen>\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="popup:#ExternalFunctionFileBrowser?after=wbStart">\r
+      </menuContribution>\r
+      <menuContribution\r
+            allPopups="false"\r
+            locationURI="menu:sFile?after=#FileNewMenu">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.importModel"\r
+               label="Import Model"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.importSharedLibrary"\r
+               label="Import Shared Library"\r
+               style="push">\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            allPopups="false"\r
+            locationURI="menu:#FileNewMenu">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.newModel"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation_add.png"\r
+               label="SD Model"\r
+               style="push">\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            allPopups="false"\r
+            locationURI="menu:org.simantics.sysdyn.ui.playback.button">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.playbackSlow"\r
+               icon="icons/control_step.png"\r
+               label="Slow"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.playbackNormal"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/control_play.png"\r
+               label="Normal"\r
+               style="push">\r
+         </command>\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.playbackFast"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/control_fastforward.png"\r
+               label="Fast"\r
+               style="push">\r
+         </command>\r
+      </menuContribution>\r
+      <menuContribution\r
+            locationURI="toolbar:org.simantics.sysdyn.ui.chartPanel">\r
+         <command\r
+               commandId="org.simantics.sysdyn.ui.chartPanelOrientation"\r
+               icon="platform:/plugin/com.famfamfam.silk/icons/page_white_text_width.png"\r
+               label="Change Orientation"\r
+               style="push"\r
+               tooltip="Change orientation">\r
+         </command>\r
+      </menuContribution>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.commands">\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newSCLModule"\r
+            name="New SCL Module">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newAnnotationType"\r
+            name="New Annotation Type">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newAnnotationValue"\r
+            name="New Annotation Value">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newLibrary"\r
+            name="New Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportSharedOntology"\r
+            name="Export Shared Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.trend.view.pin"\r
+            name="Pin Trend">\r
+         <state\r
+               class="org.eclipse.jface.commands.ToggleState"\r
+               id="org.simantics.sysdyn.ui.trend.view.pin.state">\r
+         </state>\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.trend.view.png"\r
+            name="Export To PNG">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.trend.view.svg"\r
+            name="Export To SVG">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.showModule"\r
+            name="Show Module">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.pasteSpecial"\r
+            name="Paste Special">\r
+      </command>      \r
+      <command\r
+            id="org.simantics.sysdyn.ui.removeNode"\r
+            name="Remove Node">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.renameNode"\r
+            name="Rename Node">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.enumerationIndexRenameNode"\r
+            name="Rename Node">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.ToggleSimulation"\r
+            id="org.simantics.sysdyn.ui.toggleSimulation"\r
+            name="Toggle Simulate">\r
+         <state\r
+               class="org.eclipse.jface.commands.ToggleState"\r
+               id="org.simantics.sysdyn.ui.toggleSimulation.state">\r
+         </state>\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.SynthesisSimulation"\r
+            id="org.simantics.sysdyn.ui.synthesisSimulation"\r
+            name="Slider and Trends">\r
+         <state\r
+               class="org.eclipse.jface.commands.ToggleState"\r
+               id="org.simantics.sysdyn.ui.synthesisSimulation.state">\r
+         </state>\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewModuleNodeHandler"\r
+            id="org.simantics.sysdyn.ui.newModuleNode"\r
+            name="New Module">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.activateExperiment"\r
+            name="Activate Experiment">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.assignIC"\r
+            name="Assign IC">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.RunBasicExperiment"\r
+            id="org.simantics.sysdyn.ui.run"\r
+            name="Run Basic Simulation">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.DisposeExperiment"\r
+            id="org.simantics.sysdyn.ui.dispose"\r
+            name="Quit Experiment">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.SaveResultsHandler"\r
+            id="org.simantics.sysdyn.ui.saveResults"\r
+            name="Save Results">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.SaveICHandler"\r
+            id="org.simantics.sysdyn.ui.saveIC"\r
+            name="Save Initial Condition">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.SaveHistoryHandler"\r
+            id="org.simantics.sysdyn.ui.saveHistory"\r
+            name="Save History">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.ToggleResultActivation"\r
+            id="org.simantics.sysdyn.ui.activateResult"\r
+            name="Show In Charts">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.ToggleResultSetActivation"\r
+            id="org.simantics.sysdyn.ui.activateResultSet"\r
+            name="Show In Charts">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewExperimentNodeHandler"\r
+            id="org.simantics.sysdyn.ui.newExperiment"\r
+            name="New Experiment">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportModel"\r
+            name="Export Model">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importModel"\r
+            name="Import Model">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importSharedLibrary"\r
+            name="Import Shared Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newEnumeration"\r
+            name="New Enumeration">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importMdl"\r
+            name="Import .mdl">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewFunctionHandler"\r
+            id="org.simantics.sysdyn.ui.newFunction"\r
+            name="NewFunction">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importExternalFunctionFile"\r
+            name="ImportExternalFunctionFile">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportExternalFunctionFile"\r
+            name="ExportExternalFunctionFile">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newFunctionLibrary"\r
+            name="New Function Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newSharedFunctionLibrary"\r
+            name="New Shared Function Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importFunctionLibrary"\r
+            name="Import Function Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportFunctionLibrary"\r
+            name="Export Function Library">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importModule"\r
+            name="Import Module">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportModule"\r
+            name="Export Module">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newSpreadSheet"\r
+            name="New SpreadSheet">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newModel"\r
+            name="New System Dynamics Model">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newPlaybackExperiment"\r
+            name="New Playback Experiment">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newGameExperiment"\r
+            name="New Game Experiment">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newSensitivityAnalysisExperiment"\r
+            name="New Sensitivity Analysis Experiment">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackExperimentHandler"\r
+            id="org.simantics.sysdyn.ui.playback"\r
+            name="Playback experiment">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.SlowSpeedHandler"\r
+            id="org.simantics.sysdyn.ui.playbackSlow"\r
+            name="Slow Playback">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.NormalSpeedHandler"\r
+            id="org.simantics.sysdyn.ui.playbackNormal"\r
+            name="Normal Playback">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.FastSpeedHandler"\r
+            id="org.simantics.sysdyn.ui.playbackFast"\r
+            name="Fast Playback">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackResetHandler"\r
+            id="org.simantics.sysdyn.ui.playbackReset"\r
+            name="Reset Playback">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackReloadHandler"\r
+            id="org.simantics.sysdyn.ui.playbackReload"\r
+            name="Reload Playback">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.ChartPanelOrientationHandler"\r
+            id="org.simantics.sysdyn.ui.chartPanelOrientation"\r
+            name="Chart Panel Orientation">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewXYLineChartHandler"\r
+            id="org.simantics.sysdyn.ui.newXYLineChart"\r
+            name="New XY Line Chart">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewBarChartHandler"\r
+            id="org.simantics.sysdyn.ui.newBarChart"\r
+            name="New Bar Chart">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewPieChartHandler"\r
+            id="org.simantics.sysdyn.ui.newPieChart"\r
+            name="New Pie Chart">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewSensitivityChartHandler"\r
+            id="org.simantics.sysdyn.ui.newSensitivityChart"\r
+            name="New XY Line Chart">\r
+      </command>      \r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.newComponents.NewHistoryDataHandler"\r
+            id="org.simantics.sysdyn.ui.newHistoryData"\r
+            name="New History Data">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.game.StepHandler"\r
+            id="org.simantics.sysdyn.ui.step"\r
+            name="Step">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.game.ReloadGameExperimentHandler"\r
+            id="org.simantics.sysdyn.ui.reloadGame"\r
+            name="Reload Game">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newSensitivityAnalysisExperiment"\r
+            name="New Game Experiment">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.sensitivityAnalysis.RunSensitivityAnalysisExperiment"\r
+            id="org.simantics.sysdyn.ui.runSensitivityAnalysis"\r
+            name="Run Basic Simulation">\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.sensitivityAnalysis.ToggleSimulation"\r
+            id="org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation"\r
+            name="Toggle Simulate">\r
+         <state\r
+               class="org.eclipse.jface.commands.ToggleState"\r
+               id="org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation.state">\r
+         </state>\r
+      </command>\r
+      <command\r
+            defaultHandler="org.simantics.sysdyn.ui.handlers.sensitivityAnalysis.SaveResultsHandler"\r
+            id="org.simantics.sysdyn.ui.saveSensitivityAnalysisResults"\r
+            name="Save Results">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportModelButton"\r
+            name="Export Model">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.exportModelAsButton"\r
+            name="Export Model As...">\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.diagramTool"\r
+            name="Diagram Tool">\r
+         <state\r
+               id="org.eclipse.ui.commands.radioState">\r
+            <class\r
+                  class="org.eclipse.ui.handlers.RadioState">\r
+               <parameter\r
+                     name="default"\r
+                     value="pointer">\r
+               </parameter>\r
+               <parameter\r
+                     name="persisted"\r
+                     value="false">\r
+               </parameter>\r
+            </class>\r
+         </state>\r
+      </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.importBPMN"\r
+            name="Import BPMN">\r
+      </command>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.handlers">\r
+         \r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.EnumerationIndexRenameNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.enumerationIndexRenameNode">\r
+      </handler>\r
+         \r
+         \r
+      <handler\r
+            class="org.simantics.sysdyn.ui.trend.PinTrend"\r
+            commandId="org.simantics.sysdyn.ui.trend.view.pin">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.trend.TrendToPng"\r
+            commandId="org.simantics.sysdyn.ui.trend.view.png">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.trend.TrendToSvg"\r
+            commandId="org.simantics.sysdyn.ui.trend.view.svg">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.NewSCLModuleHandler"\r
+            commandId="org.simantics.sysdyn.ui.newSCLModule">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.NewAnnotationTypeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newAnnotationType">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                 <test\r
+                       args="http://www.simantics.org/Layer0-0.0/Library"\r
+                       property="org.simantics.graph.resourceType"\r
+                       value="true">\r
+                 </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.NewAnnotationValueHandler"\r
+            commandId="org.simantics.sysdyn.ui.newAnnotationValue">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                 <test\r
+                       args="http://www.simantics.org/Layer0-0.0/Entity"\r
+                       property="org.simantics.graph.resourceType"\r
+                       value="true">\r
+                 </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.NewLibraryHandler"\r
+            commandId="org.simantics.sysdyn.ui.newLibrary">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                        <test\r
+                              args="http://www.simantics.org/Layer0-0.0/Library"\r
+                              property="org.simantics.graph.resourceType"\r
+                              value="true">\r
+                        </test>\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ModelNode"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.ShowModuleHandler"\r
+            commandId="org.simantics.sysdyn.ui.showModule">\r
+         <enabledWhen>\r
+            <and>\r
+               <with\r
+                     variable="selection">\r
+                  <and>\r
+                     <test\r
+                           args="http://www.simantics.org/Sysdyn-0.0/ModuleSymbol"\r
+                           property="org.simantics.graph.resourceType">\r
+                     </test>\r
+                  </and>\r
+               </with>\r
+            </and>\r
+         </enabledWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.PasteSpecialHandler"\r
+            commandId="org.simantics.sysdyn.ui.pasteSpecial">\r
+      </handler>      \r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.UnlinkNodeHandler2"\r
+            commandId="org.simantics.sysdyn.ui.removeNode">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModelNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.image.ui.modelBrowser.ImageNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.EnumerationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.operating.ui.modelBrowser.CompositeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.properties.widgets.externalFiles.ExternalFileNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SheetNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.AbstractChartNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SCLModule"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <!--\r
+                  <test\r
+                        args="org.simantics.document.workbench.browser_old.DocumentationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  -->\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.RenameNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.renameNode">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModelNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SheetNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.BarChartNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.VariableNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.EnumerationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SCLModule"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <!--\r
+                  <test\r
+                        args="org.simantics.document.workbench.browser_old.DocumentationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  -->\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportModelHandler"\r
+            commandId="org.simantics.sysdyn.ui.importModel">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportSharedLibraryHandler"\r
+            commandId="org.simantics.sysdyn.ui.importSharedLibrary">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportModelHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportModel">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModelNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportMdlHandler"\r
+            commandId="org.simantics.sysdyn.ui.importMdl">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewEnumerationNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newEnumeration">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportExternalFunctionFilesHandler"\r
+            commandId="org.simantics.sysdyn.ui.importExternalFunctionFile">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportExternalFunctionFilesHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportExternalFunctionFile">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewFunctionLibraryHandler"\r
+            commandId="org.simantics.sysdyn.ui.newFunctionLibrary">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewSharedFunctionLibraryHandler"\r
+            commandId="org.simantics.sysdyn.ui.newSharedFunctionLibrary">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportFunctionLibrary"\r
+            commandId="org.simantics.sysdyn.ui.exportFunctionLibrary">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportFunctionLibrary"\r
+            commandId="org.simantics.sysdyn.ui.importFunctionLibrary">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportModuleHandler"\r
+            commandId="org.simantics.sysdyn.ui.importModule">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModulesNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportModuleHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportModule">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.modeling.ui.modelBrowser.handlers.StandardCopyHandler"\r
+            commandId="org.eclipse.ui.edit.copy">\r
+         <enabledWhen>\r
+            <not>\r
+               <count\r
+                     value="0">\r
+               </count>\r
+            </not>\r
+         </enabledWhen>\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <test\r
+                     args="org.simantics.sysdyn.ui.browser.nodes.EnumerationNode"\r
+                     property="org.simantics.sysdyn.ui.nodeClass">\r
+               </test>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.modeling.ui.modelBrowser.handlers.StandardPasteHandler"\r
+            commandId="org.eclipse.ui.edit.paste">\r
+         <enabledWhen>\r
+            <not>\r
+               <count\r
+                     value="0">\r
+               </count>\r
+            </not>\r
+         </enabledWhen>\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ModuleTypeNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewSpreadSheetHandler"\r
+            commandId="org.simantics.sysdyn.ui.newSpreadSheet">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewModelHandler"\r
+            commandId="org.simantics.sysdyn.ui.newModel">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewPlaybackExperimentNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newPlaybackExperiment">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewGameExperimentNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newGameExperiment">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.newComponents.NewSensitivityAnalysisExperimentNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newSensitivityAnalysisExperiment">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.FindReplaceHandler"\r
+            commandId="org.eclipse.ui.edit.findReplace">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportModelAsButtonHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportModelAsButton">\r
+         <activeWhen>\r
+            <or>\r
+               <with\r
+                  variable="activePartId">\r
+                         <equals value="org.simantics.browsing.ui.graph.propertyView"/>\r
+               </with>\r
+               <with\r
+                  variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.VariableNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass2">\r
+                  </test>\r
+               </with>\r
+            </or>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.exports.ExportModelButtonHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportModelButton">\r
+         <activeWhen>\r
+            <or>\r
+               <with\r
+                     variable="activePartId">\r
+                  <equals\r
+                        value="org.simantics.browsing.ui.graph.propertyView">\r
+                  </equals>\r
+               </with>\r
+               <with\r
+                     variable="selection">\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.VariableNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass2">\r
+                  </test>\r
+               </with>\r
+            </or>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.DiagramToolHandler"\r
+            commandId="org.simantics.sysdyn.ui.diagramTool">\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator"\r
+            commandId="org.simantics.sysdyn.ui.activateExperiment">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.AssignIC"\r
+            commandId="org.simantics.sysdyn.ui.assignIC">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.ExperimentNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.ExportSharedOntologyHandler"\r
+            commandId="org.simantics.sysdyn.ui.exportSharedOntology">\r
+         <activeWhen>\r
+            <with\r
+                  variable="selection">\r
+               <or>\r
+                  <test\r
+                        args="org.simantics.sysdyn.ui.browser.nodes.SharedOntologyNode"\r
+                        property="org.simantics.sysdyn.ui.nodeClass">\r
+                  </test>\r
+               </or>\r
+            </with>\r
+         </activeWhen>\r
+      </handler>\r
+            <handler\r
+            class="org.simantics.sysdyn.ui.PropertyViewUndoHandler"\r
+            commandId="org.eclipse.ui.edit.undo">\r
+         <activeWhen>\r
+            <reference\r
+                  definitionId="org.simantics.sysdyn.ui.inExpressionField">\r
+            </reference>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.PropertyViewUndoHandler"\r
+            commandId="org.eclipse.ui.edit.redo">\r
+         <activeWhen>\r
+            <reference\r
+                  definitionId="org.simantics.sysdyn.ui.inExpressionField">\r
+            </reference>\r
+         </activeWhen>\r
+      </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.imports.ImportBPMNHandler"\r
+            commandId="org.simantics.sysdyn.ui.importBPMN">\r
+      </handler>\r
+      \r
+   </extension>\r
+   \r
+   <extension\r
+         point="org.eclipse.ui.importWizards">\r
+         \r
+      <category\r
+           id="org.simantics.sysdyn.import"\r
+           name="Sysdyn">\r
+      </category>\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.models.ImportWizardModel"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.ui.wizards.modelImport"\r
+            name="Import Sysdyn Model">\r
+      </wizard> -->\r
+      <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.model.SysdynModelImportWizard"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.import.model2"\r
+            name="Import Sysdyn Model">\r
+      </wizard>\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.modules.ImportWizardModule"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/bricks.png"\r
+            id="org.simantics.sysdyn.ui.wizards.moduleImport"\r
+            name="Import Sysdyn Module">\r
+      </wizard>\r
+      <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.functions.ImportWizardFunction"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/brick.png"\r
+            id="org.simantics.sysdyn.ui.wizards.functionImport"\r
+            name="Import Sysdyn Function Library">\r
+      </wizard>\r
+      <wizard\r
+            category="org.simantics.sysdyn.import"\r
+            class="org.simantics.sysdyn.ui.wizards.mdl.ImportWizardMdl"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.ui.wizards.mdlImport"\r
+            name="Import Vensim Model (.mdl)">\r
+      </wizard> -->\r
+   </extension>\r
+   \r
+   <extension\r
+         point="org.eclipse.ui.exportWizards">\r
+         \r
+      <category\r
+           id="org.simantics.sysdyn.export"\r
+           name="Sysdyn">\r
+      </category>\r
+<!--     <wizard\r
+            category="org.simantics.sysdyn.export"\r
+            class="org.simantics.sysdyn.ui.wizards.models.ExportWizardModel"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.export.model"\r
+            name="Export Sysdyn Model">\r
+      </wizard> -->\r
+        <wizard\r
+            category="org.simantics.sysdyn.export"\r
+            class="org.simantics.sysdyn.ui.wizards.model.SysdynModelExportWizard"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/chart_organisation.png"\r
+            id="org.simantics.sysdyn.export.model2"\r
+            name="Export Sysdyn Model">\r
+      </wizard>\r
+<!--      <wizard\r
+            category="org.simantics.sysdyn.export"\r
+            class="org.simantics.sysdyn.ui.wizards.modules.ExportWizardModule"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/bricks.png"\r
+            id="org.simantics.sysdyn.export.module"\r
+            name="Export Sysdyn Module">\r
+      </wizard> \r
+      <wizard\r
+            category="org.simantics.sysdyn.export"\r
+            class="org.simantics.sysdyn.ui.wizards.functions.ExportWizardFunction"\r
+            icon="platform:/plugin/com.famfamfam.silk/icons/brick.png"\r
+            id="org.simantics.sysdyn.export.function"\r
+            name="Export Sysdyn Function Library">\r
+      </wizard> -->\r
+   </extension>\r
+   \r
+   <extension\r
+         point="org.eclipse.core.expressions.propertyTesters">\r
+      <propertyTester\r
+            class="org.simantics.browsing.ui.swt.NodePropertyTester"\r
+            id="org.simantics.browsing.ui.nodePropertyTester"\r
+            namespace="org.simantics.sysdyn.ui"\r
+            properties="nodeClass"\r
+            type="org.eclipse.jface.viewers.IStructuredSelection">\r
+      </propertyTester>\r
+      <propertyTester\r
+            class="org.simantics.sysdyn.ui.browser.nodes.ExportTester"\r
+            id="org.simantics.sysdyn.ui.selectionPropertyTester"\r
+            namespace="org.simantics.sysdyn.ui"\r
+            properties="nodeClass2"\r
+            type="org.eclipse.jface.viewers.IStructuredSelection">\r
+      </propertyTester>\r
+   </extension>\r
+   <extension\r
+         id="product"\r
+         point="org.eclipse.core.runtime.products">\r
+      <product\r
+            application="org.simantics.workbench.application"\r
+            description="Simantics System Dynamic Modelling Environment"\r
+            name="Simantics System Dynamic Tool">\r
+         <property\r
+               name="appName"\r
+               value="Simantics System Dynamic Tool">\r
+         </property>\r
+         <property\r
+               name="preferenceCustomization"\r
+               value="plugin_customization.ini">\r
+         </property>\r
+         <property\r
+               name="windowImages"\r
+               value="icons/simantics_sysdyn16.png,icons/simantics_sysdyn32.png,icons/simantics_sysdyn48.png,icons/simantics_sysdyn64.png,icons/simantics_sysdyn128.png">\r
+         </property>\r
+         <property\r
+               name="aboutText"\r
+               value="%about.text">\r
+         </property>\r
+         <property\r
+               name="aboutImage"\r
+               value="icons/simantics_sysdyn128.png">\r
+         </property>\r
+      </product>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.viewpointContributionBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ModuleType"\r
+               preference="1.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Project"\r
+               preference="1.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Modules"\r
+               preference="1.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Model"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationContribution"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationContribution2"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.LibraryContribution"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Experiment"\r
+               preference="1.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResult"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultSet"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Configuration"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.FunctionLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.LibraryFunctions"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SharedFunctionLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Book"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.Charts"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SCLModules"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.InitialConditions"\r
+               preference="2">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/AvailableVariableIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.AvailableEnumerations"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/UsedVariableIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.UsedEnumerations"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/EnumerationIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationIndexes"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/EnumerationReplacement">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.ReplaceableEnumerations"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ExternalFiles">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.externalFiles.ExternalFiles"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ModelBrowser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SysdynProject"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/AvailableSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.functions.SharedFunctionLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/SelectedSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.functions.SelectedSharedFunctionLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/FunctionTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeModels"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeSharedLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeSubLibraries"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ImportModuleTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.modules.ModuleTreeModels"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ExportModuleTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.modules.ModuleTreeModels"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.modules.ModuleTreeModules"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.comparableContextBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.modeling.ui.modelBrowser2.contributions.LexicalComparableContributor"\r
+               preference="1.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   \r
+   <extension\r
+         point="org.simantics.browsing.ui.common.labelerBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SharedOntologyLabeler"\r
+               preference="3.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ConfigurationLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.VariableLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ExperimentsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ModelLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ModulesLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ExperimentLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultSetLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ModuleLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.InputLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ModuleTypeLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.FunctionsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.FunctionLibraryLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SharedFunctionsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.BookLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SheetLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SCLModulesLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.InitialConditionsLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SCLModuleLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.InitialConditionLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationTypeLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationValueLabeler"\r
+               preference="2">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.LibraryLabeler"\r
+               preference="2">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/AvailableVariableIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationLabeler"\r
+               preference="1.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/UsedVariableIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.ConflictingEnumerationLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/EnumerationIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationIndexLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/EnumerationReplacement">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.ReplaceableEnumerationsLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ExternalFiles">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.externalFiles.ExternalFileLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/AvailableSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.FunctionLibraryLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/SelectedSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.FunctionLibraryLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/FunctionTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeModelLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeFunctionLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeSharedLibraryLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeSharedFolderLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ImportModuleTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeModelLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ExportModuleTree">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.modules.ModuleTreeModulesLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.wizards.functions.FunctionTreeModelLabeler"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.imagerBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SharedOntologyImager"\r
+               preference="3.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationTypeImager"\r
+               preference="3.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AnnotationValueImager"\r
+               preference="3.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.LibraryImager"\r
+               preference="3.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.browsing.ui.swt.ImageDescriptorProviderAdapter"\r
+               preference="1.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AbstractNodeImager"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultImager"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultSetImager"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartImager"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ChartsImager"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ExternalFiles">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.externalFiles.ExternalFileImager"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/AvailableSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AbstractNodeImager"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/SelectedSharedFunctionLibraries">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.AbstractNodeImager"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.labelDecoratorBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultDecorator"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.SimulationResultSetDecorator"\r
+               preference="2.0">\r
+         </implementation>\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.browser.contributions.ExperimentLabelDecorator"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.selectionProcessorBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/Browser">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.ResourceSelectionProcessor">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Modeling-0.0/ModelingBrowseContext">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.ResourceSelectionProcessor">\r
+         </implementation>\r
+      </binding>\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/ModelingBrowseContext">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.ResourceSelectionProcessor">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.browsing.ui.common.checkedStateBinding">\r
+      <binding\r
+            browseContext="http://www.simantics.org/Sysdyn-0.0/EnumerationIndexes">\r
+         <implementation\r
+               class="org.simantics.sysdyn.ui.properties.widgets.arrays.ShowInChartsCheckBox"\r
+               preference="2.0">\r
+         </implementation>\r
+      </binding>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.ui.resourceEditorAdapter">\r
+      <adapterClass\r
+            class="org.simantics.sysdyn.ui.editor.OpenDiagramFromConfigurationAdapter"\r
+            groupId="org.simantics.diagramEditor.group"\r
+            priority="100">\r
+      </adapterClass>\r
+      <adapterClass\r
+            class="org.simantics.sysdyn.ui.editor.OpenDiagramFromComponentAdapter"\r
+            priority="90">\r
+      </adapterClass>\r
+      <adapter\r
+            editorId="org.simantics.sysdyn.ui.modelicaEditor"\r
+            priority="2"\r
+            type_uris="http://www.simantics.org/Sysdyn-0.0/Configuration">\r
+      </adapter>\r
+      <adapter\r
+            editorId="org.simantics.sysdyn.ui.jfreeChartEditor"\r
+            priority="2"\r
+            type_uris="http://www.simantics.org/JFreeChart-0.0/Chart">\r
+      </adapter>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.ui.doubleClick">\r
+      <doubleClickAction\r
+            class="org.simantics.sysdyn.ui.actions.ActivateExperimentAction"\r
+            name="Activate Sysdyn Experiment"\r
+            priority="300.0">\r
+      </doubleClickAction>\r
+      <doubleClickAction\r
+            class="org.simantics.sysdyn.ui.browser.actions.ActivateResultDatasetAction"\r
+            name="Activate Result In Charts"\r
+            priority="250.0">\r
+      </doubleClickAction>  \r
+      <doubleClickAction\r
+            class="org.simantics.sysdyn.ui.browser.actions.ActivateResultSetDatasetAction"\r
+            name="Activate Result In Charts"\r
+            priority="240.0">\r
+      </doubleClickAction> \r
+      <doubleClickAction\r
+            class="org.simantics.sysdyn.ui.browser.actions.OpenSheetAction"\r
+            name="Open Spreadsheet"\r
+            priority="220.0">\r
+      </doubleClickAction>\r
+      <!--<doubleClickAction\r
+            class="org.simantics.sysdyn.ui.actions.ConsumeUnnecessaryEntersAction"\r
+            name="Consume unnecessary enters"\r
+            priority="200.0">\r
+      </doubleClickAction>-->\r
+      <doubleClickAction\r
+            class="org.simantics.sysdyn.ui.actions.ShowInstantiatedModuleAction"\r
+            name="Show Instantiated Module"\r
+            priority="100.0">\r
+      </doubleClickAction>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.ui.toolbarCommand">\r
+      <command\r
+            commandId="org.simantics.sysdyn.ui.diagramTool"\r
+            image="platform:/plugin/com.famfamfam.silk/icons/lock.png"\r
+            name="Lock Sketch"\r
+            toolbarId="org.simantics.sysdyn.ui.diagramToolbar"\r
+            type="radio"\r
+            value="lock">\r
+      </command>\r
+      <command\r
+            commandId="org.simantics.sysdyn.ui.diagramTool"\r
+            image="icons/cursor.png"\r
+            name="Pointer"\r
+            toolbarId="org.simantics.sysdyn.ui.diagramToolbar"\r
+            type="radio"\r
+            value="pointer">\r
+      </command>\r
+      <command\r
+            commandId="org.simantics.sysdyn.ui.diagramTool"\r
+            image="icons/dependency.png"\r
+            name="Create Dependency (Alt+Mouse1)"\r
+            toolbarId="org.simantics.sysdyn.ui.diagramToolbar"\r
+            type="radio"\r
+            value="dependency">\r
+      </command>\r
+      <command\r
+            commandId="org.simantics.sysdyn.ui.diagramTool"\r
+            image="icons/flow.png"\r
+            name="Create Flow (Alt+Mouse2)"\r
+            toolbarId="org.simantics.sysdyn.ui.diagramToolbar"\r
+            type="radio"\r
+            value="flow">\r
+      </command>\r
+      <command\r
+            commandId="org.simantics.sysdyn.ui.diagramTool"\r
+            image="platform:/plugin/com.famfamfam.silk/icons/textfield_add.png"\r
+            name="Create Auxiliary (Shift+A)"\r
+            toolbarId="org.simantics.sysdyn.ui.diagramToolbar"\r
+            type="radio"\r
+            value="auxiliary">\r
+      </command>\r
+   </extension>\r
+   <extension\r
+         point="org.simantics.project.feature">\r
+      <feature\r
+            class="org.simantics.sysdyn.ui.project.SysdynProject"\r
+            description="System dynamics modelling project. Create system dynamics models and simulate them with OpenModelica."\r
+            id="org.simantics.sysdyn.project"\r
+            label="System Dynamics Project"\r
+            published="true">\r
+         <requires id="org.simantics.sysdyn.dependencies"/>\r
+         <requires id="org.simantics.simulation.experimentManager"/>\r
+         <installGroup id="org.simantics.sysdyn.feature.group" version="[1.0.0,2.0.0)"/>\r
+      </feature>\r
+      <feature\r
+            class="org.simantics.project.features.DependencyValidationFeature:http://www.simantics.org/Sysdyn-0.0/ImportedOntologies"\r
+            id="org.simantics.sysdyn.dependencies"\r
+            label="System Dynamics Ontology Dependencies">\r
+      </feature>\r
+   </extension>\r
+   \r
+   \r
+   <extension point="org.simantics.scl.reflection.binding">\r
+      <namespace path="http://www.simantics.org/Sysdyn-0.0/Validations">\r
+        <namespace path="Dependencies">\r
+            <externalClass className="org.simantics.db.Resource"/>\r
+            <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+            <externalClass className="org.simantics.db.ReadGraph"/>\r
+            <externalClass className="org.simantics.db.WriteGraph"/>\r
+            <class className="org.simantics.sysdyn.ui.validation.DependencyFunction"/>\r
+        </namespace>\r
+        <namespace path="Expressions">\r
+            <externalClass className="org.simantics.db.Resource"/>\r
+            <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+            <externalClass className="org.simantics.db.ReadGraph"/>\r
+            <externalClass className="org.simantics.db.WriteGraph"/>\r
+            <class className="org.simantics.sysdyn.ui.validation.ExpressionIssueFunction"/>\r
+        </namespace>\r
+        <namespace path="Functions">\r
+            <externalClass className="org.simantics.db.Resource"/>\r
+            <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+            <externalClass className="org.simantics.db.ReadGraph"/>\r
+            <externalClass className="org.simantics.db.WriteGraph"/>\r
+            <class className="org.simantics.sysdyn.ui.validation.Functions"/>\r
+        </namespace>\r
+        <namespace path="Enumerations">\r
+            <externalClass className="org.simantics.db.Resource"/>\r
+            <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+            <externalClass className="org.simantics.db.ReadGraph"/>\r
+            <externalClass className="org.simantics.db.WriteGraph"/>\r
+            <class className="org.simantics.sysdyn.ui.validation.EnumerationFunction"/>\r
+        </namespace>        \r
+        <namespace path="Units">\r
+            <externalClass className="org.simantics.db.Resource"/>\r
+            <externalClass className="org.simantics.db.layer0.variable.Variable"/>\r
+            <externalClass className="org.simantics.db.ReadGraph"/>\r
+            <externalClass className="org.simantics.db.WriteGraph"/>\r
+            <class className="org.simantics.sysdyn.ui.validation.UnitFunction"/>\r
+        </namespace>             \r
+      </namespace>\r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.ui.preferencePages">\r
+      <page\r
+            class="org.simantics.sysdyn.ui.preferences.SolverPreferencePage"\r
+            id="org.simantics.sysdyn.solver.preferences"\r
+            name="Solver">\r
+      </page>\r
+      <page\r
+            class="org.simantics.sysdyn.ui.preferences.ModelicaPreferencePage"\r
+            id="org.simantics.modelica.preferences"\r
+            name="Modelica">\r
+      </page>\r
+      <page\r
+            class="org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferencePage"\r
+            id="org.simantics.sysdyn.diagram.preferences"\r
+            name="Sysdyn Diagrams">\r
+      </page>      \r
+   </extension>\r
+   <extension\r
+         point="org.eclipse.core.runtime.preferences">\r
+      <initializer\r
+            class="org.simantics.modelica.preferences.ModelicaPreferenceInitializer">\r
+      </initializer>\r
+      <initializer\r
+            class="org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferencesInitializer">\r
+      </initializer>\r
+   </extension>\r
+   \r
+   <extension point="org.eclipse.core.expressions.definitions">\r
+      <definition\r
+            id="org.simantics.sysdyn.ui.inExpressionField">\r
+         <with variable="activePartId">\r
+            <equals\r
+                  value="org.simantics.browsing.ui.graph.propertyView">\r
+            </equals>\r
+         </with>\r
+      </definition>\r
+   </extension>\r
+   \r
+</plugin>\r
diff --git a/org.simantics.sysdyn.ui/plugin_customization.ini b/org.simantics.sysdyn.ui/plugin_customization.ini
new file mode 100644 (file)
index 0000000..2d6b595
--- /dev/null
@@ -0,0 +1,4 @@
+org.eclipse.ui/SHOW_PROGRESS_ON_STARTUP = false\r
+org.eclipse.ui/DOCK_PERSPECTIVE_BAR=right\r
+\r
+org.simantics.sysdyn.solver.preferences/SOLVER_TYPE=OPENMODELICA
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/splash.bmp b/org.simantics.sysdyn.ui/splash.bmp
new file mode 100644 (file)
index 0000000..3c372f6
Binary files /dev/null and b/org.simantics.sysdyn.ui/splash.bmp differ
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..5e1333d
--- /dev/null
@@ -0,0 +1,110 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui;\r
+\r
+import java.net.URL;\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.ImageDescriptor;\r
+import org.eclipse.jface.resource.ImageRegistry;\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.Bundle;\r
+import org.osgi.framework.BundleContext;\r
+import org.simantics.issues.Severity;\r
+import org.simantics.utils.FileUtils;\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
+    public static String          FATAL_SVG_TEXT;\r
+    public static String          ERROR_SVG_TEXT;\r
+    public static String          WARNING_SVG_TEXT;\r
+    public static ImageDescriptor FATAL_DECORATION_ICON;\r
+    public static ImageDescriptor ERROR_DECORATION_ICON;\r
+    public static ImageDescriptor WARNING_DECORATION_ICON;\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
+        Bundle bundle = context.getBundle();\r
+\r
+        FATAL_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/fatal.svg"));\r
+        ERROR_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/error.svg"));\r
+        WARNING_SVG_TEXT = FileUtils.getContents(bundle.getResource("icons/warning.svg"));\r
+        FATAL_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/fatal_decoration.png"));\r
+        ERROR_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/error_decoration.png"));\r
+        WARNING_DECORATION_ICON = ImageDescriptor.createFromURL(bundle.getResource("icons/warning_decoration.png"));\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
+    @Override\r
+    protected ImageRegistry createImageRegistry() {\r
+        return super.createImageRegistry();\r
+    }\r
+\r
+    @Override\r
+    protected void initializeImageRegistry(ImageRegistry reg) {\r
+        reg.put(Severity.FATAL.toString(), FATAL_DECORATION_ICON);\r
+        reg.put(Severity.ERROR.toString(), ERROR_DECORATION_ICON);\r
+        reg.put(Severity.WARNING.toString(), WARNING_DECORATION_ICON);\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
+    public static URL getDefaultResource(String name) {\r
+        Activator plugin = getDefault();\r
+        if(plugin == null) throw new IllegalStateException("The plugin is not active.");\r
+        return plugin.getBundle().getResource(name);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/PropertyViewUndoHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/PropertyViewUndoHandler.java
new file mode 100644 (file)
index 0000000..9fc3a96
--- /dev/null
@@ -0,0 +1,51 @@
+package org.simantics.sysdyn.ui;\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.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.ui.workbench.handler.SessionUndoHandler;\r
+\r
+public class PropertyViewUndoHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        String id = event.getCommand().getId();\r
+        \r
+        Event e = (Event)event.getTrigger();\r
+        Widget w = e.widget;\r
+        Object data = w.getData(TrackedText.ID);\r
+        if (data != null) {\r
+            TrackedText text = (TrackedText) data;\r
+            if (id.equals("org.eclipse.ui.edit.undo"))\r
+                text.undo();\r
+            else\r
+                text.redo();\r
+            return null;\r
+        }\r
+        \r
+        \r
+        Composite c = ((Control)((Event)event.getTrigger()).widget).getParent();\r
+        if (c instanceof ExpressionField) {\r
+            ExpressionField f = (ExpressionField)c;\r
+            if (id.equals("org.eclipse.ui.edit.undo")) {\r
+                f.getSourceViewer().getUndoManager().undo();\r
+            }\r
+            else {\r
+                f.getSourceViewer().getUndoManager().redo();\r
+            }\r
+        } else {\r
+                SessionUndoHandler suh = new SessionUndoHandler();\r
+                suh.execute(event);\r
+                //Layer0Utils.undo();\r
+            \r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ActivateExperimentAction.java
new file mode 100644 (file)
index 0000000..4e00ace
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.actions;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.action.PriorityAction;\r
+\r
+public class ActivateExperimentAction implements IDoubleClickAction {\r
+\r
+       @Override\r
+       public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+        ReadGraph g = e.getGraph();\r
+        final Resource experiment = ResourceAdaptionUtils.toSingleResource(e.getResource());\r
+        if (experiment == null)\r
+            return;\r
+\r
+        if (g.isInstanceOf(experiment, SimulationResource.getInstance(g).Experiment)) {\r
+            final IProject project = SimanticsUI.getProject();\r
+            if (project == null)\r
+                return;\r
+\r
+            final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+            if (experimentManager == null) {\r
+                ErrorLogger.defaultLogWarning("Experiment manager not available.", new Exception());\r
+                return;\r
+            }\r
+\r
+            e.add(new PriorityAction(PriorityAction.HIGH+20) {\r
+                @Override\r
+                public void run() {\r
+                       SysdynExperimentActivator.scheduleActivation(SimanticsUI.getSession(), project, experimentManager, experiment);\r
+                }\r
+            });\r
+            e.consume();\r
+        }\r
+               \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ConsumeUnnecessaryEntersAction.java
new file mode 100644 (file)
index 0000000..b5a284d
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.actions;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.action.PriorityAction;\r
+\r
+public class ConsumeUnnecessaryEntersAction implements IDoubleClickAction {\r
+\r
+       @Override\r
+       public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+        ReadGraph g = e.getGraph();\r
+        Layer0X L0X = Layer0X.getInstance(g);\r
+        final Resource resource = ResourceAdaptionUtils.toSingleResource(e.getResource());\r
+        if(resource == null)\r
+               return;\r
+               SysdynResource sr = SysdynResource.getInstance(g);\r
+               \r
+               if(g.isInheritedFrom(resource, sr.SysdynModel) \r
+                               || (g.isInstanceOf(resource, sr.Variable)\r
+                                               && !g.isInstanceOf(resource, sr.IndependentVariable)\r
+                                               && !g.isInstanceOf(resource, sr.Input)\r
+                               )) {\r
+                       consume(e);\r
+               } else if(g.hasStatement(resource, L0X.Represents)){\r
+                       Resource represents = g.getSingleObject(resource, L0X.Represents);      \r
+                       if (g.isInstanceOf(represents, sr.Variable)\r
+                                       && !g.isInstanceOf(resource, sr.IndependentVariable)\r
+                                       && !g.isInstanceOf(resource, sr.Input)) {\r
+                               consume(e);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private void consume(DoubleClickEvent e) {\r
+        e.add(new PriorityAction(PriorityAction.HIGH) {\r
+            @Override\r
+            public void run() {\r
+               \r
+            }\r
+        });\r
+               e.consume();\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/ShowInstantiatedModuleAction.java
new file mode 100644 (file)
index 0000000..830b2c5
--- /dev/null
@@ -0,0 +1,137 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.actions;\r
+\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.ui.PartInitException;\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.request.PossibleModel;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.BrowserSelection;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleNode;\r
+import org.simantics.sysdyn.ui.editor.SysdynEditorInput;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\r
+import org.simantics.ui.workbench.ResourceEditorInput2;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+import org.simantics.utils.ui.action.PriorityAction;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * Open an editor for a module instance. \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ShowInstantiatedModuleAction implements IDoubleClickAction {\r
+\r
+    private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+    \r
+       @Override\r
+       public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+               \r
+        ReadGraph g = e.getGraph();\r
+        Layer0 l0 = Layer0.getInstance(g);\r
+        StructuralResource2 sr2 = StructuralResource2.getInstance(g);\r
+\r
+        // Open instance for a module instance, if the resource is adaptable to variable\r
+        Variable variable = AdaptionUtils.adaptToSingle(e.getResource(), Variable.class);\r
+        if(variable != null) {\r
+            Resource represents = variable.getRepresents(g);\r
+            Resource instanceOf = g.getPossibleObject(represents, l0.InstanceOf);\r
+            Resource configuration = g.getPossibleObject(instanceOf, sr2.IsDefinedBy);\r
+            if(configuration != null) {\r
+                String rvi = Variables.getRVI(g, variable);\r
+                if(!rvi.isEmpty())\r
+                    rvi = rvi.substring(1);\r
+                Resource model = Variables.getModel(g, variable);\r
+                addShowModuleAction(e, getResourceEditorInput(g, model, configuration, rvi));\r
+                return;\r
+            }\r
+        }\r
+        \r
+        if(e.getResource() instanceof IStructuredSelection) {\r
+                       Set<BrowserSelection> bss = ISelectionUtils.filterSetSelection(e.getResource(), BrowserSelection.class);\r
+                       \r
+                       if(!bss.isEmpty()) {\r
+                        // Find varaible from BrowserSelection. (Will be replaced with the Variable adaption above)\r
+                               for(BrowserSelection bs : bss) {\r
+                                       Resource configuration = (Resource)bs.getAdapter(Resource.class);\r
+                                       Resource instanceOf = g.getSingleObject(configuration, l0.InstanceOf);\r
+                                       \r
+                                       SysdynResource sr = SysdynResource.getInstance(g);\r
+                                       if(g.isInheritedFrom(instanceOf, sr.Module)) {\r
+                                               configuration = g.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+                                               variable = (Variable) bs.getAdapter(Variable.class);\r
+                                               String rvi = Variables.getRVI(g, variable).substring(1);\r
+                                               Resource model = Variables.getModel(g, variable);\r
+                                               addShowModuleAction(e, getResourceEditorInput(g, model, configuration, rvi));\r
+                                       } \r
+                               }\r
+                       } else {\r
+                               ModuleNode moduleNode = ISelectionUtils.filterSingleSelection(e.getResource(), ModuleNode.class);\r
+                               if(moduleNode != null) {\r
+                                       Resource model;\r
+                                       String rvi;\r
+                                       if(moduleNode.getVariable() != null) {\r
+                                               model = Variables.getModel(g, moduleNode.getVariable());\r
+                                               Variable var = moduleNode.getVariable();\r
+                                               rvi = Variables.getRVI(g, var).substring(1);\r
+                                       } else {\r
+                                               rvi = (String)g.getRelatedValue(moduleNode.data, Layer0.getInstance(g).HasName);\r
+                                               model = g.getSingleObject(moduleNode.data, l0.PartOf);\r
+                                       }\r
+                                       \r
+                               Resource instanceOf = g.getSingleObject(moduleNode.data, l0.InstanceOf);\r
+                                       Resource conf = g.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+                                   \r
+                                       addShowModuleAction(e, getResourceEditorInput(g, model, conf, rvi));\r
+                       }\r
+                       }\r
+        } \r
+       }\r
+       \r
+       private ResourceEditorInput2 getResourceEditorInput(ReadGraph g, Resource model, Resource configuration, String rvi) throws DatabaseException {\r
+\r
+               if(model == null) {\r
+                       model = g.syncRequest(new PossibleModel(model));\r
+                       rvi = null;\r
+               }\r
+               \r
+               Resource diagram = g.getSingleObject(configuration, ModelingResources.getInstance(g).CompositeToDiagram);\r
+               return new SysdynEditorInput(EDITOR_ID, diagram, model, rvi == null ? "" : "/" + rvi);\r
+       }\r
+       \r
+       private void addShowModuleAction(DoubleClickEvent e, final ResourceEditorInput2 editorInput) {\r
+        e.add(new PriorityAction(PriorityAction.HIGH) {\r
+            @Override\r
+            public void run() {\r
+               try {\r
+                                       WorkbenchUtils.openEditor(EDITOR_ID, editorInput);\r
+                               } catch (PartInitException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+            }\r
+        });\r
+               e.consume();\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/actions/SysdynVariableRemover.java
new file mode 100644 (file)
index 0000000..107a172
--- /dev/null
@@ -0,0 +1,115 @@
+package org.simantics.sysdyn.ui.actions;\r
+\r
+import java.util.Map;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithSupertype;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.Instances;\r
+import org.simantics.db.layer0.adapter.Remover;\r
+import org.simantics.db.layer0.adapter.impl.EntityRemover;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.project.ontology.ProjectResource;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Remover for sysdyn variables. The main purpose is to take care that input and output references\r
+ * are removed \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynVariableRemover implements Remover {\r
+    \r
+    private Resource resource;\r
+     \r
+    public SysdynVariableRemover(Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+\r
+    @Override\r
+    public String canRemove(ReadGraph graph, Map<Object, Object> aux) throws DatabaseException {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void remove(WriteGraph graph) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        // Take care of inputs and outputs\r
+        if(graph.hasStatement(resource, SR.IsOutput) || graph.isInstanceOf(resource, SR.Input)) {\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            ProjectResource PROJ = ProjectResource.getInstance(graph);\r
+            Resource configuration = graph.getPossibleObject(resource, L0.PartOf);\r
+            if(configuration != null) {\r
+                Resource moduleType =  graph.getPossibleObject(configuration, L0.PartOf);\r
+                if(graph.isInheritedFrom(moduleType, SR.Module)) {\r
+                    Resource project = moduleType;\r
+                    do {\r
+                        project = graph.getPossibleObject(project, L0.PartOf);\r
+                    } while (project != null && !graph.isInstanceOf(project, PROJ.Project));\r
+\r
+                    if(project != null) {\r
+                        for(Resource model : graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, SR.SysdynModel))) {\r
+                            removeOutputReferencesFromModel(graph, model, resource, moduleType);\r
+                        }\r
+                    }\r
+\r
+                }\r
+            }\r
+        }\r
+\r
+        // Remove possible shadow variables\r
+        for(Resource shadow : graph.getObjects(resource, SR.Shadow_original_Inverse)) {\r
+            Resource element = graph.getPossibleObject(shadow, ModelingResources.getInstance(graph).ComponentToElement);\r
+            // TODO: not sure if this is correct, but without this the removal \r
+            // of a model with several shadow variables that have the same \r
+            // original variable fails in an assertion error\r
+            if (element != null)\r
+               RemoverUtil.remove(graph, element);\r
+        }\r
+        \r
+        EntityRemover.remove(graph, resource);\r
+\r
+    }\r
+\r
+    private void removeOutputReferencesFromModel(WriteGraph graph, Resource model, Resource reference, Resource moduleType) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        StructuralResource2 SR2 = StructuralResource2.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        \r
+        Instances moduleInstanceFinder = graph.adapt(moduleType, Instances.class);\r
+        \r
+        denyReferences(graph, moduleInstanceFinder, graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration), reference);\r
+        \r
+        for(Resource type : graph.syncRequest(new ObjectsWithSupertype(model, L0.ConsistsOf, SR.Module))) {\r
+            Resource configuration = graph.getPossibleObject(type, SR2.IsDefinedBy);\r
+            denyReferences(graph, moduleInstanceFinder, configuration, reference);\r
+\r
+        }\r
+        \r
+    }\r
+    \r
+    private void denyReferences(WriteGraph graph, Instances moduleInstanceFinder, Resource indexRoot, Resource reference) throws DatabaseException {\r
+        StructuralResource2 SR2 = StructuralResource2.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+        for(Resource module : moduleInstanceFinder.find(graph, indexRoot)) {\r
+            for(Statement stm : graph.getStatements(module, SR2.IsConnectedTo)) {\r
+                Resource connection = stm.getObject();\r
+                Resource ref = graph.getPossibleObject(connection, SR.Dependency_refersTo);\r
+                if(ref != null && ref.equals(reference)) {\r
+                    graph.deny(connection, SR.Dependency_refersTo);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/BrowserSelection.java
new file mode 100644 (file)
index 0000000..cfd31c8
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+\r
+public class BrowserSelection implements IAdaptable, ISelection {\r
+       private Resource resource;\r
+       private Object originalInput;\r
+       private Variable variable;\r
+\r
+       public BrowserSelection(Object originalInput, VariableNode<Variable> vn) {\r
+               this.originalInput = originalInput;\r
+               this.resource = vn.data;\r
+               Variable variable = vn.getVariable();\r
+               if(variable != null) {\r
+                       this.variable = variable;\r
+               }\r
+       }\r
+\r
+       @SuppressWarnings("rawtypes")\r
+       @Override\r
+       public Object getAdapter(Class adapter) {\r
+               if (adapter == Resource.class)\r
+                       return resource;\r
+               if (adapter == Variable.class)\r
+                       return variable;\r
+               if (NodeContext.class.equals(adapter))\r
+            return originalInput;\r
+               if (originalInput instanceof IAdaptable) {\r
+                       IAdaptable input = (IAdaptable)originalInput;\r
+                       return input.getAdapter(adapter);\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public boolean isEmpty() {\r
+               if(originalInput == null)\r
+                       return true;\r
+               return false;\r
+       }\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..8cda472
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.platform.GraphExplorerView;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.ContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver;\r
+import org.simantics.browsing.ui.swt.GraphExplorerFactory;\r
+import org.simantics.browsing.ui.swt.IContextMenuInitializer;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ResourceRead;\r
+import org.simantics.db.common.utils.Logger;\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.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.ui.selection.AnyResource;\r
+import org.simantics.ui.selection.AnyVariable;\r
+import org.simantics.ui.selection.WorkbenchSelectionContentType;\r
+import org.simantics.ui.workbench.IPropertyPage;\r
+import org.simantics.utils.datastructures.BinaryFunction;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+\r
+\r
+public class SysdynBrowser extends GraphExplorerView {\r
+    \r
+    private static final Set<String> browseContexts  = new HashSet<String>(Arrays.asList(\r
+            "http://www.simantics.org/Sysdyn-1.1/Browser",  \r
+            "http://www.semantum.fi/SimupediaWorkbench-1.0/OldBrowser",\r
+            "http://www.simantics.org/Image-1.1/Browser"));    \r
+\r
+    private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {\r
+\r
+        \r
+        /*\r
+        private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN };\r
+        \r
+        @Override\r
+        public Object[] call(GraphExplorer explorer, Object[] objects) {\r
+            Object[] result = new Object[objects.length];\r
+            for (int i = 0; i < objects.length; i++) {\r
+                SelectionElement context = new SelectionElement(KEYS, objects[i]);\r
+                context.setHint(SelectionHints.KEY_MAIN, objects[i]);\r
+                result[i] = context;\r
+            }\r
+            return result;\r
+        }\r
+        */\r
+        \r
+        class SelectionElement extends AdaptableHintContext {\r
+\r
+            private Variable variable;\r
+            private Resource resource;\r
+            \r
+            public SelectionElement(Variable variable, Resource resource, Key... keys) {\r
+                super(keys);\r
+                this.variable = variable;\r
+                this.resource = resource;\r
+            }\r
+\r
+            @SuppressWarnings("unchecked")\r
+            @Override\r
+            public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {\r
+                if(contentType instanceof AnyResource) return (T)resource;\r
+                else if(contentType instanceof AnyVariable) {\r
+                    AnyVariable type = (AnyVariable)contentType;\r
+                    try {\r
+                        \r
+                        if(variable != null) return (T)variable;\r
+                        \r
+                        if(resource == null) return null;\r
+                        \r
+                        return (T) type.processor.sync(new ResourceRead<Variable>(resource) {\r
+                            @Override\r
+                            public Variable perform(ReadGraph graph) throws DatabaseException {\r
+                                return Variables.getPossibleVariable(graph, resource);\r
+                            }\r
+                            \r
+                        });\r
+                    } catch (DatabaseException e) {\r
+                        Logger.defaultLogError(e);\r
+                    }\r
+                } \r
+                return null;\r
+            }                        \r
+\r
+        }\r
+\r
+               @Override\r
+               public Object[] call(GraphExplorer explorer, Object[] objects) {\r
+               Object[] result = new Object[objects.length];\r
+               for (int i = 0; i < objects.length; i++) {\r
+                       \r
+                       NodeContext ctx = (NodeContext)objects[i];        \r
+                   @SuppressWarnings("unchecked")\r
+                               VariableNode<Variable> vn = (VariableNode<Variable>) ctx.getAdapter(VariableNode.class);\r
+                   IHintContext context;\r
+                   if(vn != null && vn.getVariable() != null) {\r
+                       context = new SelectionElement(vn.getVariable(),vn.data, SelectionHints.KEY_MAIN, SelectionHints.KEY_SELECTION_PROPERTY);\r
+                       context.setHint(SelectionHints.KEY_MAIN, new BrowserSelection(objects[i], vn));\r
+                       context.setHint(SelectionHints.KEY_SELECTION_PROPERTY, vn.getVariable());\r
+                   } else {\r
+                       Object resource = ctx.getAdapter(Resource.class);\r
+                       context = new SelectionElement(null, resource == null ? null : (Resource)resource, SelectionHints.KEY_MAIN);\r
+                       context.setHint(SelectionHints.KEY_MAIN, objects[i]);\r
+                   }\r
+                   result[i] = context;\r
+               }\r
+               return result;\r
+               }\r
+       \r
+    };\r
+    \r
+    protected GraphExplorer createExplorerControl(Composite parent) {\r
+        return GraphExplorerFactory.getInstance()\r
+        .selectionDataResolver(new DefaultSelectionDataResolver())\r
+        .selectionTransformation(selectionTransformation)\r
+        .create(parent, getStyle());\r
+    }\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("rawtypes")\r
+       @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if (adapter == IPropertyPage.class)\r
+            return new SysdynPropertyPage(getSite(), Collections.singleton(SysdynResource.URIs.Browser));\r
+        return super.getAdapter(adapter);\r
+    }\r
+    \r
+    public SysdynBrowser() {\r
+       hideComparatorSelector = true;\r
+       hideViewpointSelector = true;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynModelBrowser.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/SysdynModelBrowser.java
new file mode 100644 (file)
index 0000000..b2e0e0e
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.simantics.structural.ui.modelBrowser.ModelBrowser2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.ui.workbench.IPropertyPage;\r
+\r
+/**\r
+ * Model browser for sysdyn models. Content configured in SysdynModelingViewpoint.pgraph\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynModelBrowser extends ModelBrowser2 {\r
+\r
+    final private Set<String> browseContexts  = new HashSet<String>(Arrays.asList(SysdynResource.URIs.ModelingBrowseContext, "http://www.simantics.org/Operating-1.1/Browser", "http://www.simantics.org/Image-1.1/Browser"));\r
+\r
+    @Override\r
+    protected IPropertyPage getPropertyPage() {\r
+        return new SysdynPropertyPage(getSite(), Collections.singleton(SysdynResource.URIs.ModelingBrowseContext));\r
+    }\r
+\r
+    @Override\r
+    protected Set<String> getBrowseContexts() {\r
+        return browseContexts;\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultDatasetAction.java
new file mode 100644 (file)
index 0000000..8c7e6fb
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions;\r
+\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+/**\r
+ * Activates a result dataset to be shown in charts and other result visualizations\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ActivateResultDatasetAction implements IDoubleClickAction {\r
+\r
+    @Override\r
+    public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+        final Resource result = ResourceAdaptionUtils.toSingleResource(e.getResource());\r
+        if (result == null)\r
+            return;\r
+\r
+        ReadGraph graph = e.getGraph();\r
+\r
+        if(graph.isInstanceOf(result, SysdynResource.getInstance(graph).Result)) {\r
+\r
+            graph.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException {\r
+                    SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    if(graph.isInstanceOf(result, sr.Result)) {\r
+                        if (graph.hasStatement(result, sr.Result_showResult)) {\r
+                            graph.denyStatement(result, sr.Result_showResult, result);\r
+                        } else {\r
+                            graph.claim(result, sr.Result_showResult, result);\r
+                        }\r
+                    }                \r
+                }\r
+            });\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/ActivateResultSetDatasetAction.java
new file mode 100644 (file)
index 0000000..3ad688e
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions;\r
+\r
+import java.util.Collection;\r
+\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.sysdyn.SysdynResource;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+/**\r
+ * Activates the result datasets of a result set to be shown in charts and other result visualizations\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ActivateResultSetDatasetAction implements IDoubleClickAction {\r
+\r
+    @Override\r
+    public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+        final Resource resultSet = ResourceAdaptionUtils.toSingleResource(e.getResource());\r
+        if (resultSet == null)\r
+            return;\r
+\r
+        ReadGraph graph = e.getGraph();\r
+\r
+        if(graph.isInstanceOf(resultSet, SysdynResource.getInstance(graph).ResultSet)) {\r
+\r
+            graph.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException {\r
+                    SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    if(graph.isInstanceOf(resultSet, sr.ResultSet)) {\r
+                       // If there is at least one result which shown, clear them all.\r
+                       // If not one result is shown, show them all.\r
+                       boolean resultShown = false;\r
+                       Collection<Resource> results = graph.getObjects(resultSet, sr.Experiment_result); \r
+                       for (Resource result : results) {\r
+                               if (graph.hasStatement(result, sr.Result_showResult)) {\r
+                                       resultShown = true;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       for (Resource result : results) {\r
+                               if (resultShown) { \r
+                                       graph.denyStatement(result, sr.Result_showResult, result);\r
+                            } else {\r
+                                graph.claim(result, sr.Result_showResult, result);\r
+                            }\r
+                       }\r
+                    }                \r
+                }\r
+            });\r
+            e.consume();\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/OpenSheetAction.java
new file mode 100644 (file)
index 0000000..91e560e
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions;\r
+\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.PlatformUI;\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.RVI;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.ui.DoubleClickEvent;\r
+import org.simantics.ui.IDoubleClickAction;\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
+ * Opens the selected spreadsheet in a spreadsheet editor \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class OpenSheetAction implements IDoubleClickAction {\r
+\r
+    @Override\r
+    public void doubleClickEvent(DoubleClickEvent e) throws DatabaseException {\r
+        Resource result = ResourceAdaptionUtils.toSingleResource(e.getResource());\r
+        if (result == null)\r
+            return;\r
+        \r
+        ReadGraph graph = e.getGraph();\r
+        SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+\r
+        final Resource sheet = result;\r
+\r
+        if(graph.isInstanceOf(sheet, SHEET.Spreadsheet)) {\r
+               \r
+            Variable variable = graph.adapt(sheet, Variable.class);\r
+            final Resource model = Variables.getModel(graph, variable);\r
+            final RVI rvi = variable.getRVI(graph);\r
+            \r
+            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+                private static final String EDITOR_ID = "org.simantics.spreadsheet.ui.editor2";\r
+\r
+                @Override\r
+                public void run() {\r
+                    try {\r
+                        WorkbenchUtils.openEditor(EDITOR_ID, new ResourceEditorInput2(EDITOR_ID, sheet, model, rvi));\r
+                    } catch (PartInitException e) {\r
+                        e.printStackTrace();\r
+                    }\r
+                }\r
+            });\r
+\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/ChartDropAction.java
new file mode 100644 (file)
index 0000000..e5e308a
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.drop;\r
+\r
+import java.util.Iterator;\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\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.PossibleObjectWithType;\r
+import org.simantics.db.common.request.SingleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.DropActionFactory;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Action for droppin variables to charts\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartDropAction implements DropActionFactory {\r
+\r
+    @Override\r
+    public Runnable create(ReadGraph g, Object target, Object source, int operation) throws DatabaseException {\r
+\r
+        final Resource targetChart = AdaptionUtils.adaptToSingle(target, Resource.class);\r
+        if(targetChart == null || source == null || !(source instanceof IStructuredSelection))\r
+            return null;\r
+        \r
+        final IStructuredSelection selection = (IStructuredSelection) source;\r
+\r
+        return new Runnable() {\r
+\r
+            @Override\r
+            public void run() {\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        SysdynResource sr = SysdynResource.getInstance(graph);\r
+                        Layer0 L0 = Layer0.getInstance(graph);\r
+                        JFreeChartResource JFREE = JFreeChartResource.getInstance(graph);\r
+\r
+                        Iterator<?> iterator = selection.iterator();\r
+                        \r
+                        // Run through all selections and add all IndependentVariables and Inputs to the target chart\r
+                        while(iterator.hasNext()) {\r
+\r
+                            Variable variable = AdaptionUtils.adaptToSingle(iterator.next(), Variable.class);\r
+                            if(variable == null)\r
+                                continue;\r
+\r
+                            Resource represents = (Resource)variable.getPropertyValue(graph, Variables.REPRESENTS);\r
+                            if(represents == null || \r
+                                    !(graph.isInstanceOf(represents, sr.IndependentVariable) || \r
+                                            graph.isInstanceOf(represents, sr.Input)))\r
+                                continue;\r
+\r
+                            Resource plot = graph.syncRequest(new PossibleObjectWithType(targetChart, L0.ConsistsOf, JFREE.Plot));\r
+                            if(plot != null) {\r
+                                if(graph.isInstanceOf(plot, JFREE.XYPlot)) {\r
+                                    dropToLineChart(graph, targetChart, variable);\r
+                                } else if(graph.isInstanceOf(plot, JFREE.CategoryPlot)) {\r
+                                    dropToBarChart(graph, targetChart, variable);\r
+                                } else if(graph.isInstanceOf(plot, JFREE.PiePlot)) {\r
+                                    dropToPieChart(graph, targetChart, variable);\r
+                                }\r
+                            }\r
+                        }\r
+\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+\r
+    /**\r
+     * Drop variable to a pie chart\r
+     * @param graph ReadGraph\r
+     * @param pieChart Pie chart resource\r
+     * @param variable Dropped variable\r
+     * @throws DatabaseException\r
+     */\r
+    private void dropToPieChart(WriteGraph graph, Resource pieChart, Variable variable) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+        Resource plot = graph.syncRequest(new SingleObjectWithType(pieChart, l0.ConsistsOf, jfree.Plot));\r
+        if(plot == null)\r
+            return;\r
+\r
+        Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset));\r
+\r
+        if(dataset == null)\r
+            return;\r
+\r
+        // Create the series and attach it to the dataset\r
+        String rvi = Variables.getRVI(graph, variable);\r
+        Resource series = ChartUtils.createSeries(graph, dataset, rvi);\r
+        graph.claimLiteral(series, jfree.Series_exploded, false); \r
+    }\r
+\r
+    /**\r
+     * Drop variable to a bar chart\r
+     * @param graph ReadGraph\r
+     * @param barChart Bar chart resource\r
+     * @param variable Dropped variable\r
+     * @throws DatabaseException\r
+     */\r
+    private void dropToBarChart(WriteGraph graph, Resource barChart, Variable variable) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+        Resource plot = graph.syncRequest(new SingleObjectWithType(barChart, l0.ConsistsOf, jfree.Plot));\r
+        if(plot == null)\r
+            return;\r
+\r
+        Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset));\r
+\r
+        if(dataset == null)\r
+            return;\r
+\r
+        // Create the series and attach it to the dataset\r
+        String rvi = Variables.getRVI(graph, variable);\r
+        ChartUtils.createSeries(graph, dataset, rvi);\r
+    }\r
+\r
+    /**\r
+     * Drop variable to a line chart\r
+     * @param graph ReadGraph\r
+     * @param lineChart Line chart resource\r
+     * @param variable Dropped variable\r
+     * @throws DatabaseException\r
+     */\r
+    private void dropToLineChart(WriteGraph graph, Resource lineChart, Variable variable) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+        Resource plot = graph.syncRequest(new SingleObjectWithType(lineChart, l0.ConsistsOf, jfree.Plot));\r
+        if(plot == null)\r
+            return;\r
+\r
+        Resource rangeAxis = null;\r
+        Resource dataset = null;\r
+        Resource rangeAxisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList);\r
+        if(rangeAxisList == null ||  ListUtils.toList(graph, rangeAxisList).isEmpty()) {\r
+            // No range axis -> Create a new one\r
+            rangeAxis = ChartUtils.createNumberRangeAxis(graph, plot);\r
+            Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis);\r
+            dataset = ChartUtils.createXYDataset(graph, plot, domainAxis, rangeAxis);\r
+        } else {\r
+            rangeAxis = ListUtils.toList(graph, rangeAxisList).get(0);\r
+            dataset = graph.getPossibleObject(rangeAxis, jfree.Dataset_mapToRangeAxis_Inverse);\r
+        }\r
+\r
+        // Create the series and attach it to the dataset\r
+        String rvi = Variables.getRVI(graph, variable);\r
+        ChartUtils.createSeries(graph, dataset, rvi);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/drop/FunctionDropAction.java
new file mode 100644 (file)
index 0000000..cb3e162
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.drop;\r
+\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.layer0.adapter.DropActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Action for moving functions and function libraries in model browser \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FunctionDropAction implements DropActionFactory {\r
+\r
+    @Override\r
+    public Runnable create(ReadGraph g, Object target, Object source, int operation) throws DatabaseException {\r
+        Resource t = AdaptionUtils.adaptToSingle(target, Resource.class);\r
+        Resource s = AdaptionUtils.adaptToSingle(source, Resource.class);\r
+\r
+        if(t == null || s == null)\r
+            return null;\r
+\r
+        SysdynResource sr = SysdynResource.getInstance(g);\r
+        Layer0 L0 = Layer0.getInstance(g);\r
+\r
+        // If target is a function, find functions parent to be the drop target\r
+        if(g.isInstanceOf(t, sr.SysdynModelicaFunction))\r
+            t = g.getSingleObject(t, L0.PartOf);\r
+\r
+        final Resource library = t;\r
+        final Resource tobemoved = s;\r
+\r
+        // Libraries and model accept drops\r
+        if(!(g.isInstanceOf(library, sr.SysdynModelicaFunctionLibrary) || \r
+                g.isInstanceOf(library, sr.SysdynModel) ||\r
+                g.isInstanceOf(library, sr.SharedFunctionOntology)))\r
+            return null;\r
+\r
+        // Functions and function libraries can be dropped\r
+        if(!(g.isInstanceOf(tobemoved, sr.SysdynModelicaFunction) || \r
+                g.isInstanceOf(tobemoved, sr.SysdynModelicaFunctionLibrary)))\r
+            return null;\r
+\r
+\r
+        return new Runnable() {\r
+\r
+            @Override\r
+            public void run() {\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        Layer0 L0 = Layer0.getInstance(graph);\r
+                        Resource oldLib = graph.getSingleObject(tobemoved, L0.PartOf);\r
+\r
+                        // Remove dragged entity from its parent and add it to the new parent\r
+                        graph.claim(tobemoved, L0.PartOf, library);\r
+                        graph.deny(tobemoved, L0.PartOf, oldLib);\r
+                    }\r
+\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewBarChartAction.java
new file mode 100644 (file)
index 0000000..2e16bce
--- /dev/null
@@ -0,0 +1,111 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.util.Collections;\r
+import java.util.UUID;\r
+\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new bar chart to a model\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewBarChartAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource model = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                        G2DResource g2d = G2DResource.getInstance(graph);\r
+\r
+                        // Chart\r
+                        Resource jfreechart = GraphUtils.create2(graph, jfree.Chart,\r
+                                l0.HasName, "BarChart" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, NameUtils.findFreshLabel(graph, "Bar Chart", model),\r
+                                l0.PartOf, model,\r
+                                jfree.Chart_visibleBorder, true,\r
+                                jfree.Chart_borderWidth, 3,\r
+                                jfree.Chart_visibleLegend, false\r
+                                );\r
+                        \r
+                        // Border color\r
+                        graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                        // Title\r
+                        GraphUtils.create2(graph, jfree.TextTitle,\r
+                                l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, "Bar Chart Title",\r
+                                jfree.Title_position, jfree.Top,\r
+                                l0.PartOf, jfreechart);\r
+                        \r
+                        // X-axis\r
+                        Resource domainAxis = GraphUtils.create2(graph, jfree.CategoryAxis,\r
+                                l0.HasName, "CategoryAxis" + UUID.randomUUID().toString());\r
+                        \r
+                        // Y-axis\r
+                        Resource rangeAxis = GraphUtils.create2(graph, jfree.NumberAxis,\r
+                                l0.HasName, "NumberAxis" + UUID.randomUUID().toString());\r
+\r
+                        // Renderer\r
+                        Resource renderer = GraphUtils.create2(graph, jfree.BarRenderer);\r
+                        \r
+                        // Dataset \r
+                        Resource dataset = GraphUtils.create2(graph, jfree.CategoryDataset,\r
+                                l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(),\r
+                                jfree.Dataset_mapToDomainAxis, domainAxis,\r
+                                jfree.Dataset_mapToRangeAxis, rangeAxis,\r
+                                jfree.Dataset_seriesList, ListUtils.create(graph, Collections.<Resource>emptyList()),\r
+                                jfree.Dataset_renderer, renderer);\r
+\r
+                        // Plot\r
+                        GraphUtils.create2(graph, jfree.CategoryPlot,\r
+                                l0.HasName, "Category plot" + UUID.randomUUID().toString(),\r
+                                l0.PartOf, jfreechart,\r
+                                jfree.Plot_domainAxis, domainAxis,\r
+                                jfree.Plot_rangeAxis, rangeAxis,\r
+                                jfree.Plot_rangeAxisList, ListUtils.create(graph, Collections.singletonList(rangeAxis)),\r
+                                l0.ConsistsOf, dataset,\r
+                                l0.ConsistsOf, domainAxis,\r
+                                l0.ConsistsOf, rangeAxis);\r
+                    }\r
+\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewEnumerationAction.java
new file mode 100644 (file)
index 0000000..ffc74ba
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.util.Collections;\r
+\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new enumeration to a model or module\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewEnumerationAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource resource = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph g) throws DatabaseException {\r
+                        SysdynResource sr = SysdynResource.getInstance(g);\r
+                        Layer0 l0 = Layer0.getInstance(g);\r
+\r
+                        // Find the configuration from...\r
+                        Resource configuration = null;\r
+                        if(g.isInstanceOf(resource, sr.Configuration)) {\r
+                            configuration = resource;\r
+                        } else if(g.isInheritedFrom(resource, sr.ModuleSymbol)) {\r
+                            // Module symbol\r
+                            Resource module = g.getPossibleObject(resource,ModelingResources.getInstance(g).SymbolToComponentType);\r
+                            configuration = g.getPossibleObject(module, StructuralResource2.getInstance(g).IsDefinedBy);\r
+                        } else {\r
+                            // Module instance\r
+                            Resource instanceOf = g.getSingleObject(resource, l0.InstanceOf);\r
+                            if(g.isInheritedFrom(instanceOf, sr.Module)) {\r
+                                configuration = g.getPossibleObject(instanceOf, StructuralResource2.getInstance(g).IsDefinedBy);\r
+                            } else {\r
+                                return;\r
+                            }\r
+                        }\r
+\r
+                        // Find unique name\r
+                        String name = NameUtils.findFreshName(g, "Enum", configuration, l0.ConsistsOf, "%s%d");\r
+                        \r
+                        // Create enumeration\r
+                        GraphUtils.create2(g, \r
+                                sr.Enumeration,\r
+                                l0.HasName, name,\r
+                                sr.Enumeration_enumerationIndexList, ListUtils.create(g, Collections.<Resource>emptyList()),\r
+                                l0.PartOf, configuration);\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewExperimentAction.java
new file mode 100644 (file)
index 0000000..05f7914
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new basic experiment\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewExperimentAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource model = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        String name = NameUtils.findFreshName(graph, getNameSuggestion(), model, l0.ConsistsOf, "%s%d");\r
+\r
+                        Resource experiment = GraphUtils.create2(graph, getExperimentType(graph),\r
+                                l0.HasName, name,\r
+                                l0.HasLabel, name,\r
+                                l0.PartOf, model);\r
+                        \r
+                        configureExperiment(graph, experiment);\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+    /**\r
+     * Override to do experiment-specific alterations\r
+     */\r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Get the type of this experiment.\r
+     * \r
+     * @param g ReadGraph\r
+     * @return The type resource of this experiment\r
+     */\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).BasicExperiment;\r
+    }\r
+    \r
+    /**\r
+     * Returns the suggested name for this experiment.\r
+     * If the name has already been taken, appropriate prefix needs to be added. \r
+     *  \r
+     * @return Suggested name for this experiment. \r
+     */\r
+    protected String getNameSuggestion() {\r
+        return "Experiment";\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionAction.java
new file mode 100644 (file)
index 0000000..a76b5c1
--- /dev/null
@@ -0,0 +1,72 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new modelica function to a model, function library or shared function library.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewFunctionAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource resource = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph g) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(g);\r
+                        SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+                        Resource library = null;\r
+                        if(g.isInstanceOf(resource, sr.SysdynModel) || g.isInstanceOf(resource, l0.Library))\r
+                            library = resource;\r
+                        else if (g.isInstanceOf(resource, sr.SysdynModelicaFunction))\r
+                            library = g.getPossibleObject(resource, l0.PartOf);\r
+\r
+                        if(library == null)\r
+                            return;\r
+\r
+\r
+                        String name = NameUtils.findFreshName(g, "Function", library, l0.ConsistsOf, "%s%d");\r
+\r
+                        GraphUtils.create2(g, sr.SysdynModelicaFunction,\r
+                                l0.HasName, name,\r
+                                l0.HasDescription, "",\r
+                                sr.SysdynModelicaFunction_modelicaFunctionCode, "",\r
+                                l0.PartOf, library);\r
+                    }\r
+                });\r
+\r
+            }\r
+        };\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewFunctionLibraryAction.java
new file mode 100644 (file)
index 0000000..031e37e
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ResourceNotFoundException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new function library\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewFunctionLibraryAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource resource = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                createLibrary(resource, false);\r
+            }\r
+        };\r
+    }\r
+    \r
+    /**\r
+     * Create a new Library to the selected root or to SharedOntologies\r
+     * \r
+     * @param libraryLocation Resource of the model or other \r
+     * library where the new library will be added.\r
+     * @param shared is the library a shared library\r
+     */\r
+    protected static void createLibrary(final Resource libraryLocation, final boolean shared) {\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+                // Libraries can be created to model, function library and shared function library\r
+                if(!(g.isInstanceOf(libraryLocation, sr.SysdynModel) ||\r
+                        g.isInstanceOf(libraryLocation, sr.SysdynModelicaFunctionLibrary) ||\r
+                                g.isInstanceOf(libraryLocation, sr.SharedFunctionOntology)))\r
+                    return;\r
+\r
+                Resource root = libraryLocation;\r
+\r
+                String name = "FunctionLibrary";\r
+                Resource libraryType = sr.SysdynModelicaFunctionLibrary;\r
+                \r
+                if(shared) {\r
+                    \r
+                    try {\r
+                        root = g.getResource("http://SharedOntologies");\r
+                    } catch (ResourceNotFoundException e) {\r
+                        root = g.getResource("http:/");\r
+                        root = GraphUtils.create2(g, l0.Library, \r
+                                l0.HasName, "SharedOntologies",\r
+                                l0.PartOf, root);\r
+                    }\r
+                    \r
+                    name = "Shared" + name;\r
+                    libraryType = sr.SharedFunctionOntology;\r
+                }\r
+\r
+                name = NameUtils.findFreshName(g, name, root, l0.ConsistsOf, "%s%d");\r
+                \r
+                Resource functionLibrary = GraphUtils.create2(g, libraryType,\r
+                        l0.HasName, name,\r
+                        l0.HasDescription, "",\r
+                        l0.PartOf, root);\r
+                \r
+                if(shared)\r
+                    g.claim(libraryLocation, l0.IsLinkedTo, functionLibrary);\r
+            }\r
+        });\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewHistoryDataAction.java
new file mode 100644 (file)
index 0000000..43f0ffa
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.util.UUID;\r
+\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Create a new history data\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewHistoryDataAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource experiment = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\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
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        if(!graph.isInstanceOf(experiment, sr.Experiment))\r
+                            return; // Not called from an experiment\r
+\r
+                        Resource model = graph.getPossibleObject(experiment, l0.PartOf);\r
+                        // Create the history dataset\r
+                        GraphUtils.create2(graph, \r
+                                sr.HistoryDataset,\r
+                                l0.HasName, "HistoryDataset" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, NameUtils.findFreshLabel(graph, "History Dataset", experiment),\r
+                                sr.Experiment_result_Inverse, experiment, \r
+                                sr.HistoryDataset_columns, Boolean.TRUE,\r
+                                l0.PartOf, model);\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewLineChartAction.java
new file mode 100644 (file)
index 0000000..b21e7fc
--- /dev/null
@@ -0,0 +1,110 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.UUID;\r
+\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new line chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewLineChartAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource model = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                        G2DResource g2d = G2DResource.getInstance(graph);\r
+\r
+                        // Chart\r
+                        Resource jfreechart = GraphUtils.create2(graph, jfree.Chart,\r
+                                l0.HasName, "Chart" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, NameUtils.findFreshLabel(graph, "Chart", model),\r
+                                l0.PartOf, model,\r
+                                jfree.Chart_visibleBorder, true,\r
+                                jfree.Chart_borderWidth, 3);\r
+                        graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                        // Title\r
+                        GraphUtils.create2(graph, jfree.TextTitle,\r
+                                l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, "Chart Title",\r
+                                jfree.Title_position, jfree.Top,\r
+                                l0.PartOf, jfreechart);\r
+\r
+                        // X-axis\r
+                        Resource domainAxis = GraphUtils.create2(graph, jfree.NumberAxis,\r
+                                l0.HasName, "NumberAxis" + UUID.randomUUID().toString());\r
+                        \r
+                        // Y-axis\r
+                        Resource rangeAxis = GraphUtils.create2(graph, jfree.NumberAxis,\r
+                                l0.HasName, "NumberAxis" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, "Y-axis");\r
+                        \r
+                        // Renderer\r
+                        Resource renderer = GraphUtils.create2(graph, jfree.XYLineRenderer);\r
+\r
+                        // Dataset\r
+                        Resource dataset = GraphUtils.create2(graph, jfree.XYDataset,\r
+                                l0.HasName, "XYDataset" + UUID.randomUUID().toString(),\r
+                                jfree.Dataset_mapToDomainAxis, domainAxis,\r
+                                jfree.Dataset_mapToRangeAxis, rangeAxis,\r
+                                jfree.Dataset_seriesList, ListUtils.create(graph, new ArrayList<Resource>()),\r
+                                jfree.Dataset_renderer, renderer);\r
+\r
+                        // Plot\r
+                        GraphUtils.create2(graph, jfree.XYPlot,\r
+                                l0.HasName, "XYPlot" + UUID.randomUUID().toString(),\r
+                                l0.PartOf, jfreechart,\r
+                                jfree.Plot_domainAxis, domainAxis,\r
+                                jfree.Plot_rangeAxis, rangeAxis,\r
+                                jfree.Plot_rangeAxisList, ListUtils.create(graph, Collections.singletonList(rangeAxis)),\r
+                                l0.ConsistsOf, dataset,\r
+                                l0.ConsistsOf, domainAxis,\r
+                                l0.ConsistsOf, rangeAxis);\r
+                    }\r
+\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewModuleTypeAction.java
new file mode 100644 (file)
index 0000000..1d503d0
--- /dev/null
@@ -0,0 +1,144 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\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.NameUtils;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.db.layer0.adapter.Template;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+/**\r
+ * Creates a new module type\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewModuleTypeAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource model = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph g) throws DatabaseException {\r
+                        SysdynResource sr = SysdynResource.getInstance(g);\r
+                        Layer0 l0 = Layer0.getInstance(g);\r
+                        Layer0X L0X = Layer0X.getInstance(g);\r
+                        ModelingResources mr = ModelingResources.getInstance(g);\r
+                        StructuralResource2 sr2 = StructuralResource2.getInstance(g);\r
+\r
+                        String name = NameUtils.findFreshName(g, "ModuleType", model, l0.ConsistsOf, "%s%d");\r
+\r
+                        Resource moduleType = g.newResource();\r
+                        g.claimLiteral(moduleType, l0.HasName, name);\r
+                        g.claim(moduleType, l0.Inherits, sr.Module);\r
+                        g.claim(moduleType, l0.PartOf, model);\r
+\r
+\r
+\r
+                        Resource configuration = GraphUtils.create2(g, \r
+                                sr.Configuration,\r
+                                l0.HasName, name + "Configuration",\r
+                                l0.PartOf, moduleType);\r
+\r
+                        g.claim(moduleType, sr2.IsDefinedBy , configuration);\r
+\r
+                        Resource diagram = g.newResource();\r
+                        g.adapt(sr.ConfigurationDiagramTemplate, Template.class).apply(g,\r
+                                ArrayMap\r
+                                .keys("", "diagram", "name")\r
+                                .values(configuration, diagram, "Diagrammi")\r
+                                );\r
+\r
+\r
+                        // Remove default mapping and add sysdyn mapping\r
+                        for(Resource trigger : g.getObjects(diagram, L0X.HasTrigger)) {\r
+                            if(g.isInstanceOf(trigger, mr.DiagramToCompositeMapping)) {\r
+                                g.deny(diagram, L0X.HasTrigger, trigger);\r
+                            }\r
+                        }\r
+\r
+                        Resource mapping = g.newResource();\r
+                        g.claim(mapping, l0.InstanceOf, null, sr.DiagramToCompositeMapping);\r
+                        g.claim(diagram, L0X.HasTrigger, mapping);\r
+\r
+                        Resource moduleSymbol = g.newResource();\r
+                        g.claimLiteral(moduleSymbol, l0.HasName, name + " Symbol");\r
+                        g.claimLiteral(moduleSymbol, l0.HasLabel, name + " Symbol");\r
+                        g.claim(moduleSymbol, l0.Inherits, sr.ModuleSymbol);\r
+                        g.claim(moduleSymbol, mr.SymbolToComponentType, moduleType);\r
+                        g.claim(moduleSymbol, l0.PartOf, moduleType);\r
+\r
+                        Resource terminal = g.newResource();\r
+                        g.claim(terminal, l0.InstanceOf, sr.SysdynTerminal);\r
+                        Resource relation = createTerminalRelation(g, moduleSymbol, sr.IsHeadOfTerminal, sr.Variable_isHeadOf);\r
+                        DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal, relation);               \r
+\r
+                        Resource terminal2 = g.newResource();\r
+                        g.claim(terminal2, l0.InstanceOf, sr.SysdynTerminal);\r
+                        relation = createTerminalRelation(g, moduleSymbol, sr.IsTailOfTerminal, sr.Variable_isTailOf);\r
+                        DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal2, relation);\r
+\r
+                        g.claim(moduleSymbol, sr2.IsDefinedBy, OrderedSetUtils.create(g, sr2.Composite, terminal, terminal2));\r
+\r
+\r
+\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+    public static Resource createTerminalRelation(WriteGraph graph, Resource symbol, Resource connectionRelation, Resource configurationRelation) throws DatabaseException {\r
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+\r
+        Resource terminalRelation = null;\r
+        terminalRelation = GraphUtils.create(graph,\r
+                MOD.DiagramConnectionRelationToConnectionRelation, configurationRelation,\r
+                L0.PartOf, symbol,\r
+                L0.HasName, NameUtils.getSafeName(graph, connectionRelation)\r
+                );\r
+\r
+        graph.claim(terminalRelation, L0.SubrelationOf, null, connectionRelation);\r
+        Resource inverse = GraphUtils.create(graph,\r
+                L0.PartOf, terminalRelation, \r
+                L0.HasName, "Inverse");\r
+\r
+        graph.claim(inverse, L0.SubrelationOf, null, STR.Connects);\r
+        graph.claim(terminalRelation, L0.InverseOf, inverse);\r
+\r
+        return terminalRelation;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewPieChartAction.java
new file mode 100644 (file)
index 0000000..1ae83a6
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.util.Collections;\r
+import java.util.UUID;\r
+\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.ActionFactory;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new pie chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewPieChartAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource model = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                        G2DResource g2d = G2DResource.getInstance(graph);\r
+\r
+                        // Chart\r
+                        Resource jfreechart = GraphUtils.create2(graph, jfree.Chart,\r
+                                l0.HasName, "PieChart" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, NameUtils.findFreshLabel(graph, "Pie Chart", model),\r
+                                l0.PartOf, model,\r
+                                jfree.Chart_visibleBorder, true,\r
+                                jfree.Chart_borderWidth, 3);\r
+                        graph.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                        // Title\r
+                        GraphUtils.create2(graph, jfree.TextTitle,\r
+                                l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                                l0.HasLabel, "Pie Chart Title",\r
+                                jfree.Title_position, jfree.Top,\r
+                                l0.PartOf, jfreechart);\r
+                        \r
+                        // Dataset\r
+                        Resource dataset = GraphUtils.create2(graph, jfree.PieDataset,\r
+                                l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(),\r
+                                jfree.Dataset_seriesList, ListUtils.create(graph, Collections.<Resource>emptyList())\r
+                                );\r
+\r
+                        // Plot\r
+                        GraphUtils.create2(graph, jfree.PiePlot,\r
+                                l0.HasName, "PiePlot" + UUID.randomUUID().toString(),\r
+                                l0.PartOf, jfreechart,\r
+                                l0.ConsistsOf, dataset\r
+                                );\r
+                    }\r
+\r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSharedFunctionLibraryAction.java
new file mode 100644 (file)
index 0000000..98efd11
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import org.simantics.db.Resource;\r
+\r
+/**\r
+ * Creates a new shared function library\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewSharedFunctionLibraryAction extends NewFunctionLibraryAction {\r
+    \r
+    \r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource resource = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                createLibrary(resource, true);\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSheetAction.java
new file mode 100644 (file)
index 0000000..e579df6
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\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.layer0.adapter.ActionFactory;\r
+import org.simantics.sysdyn.utils.SheetUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new spreadsheet to a book\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewSheetAction implements ActionFactory{\r
+\r
+    @Override\r
+    public Runnable create(Object target) {\r
+        if(!(target instanceof Resource))\r
+            return null;\r
+        final Resource book = (Resource)target;\r
+\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+\r
+                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        SheetUtils.createSheet(graph, book, null, new String[] {}, new int[] {50});\r
+                    }\r
+                    \r
+                });\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/newActions/NewSimulationPlaybackExperimentAction.java
new file mode 100644 (file)
index 0000000..b0363b9
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.newActions;\r
+\r
+import java.awt.Color;\r
+\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.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Creates a new simulation playback experiment\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewSimulationPlaybackExperimentAction extends NewExperimentAction {\r
+    \r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+        G2DResource g2d = G2DResource.getInstance(graph);\r
+        Resource defaultGradient = GraphUtils.create2(graph, g2d.ColorGradient);\r
+        graph.claim(experiment, g2d.HasColorGradient, defaultGradient);\r
+\r
+        Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, \r
+                g2d.HasGradientPosition, 0.0);\r
+        graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(0, 62, 133).getColorComponents(new float[4]));\r
+        graph.claim(defaultGradient, g2d.HasColorPlacement, placement);\r
+        \r
+        placement = GraphUtils.create2(graph, g2d.ColorPlacement, \r
+                g2d.HasGradientPosition, 1.0);\r
+        graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(255, 230, 0).getColorComponents(new float[4]));\r
+        graph.claim(defaultGradient, g2d.HasColorPlacement, placement);\r
+    }\r
+\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).PlaybackExperiment;\r
+    }\r
+\r
+    protected String getNameSuggestion() {\r
+        return "Playback Experiment";\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/actions/remove/ModuleTypeRemover.java
new file mode 100644 (file)
index 0000000..e21bd81
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.actions.remove;\r
+\r
+import java.util.Map;\r
+\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.adapter.Remover;\r
+import org.simantics.modeling.ui.modelBrowser.handlers.DeleteNodeHandler;\r
+\r
+/**\r
+ * Remover for module type nodes. Not functioning - {@link DeleteNodeHandler} prevents deleting other than entityNodes\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleTypeRemover implements Remover {\r
+\r
+    private Resource resource;\r
+    \r
+    public ModuleTypeRemover(ReadGraph graph, Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+    \r
+    @Override\r
+    public String canRemove(ReadGraph graph, Map<Object, Object> aux) throws DatabaseException {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void remove(WriteGraph graph) throws DatabaseException {\r
+        System.out.println("Delete resource " + resource);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleContentChildRule.java
new file mode 100644 (file)
index 0000000..df545e7
--- /dev/null
@@ -0,0 +1,75 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.childrules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+/**\r
+ * Child rule for displaying children of module types in Modules folder\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleContentChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        ArrayList<Resource> children = new ArrayList<Resource>();\r
+        \r
+        if(!(parent instanceof Resource)) {\r
+            return children;\r
+        }\r
+        \r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        StructuralResource2 str = StructuralResource2.getInstance(graph);\r
+\r
+        Resource symbol = (Resource)parent;\r
+        \r
+        // Find module component\r
+        Resource component = graph.getPossibleObject(symbol,ModelingResources.getInstance(graph).SymbolToComponentType);\r
+        \r
+        if(component == null)\r
+            return children;\r
+        \r
+        // Find component configuration\r
+        Resource configuration = graph.getSingleObject(component, str.IsDefinedBy);\r
+        \r
+        if(configuration == null)\r
+            return children;\r
+        \r
+        // Add all components \r
+        children.addAll(graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, str.Component)));\r
+        \r
+        return children;\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child)\r
+            throws DatabaseException {\r
+        return new ArrayList<Resource>();\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/ModuleTypeChildRule.java
new file mode 100644 (file)
index 0000000..111d12c
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.childrules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Child rule for finding module types defined in a model\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleTypeChildRule implements ChildRule {\r
+\r
+       @Override\r
+       public boolean isCompatible(Class<?> contentType) {\r
+               return contentType.equals(Resource.class);\r
+       }\r
+\r
+       @Override\r
+       public Collection<?> getChildren(ReadGraph graph, Object parent)\r
+                       throws DatabaseException {\r
+\r
+       ArrayList<Resource> children = new ArrayList<Resource>();\r
+       \r
+               if(!(parent instanceof Resource)) {\r
+                       return children;\r
+               }\r
+               \r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+\r
+               Resource model = (Resource)parent;\r
+               if(!graph.isInstanceOf(model, SysdynResource.getInstance(graph).SysdynModel))\r
+                   return children;\r
+               \r
+               // Find all component types that are inherited from SYSDYN.Module\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType))) {\r
+               if(graph.isInheritedFrom(r, SysdynResource.getInstance(graph).Module)) {\r
+                       Resource symbol = graph.getPossibleObject(r,ModelingResources.getInstance(graph).ComponentTypeToSymbol);\r
+                       children.add(symbol);\r
+               }\r
+        }\r
+               \r
+               return children;\r
+       }\r
+\r
+       @Override\r
+       public Collection<?> getParents(ReadGraph graph, Object child)\r
+                       throws DatabaseException {\r
+               return new ArrayList<Resource>();\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/childrules/VariableChildRule.java
new file mode 100644 (file)
index 0000000..270ad22
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.childrules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\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.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Child rule for building model configuration out of Variable nodes\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class VariableChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Variable.class) || contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        \r
+        ArrayList<Variable> result = new ArrayList<Variable>();\r
+        \r
+        if (parent == null) {\r
+            return result;\r
+        }\r
+        \r
+        Variable variable = null;\r
+        \r
+        if(parent instanceof Variable) {\r
+            variable = (Variable) parent;\r
+        } else if(parent instanceof Resource) {\r
+            variable = Variables.getVariable(graph, (Resource)parent);\r
+        }\r
+        \r
+        if(variable == null)\r
+            return result;\r
+        \r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        ArrayList<Variable> variables = new ArrayList<Variable>();\r
+\r
+        for(Variable child : variable.getChildren(graph)) {\r
+            Resource represents = (Resource)child.getPropertyValue(graph, Variables.REPRESENTS);\r
+            if(graph.isInstanceOf(represents, sr.IndependentVariable)) {\r
+                variables.add(child);\r
+            } else if (graph.isInstanceOf(represents, sr.Input)) {\r
+                variables.add(child);\r
+            } else if (graph.isInstanceOf(represents, sr.Module)) {\r
+                variables.add(child);\r
+            } else if (graph.isInstanceOf(represents, sr.Enumeration)) {\r
+                variables.add(child);\r
+            }\r
+        }\r
+        \r
+        for (Variable v : variables) {\r
+            result.add(v);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return null;\r
+    }\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..2106ce5
--- /dev/null
@@ -0,0 +1,241 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.viewers.IDecoration;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.swt.ImagerContributor;\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.issues.Severity;\r
+import org.simantics.issues.common.MaxIssueSeverityRecursive;\r
+import org.simantics.issues.ontology.IssueResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.BookNode;\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.FunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialCondition;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialConditionsFolder;\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.SCLModule;\r
+import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.SheetNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+import org.simantics.utils.ui.gfx.DecorationOverlayIcon;\r
+\r
+/**\r
+ * Imager for nodes in old sysdyn model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class AbstractNodeImager extends ImagerContributor<AbstractNode<Resource>> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+\r
+        String image = null;\r
+        if (node instanceof SharedFunctionsFolder)\r
+            image = "icons/folder_link.png";\r
+        else if (node instanceof ExperimentsFolder || \r
+                node instanceof ModulesNode || \r
+                node instanceof FunctionsFolder ||\r
+                node instanceof FunctionLibraryNode ||\r
+                node instanceof SCLModulesFolder ||\r
+                node instanceof InitialConditionsFolder ||\r
+                node instanceof SharedFunctionLibraryNode)\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 SCLModule)\r
+            image = "icons/box.png";\r
+        else if (node instanceof InitialCondition)\r
+            image = "icons/table.png";\r
+        else if (node instanceof ExperimentNode) {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            if(graph.isInstanceOf(node.data, sr.PlaybackExperiment))\r
+                image = "icons/timeline_marker.png";\r
+            else if(graph.isInstanceOf(node.data, sr.GameExperiment))\r
+                image = "icons/time_go.png";\r
+            else if(graph.isInstanceOf(node.data, sr.SensitivityAnalysisExperiment))\r
+                image = "icons/time_rainbow.png";\r
+            else\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 FunctionNode) {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions)) {\r
+                // Sysdyn functions\r
+                image =  "icons/sysdynFunction.png";\r
+            } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Modelica_Functions)) {\r
+                image =  "icons/modelicaFunction.png";\r
+            } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Modelica_Array_Functions)) {\r
+                image =  "icons/modelicaArrayFunction.png";\r
+            } else if (graph.hasStatement(node.data, l0.PartOf, sr.Built$in_Functions_Vensim_Functions)) {\r
+                image =  "icons/vensimFunction.png";\r
+            } else {\r
+                Resource r = graph.getPossibleObject(node.data, l0.PartOf);\r
+                if (r != null) {\r
+                    boolean shared = false;\r
+                    do {\r
+                        shared = graph.isInstanceOf(r, sr.SharedFunctionOntology);\r
+                        r = graph.getPossibleObject(r, l0.PartOf);\r
+                    } while (!shared && (r != null));\r
+                    if (shared) {\r
+                        image =  "icons/functionLink.png";\r
+                    } else {\r
+                        image =  "icons/function.png";\r
+                    }\r
+                }\r
+            }\r
+        } else if (node instanceof VariableNode)\r
+            // Must be queried after FunctionNode\r
+            image =  "icons/brick.png";\r
+        else if (node instanceof BookNode)\r
+            image =  "icons/table_multiple.png";\r
+        else if (node instanceof SheetNode)\r
+            image =  "icons/table.png";\r
+\r
+        if (image != null) {\r
+\r
+            ImageDescriptor id = ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image));\r
+\r
+            Severity maxSeverity = getMaxSeverity(graph, node);\r
+            \r
+            if (maxSeverity == null)\r
+                return id;\r
+            else\r
+                return getDecoration(id, maxSeverity);\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * \r
+     * @param graph\r
+     * @param node\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    private Severity getMaxSeverity(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        IssueResource.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+        HashSet<Resource> issueTypes = new HashSet<Resource>();\r
+        issueTypes.add(SR.Variable);\r
+        issueTypes.add(SR.Configuration);\r
+        issueTypes.add(SR.Module);\r
+        \r
+        Resource data = node.data;\r
+        if(node instanceof ModuleTypeNode) {\r
+            Resource symbol = node.data;\r
+            Resource moduleType = graph.getPossibleObject(symbol, L0.PartOf);\r
+            data = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy);\r
+        } else if(node instanceof ModuleNode) {\r
+            Resource moduleType = graph.getPossibleObject(node.data, L0.InstanceOf);\r
+            data = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy);\r
+        } else if(node instanceof ModelNode) {\r
+            data = graph.getPossibleObject(node.data, SimulationResource.getInstance(graph).HasConfiguration);\r
+        }\r
+\r
+        Severity maxSeverity = getMaxSeverityStructural(graph, data, issueTypes, null);  \r
+        return maxSeverity;\r
+    }\r
+    \r
+    /**\r
+     * Recursive function for obtaining maximum severity of a configuration and its module\r
+     * children\r
+     * \r
+     * @param graph readGraph\r
+     * @param resource Resource from which issues are searched for. If the resource is configuraiton, issues are searched also from its module children.\r
+     * @param issueTypes Issue type resources\r
+     * @param severity Maximum current severity\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    private Severity getMaxSeverityStructural(ReadGraph graph, Resource resource, HashSet<Resource> issueTypes, Severity severity) throws DatabaseException {\r
+        if(resource == null)\r
+            return severity;\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        Resource data = resource;\r
+        Severity maxSeverity = graph.syncRequest(new MaxIssueSeverityRecursive(data, L0.ConsistsOf, issueTypes));\r
+\r
+        // Try structural\r
+        if(graph.isInstanceOf(data, SR.Configuration)) {\r
+            Collection<Resource> moduleChildren =  graph.syncRequest(new ModuleChildren(data));\r
+            for(Resource r : moduleChildren) {\r
+                Resource moduleType = graph.getPossibleObject(r, L0.InstanceOf);\r
+                Resource configuration = graph.getPossibleObject(moduleType, StructuralResource2.getInstance(graph).IsDefinedBy);\r
+                if(configuration != null)\r
+                    maxSeverity = getMaxSeverityStructural(graph, configuration, issueTypes, maxSeverity);\r
+            }\r
+        }\r
+\r
+        return Severity.moreSevere(maxSeverity, severity);\r
+    }\r
+\r
+    /**\r
+     * Request for obtaining all module children of a configuration\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class ModuleChildren implements Read<Collection<Resource>> {\r
+        \r
+        Resource configuration; \r
+        \r
+        public ModuleChildren(Resource configuration) {\r
+            this.configuration = configuration;\r
+        }\r
+\r
+        @Override\r
+        public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+            return graph.syncRequest(new ObjectsWithType(configuration, Layer0.getInstance(graph).ConsistsOf, SysdynResource.getInstance(graph).Module));\r
+        }\r
+    }\r
+\r
+    private ImageDescriptor getDecoration(ImageDescriptor original, Severity severity) {\r
+        ImageDescriptor img = Activator.getDefault().getImageRegistry().getDescriptor(severity.toString());\r
+        if (original == null || original.getImageData() == null) \r
+            return img;\r
+        else\r
+            return new DecorationOverlayIcon(original, img, IDecoration.BOTTOM_LEFT);\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..6fd403f
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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
+\r
+public class AbstractNodeLabeler extends LabelerContributor<AbstractNode<Resource>> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+        if (!graph.hasStatement(node.data))\r
+            return "";\r
+        return graph.adapt(node.data, String.class);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationContribution.java
new file mode 100644 (file)
index 0000000..19d9ce1
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.annotation.ontology.AnnotationResource;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.ISpecialFolder;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationType;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationValue;\r
+\r
+public class AnnotationContribution  extends ViewpointContributor<AbstractNode<Resource>> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+       \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        \r
+        if(node instanceof ISpecialFolder) return result;\r
+        \r
+       AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
+        if(graph.isInstanceOf(node.data, L0.Library)) {\r
+               for(Resource anno : graph.syncRequest(new ObjectsWithType(node.data, L0.ConsistsOf, ANNO.AnnotationType))) {\r
+                result.add(new AnnotationType(anno));\r
+               }\r
+        }\r
+       for(Resource anno : graph.syncRequest(new ObjectsWithType(node.data, L0.ConsistsOf, ANNO.Annotation))) {\r
+            result.add(new AnnotationValue(anno));\r
+       }\r
+        \r
+        return result;\r
+        \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/AnnotationContribution2.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationContribution2.java
new file mode 100644 (file)
index 0000000..a29c1da
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.annotation.ontology.AnnotationResource;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationType;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationValue;\r
+\r
+public class AnnotationContribution2  extends ViewpointContributor<Resource> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, Resource res) throws DatabaseException {\r
+       \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        \r
+       AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
+        if(graph.isInstanceOf(res, L0.Library)) {\r
+               for(Resource anno : graph.syncRequest(new ObjectsWithType(res, L0.ConsistsOf, ANNO.AnnotationType))) {\r
+                result.add(new AnnotationType(anno));\r
+               }\r
+        }\r
+       for(Resource anno : graph.syncRequest(new ObjectsWithType(res, L0.ConsistsOf, ANNO.Annotation))) {\r
+            result.add(new AnnotationValue(anno));\r
+       }\r
+        \r
+        return result;\r
+        \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/AnnotationTypeImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationTypeImager.java
new file mode 100644 (file)
index 0000000..660fd9d
--- /dev/null
@@ -0,0 +1,25 @@
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\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.browser.nodes.AnnotationType;\r
+\r
+public class AnnotationTypeImager extends ImagerContributor<AnnotationType> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, AnnotationType node) throws DatabaseException {\r
+       \r
+        try {\r
+               return ImageDescriptor.createFromURL(new URL("platform:/plugin/com.famfamfam.silk/icons/note.png"));\r
+        } catch (MalformedURLException e) {\r
+               e.printStackTrace();\r
+        }\r
+        return null;\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationTypeLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationTypeLabeler.java
new file mode 100644 (file)
index 0000000..96221a0
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationType;\r
+\r
+public class AnnotationTypeLabeler extends LabelerContributor<AnnotationType>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, AnnotationType input) throws DatabaseException {\r
+       Layer0 L0 = Layer0.getInstance(graph);\r
+       Resource relation = graph.getSingleObject(input.data, L0.HasRange_Inverse);\r
+        return NameUtils.getSafeName(graph, relation);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueImager.java
new file mode 100644 (file)
index 0000000..b6a88ab
--- /dev/null
@@ -0,0 +1,25 @@
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\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.browser.nodes.AnnotationValue;\r
+\r
+public class AnnotationValueImager extends ImagerContributor<AnnotationValue> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, AnnotationValue node) throws DatabaseException {\r
+       \r
+        try {\r
+               return ImageDescriptor.createFromURL(new URL("platform:/plugin/com.famfamfam.silk/icons/note.png"));\r
+        } catch (MalformedURLException e) {\r
+               e.printStackTrace();\r
+        }\r
+        return null;\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/AnnotationValueLabeler.java
new file mode 100644 (file)
index 0000000..320b36b
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.AnnotationValue;\r
+\r
+public class AnnotationValueLabeler extends LabelerContributor<AnnotationValue>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, AnnotationValue input) throws DatabaseException {\r
+        return NameUtils.getSafeName(graph, input.data);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Book.java
new file mode 100644 (file)
index 0000000..8bd950f
--- /dev/null
@@ -0,0 +1,29 @@
+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.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.BookNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SheetNode;\r
+\r
+public class Book extends ViewpointContributor<BookNode> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, BookNode book) throws DatabaseException {\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(book.data, l0.ConsistsOf, SpreadsheetResource.getInstance(graph).Spreadsheet))) {\r
+            result.add(new SheetNode(r));\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/BookLabeler.java
new file mode 100644 (file)
index 0000000..88d2850
--- /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.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.BookNode;\r
+\r
+public class BookLabeler  extends LabelerContributor<BookNode>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, BookNode input) throws DatabaseException {\r
+        return "SpreadSheets";\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, BookNode input) throws DatabaseException {\r
+       return -1;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartImager.java
new file mode 100644 (file)
index 0000000..11bb85e
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.BarChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.LineChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.PieChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SensitivityChartNode;\r
+\r
+/**\r
+ * Provides image for {@link LineChartNode} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartImager extends ImagerContributor<AbstractChartNode<Resource>> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, AbstractChartNode<Resource> input) throws DatabaseException {\r
+        if(input instanceof SensitivityChartNode)\r
+            return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/rainbow.png"));\r
+        else if(input instanceof BarChartNode)\r
+            return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar.png"));\r
+        else if(input instanceof PieChartNode)\r
+            return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_pie.png"));\r
+        else\r
+            return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_line.png"));\r
+\r
+        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartLabeler.java
new file mode 100644 (file)
index 0000000..1301ab5
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.AbstractChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.LineChartNode;\r
+\r
+/**\r
+ * Provides label for {@link LineChartNode} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartLabeler extends LabelerContributor<AbstractChartNode<Resource>> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, AbstractChartNode<Resource> chart) throws DatabaseException {\r
+        String name = graph.getPossibleRelatedValue(chart.data, Layer0.getInstance(graph).HasLabel);\r
+        return name == null ? "Chart (no label)" : name;\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/Charts.java
new file mode 100644 (file)
index 0000000..5abab1e
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.BarChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.LineChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.PieChartNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SensitivityChartNode;\r
+\r
+/**\r
+ * Class for creating chart nodes for model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Charts extends ViewpointContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ChartsFolder folder) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        JFreeChartResource JFREE = JFreeChartResource.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        for(Resource chart : graph.syncRequest(\r
+                new ObjectsWithType(folder.data,\r
+                        L0.ConsistsOf, \r
+                        JFREE.Chart))) {\r
+            Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, L0.ConsistsOf, JFREE.Plot));\r
+            if(plot != null) {\r
+                if(graph.isInstanceOf(plot, SR.Charts_SensitivityPlot)) {\r
+                    result.add(new SensitivityChartNode(chart));\r
+                } else if(graph.isInstanceOf(plot, JFREE.XYPlot)) {\r
+                    result.add(new LineChartNode(chart));\r
+                } else if(graph.isInstanceOf(plot, JFREE.CategoryPlot)) {\r
+                    result.add(new BarChartNode(chart));\r
+                } else if(graph.isInstanceOf(plot, JFREE.PiePlot)) {\r
+                    result.add(new PieChartNode(chart));\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsImager.java
new file mode 100644 (file)
index 0000000..e51b8e7
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.ChartsFolder;\r
+\r
+/**\r
+ * Provides image for {@link ChartsFolder} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsImager extends ImagerContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, ChartsFolder chartNode) throws DatabaseException {\r
+        return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/folder.png"));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ChartsLabeler.java
new file mode 100644 (file)
index 0000000..ff4dc7a
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.ChartsFolder;\r
+\r
+/**\r
+ * Provides label for {@link ChartsFolder} in model browser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsLabeler extends LabelerContributor<ChartsFolder> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, ChartsFolder input) throws DatabaseException {\r
+        return "Charts";\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, ChartsFolder input) throws DatabaseException {\r
+       return -3;\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..fdb9ee0
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.TreeMap;\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.common.request.ObjectsWithType;\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.layer0.Layer0;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.BookNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.EnumerationNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.InputNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModuleNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+public class Configuration extends ViewpointContributor<ConfigurationNode<Resource>> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, ConfigurationNode<Resource> configuration) throws DatabaseException {\r
+               ArrayList<Object> result = new ArrayList<Object>();\r
+               Variable variable = configuration.getVariable();\r
+               \r
+               if (variable == null) {\r
+                       return result;\r
+               }\r
+               \r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               TreeMap<String, Variable> variables = new TreeMap<String, Variable>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               TreeMap<String, Variable> inputs = new TreeMap<String, Variable>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               TreeMap<String, Variable> modules = new TreeMap<String, Variable>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               TreeMap<String, Variable> enumerations = new TreeMap<String, Variable>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+\r
+\r
+               for(Variable child : variable.getChildren(graph)) {\r
+                       Resource represents = (Resource)child.getPropertyValue(graph, Variables.REPRESENTS);\r
+                       if(graph.isInstanceOf(represents, sr.IndependentVariable)) {\r
+                               variables.put(child.getName(graph), child);\r
+                       } else if (graph.isInstanceOf(represents, sr.Input)) {\r
+                               inputs.put(child.getName(graph), child);\r
+                       } else if (graph.isInstanceOf(represents, sr.Module)) {\r
+                               modules.put(child.getName(graph), child);\r
+                       } else if (graph.isInstanceOf(represents, sr.Enumeration)) {\r
+                               enumerations.put(child.getName(graph), child);\r
+                       }\r
+               }\r
+               \r
+               for (String s : variables.keySet()) {\r
+                       Variable v = variables.get(s);\r
+                       Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS);\r
+                       result.add(new VariableNode<Variable>(v, represents));\r
+               }\r
+               \r
+               for (String s : inputs.keySet()) {\r
+                       Variable v = inputs.get(s);\r
+                       Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS);\r
+                       result.add(new InputNode(v, represents));\r
+               }\r
+               \r
+               for (String s : modules.keySet()) {\r
+                       Variable v = modules.get(s);\r
+                       Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS);\r
+                       result.add(new ModuleNode(v, represents));\r
+               }\r
+               \r
+               for (String s : enumerations.keySet()) {\r
+                       Variable v = enumerations.get(s);\r
+                       Resource represents = (Resource)v.getPropertyValue(graph, Variables.REPRESENTS);\r
+                       result.add(new EnumerationNode(v, represents));\r
+               }\r
+               \r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(\r
+                       configuration.data,\r
+                       Layer0.getInstance(graph).ConsistsOf, \r
+                       SpreadsheetResource.getInstance(graph).Book))) {\r
+                   result.add(new BookNode(r));\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..c3039e4
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.sysdyn.ui.browser.nodes.ConfigurationNode;\r
+\r
+public class ConfigurationLabeler extends LabelerContributor<ConfigurationNode<Resource>>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, ConfigurationNode<Resource> conf) throws DatabaseException {\r
+        return "Configuration";\r
+    }\r
+\r
+    @Override\r
+    public int getCategory(ReadGraph graph, ConfigurationNode<Resource> input) throws DatabaseException {\r
+       return -7;\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..9e7aff0
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+\r
+public class Experiment extends ViewpointContributor<ExperimentsFolder> {\r
+\r
+    @SuppressWarnings("unchecked")\r
+       @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ExperimentsFolder experimentsFolder) throws DatabaseException {\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(experimentsFolder.data, l0.ConsistsOf, SimulationResource.getInstance(graph).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..d86672d
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.simulation.ontology.SimulationResource;\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.data, SimulationResource.getInstance(graph).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..37c0295
--- /dev/null
@@ -0,0 +1,42 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+\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.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\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
+       \r
+        String name = graph.getPossibleRelatedValue(experiment.data, Layer0.getInstance(graph).HasLabel);\r
+        \r
+        SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+                       \r
+        String icName = null;\r
+        Resource ic = graph.getPossibleObject(experiment.data, SYSDYN.Experiment_ic);\r
+        if(ic != null) {\r
+               icName = NameUtils.getSafeName(graph, ic);\r
+        }\r
+        \r
+        return (name == null ? "Experiment (no name)" : name) + (icName != null ? " (" + icName + ")" : "");\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..98f5f33
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+\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
+    @Override\r
+    public int getCategory(ReadGraph graph, ExperimentsFolder input) throws DatabaseException {\r
+       return -6;\r
+    }     \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraries.java
new file mode 100644 (file)
index 0000000..5cd6bbe
--- /dev/null
@@ -0,0 +1,81 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.TreeMap;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+public class FunctionLibraries  extends ViewpointContributor<FunctionsFolder> {\r
+\r
+       @Override\r
+    public Collection<?> getContribution(ReadGraph graph, FunctionsFolder functionsFolder)\r
+    throws DatabaseException {\r
+\r
+       Layer0 l0 = Layer0.getInstance(graph);\r
+       SysdynResource sr = SysdynResource.getInstance(graph);\r
+       \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        \r
+               TreeMap<String, Resource> sortResult = new TreeMap<String, Resource>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+        // Find and sort model functions\r
+        for(Resource function : graph.syncRequest(new ObjectsWithType(functionsFolder.data, l0.ConsistsOf, sr.SysdynModelicaFunction))) {\r
+                       sortResult.put(NameUtils.getSafeName(graph, function), function);\r
+        }\r
+               for(Resource function : sortResult.values())\r
+                       result.add(new FunctionNode(function));\r
+        \r
+        // Find and sort model function libraries\r
+               sortResult.clear();\r
+        for(Resource functionLibrary : graph.syncRequest(new ObjectsWithType(functionsFolder.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) {\r
+                       sortResult.put(NameUtils.getSafeName(graph, functionLibrary), functionLibrary);\r
+               }\r
+               for(Resource functionLibrary : sortResult.values())\r
+                       result.add(new FunctionLibraryNode<Resource>(functionLibrary));\r
+               \r
+               // Find built-in functions\r
+        Resource sysdyn = graph.getPossibleResource("http://www.simantics.org/Sysdyn-1.1");\r
+        if(sysdyn != null) {\r
+               for(Resource library : graph.syncRequest(new ObjectsWithType(sysdyn, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))) {\r
+                        result.add(new FunctionLibraryNode<Resource>(library));\r
+               }\r
+        }\r
+        \r
+        \r
+        result.add(new SharedFunctionsFolder(functionsFolder.data));\r
+        \r
+        return result;\r
+\r
+    }\r
+\r
+    @Override\r
+    public String getViewpointId() {\r
+        return "Standard";\r
+    }\r
+    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionLibraryLabeler.java
new file mode 100644 (file)
index 0000000..96ef1f9
--- /dev/null
@@ -0,0 +1,24 @@
+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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+\r
+public class FunctionLibraryLabeler extends LabelerContributor<FunctionLibraryNode<Resource>>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, FunctionLibraryNode<Resource> input)\r
+                       throws DatabaseException {\r
+               String name = NameUtils.getSafeName(graph, input.data);\r
+               return name;\r
+       }\r
+\r
+       @Override\r
+       public int getCategory(ReadGraph graph, FunctionLibraryNode<Resource> input) throws DatabaseException {\r
+               return -1;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/FunctionsLabeler.java
new file mode 100644 (file)
index 0000000..421c9e6
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.FunctionsFolder;\r
+\r
+public class FunctionsLabeler  extends LabelerContributor<FunctionsFolder>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, FunctionsFolder input) throws DatabaseException {\r
+        return "Functions";\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, FunctionsFolder input) throws DatabaseException {\r
+       return -4;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditionLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditionLabeler.java
new file mode 100644 (file)
index 0000000..97a1a3a
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialCondition;\r
+\r
+public class InitialConditionLabeler extends LabelerContributor<InitialCondition>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, InitialCondition input) throws DatabaseException {\r
+        return NameUtils.getSafeName(graph, input.data);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditions.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditions.java
new file mode 100644 (file)
index 0000000..138e890
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialCondition;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialConditionsFolder;\r
+\r
+public class InitialConditions extends ViewpointContributor<InitialConditionsFolder> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, InitialConditionsFolder model)\r
+    throws DatabaseException {\r
+\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+        \r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, SYSDYN.InitialCondition))) {\r
+                result.add(new InitialCondition(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/InitialConditionsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/InitialConditionsLabeler.java
new file mode 100644 (file)
index 0000000..21d4541
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.InitialConditionsFolder;\r
+\r
+public class InitialConditionsLabeler  extends LabelerContributor<InitialConditionsFolder>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, InitialConditionsFolder input) throws DatabaseException {\r
+        return "Initial Conditions";\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, InitialConditionsFolder input) throws DatabaseException {\r
+       return -2;\r
+    }\r
+    \r
+}
\ No newline at end of file
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..7d34ce2
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\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
+       Layer0 l0 = Layer0.getInstance(graph);\r
+       Layer0X L0X = Layer0X.getInstance(graph);\r
+        Resource varres = var.data;\r
+        StringBuilder sb = new StringBuilder();\r
+        for(Resource r : graph.getObjects(varres, l0.HasName))\r
+            sb.append(graph.getValue(r));\r
+               if(graph.isInstanceOf(varres, L0X.Realization)) {\r
+                       varres = graph.getPossibleObject(varres, L0X.Represents);\r
+                       if(varres == null) return sb.toString();\r
+               }\r
+               sb.append(" : ");\r
+               for(Resource t : graph.getObjects(varres, l0.InstanceOf))\r
+                       for(Resource r : graph.getObjects(t, l0.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/LibraryContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryContribution.java
new file mode 100644 (file)
index 0000000..9101dbf
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.Library;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class LibraryContribution  extends ViewpointContributor<AbstractNode<Resource>> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+       \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        \r
+        if(!(node instanceof ModelNode || node instanceof Library)) return result;\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        if(!graph.isInstanceOf(node.data, L0.SharedOntology)) {\r
+               for(Resource lib : graph.syncRequest(new ObjectsWithType(node.data, L0.ConsistsOf, L0.Library))) {\r
+                result.add(new Library(lib));\r
+               }\r
+        }\r
+        \r
+        return result;\r
+        \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/LibraryFunctions.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryFunctions.java
new file mode 100644 (file)
index 0000000..6e3a1a1
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.TreeMap;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionNode;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+public class LibraryFunctions extends ViewpointContributor<FunctionLibraryNode<Resource>> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph,\r
+                       FunctionLibraryNode<Resource> library) throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+               \r
+               TreeMap<String, Resource> sortResult = new TreeMap<String, Resource>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+\r
+               // Find and sort functions in library\r
+               for(Resource function : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, SysdynResource.getInstance(graph).SysdynModelicaFunction))) {\r
+                       sortResult.put(NameUtils.getSafeName(graph, function), function);\r
+               }\r
+               for(Resource function : sortResult.values())\r
+                       result.add(new FunctionNode(function));\r
+\r
+               // Find and sort libraries in library\r
+               sortResult.clear();\r
+               for(Resource functionLibrary : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, SysdynResource.getInstance(graph).SysdynModelicaFunctionLibrary))) {\r
+                       sortResult.put(NameUtils.getSafeName(graph, functionLibrary), functionLibrary);\r
+               }\r
+               for(Resource functionLibrary : sortResult.values())\r
+                       result.add(new FunctionLibraryNode<Resource>(functionLibrary));\r
+               \r
+               return result;\r
+\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/LibraryImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryImager.java
new file mode 100644 (file)
index 0000000..b8c6df4
--- /dev/null
@@ -0,0 +1,25 @@
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\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.browser.nodes.Library;\r
+\r
+public class LibraryImager extends ImagerContributor<Library> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, Library node) throws DatabaseException {\r
+       \r
+        try {\r
+               return ImageDescriptor.createFromURL(new URL("platform:/plugin/com.famfamfam.silk/icons/folder.png"));\r
+        } catch (MalformedURLException e) {\r
+               e.printStackTrace();\r
+        }\r
+        return null;\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/LibraryLabeler.java
new file mode 100644 (file)
index 0000000..ce2daf2
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.Library;\r
+\r
+public class LibraryLabeler extends LabelerContributor<Library> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, Library input) throws DatabaseException {\r
+        return NameUtils.getSafeName(graph, input.data);\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..ddcf935
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.primitiverequest.PossibleObject;\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.operation.Layer0X;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\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.FunctionsFolder;\r
+import org.simantics.sysdyn.ui.browser.nodes.InitialConditionsFolder;\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.SCLModulesFolder;\r
+\r
+/**\r
+ * Provides children for a model in model browser\r
+ * @author Teemu Lempinen\r
+ *\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<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        \r
+        Layer0X L0X = Layer0X.getInstance(graph);\r
+        Resource baseRealization = graph.syncRequest(new PossibleObject(model.data, L0X.HasBaseRealization));\r
+        if (baseRealization != null) {\r
+               try {\r
+                       String URI = graph.getURI(baseRealization);\r
+               Variable variable = Variables.getVariable(graph, URI);\r
+                result.add(new ConfigurationNode<Resource>(variable, baseRealization));\r
+               } catch (DatabaseException e) {\r
+               }\r
+        }\r
+        result.add(new ExperimentsFolder(model.data));\r
+        result.add(new ModulesNode(model.data));\r
+        result.add(new FunctionsFolder(model.data));\r
+        result.add(new ChartsFolder(model.data));\r
+        result.add(new SCLModulesFolder(model.data));\r
+        result.add(new InitialConditionsFolder(model.data));\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..16798d8
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\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.data, Layer0.getInstance(graph).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/ModuleLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleLabeler.java
new file mode 100644 (file)
index 0000000..6c26809
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\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
+       Layer0 l0 = Layer0.getInstance(graph);\r
+       Layer0X L0X = Layer0X.getInstance(graph);\r
+        Resource resource = module.data;\r
+        StringBuilder sb = new StringBuilder();\r
+        for(Resource r : graph.getObjects(resource, l0.HasName))\r
+            sb.append(graph.getValue(r));\r
+               if(graph.isInstanceOf(resource, L0X.Realization)) {\r
+                       resource = graph.getPossibleObject(resource, L0X.Represents);\r
+                       if(resource == null) return sb.toString();\r
+               }\r
+               sb.append(" : ");\r
+               for(Resource t : graph.getObjects(resource, l0.InstanceOf))\r
+                       for(Resource r : graph.getObjects(t, l0.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/ModuleType.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleType.java
new file mode 100644 (file)
index 0000000..4ebe335
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.TreeMap;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.contributor.viewpoint.ViewpointContributor;\r
+import org.simantics.databoard.Bindings;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.EnumerationNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.InputNode;\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.VariableNode;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+public class ModuleType extends ViewpointContributor<ModuleTypeNode> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, ModuleTypeNode module) throws DatabaseException {\r
+               ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               StructuralResource2 str = StructuralResource2.getInstance(graph);\r
+               \r
+               ModelingResources mr = ModelingResources.getInstance(graph);\r
+               Resource instance =  graph.getPossibleObject(module.data, mr.SymbolToComponentType);\r
+\r
+               if(instance == null) return result;\r
+               Resource conf = graph.getSingleObject(instance, str.IsDefinedBy);\r
+               \r
+               // Independent variables\r
+               TreeMap<String, Resource> variables = new TreeMap<String, Resource>(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.IndependentVariable))) {\r
+                       variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r);\r
+               }\r
+               for(String key : variables.keySet())\r
+                       result.add(new VariableNode<Resource>(variables.get(key)));\r
+               \r
+               // Inputs\r
+               variables.clear();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Input))) {\r
+                       variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r);\r
+               }\r
+               for(String key : variables.keySet())\r
+                       result.add(new InputNode(variables.get(key)));\r
+               \r
+               // Modules\r
+               variables.clear();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Module))) {\r
+                       variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r);\r
+               }\r
+               for(String key : variables.keySet())\r
+                       result.add(new ModuleNode(variables.get(key)));\r
+               \r
+               // Enumerations\r
+               variables.clear();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, sr.Enumeration))) {\r
+                       variables.put((String)graph.getPossibleRelatedValue(r, l0.HasName, Bindings.STRING), r);\r
+               }\r
+               for(String key : variables.keySet())\r
+                       result.add(new EnumerationNode(variables.get(key)));\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/ModuleTypeLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModuleTypeLabeler.java
new file mode 100644 (file)
index 0000000..3265401
--- /dev/null
@@ -0,0 +1,34 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\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.data, mr.SymbolToComponentType);\r
+        String label = null;\r
+        if(typeResource != null)\r
+            label = graph.getPossibleRelatedValue(typeResource, Layer0.getInstance(graph).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..41bf4e9
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\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<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, st.ComponentType))) {\r
+               if(graph.isInheritedFrom(r, SysdynResource.getInstance(graph).Module)) {\r
+                       Resource symbol = graph.getPossibleObject(r,ModelingResources.getInstance(graph).ComponentTypeToSymbol);\r
+                       result.add(new ModuleTypeNode(symbol));\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/ModulesLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/ModulesLabeler.java
new file mode 100644 (file)
index 0000000..36d64d0
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+\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
+    @Override\r
+    public int getCategory(ReadGraph graph, ModulesNode input) throws DatabaseException {\r
+       return -5;\r
+    }     \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..8c7a8c6
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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..0d381be
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.ontology.ProjectResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedOntologyNode;\r
+\r
+public class Project extends ViewpointContributor<Resource> {\r
+\r
+    @SuppressWarnings("unchecked")\r
+       @Override\r
+    public Collection<?> getContribution(ReadGraph graph, Resource project)\r
+    throws DatabaseException {\r
+\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(project, l0.ConsistsOf, sr.SysdynModel))) {\r
+            try {\r
+                result.add(graph.adapt(r, AbstractNode.class));\r
+            } catch(DatabaseException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+        \r
+        ProjectResource PROJ = ProjectResource.getInstance(graph);\r
+        if(!graph.isInstanceOf(project, PROJ.Project)) return Collections.emptyList();\r
+        Collection<Resource> ontologies = Simantics.applySCL("Simantics/SharedOntologies", "traverseSharedOntologies", graph, graph.getRootLibrary());\r
+        for(Resource o : ontologies) {\r
+               if(!graph.isImmutable(o))\r
+                       result.add(new SharedOntologyNode(o));\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/SCLModuleLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModuleLabeler.java
new file mode 100644 (file)
index 0000000..97cdb9b
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.SCLModule;\r
+\r
+public class SCLModuleLabeler extends LabelerContributor<SCLModule>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SCLModule input) throws DatabaseException {\r
+        return NameUtils.getSafeName(graph, input.data);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModules.java
new file mode 100644 (file)
index 0000000..edd997f
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.SCLModule;\r
+import org.simantics.sysdyn.ui.browser.nodes.SCLModulesFolder;\r
+\r
+public class SCLModules extends ViewpointContributor<SCLModulesFolder> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, SCLModulesFolder model)\r
+    throws DatabaseException {\r
+\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        \r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, L0.SCLModule))) {\r
+                result.add(new SCLModule(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/SCLModulesLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SCLModulesLabeler.java
new file mode 100644 (file)
index 0000000..b291017
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.SCLModulesFolder;\r
+\r
+public class SCLModulesLabeler  extends LabelerContributor<SCLModulesFolder>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SCLModulesFolder input) throws DatabaseException {\r
+        return "SCL Modules";\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, SCLModulesFolder input) throws DatabaseException {\r
+       return -2;\r
+    }\r
+    \r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionLibraries.java
new file mode 100644 (file)
index 0000000..7d5c736
--- /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
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
+\r
+public class SharedFunctionLibraries extends ViewpointContributor<SharedFunctionsFolder> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph,\r
+                       SharedFunctionsFolder sharedFunctionsFolder) throws DatabaseException {\r
+               \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+\r
+        \r
+        for(Resource sharedLibrary : graph.syncRequest(new ObjectsWithType(\r
+                       sharedFunctionsFolder.data, \r
+                       Layer0.getInstance(graph).IsLinkedTo, \r
+                       SysdynResource.getInstance(graph).SharedFunctionOntology)))\r
+        {\r
+               result.add(new SharedFunctionLibraryNode(sharedLibrary));\r
+        }\r
+        \r
+               return result;\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedFunctionsLabeler.java
new file mode 100644 (file)
index 0000000..c1c8c0a
--- /dev/null
@@ -0,0 +1,25 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.SharedFunctionsFolder;\r
+\r
+public class SharedFunctionsLabeler extends LabelerContributor<SharedFunctionsFolder>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SharedFunctionsFolder input) throws DatabaseException {\r
+        return "Shared Functions";\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyImager.java
new file mode 100644 (file)
index 0000000..5c51a8f
--- /dev/null
@@ -0,0 +1,25 @@
+package org.simantics.sysdyn.ui.browser.contributions;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\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.browser.nodes.SharedOntologyNode;\r
+\r
+public class SharedOntologyImager extends ImagerContributor<SharedOntologyNode> {\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, SharedOntologyNode node) throws DatabaseException {\r
+       \r
+        try {\r
+               return ImageDescriptor.createFromURL(new URL("platform:/plugin/com.famfamfam.silk/icons/folder.png"));\r
+        } catch (MalformedURLException e) {\r
+               e.printStackTrace();\r
+        }\r
+        return null;\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SharedOntologyLabeler.java
new file mode 100644 (file)
index 0000000..9ebfc57
--- /dev/null
@@ -0,0 +1,21 @@
+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.common.utils.Versions;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedOntologyNode;\r
+\r
+public class SharedOntologyLabeler extends LabelerContributor<SharedOntologyNode> {\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SharedOntologyNode node) throws DatabaseException {\r
+       return Versions.getStandardNameString(graph, node.data);\r
+    }\r
+    \r
+    @Override\r
+    public int getCategory(ReadGraph graph, SharedOntologyNode node) throws DatabaseException {\r
+       return -1;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SheetLabeler.java
new file mode 100644 (file)
index 0000000..ff4bd59
--- /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.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.SheetNode;\r
+\r
+public class SheetLabeler  extends LabelerContributor<SheetNode>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SheetNode sheet) throws DatabaseException {\r
+        return  graph.getPossibleRelatedValue(sheet.data, Layer0.getInstance(graph).HasName);\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..f7bd86f
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.common.node.AbstractNode;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.HistoryDataNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode;\r
+\r
+public class SimulationResult  extends ViewpointContributor<AbstractNode<Resource>> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, AbstractNode<Resource> node) throws DatabaseException {\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        if (!(node instanceof ExperimentNode || node instanceof SimulationResultSetNode))\r
+               return result;\r
+        for(final Resource r : graph.syncRequest(new ObjectsWithType(node.data, sr.Experiment_result, sr.Result))) {\r
+            if(graph.isInstanceOf(r, sr.HistoryDataset)) {\r
+                result.add(new HistoryDataNode(r));\r
+            } else {\r
+                result.add(new SimulationResultNode<Resource>(r));\r
+\r
+                String resultPath = (String)graph.getPossibleRelatedValue(r, sr.Result_resultFile);\r
+                File file = new File(resultPath);\r
+                if(!file.exists()) {\r
+                    graph.asyncRequest(new WriteRequest() {\r
+\r
+                        @Override\r
+                        public void perform(WriteGraph graph) throws DatabaseException {\r
+                            String resultPath = (String)graph.getPossibleRelatedValue(r, SysdynResource.getInstance(graph).Result_resultFile);\r
+                            File file = new File(resultPath);\r
+                            if(!file.exists()) {\r
+                                Layer0 l0 = Layer0.getInstance(graph);\r
+                                graph.deny(r, l0.PartOf);\r
+                                graph.deny(r, graph.getInverse(SysdynResource.getInstance(graph).Experiment_result));\r
+                            }\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..3676eba
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultDecorator extends LabelDecoratorContributor<SimulationResultNode<Resource>>{\r
+\r
+    @Override\r
+    public LabelDecorator getDecorator(ReadGraph graph, SimulationResultNode<Resource> result) throws DatabaseException {\r
+        if (graph.hasStatement(result.data, SysdynResource.getInstance(graph).Result_showResult)) {\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 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.NORMAL);\r
+            }\r
+        };\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..3dc688d
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultImager extends ImagerContributor<SimulationResultNode<Resource>>{\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, SimulationResultNode<Resource> result) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        if(graph.isInstanceOf(result.data, sr.HistoryDataset))\r
+            return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/table.png"));\r
+        if(graph.hasStatement(result.data, sr.Result_showResult))\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..f0e968e
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultNode;\r
+\r
+public class SimulationResultLabeler extends LabelerContributor<SimulationResultNode<Resource>>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SimulationResultNode<Resource> result) throws DatabaseException {\r
+        String name = graph.getPossibleRelatedValue(result.data, Layer0.getInstance(graph).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/SimulationResultSet.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSet.java
new file mode 100644 (file)
index 0000000..dfbe881
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode;\r
+\r
+public class SimulationResultSet extends ViewpointContributor<ExperimentNode> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ExperimentNode experiment) throws DatabaseException {\r
+        ArrayList<SimulationResultSetNode> results = new ArrayList<SimulationResultSetNode>();\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        for(final Resource r : graph.syncRequest(new ObjectsWithType(experiment.data, sr.Experiment_resultSet, sr.ResultSet))) {\r
+            results.add(new SimulationResultSetNode(r));\r
+        }\r
+        return results;\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/SimulationResultSetDecorator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetDecorator.java
new file mode 100644 (file)
index 0000000..2491ee5
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode;\r
+\r
+public class SimulationResultSetDecorator extends LabelDecoratorContributor<SimulationResultSetNode>{\r
+\r
+    @Override\r
+    public LabelDecorator getDecorator(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException {\r
+       SysdynResource sr = SysdynResource.getInstance(graph);\r
+       for (Resource result : graph.getObjects(resultSet.data, sr.Experiment_result)) {\r
+               if (graph.hasStatement(result, sr.Result_showResult)) {\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
+       }\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.NORMAL);\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetImager.java
new file mode 100644 (file)
index 0000000..88c7380
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode;\r
+\r
+public class SimulationResultSetImager extends ImagerContributor<SimulationResultSetNode>{\r
+\r
+    @Override\r
+    public ImageDescriptor getDescriptor(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+       for (Resource result : graph.getObjects(resultSet.data, sr.Experiment_result)) {\r
+               if (graph.hasStatement(result, sr.Result_showResult)) {\r
+                return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_3.png"));\r
+               }\r
+       }\r
+        return ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/chart_bar_3_blackAndWhite.png"));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SimulationResultSetLabeler.java
new file mode 100644 (file)
index 0000000..16c4259
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.browser.nodes.SimulationResultSetNode;\r
+\r
+public class SimulationResultSetLabeler extends LabelerContributor<SimulationResultSetNode>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, SimulationResultSetNode resultSet) throws DatabaseException {\r
+        String name = graph.getPossibleRelatedValue(resultSet.data, Layer0.getInstance(graph).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/SysdynProject.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/contributions/SysdynProject.java
new file mode 100644 (file)
index 0000000..91c46b6
--- /dev/null
@@ -0,0 +1,39 @@
+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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural.ui.modelBrowser.nodes.AbstractNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class SysdynProject  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
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(project, L0.ConsistsOf, SysdynResource.getInstance(graph).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
+}
\ No newline at end of file
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..6302ad0
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.ui.browser.nodes.VariableNode;\r
+\r
+public class VariableLabeler  extends LabelerContributor<VariableNode<Resource>>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, VariableNode<Resource> var) throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               Layer0X L0X = Layer0X.getInstance(graph);\r
+               Resource varres = var.data;\r
+               StringBuilder sb = new StringBuilder();\r
+               for(Resource r : graph.getObjects(varres, l0.HasName))\r
+                       sb.append(graph.getValue(r));\r
+               if(graph.isInstanceOf(varres, L0X.Realization)) {\r
+                       varres = graph.getPossibleObject(varres, L0X.Represents);\r
+                       if(varres == null) return sb.toString();\r
+               }\r
+               sb.append(" : ");\r
+               for(Resource t : graph.getObjects(varres, l0.InstanceOf))\r
+                       for(Resource r : graph.getObjects(t, l0.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/imagerules/ChartImageRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ChartImageRule.java
new file mode 100644 (file)
index 0000000..044d9bc
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.imagerules;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.images.ImageRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+public class ChartImageRule implements ImageRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return Resource.class.equals(contentType);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, ImageDescriptor> getImage(ReadGraph graph, Object content) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+        String image = "icons/chart_line.png";\r
+\r
+        Resource chart = (Resource) content;\r
+\r
+        Resource plot = graph.syncRequest(new PossibleObjectWithType(chart, l0.ConsistsOf, jfree.Plot));\r
+        if(plot != null) {\r
+            if(graph.isInstanceOf(plot, jfree.CategoryPlot)) {\r
+                image = "icons/chart_bar.png";\r
+            } else if(graph.isInstanceOf(plot, jfree.PiePlot)) {\r
+                image = "icons/chart_pie.png";\r
+            }\r
+        }\r
+\r
+        return Collections.singletonMap(ColumnKeys.SINGLE, \r
+                ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image))\r
+                );    \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/ResultImageRule.java
new file mode 100644 (file)
index 0000000..ed7024e
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.imagerules;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.images.ImageRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+public class ResultImageRule implements ImageRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return Resource.class.equals(contentType);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, ImageDescriptor> getImage(ReadGraph graph, Object content) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Resource data = (Resource) content;\r
+        \r
+        String image = "icons/chart_bar_blackAndWhite.png";\r
+        if(graph.hasStatement(data, sr.Result_showResult))\r
+            image ="icons/chart_bar.png";\r
+        \r
+        return Collections.singletonMap(ColumnKeys.SINGLE, \r
+                ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image))\r
+                );   \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/imagerules/VariableImageRule.java
new file mode 100644 (file)
index 0000000..ba780a6
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.imagerules;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.images.ImageRule;\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.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class VariableImageRule implements ImageRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return Variable.class.equals(contentType);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, ImageDescriptor> getImage(ReadGraph graph, Object content) throws DatabaseException {\r
+        Variable var = AdaptionUtils.adaptToSingle(content, Variable.class);\r
+\r
+        String image =  "icons/brick.png";\r
+        \r
+        Resource r =  (Resource)var.getPropertyValue(graph, Variables.REPRESENTS);\r
+        if(r != null) {\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            Resource type = graph.getSingleObject(r, L0.InstanceOf);\r
+            if(graph.isInheritedFrom(type, sr.Module)) {\r
+                image = "icons/bricks.png";\r
+            }\r
+        }\r
+\r
+        return Collections.singletonMap(ColumnKeys.SINGLE, \r
+                ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(image))\r
+                );\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/ModuleTypeLabelRule.java
new file mode 100644 (file)
index 0000000..90d7234
--- /dev/null
@@ -0,0 +1,32 @@
+package org.simantics.sysdyn.ui.browser.labelrules;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.labels.LabelRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.modeling.ModelingResources;\r
+\r
+public class ModuleTypeLabelRule implements LabelRule {\r
+    public static final ModuleTypeLabelRule INSTANCE = new ModuleTypeLabelRule();\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, Object content) throws DatabaseException {\r
+        Resource symbol = (Resource)content;\r
+        Resource component = graph.getSingleObject(symbol, ModelingResources.getInstance(graph).SymbolToComponentType);\r
+        \r
+        return Collections.singletonMap(ColumnKeys.SINGLE, \r
+                NameUtils.getSafeName(graph, component)\r
+                );\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/labelrules/VariableNameLabelRule.java
new file mode 100644 (file)
index 0000000..8e97b42
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.labelrules;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.labels.LabelRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class VariableNameLabelRule  implements LabelRule {\r
+    public static final ModuleTypeLabelRule INSTANCE = new ModuleTypeLabelRule();\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Variable.class);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, Object content) throws DatabaseException {\r
+        Variable var = AdaptionUtils.adaptToSingle(content, Variable.class);\r
+        return Collections.singletonMap(ColumnKeys.SINGLE, \r
+                var != null ? var.getName(graph) : "No variable"\r
+                );\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodeTypes/ModuleSymbolNodeType.java
new file mode 100644 (file)
index 0000000..e4e8fde
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodeTypes;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.WeakHashMap;\r
+\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.NodeContextBuilder;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.ui.selection.WorkbenchSelectionElement;\r
+\r
+/**\r
+ * Experimental node type for Module symbols. Copied mostly from {@link SpecialNodeType}. \r
+ * Not necessary needed.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleSymbolNodeType implements NodeType {\r
+    \r
+    private Resource resource;\r
+    private Class<?> contentType;\r
+    \r
+    private static final WeakHashMap<Resource, ModuleSymbolNodeType> nodeTypeCache =\r
+            new WeakHashMap<Resource, ModuleSymbolNodeType>();\r
+\r
+    public ModuleSymbolNodeType(Resource resource) {\r
+        this.resource = resource;\r
+        this.contentType = Resource.class;\r
+    }\r
+    \r
+    public static ModuleSymbolNodeType  create(Resource entityType) {\r
+        synchronized(nodeTypeCache) {\r
+            ModuleSymbolNodeType result = nodeTypeCache.get(entityType);\r
+            if(result == null) {\r
+                result = new ModuleSymbolNodeType(entityType);\r
+                nodeTypeCache.put(entityType, result);\r
+            }\r
+            return result;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public NodeContext createNodeContext(ReadGraph graph, Object content)\r
+            throws DatabaseException {\r
+        if(contentType.isInstance(content))\r
+            return NodeContextBuilder.buildWithData(KEY_SEQUENCE,\r
+                    new Object[] {content, this}\r
+            );\r
+        else\r
+            return null;\r
+    }\r
+\r
+    @Override\r
+    public Class<?> getContentType() {\r
+        return contentType;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        return resource.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
+        ModuleSymbolNodeType other = (ModuleSymbolNodeType) obj;\r
+        return resource.equals(other.resource);\r
+    }\r
+\r
+    @Override\r
+    public boolean inherits(ReadGraph graph, NodeType superType) {\r
+        // Special node type does not support inheritance\r
+        return equals(superType);\r
+    }\r
+\r
+    @Override\r
+    public Collection<NodeType> getSuper(ReadGraph g) {\r
+        return Collections.emptyList();\r
+    }\r
+    \r
+    @Override\r
+    public String toString(ReadGraph graph) throws DatabaseException {\r
+        return "(" + NameUtils.getSafeName(graph, resource) + ")";\r
+    }\r
+\r
+    @Override\r
+    public WorkbenchSelectionElement getWorkbenchSelectionElement(NodeContext context) {\r
+        return null;\r
+    }\r
+    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AbstractChartNode.java
new file mode 100644 (file)
index 0000000..0d17007
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import java.util.Iterator;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\r
+import org.simantics.databoard.Bindings;\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.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public abstract class AbstractChartNode<T> extends AbstractNode<Resource> implements IDropTargetNode, IDeletableNode {\r
+\r
+    public AbstractChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+\r
+\r
+    /**\r
+     * Add variable to this chart, if the dropped element(s) can be adapted to a {@link Variable} \r
+     */\r
+    @Override\r
+    public void drop(Object data) {\r
+        IStructuredSelection selection = (IStructuredSelection)data;\r
+        Iterator<?> iterator = selection.iterator();\r
+        while(iterator.hasNext()) {\r
+            Object o = iterator.next();\r
+            if(o instanceof IAdaptable) {\r
+                Variable v = (Variable) ((IAdaptable)o).getAdapter(Variable.class);\r
+                if(v != null) {\r
+                    addVariableToChart(v);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Adds a variable to this chart and map it to the first rangeAxis\r
+     * @param variable\r
+     */\r
+    protected abstract void addVariableToChart(final Variable variable);\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    graph.markUndoPoint();\r
+                    String chartName = graph.getRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                    RemoverUtil.remove(graph, data);\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed chart '" + chartName +"' " + data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationType.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationType.java
new file mode 100644 (file)
index 0000000..d5f3b6b
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleObject;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class AnnotationType extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public AnnotationType(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    RemoverUtil.remove(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        Session session = Simantics.getSession();\r
+        try {\r
+                       Resource relation =  session.syncRequest(new PossibleObject(data, session.getService(Layer0.class).HasRange_Inverse));\r
+                       if(relation != null)\r
+                               return new LabelModifier(session, relation, session.getService(Layer0.class).HasName);\r
+               } catch (Exception e) {\r
+                       Logger.defaultLogError(e);\r
+               }\r
+               return null;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationValue.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/AnnotationValue.java
new file mode 100644 (file)
index 0000000..0f551ee
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.Session;\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.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class AnnotationValue extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public AnnotationValue(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    RemoverUtil.remove(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+       Session session = Simantics.getSession();\r
+       return new LabelModifier(session, data, session.getService(Layer0.class).HasName);\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BarChartNode.java
new file mode 100644 (file)
index 0000000..9dff79b
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.request.SingleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\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.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Bar chart node\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class BarChartNode extends AbstractChartNode<Resource> {\r
+\r
+    public BarChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Adds a variable to this chart\r
+     * @param variable\r
+     */\r
+    @Override\r
+    protected void addVariableToChart(final Variable variable) {\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot));\r
+                if(plot == null)\r
+                    return;\r
+\r
+                Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset));\r
+                \r
+                if(dataset == null)\r
+                    return;\r
+                \r
+                // Create the series and attach it to the dataset\r
+                String rvi = Variables.getRVI(graph, variable);\r
+                ChartUtils.createSeries(graph, dataset, rvi);\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/BookNode.java
new file mode 100644 (file)
index 0000000..02f5bc5
--- /dev/null
@@ -0,0 +1,11 @@
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class BookNode extends AbstractNode<Resource> {\r
+\r
+    public BookNode(Resource data) {\r
+        super(data);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ChartsFolder.java
new file mode 100644 (file)
index 0000000..d75b01b
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+/**\r
+ * Folder containing all sysdyn charts\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartsFolder extends AbstractNode<Resource> {\r
+\r
+    public ChartsFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\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..4b61442
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.layer0.variable.Variable;\r
+\r
+public class ConfigurationNode<T> extends VariableNode<Resource> implements IDeletable {\r
+       \r
+       public ConfigurationNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+       \r
+    public ConfigurationNode(Variable variable, Resource represents) {\r
+        super(variable, represents);\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/EnumerationNode.java
new file mode 100644 (file)
index 0000000..bfa2943
--- /dev/null
@@ -0,0 +1,112 @@
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.databoard.Bindings;\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.ObjectsWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class EnumerationNode extends VariableNode<Resource> implements IModifiableNode, IDeletableNode {\r
+\r
+       public EnumerationNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+       \r
+       public EnumerationNode(Variable variable, Resource represents) {\r
+        super(variable, represents);\r
+       }\r
+    \r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        \r
+        final Session session = SimanticsUI.getSession();\r
+        LabelModifier modifier = new LabelModifier(session, data, session.getService(Layer0.class).HasName) {\r
+            @Override\r
+            public String isValid(String label) {\r
+                if (!new VariableNameValidator().isValid(data, label))\r
+                    return "Not valid";\r
+                else\r
+                    return null;\r
+            }\r
+            \r
+            @Override\r
+            public void modify(final String label) {\r
+                try {\r
+                                       session.syncRequest(new WriteRequest() {\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph)\r
+                                                               throws DatabaseException {\r
+\r
+                                               String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName);\r
+                                               if(!originalName.equals(label)) {\r
+                                                   Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf);\r
+                                                   new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label);\r
+                                                       graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label);\r
+                                               }\r
+                                               }\r
+                                       });\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+\r
+               super.modify(label);\r
+            }\r
+        };\r
+        return modifier;\r
+    }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    graph.markUndoPoint();\r
+                    SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    for(Resource redeclaration : graph.getObjects(data, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
+                       graph.deny(redeclaration, sr.Module_redeclaration_Inverse);\r
+                    }\r
+                    \r
+                    for(Resource redeclaration : graph.getObjects(data, sr.Redeclaration_replacingEnumeration_Inverse)) {\r
+                       graph.deny(redeclaration, sr.Module_redeclaration_Inverse);\r
+                    }\r
+                    \r
+                    Layer0 L0 = Layer0.getInstance(graph);\r
+                    Resource conf = graph.getPossibleObject(data, L0.PartOf);\r
+                    for(Resource var : graph.syncRequest(new ObjectsWithType(conf, L0.ConsistsOf, sr.Variable))) {\r
+                        Resource arrayIndexes = graph.getPossibleObject(var, sr.Variable_arrayIndexesList);\r
+                        if(arrayIndexes != null) {\r
+                            if(ListUtils.getNode(graph, arrayIndexes, data) != null) {\r
+                                ListUtils.removeElement(graph, arrayIndexes, data);\r
+                            }\r
+                        }\r
+                    }\r
+                    \r
+                    String enumerationName = graph.getPossibleRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                    RemoverUtil.remove(graph, data);\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed Enumeration " + enumerationName + " "+ data.toString());\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }        \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..e059b64
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.databoard.Bindings;\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.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.handlers.SysdynExperimentActivator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class ExperimentNode extends AbstractNode<Resource> implements IDoubleClickableNode, IDeletableNode, IModifiableNode{\r
+\r
+    public ExperimentNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public boolean handleDoubleClick() {\r
+        if (data == 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, data);\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) {\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
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    Collection<Resource> results = graph.getObjects(data, SysdynResource.getInstance(graph).Experiment_result);\r
+                    if(results != null)\r
+                        for(Resource result : results) \r
+                            SimulationResultNode.unlinkResult(graph, result);\r
+                    Collection<Resource> resultSets = graph.getObjects(data, SysdynResource.getInstance(graph).Experiment_resultSet);\r
+                    if(resultSets != null)\r
+                        for(Resource resultSet : resultSets) \r
+                            SimulationResultSetNode.unlinkResultSet(graph, resultSet);\r
+                    String ontologyName = graph.getPossibleRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                    RemoverUtil.remove(graph, data);\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed experiment " + ontologyName + " "+ data.toString());\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }        \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..76be910
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class ExperimentsFolder extends AbstractNode<Resource> {\r
+\r
+    public ExperimentsFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExportTester.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/ExportTester.java
new file mode 100644 (file)
index 0000000..dad1cd4
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************\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.nodes;\r
+\r
+import java.util.Collection;\r
+\r
+import org.eclipse.core.expressions.PropertyTester;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.PossibleModel;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * This class tests whether the export functionality is active\r
+ * \r
+ * @author Tuomas Miettinen\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class ExportTester extends PropertyTester {\r
+\r
+    @Override\r
+    public boolean test(Object receiver, final String property, final Object[] args, final Object expectedValue) {\r
+       // Find the resource from the receiver.\r
+        Resource inputResource = ResourceAdaptionUtils.toSingleResource(receiver);\r
+        if (inputResource == null) {\r
+               @SuppressWarnings("rawtypes")\r
+                       Collection<AbstractNode> a = AdaptionUtils.adaptToCollection(receiver, AbstractNode.class);\r
+               if (a.size() > 1) // Multiple selections.\r
+                       return false;\r
+               if (a.size() == 1)\r
+                       inputResource = (Resource)a.iterator().next().data;\r
+        }\r
+        if (inputResource == null) {\r
+               \r
+               IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+               IEditorPart editor = page.getActiveEditor();\r
+               if (editor instanceof DiagramEditor) {\r
+               inputResource = ((DiagramEditor)editor).getInputResource();\r
+               } else {\r
+                       return false;\r
+               }\r
+       }\r
+        final Resource resource = inputResource;\r
+\r
+        Session session = SimanticsUI.peekSession();\r
+        if (session == null)\r
+            return false;\r
+\r
+        if (DatabaseJob.inProgress())\r
+            return false;\r
+\r
+        // Check if we can get the model of the resource.\r
+        try {\r
+            return session.syncRequest(new Read<Boolean>() {\r
+                @Override\r
+                public Boolean perform(ReadGraph g) throws DatabaseException {\r
+                       if (g.sync(new PossibleModel(resource)) != null) {\r
+                               return true;\r
+                       }\r
+                       return false;\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            // Purposefully not logging these exceptions, there might be way too\r
+            // many even under normal circumstances.\r
+            // TODO: add debug tracing options controlling the printing of these exceptions\r
+            return false;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionLibraryNode.java
new file mode 100644 (file)
index 0000000..8813df9
--- /dev/null
@@ -0,0 +1,104 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\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.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.FunctionLibraryNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class FunctionLibraryNode<T> extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode, IDropTargetNode {\r
+\r
+       \r
+    public FunctionLibraryNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+               try {\r
+                       Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName;\r
+                       LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) {\r
+                               @Override\r
+                   public String isValid(String label) {\r
+                       if (!new FunctionLibraryNameValidator().isValid(data, label))\r
+                           return "Not valid";\r
+                       else\r
+                           return null;\r
+                   }\r
+                       };\r
+                       return modifier;\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+           SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+               @Override\r
+               public void perform(WriteGraph graph) throws DatabaseException {\r
+                   graph.markUndoPoint();\r
+                   Layer0Utils.addCommentMetadata(graph, "Removed " + NameUtils.getSafeName(graph, data));\r
+                   RemoverUtil.remove(graph, data);\r
+               }\r
+           });\r
+       }\r
+\r
+       @Override\r
+       public void drop(Object data) {\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(data);\r
+               final Resource library = this.data;\r
+               if(resources.length > 0) {\r
+                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       \r
+                                       // Fixing #5196\r
+                                       // Prevent dropping functions to immutable function libraries such as Built-in Functions, Modelica Array Functions etc.\r
+                                       if (graph.isImmutable(library))\r
+                                           return;\r
+                                       \r
+                                       for(Resource tobeMoved : resources) {\r
+                                               if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) ||\r
+                                                               graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) {\r
+                                                       graph.deny(tobeMoved, l0.PartOf);\r
+                                                       graph.claim(tobeMoved, l0.PartOf, library);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionNode.java
new file mode 100644 (file)
index 0000000..df983ed
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\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.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.FunctionNameValidator;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class FunctionNode extends VariableNode<Resource> implements IDeletableNode, IModifiableNode, IDropTargetNode {\r
+       \r
+    public FunctionNode(final Resource resource) {\r
+       super(resource);\r
+    }\r
+    \r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+               try {\r
+                       Resource hasName = Layer0.getInstance(Simantics.getSession()).HasName;\r
+                       LabelModifier modifier = new LabelModifier(Simantics.getSession(), data, hasName) {\r
+                @Override\r
+                public String isValid(String label) {\r
+                    if (!new FunctionNameValidator().isValid(data, label))\r
+                        return "Not valid";\r
+                    else\r
+                        return null;\r
+                }\r
+                       };\r
+                       return modifier;\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+           Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+               @Override\r
+               public void perform(WriteGraph graph) throws DatabaseException {\r
+                graph.markUndoPoint();\r
+                Layer0Utils.addCommentMetadata(graph, "Removed " + NameUtils.getSafeName(graph, data));\r
+                   RemoverUtil.remove(graph, data);\r
+               }\r
+           });\r
+       }\r
+       \r
+       @Override\r
+       public void drop(Object data) {\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(data);\r
+               final Resource thisFunction = this.data;\r
+               \r
+               if(resources.length > 0) {\r
+                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       Resource library = null;\r
+                                       for(Resource tobeMoved : resources) {\r
+                                               if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) ||\r
+                                                               graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) {\r
+                                                       if(library == null) {\r
+                                                               library = graph.getSingleObject(thisFunction, l0.PartOf);\r
+                                                       }\r
+                                                       graph.deny(tobeMoved, l0.PartOf);\r
+                                                       graph.claim(tobeMoved, l0.PartOf, library);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/FunctionsFolder.java
new file mode 100644 (file)
index 0000000..2bdb2e4
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\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.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class FunctionsFolder extends AbstractNode<Resource> implements IDropTargetNode{\r
+\r
+    public FunctionsFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\r
+    \r
+       @Override\r
+       public void drop(Object data) {\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(data);\r
+               final Resource library = this.data;\r
+               if(resources.length > 0) {\r
+                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       for(Resource tobeMoved : resources) {\r
+                                               if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) ||\r
+                                                               graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) {\r
+                                                       graph.deny(tobeMoved, l0.PartOf);\r
+                                                       graph.claim(tobeMoved, l0.PartOf, library);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+       \r
+\r
+
+       \r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/HistoryDataNode.java
new file mode 100644 (file)
index 0000000..196a52e
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.DeleteException;\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.util.RemoverUtil;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class HistoryDataNode extends SimulationResultNode<Resource> {\r
+\r
+    public HistoryDataNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    RemoverUtil.remove(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialCondition.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialCondition.java
new file mode 100644 (file)
index 0000000..dcd937a
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.Session;\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.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class InitialCondition extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public InitialCondition(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    RemoverUtil.remove(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        Session session = SimanticsUI.getSession();\r
+        return new LabelModifier(session, data, session.getService(Layer0.class).HasName);\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialConditionsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/InitialConditionsFolder.java
new file mode 100644 (file)
index 0000000..abf40d4
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.ISpecialFolder;\r
+import org.simantics.db.Resource;\r
+\r
+public class InitialConditionsFolder extends AbstractNode<Resource> implements ISpecialFolder {\r
+    \r
+    public InitialConditionsFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\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..ca731e9
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.layer0.variable.Variable;\r
+\r
+public class InputNode  extends VariableNode<Resource> {\r
+\r
+       public InputNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+       \r
+    public InputNode(Variable variable, Resource represents) {\r
+        super(variable, represents);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/Library.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/Library.java
new file mode 100644 (file)
index 0000000..736081e
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.Session;\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.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class Library extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public Library(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    RemoverUtil.remove(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+       Session session = Simantics.getSession();\r
+       return new LabelModifier(session, data, session.getService(Layer0.class).HasName);\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/LineChartNode.java
new file mode 100644 (file)
index 0000000..ef2ec49
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.SingleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\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.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Node representing a  line chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class LineChartNode extends AbstractChartNode<Resource> {\r
+\r
+    public LineChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+\r
+    /**\r
+     * Adds a variable to this chart and map it to the first rangeAxis\r
+     * @param variable\r
+     */\r
+    @Override\r
+    protected void addVariableToChart(final Variable variable) {\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot));\r
+                if(plot == null)\r
+                    return;\r
+\r
+                Resource rangeAxis = null;\r
+                Resource dataset = null;\r
+                Resource rangeAxisList = graph.getPossibleObject(plot, jfree.Plot_rangeAxisList);\r
+                if(rangeAxisList == null ||  ListUtils.toList(graph, rangeAxisList).isEmpty()) {\r
+                    // No range axis -> Create a new one\r
+                    rangeAxis = ChartUtils.createNumberRangeAxis(graph, plot);\r
+                    Resource domainAxis = graph.getPossibleObject(plot, jfree.Plot_domainAxis);\r
+                    dataset = ChartUtils.createXYDataset(graph, plot, domainAxis, rangeAxis);\r
+                } else {\r
+                    rangeAxis = ListUtils.toList(graph, rangeAxisList).get(0);\r
+                    dataset = graph.getPossibleObject(rangeAxis, jfree.Dataset_mapToRangeAxis_Inverse);\r
+                }\r
+                \r
+                // Create the series and attach it to the dataset\r
+                String rvi = Variables.getRVI(graph, variable);\r
+                ChartUtils.createSeries(graph, dataset, rvi);\r
+            }\r
+        });\r
+    }\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..1397186
--- /dev/null
@@ -0,0 +1,160 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.databoard.Bindings;\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.common.utils.NameUtils;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.request.Write;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.ModelNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class ModelNode extends AbstractNode<Resource> implements IDoubleClickableNode, IDeletableNode, IModifiableNode {\r
+\r
+       Listener<String> configurationNameSynchronizer;\r
+       private boolean disposed = false;\r
+       \r
+    public ModelNode(Resource resource) {\r
+        super(resource);\r
+               \r
+        // Not the best solution for name sync\r
+        configurationNameSynchronizer = new Listener<String>() {\r
+\r
+               @Override\r
+                       public void execute(final String result) {\r
+                   if (result == null)\r
+                       return;\r
+                               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                                       \r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               SimulationResource sim = SimulationResource.getInstance(graph);\r
+                                               Resource configuration = graph.getPossibleObject(data, sim.HasConfiguration);\r
+                                               \r
+                                               String label = graph.getPossibleRelatedValue2(configuration, l0.HasLabel, Bindings.STRING);\r
+                                               if (label != null)\r
+                                                   return;\r
+                                               \r
+                                               graph.claimLiteral(configuration, l0.HasLabel, result);\r
+                                               Layer0Utils.addCommentMetadata(graph, "Created ModelNode to model browser for model " + result);\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 disposed;\r
+                       }\r
+               };\r
+               \r
+        SimanticsUI.getSession().asyncRequest(new Read<String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph) throws DatabaseException {\r
+                               return graph.getPossibleRelatedValue(data, Layer0.getInstance(graph).HasLabel);\r
+                       }\r
+               \r
+        }, configurationNameSynchronizer);\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) {\r
+            @Override\r
+            public String isValid(String label) {\r
+                if (!new ModelNameValidator().isValid(data, label))\r
+                    return "Not valid";\r
+                else\r
+                    return null;\r
+            }\r
+            \r
+            @Override\r
+            protected Write getWriteRequest(final String label) {\r
+                return new WriteRequest() {\r
+                    @Override\r
+                    public void perform(WriteGraph g) throws DatabaseException {\r
+                        g.markUndoPoint();\r
+                       Layer0 l0 = Layer0.getInstance(g);\r
+                       String oldName = g.getPossibleRelatedValue2(data, l0.HasLabel, Bindings.STRING);\r
+                        g.claimLiteral(data, l0.HasLabel, label);\r
+                        String safeName = NameUtils.findFreshName(g, label, g.getSingleObject(data, l0.PartOf), l0.ConsistsOf, "%s%d");\r
+                        g.claimLiteral(data, l0.HasName, safeName);\r
+                        Layer0Utils.addCommentMetadata(g, "Renamed model " + oldName + " to " + label + " " + data.toString());\r
+                    }\r
+                };\r
+            }\r
+        };\r
+        return modifier;\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+       disposed = true;\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    \r
+                    graph.markUndoPoint();\r
+                    \r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                       \r
+                    for(Resource r : graph.getObjects(data, l0.ConsistsOf))\r
+                        if(graph.isInstanceOf(r, SysdynResource.getInstance(graph).Result))\r
+                            SimulationResultNode.deleteResultFiles(graph, r);\r
+\r
+                    String modelName = graph.getPossibleRelatedValue2(data, l0.HasName, Bindings.STRING);\r
+                    String modelResource = data.toString();\r
+                    RemoverUtil.remove(graph, data);\r
+                    \r
+                    Layer0Utils.addCommentMetadata(graph, "Removed model '" + modelName +"' " + modelResource);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }\r
+        \r
+    }\r
+\r
+       @Override\r
+       public boolean handleDoubleClick() {\r
+               return false;\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..297124a
--- /dev/null
@@ -0,0 +1,114 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\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.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.layer0.adapter.PasteHandler;\r
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModuleNode extends ConfigurationNode<Resource> implements IModifiableNode {\r
+\r
+       Resource configuration;\r
+       \r
+       public ModuleNode(Resource resource) {\r
+               super(resource);\r
+               \r
+\r
+        SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                       Resource type =  graph.getPossibleObject(data, Layer0.getInstance(graph).InstanceOf);\r
+                       configuration = graph.getPossibleObject(type, StructuralResource2.getInstance(graph).IsDefinedBy);                              \r
+                       }\r
+               });\r
+       }\r
+       \r
+    public ModuleNode(Variable variable, Resource represents) {\r
+        super(variable, represents);\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                       Resource type =  graph.getPossibleObject(data, Layer0.getInstance(graph).InstanceOf);\r
+                       configuration = graph.getPossibleObject(type, StructuralResource2.getInstance(graph).IsDefinedBy);                              \r
+                       }\r
+               });\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(PasteHandler.class == adapter && configuration != null) \r
+            return new DefaultPasteHandler(configuration);\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        try {\r
+            final Session session = SimanticsUI.getSession();\r
+            Resource hasName = Layer0.getInstance(session).HasName;\r
+            LabelModifier modifier = new LabelModifier(session, data, hasName) {\r
+                @Override\r
+                public String isValid(String label) {\r
+                    if (!new VariableNameValidator().isValid(data, label))\r
+                        return "Not valid";\r
+                    else\r
+                        return null;\r
+                }\r
+                \r
+                @Override\r
+                public void modify(final String label) {\r
+                    try {\r
+                                       session.syncRequest(new WriteRequest() {\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph)\r
+                                                               throws DatabaseException {\r
+\r
+                                               String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName);\r
+                                               if(!originalName.equals(label)) {\r
+                                                   Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf);\r
+                                                   new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label);\r
+                                                       graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label);\r
+                                               }\r
+                                               }\r
+                                       });\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+\r
+                       super.modify(label);\r
+                }\r
+            };\r
+            return modifier;\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return null;\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..06e93bd
--- /dev/null
@@ -0,0 +1,216 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import java.util.Collection;\r
+\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.databoard.Bindings;\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.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.layer0.adapter.PasteHandler;\r
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.issues.ontology.IssueResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.ui.utils.ModuleTypeNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModuleTypeNode extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+       \r
+       Listener<String> configurationNameSynchronizer;\r
+       private boolean disposed = false;\r
+       private Resource configuration;\r
+       \r
+    public ModuleTypeNode(Resource resource) {\r
+        super(resource);\r
+\r
+        SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                       ModelingResources mr = ModelingResources.getInstance(graph);\r
+                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+                       Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+                       configuration = graph.getPossibleObject(type, sr2.IsDefinedBy);                         \r
+                       }\r
+               });\r
+        \r
+        // Not the best solution for name sync\r
+        configurationNameSynchronizer = new Listener<String>() {\r
+\r
+               @Override\r
+                       public void execute(final String result) {\r
+                   if(result == null)\r
+                       return; \r
+                   \r
+                               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                                       \r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               if(configuration != null) {\r
+                                                   Layer0 L0 = Layer0.getInstance(graph);\r
+                                                   String currentLabel = graph.getRelatedValue2(configuration, L0.HasLabel, Bindings.STRING);\r
+                                                   if (!currentLabel.equals(result))\r
+                                                       graph.claimLiteral(configuration, L0.HasLabel, result);\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 disposed;\r
+                       }\r
+               };\r
+               \r
+        SimanticsUI.getSession().asyncRequest(new Read<String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                ModelingResources mr = ModelingResources.getInstance(graph);\r
+                Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+                               return (String) (type != null ? graph.getRelatedValue(type, l0.HasName) : null);\r
+                       }\r
+               \r
+        }, configurationNameSynchronizer);\r
+        \r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        Modifier modifier = null;\r
+        try {\r
+            modifier = SimanticsUI.getSession().syncRequest(new Read<Modifier>() {\r
+\r
+                @Override\r
+                public Modifier perform(ReadGraph graph) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+                    ModelingResources mr = ModelingResources.getInstance(graph);\r
+                    Layer0 l0 = Layer0.getInstance(graph);\r
+                    Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+\r
+                    LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), type, l0.HasName) {\r
+                        @Override\r
+                        public String isValid(String label) {\r
+                            if (!new ModuleTypeNameValidator().isValid(data, label))\r
+                                return "Not valid";\r
+                            else\r
+                                return null;\r
+                        }\r
+                    };\r
+\r
+\r
+                    return modifier;\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        return modifier;\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+       disposed = true;\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException{\r
+                    graph.markUndoPoint();\r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                    StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+                    ModelingResources mr = ModelingResources.getInstance(graph);\r
+\r
+                    Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+                    Resource model = graph.getSingleObject(type, l0.PartOf);\r
+                    Resource modelConfiguration = graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
+                    if (!graph.syncRequest(new ObjectsWithType(modelConfiguration, l0.ConsistsOf, type)).isEmpty()) {\r
+                        throw new ModuleDeleteException("The module is used at the model configuration");\r
+                    }\r
+                    Collection<Resource> moduleTypes = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType));\r
+                    for(Resource r : moduleTypes) {\r
+                        Resource configuration = graph.getPossibleObject(r, st.IsDefinedBy);\r
+                        if(configuration != null && !graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, type)).isEmpty()) {\r
+                            throw new ModuleDeleteException("The module is used at another module: " + graph.getRelatedValue(r, l0.HasName));\r
+                        }\r
+                    }\r
+                    \r
+                    IssueResource ISSUE = IssueResource.getInstance(graph);\r
+                    // Remove issues\r
+                    for(Resource issueSource : graph.syncRequest(new ObjectsWithType(type, l0.ConsistsOf, ISSUE.Sources_DependencyTracker))) {\r
+                        for(Resource issue : graph.syncRequest(new ObjectsWithType(issueSource, ISSUE.IssueSource_Manages, ISSUE.Issue))) {\r
+                            RemoverUtil.remove(graph, issue);\r
+                        }\r
+                    }\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed Module Type " + graph.getRelatedValue2(type, l0.HasName, Bindings.STRING) + " " + type.toString());\r
+                    RemoverUtil.remove(graph, type);\r
+                }\r
+            });\r
+        } catch (ModuleDeleteException e) {\r
+            Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+            MessageDialog dialog = new MessageDialog(shell, "Unable to delete", null, e.message, SWT.ERROR,\r
+                    new String[] { "OK" }, 0);\r
+            dialog.create();\r
+            dialog.open();\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+    \r
+    private class ModuleDeleteException extends DatabaseException {\r
+        private static final long serialVersionUID = 4076002781765246919L;\r
+        String message;\r
+        \r
+        public ModuleDeleteException(String message) {\r
+            this.message = message;\r
+        }\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(PasteHandler.class == adapter && configuration != null) \r
+            return new DefaultPasteHandler(configuration);\r
+        return super.getAdapter(adapter);\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..faf9fae
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class ModulesNode extends AbstractNode<Resource> {\r
+    \r
+    public ModulesNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\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..ce15295
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class OperatingInterfacesFolder extends AbstractNode<Resource> {\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/PieChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/PieChartNode.java
new file mode 100644 (file)
index 0000000..776cbdb
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.request.SingleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\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.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Node for pie charts\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class PieChartNode extends AbstractChartNode<Resource> {\r
+\r
+    public PieChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+\r
+    /**\r
+     * Adds a variable to this chart\r
+     * @param variable\r
+     */\r
+    @Override\r
+    protected void addVariableToChart(final Variable variable) {\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                Resource plot = graph.syncRequest(new SingleObjectWithType(data, l0.ConsistsOf, jfree.Plot));\r
+                if(plot == null)\r
+                    return;\r
+\r
+                Resource dataset = graph.syncRequest(new PossibleObjectWithType(plot, l0.ConsistsOf, jfree.Dataset));\r
+                \r
+                if(dataset == null)\r
+                    return;\r
+                \r
+                // Create the series and attach it to the dataset\r
+                String rvi = Variables.getRVI(graph, variable);\r
+                Resource series = ChartUtils.createSeries(graph, dataset, rvi);\r
+                graph.claimLiteral(series, jfree.Series_exploded, false);\r
+            }\r
+        });        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModule.java
new file mode 100644 (file)
index 0000000..9307287
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.databoard.Bindings;\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.WriteRequest;\r
+import org.simantics.db.exception.CancelTransactionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SCLModule extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public SCLModule(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    String ontologyName = graph.getPossibleRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                    RemoverUtil.remove(graph, data);\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed SCL Module " + ontologyName + " "+ data.toString());\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        Session session = SimanticsUI.getSession();\r
+        return new LabelModifier(session, data, session.getService(Layer0.class).HasName);\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SCLModulesFolder.java
new file mode 100644 (file)
index 0000000..425a602
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.ISpecialFolder;\r
+import org.simantics.db.Resource;\r
+\r
+public class SCLModulesFolder extends AbstractNode<Resource> implements ISpecialFolder {\r
+    \r
+    public SCLModulesFolder(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SensitivityChartNode.java
new file mode 100644 (file)
index 0000000..026330c
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.layer0.variable.Variable;\r
+\r
+public class SensitivityChartNode extends AbstractChartNode<Resource> {\r
+\r
+    public SensitivityChartNode(Resource data) {\r
+        super(data);\r
+    }\r
+\r
+    @Override\r
+    protected void addVariableToChart(Variable variable) {\r
+        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionLibraryNode.java
new file mode 100644 (file)
index 0000000..ec8d5f8
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.browsing.ui.graph.impl.LabelModifier;\r
+import org.simantics.databoard.Bindings;\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.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.SharedFunctionLibraryNameValidator;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class SharedFunctionLibraryNode extends FunctionLibraryNode<Resource> implements IDropTargetNode {\r
+\r
+    public SharedFunctionLibraryNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                String ontologyName = graph.getPossibleRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                RemoverUtil.remove(graph, data);\r
+                Layer0Utils.addCommentMetadata(graph, "Removed Shared Function Library " + ontologyName + " "+ data.toString());\r
+                       }\r
+               });\r
+       }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        try {\r
+            Resource hasName = Layer0.getInstance(Simantics.getSession()).HasName;\r
+            LabelModifier modifier = new LabelModifier(Simantics.getSession(), data, hasName) {\r
+                @Override\r
+                public String isValid(String label) {\r
+                    if (!new SharedFunctionLibraryNameValidator().isValid(data, label))\r
+                        return "Not valid";\r
+                    else\r
+                        return null;\r
+                }\r
+            };\r
+            return modifier;\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return null;\r
+    }\r
+       \r
+       @Override\r
+       public void drop(Object data) {\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(data);\r
+               final Resource library = this.data;\r
+               if(resources.length > 0) {\r
+                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       for(Resource tobeMoved : resources) {\r
+                                               if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) ||\r
+                                                               graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) {\r
+                                                       graph.deny(tobeMoved, l0.PartOf);\r
+                                                       graph.claim(tobeMoved, l0.PartOf, library);\r
+                                               }\r
+                                       }\r
+                                       \r
+                               }\r
+                       });\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedFunctionsFolder.java
new file mode 100644 (file)
index 0000000..0531fd9
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class SharedFunctionsFolder extends AbstractNode<Resource> {\r
+\r
+       public SharedFunctionsFolder(Resource data) {\r
+               super(data);\r
+       }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(clazz == adapter) // There is no resource for this node..\r
+            return null;\r
+        return super.getAdapter(adapter);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedOntologyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SharedOntologyNode.java
new file mode 100644 (file)
index 0000000..678a4c0
--- /dev/null
@@ -0,0 +1,48 @@
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\r
+import org.simantics.browsing.ui.common.node.IModifiableNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.databoard.Bindings;\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.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SharedOntologyNode extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+    public SharedOntologyNode(Resource data) {\r
+        super(data);\r
+    }\r
+    \r
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            Simantics.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    graph.markUndoPoint();\r
+                    String ontologyName = graph.getPossibleRelatedValue2(data, Layer0.getInstance(graph).HasName, Bindings.STRING);\r
+                    RemoverUtil.remove(graph, data);\r
+                    Layer0Utils.addCommentMetadata(graph, "Removed Shared Ontology " + ontologyName + " "+ data.toString());\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }    \r
+    }\r
+\r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SheetNode.java
new file mode 100644 (file)
index 0000000..39fdb22
--- /dev/null
@@ -0,0 +1,83 @@
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.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.variable.RVI;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.utils.SheetNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorInput2;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+public class SheetNode extends AbstractNode<Resource> implements IModifiableNode, IDoubleClickableNode {\r
+\r
+    public SheetNode(Resource data) {\r
+        super(data);\r
+    }\r
+    \r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        \r
+        Session session = SimanticsUI.getSession();\r
+        LabelModifier modifier = new LabelModifier(session, data, session.getService(Layer0.class).HasName) {\r
+            @Override\r
+            public String isValid(String label) {\r
+                if (!new SheetNameValidator().isValid(data, label))\r
+                    return "Not valid";\r
+                else\r
+                    return null;\r
+            }\r
+        };\r
+        return modifier;\r
+    }\r
+\r
+    @Override\r
+    public boolean handleDoubleClick() {\r
+        \r
+        try {\r
+            \r
+            SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                @Override\r
+                public void run(ReadGraph graph) throws DatabaseException {\r
+\r
+                    Variable variable = graph.adapt(data, Variable.class);\r
+                    final Resource model = Variables.getModel(graph, variable);\r
+                    final RVI rvi = variable.getRVI(graph);\r
+\r
+                    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+                        \r
+                        private static final String EDITOR_ID = "org.simantics.spreadsheet.ui.editor2";\r
+                        \r
+                        @Override\r
+                        public void run() {\r
+                            try {\r
+                                System.out.println("Activating sheet: model=" + model + " rvi=" + rvi);\r
+                                WorkbenchUtils.openEditor(EDITOR_ID, new ResourceEditorInput2(EDITOR_ID, data, model, rvi));\r
+                            } catch (PartInitException e) {\r
+                                e.printStackTrace();\r
+                            }\r
+                        }\r
+                    });\r
+                }\r
+            });\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        return true;\r
+    }\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..bc9c4a3
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import java.io.File;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.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.util.RemoverUtil;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.handlers.ToggleResultActivation;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SimulationResultNode<T>  extends AbstractNode<Resource> implements IDoubleClickableNode, IDeletableNode, 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(), data) {\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
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                    unlinkResult(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    public static void unlinkResult(WriteGraph graph, Resource result) throws DatabaseException  {\r
+        deleteResultFiles(graph, result);\r
+        RemoverUtil.remove(graph, result);\r
+    }\r
+    \r
+    public static void deleteResultFiles(WriteGraph graph, Resource result) throws DatabaseException  {\r
+        String path;\r
+        path = graph.getPossibleRelatedValue(result, SysdynResource.getInstance(graph).Result_resultFile);\r
+        if(path != null) {\r
+            File file = new File(path);\r
+            file.delete();\r
+            File parent = file.getParentFile();\r
+            if(parent.listFiles() != null && parent.listFiles().length == 0)\r
+                parent.delete();\r
+        }\r
+    }\r
+\r
+\r
+       @Override\r
+       public boolean handleDoubleClick() {\r
+               Resource[] resources = {data};\r
+               ToggleResultActivation.toggleActivation(resources);\r
+               return true;\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultSetNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/browser/nodes/SimulationResultSetNode.java
new file mode 100644 (file)
index 0000000..194e1c9
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\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.util.RemoverUtil;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.handlers.ToggleResultSetActivation;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SimulationResultSetNode  extends AbstractNode<Resource> implements IDoubleClickableNode, IDeletableNode, IModifiableNode {\r
+\r
+    public SimulationResultSetNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data) {\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
+    @Override\r
+    public void delete() throws DeleteException {\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException, CancelTransactionException {\r
+                                       unlinkResultSet(graph, data);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    public static void unlinkResultSet(WriteGraph graph, Resource resultSet) throws DatabaseException  {\r
+       SysdynResource sr = SysdynResource.getInstance(graph);\r
+       for (Resource result : graph.syncRequest(new ObjectsWithType(resultSet, sr.Experiment_result, sr.Result))) {\r
+                       SimulationResultNode.unlinkResult(graph, result);\r
+       }\r
+        RemoverUtil.remove(graph, resultSet);\r
+    }\r
+\r
+       @Override\r
+       public boolean handleDoubleClick() {\r
+               Resource[] resources = {data};\r
+               ToggleResultSetActivation.toggleActivation(resources);\r
+               return true;\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..4345615
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.IDeletable;\r
+import org.simantics.db.Resource;\r
+\r
+public class SymbolNode extends AbstractNode<Resource> 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..fdfcb13
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.browser.nodes;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.db.Session;\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.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class VariableNode<T> extends AbstractNode<Resource> implements IModifiableNode {\r
+\r
+       Variable variable;\r
+\r
+       public VariableNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+\r
+       public VariableNode(Variable variable, Resource represents) {\r
+               super(represents);\r
+               this.variable = variable;\r
+       }\r
+\r
+       public Variable getVariable() {\r
+               return variable;\r
+       }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        try {\r
+            final Session session = SimanticsUI.getSession();\r
+            Resource hasName = Layer0.getInstance(session).HasName;\r
+            LabelModifier modifier = new LabelModifier(session, data, hasName) {\r
+                @Override\r
+                public String isValid(String label) {\r
+                    if (!new VariableNameValidator().isValid(data, label))\r
+                        return "Not valid";\r
+                    else\r
+                        return null;\r
+                }\r
+                \r
+                @Override\r
+                public void modify(final String label) {\r
+                    try {\r
+                                       session.syncRequest(new WriteRequest() {\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph)\r
+                                                               throws DatabaseException {\r
+\r
+                                               String originalName = graph.getRelatedValue(data, Layer0.getInstance(graph).HasName);\r
+                                               if(!originalName.equals(label)) {\r
+                                                   Resource configuration = graph.getPossibleObject(data, Layer0.getInstance(graph).PartOf);\r
+                                                   new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, label);\r
+                                                       graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label);\r
+                                               }\r
+                                               }\r
+                                       });\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+\r
+                       super.modify(label);\r
+                }\r
+            };\r
+            return modifier;\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return null;\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..240874f
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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(L0.InstanceOf, Element, ElementType),\r
+                               bf(MOD.SymbolToComponentType, ElementType, ComponentType)\r
+                        ),\r
+                        // If element type of the element has a corresponding component type\r
+                        createComponentRule(),\r
+                    \r
+                        if_(and(b(DIA.Connection, Element), bf(L0.InstanceOf, Element, ElementType), bf(MOD.DiagramConnectionTypeToConnectionType, ElementType, ComponentType)),\r
+                                createNormalConnectionRule(),\r
+\r
+                                if_(b(DIA.Flag, Element),\r
+                                        createFlagRule()\r
+                                )\r
+                        )\r
+                    )\r
+                )\r
+            );\r
+    }\r
+\r
+    @Override\r
+    protected IRuleInstruction destructiveRule() {\r
+        return\r
+        if_(and(bf(L0.ConsistsOf, Configuration, Component),\r
+                b(mapped, Component) // handle only mapped components\r
+        ),\r
+        query(\r
+                if_(and(bf(MOD.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, STR.IsConnectedTo),\r
+                        b(mapped, Connection)\r
+                ),\r
+                // If component has a mapped connection\r
+                unless(\r
+                        bf(MOD.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(MOD.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(MOD.DiagramConnectionToConnection, Element, Connection),\r
+                Connection\r
+        ),\r
+        bb(L0.InstanceOf, Connection, ComponentType),\r
+        bb(L0.PartOf, Connection, Configuration),\r
+        b(mapped, Connection)\r
+\r
+        );\r
+    }\r
+    \r
+//    @Override\r
+//    protected IInstruction claimBasicConnection() {\r
+//        return and(exists(\r
+//                bf(MOD.DiagramConnectionToConnection, Element, Connection),\r
+//                Connection\r
+//        ),\r
+//        bb(L0.InstanceOf, Connection, ComponentType),\r
+//        b(mapped, Connection),\r
+//        bb(L0.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..c1bbf18
--- /dev/null
@@ -0,0 +1,208 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import java.awt.dnd.DnDConstants;\r
+import java.util.Collections;\r
+import java.util.Set;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Session;\r
+import org.simantics.diagram.handler.DeleteHandler;\r
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.g2d.canvas.Hints;\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.handler.PickRequest;\r
+import org.simantics.g2d.diagram.participant.DiagramParticipant;\r
+import org.simantics.g2d.diagram.participant.ElementInteractor;\r
+import org.simantics.g2d.diagram.participant.ElementPainter;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.diagram.participant.ZOrderHandler;\r
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementClasses;\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.g2d.participant.GridPainter;\r
+import org.simantics.g2d.participant.RulerPainter;\r
+import org.simantics.g2d.tooltip.TerminalTooltipParticipant;\r
+import org.simantics.jfreechart.chart.element.PopulateChartDropParticipant;\r
+import org.simantics.modeling.mapping.ElementCopyAdvisor;\r
+import org.simantics.modeling.mapping.MappedElementCopyAdvisor;\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.editor.participant.CreateVariablesShortcutParticipant;\r
+import org.simantics.sysdyn.ui.editor.participant.SelectionUpdaterParticipant;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynComponentCopyAdvisor;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynPopulateElementDropParticipant;\r
+import org.simantics.sysdyn.ui.elements.CloudFactory;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementClasses;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementFactory;\r
+import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses;\r
+import org.simantics.sysdyn.ui.elements.connections.RouteFlowEdgeClass;\r
+import org.simantics.sysdyn.ui.elements.connections.SysdynConnectionClass;\r
+import org.simantics.sysdyn.ui.handlers.ExtendedCopyPasteHandler;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.ui.workbench.IPropertyPage;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+import org.simantics.utils.threads.AWTThread;\r
+import org.simantics.utils.threads.ThreadUtils;\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
+       public void createPartControl(Composite parent) {\r
+               super.createPartControl(parent);\r
+       } \r
+\r
+       @Override\r
+       protected Set<String> getPropertyPageContexts() {\r
+               return Collections.singleton(SysdynResource.URIs.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
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               ElementClass dependencyClass = SysdynConnectionClass.CLASS.newClassWith(new StaticObjectAdapter(sr.DependencyConnection));\r
+               ElementClass flowClass = RouteFlowEdgeClass.FLOW_CLASS.newClassWith(new StaticObjectAdapter(sr.FlowConnection));\r
+               return SysdynElementClassProviders.mappedProvider(\r
+                               ElementClasses.CONNECTION, dependencyClass,\r
+                               ElementClasses.FLAG, CloudFactory.createElementClass(sr.CloudSymbol, SysdynElementFactory.createTerminals(graph, sr.CloudSymbol)),\r
+                               ConnectionClasses.FLOW, flowClass,\r
+                               ConnectionClasses.DEPENDENCY, dependencyClass,\r
+                               SysdynElementClasses.VALVE,  CloudFactory.createElementClass(sr.ValveSymbol, SysdynElementFactory.createTerminals(graph, sr.ValveSymbol))\r
+               );\r
+\r
+\r
+       }\r
+       \r
+       @Override\r
+    public void initializeCanvasContext(CanvasContext ctx) {\r
+       super.initializeCanvasContext(ctx);\r
+       // GRID and RULER have to be set here. They cause deadlocks in Show Module if set in onCreated()\r
+               IHintContext h = ctx.getDefaultHintContext();\r
+               h.setHint(GridPainter.KEY_GRID_ENABLED, Boolean.FALSE);\r
+               h.setHint(RulerPainter.KEY_RULER_ENABLED, Boolean.FALSE);\r
+               h.setHint(Hints.KEY_DISPLAY_MARGINS, Boolean.FALSE);\r
+               h.setHint(Hints.KEY_DISPLAY_PAGE, Boolean.FALSE);\r
+    }\r
+\r
+       @Override\r
+       protected void onCreated() {\r
+           sourceDiagram.setHint(DiagramHints.KEY_ALLOW_ROUTE_POINTS, Boolean.FALSE);\r
+           sourceDiagram.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new SysdynComponentCopyAdvisor()));\r
+\r
+           ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() { \r
+\r
+               @Override\r
+               public void run() {\r
+                   if (isDisposed())  {\r
+                       return; \r
+                   } else {\r
+                       if(canvasContext != null && sourceDiagram != null) {\r
+                           ElementPainter ep = canvasContext.getSingleItem(ElementPainter.class);\r
+                           for(IElement e : sourceDiagram.getElements()) {\r
+                               if(e.getElementClass().getId().contains("Connection")){\r
+                                   ep.update(e);\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+               }\r
+           });\r
+       }\r
+\r
+       @Override\r
+       protected void addKeyBindingParticipants(CanvasContext ctx) {\r
+               ctx.add(new DeleteHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+               ctx.add(new CreateVariablesShortcutParticipant(synchronizer));\r
+               ctx.add(new ExtendedCopyPasteHandler(getEditorSite().getActionBars().getStatusLineManager()).setWorkbenchSite(getEditorSite()));\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
+        addWorkbenchSelectionProvider(ctx);\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
+    protected void addDropParticipants(ICanvasContext ctx) {\r
+        ctx.getDefaultHintContext().setHint(Hints.KEY_ALLOWED_DRAG_ACTIONS, DnDConstants.ACTION_COPY);\r
+\r
+        ctx.add(new SysdynPopulateElementDropParticipant(synchronizer));\r
+        ctx.add(new PopulateChartDropParticipant(synchronizer));\r
+    }\r
+\r
+       @Override\r
+       protected void addOtherParticipants(CanvasContext ctx) {\r
+           ctx.add(new SelectionUpdaterParticipant());\r
+       }\r
+\r
+       @Override \r
+       protected PointerInteractor getPointerInteractor() {\r
+               return new org.simantics.sysdyn.ui.editor.participant.SysdynPointerInteractor(true, true, true, false, true, false, synchronizer.getElementClassProvider(), PickRequest.PickSorter.CONNECTIONS_FIRST);\r
+       }\r
+\r
+       @Override\r
+       protected IConnectionAdvisor getConnectionAdvisor(IModelingRules modelingRules, Session session) {\r
+               return new SysdynConnectionAdvisor(modelingRules, sessionContext.getSession());\r
+       }\r
+\r
+       @Override\r
+    protected void addDiagramParticipants(ICanvasContext ctx) {\r
+        ctx.add(new ZOrderHandler());\r
+        ctx.add(getPointerInteractor());\r
+        ctx.add(new ElementInteractor(PickRequest.PickSorter.CONNECTIONS_FIRST));\r
+        ctx.add(new Selection());\r
+        ctx.add(new DiagramParticipant());\r
+        ctx.add(new ElementPainter());\r
+        //ctx.add(new ElementHeartbeater());\r
+        //ctx.add(new ZoomTransitionParticipant(TransitionFunction.SIGMOID));\r
+        //ctx.add(new TooltipParticipant());\r
+        ctx.add(new TerminalTooltipParticipant());\r
+    }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromComponentAdapter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromComponentAdapter.java
new file mode 100644 (file)
index 0000000..fb89ccc
--- /dev/null
@@ -0,0 +1,204 @@
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.IEditorPart;\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.db.layer0.request.PossibleModel;\r
+import org.simantics.db.layer0.variable.RVI;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.content.ConnectionUtil;\r
+import org.simantics.diagram.flag.FlagUtil;\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.layer0.Layer0;\r
+import org.simantics.modeling.ComponentUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.actions.NavigateToTarget;\r
+import org.simantics.modeling.ui.Activator;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.threads.SWTThread;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class OpenDiagramFromComponentAdapter extends AbstractResourceEditorAdapter {\r
+\r
+    private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+\r
+    public OpenDiagramFromComponentAdapter() {\r
+        super("Diagram Editor", Activator.COMPOSITE_ICON);\r
+    }\r
+\r
+    @Override\r
+    public boolean canHandle(ReadGraph graph, Object input) throws DatabaseException {\r
+        Resource r = tryGetResource(graph, input);\r
+        if (r == null)\r
+            return false;\r
+        Variable v = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+        Collection<Runnable> rs = tryFindDiagram(graph, r, v);\r
+        return !rs.isEmpty();\r
+    }\r
+\r
+    private Resource tryGetResource(ReadGraph graph, Object input) throws DatabaseException {\r
+        Resource r = ResourceAdaptionUtils.toSingleResource(input);\r
+        if (r == null) {\r
+            Variable v = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+            r = findResource(graph, v);\r
+        }\r
+        return r;\r
+    }\r
+\r
+    private Resource findResource(ReadGraph graph, Variable v) throws DatabaseException {\r
+        while (v != null) {\r
+            Resource r = v.getPossibleRepresents(graph);\r
+            if (r != null)\r
+                return r;\r
+            v = v.browsePossible(graph, ".");\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void openEditor(final Object input) throws Exception {\r
+        final Display d = Display.getCurrent();\r
+        if (d == null)\r
+            return;\r
+\r
+        SimanticsUI.getSession().syncRequest(new ReadRequest() {\r
+            @Override\r
+            public void run(ReadGraph graph) throws DatabaseException {\r
+                Resource r = tryGetResource(graph, input);\r
+                if (r == null)\r
+                    return;\r
+\r
+                Variable v = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+\r
+                final Collection<Runnable> rs = tryFindDiagram(graph, r, v);\r
+                if (rs.isEmpty())\r
+                    return;\r
+\r
+                SWTThread.getThreadAccess(d).asyncExec(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        for (Runnable runnable : rs) {\r
+                            runnable.run();\r
+                        }\r
+                    }\r
+                });\r
+            }\r
+        });\r
+    }\r
+\r
+    private Collection<Runnable> tryFindDiagram(ReadGraph g, Resource module, Variable variable) throws DatabaseException {\r
+        try {\r
+            return findDiagram(g, module, variable);\r
+        } catch (DatabaseException e) {\r
+            return Collections.emptyList();\r
+        }\r
+    }\r
+\r
+    private Collection<Runnable> findDiagram(ReadGraph g, Resource module, Variable variable) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(g);\r
+        SysdynResource SYSDYN = SysdynResource.getInstance(g);\r
+\r
+        if (g.isInstanceOf(module, SYSDYN.IndependentVariable) || g.isInstanceOf(module, SYSDYN.Input) || g.isInstanceOf(module, SYSDYN.Module)) {\r
+            Collection<Runnable> result = new ArrayList<Runnable>(1);\r
+\r
+            Variable moduleVariable = Variables.getVariable(g, module);\r
+            RVI rvi = moduleVariable.getRVI(g);\r
+            \r
+            Resource composite = g.getSingleObject(module, l0.PartOf);\r
+            Resource model = g.syncRequest(new PossibleModel(composite));\r
+\r
+            final Resource diagram = ComponentUtils.getCompositeDiagram(g, composite);\r
+            \r
+//            final ResourceArray compositePath = StructuralVariables.getCompositeArray(g, composite);\r
+//            final ResourceArray variablePath = compositePath.removeFromBeginning(1);\r
+//\r
+//            Resource model = StructuralVariables.getModel(g, compositePath.head());\r
+//            if (model == null)\r
+//                return Collections.emptyList();\r
+//\r
+//            String rvi = StructuralVariables.getRVI(g, variablePath);\r
+//            if (rvi == null)\r
+//                return Collections.emptyList();\r
+\r
+            if (variable != null) {\r
+                // Get proper RVI from variable if it exists.\r
+                Variable context = Variables.getPossibleContext(g, variable);\r
+                if (context != null) {\r
+                    // We want the composite's RVI, not the component in it.\r
+                    Variable parent = variable.getParent(g);\r
+                    if (parent != null) {\r
+                       rvi = parent.getRVI(g);\r
+//                        String contextURI = context.getURI(g);\r
+//                        String parentURI = parent.getURI(g);\r
+//                        rvi = parentURI.replace(contextURI, "");\r
+                       model = Variables.getModel(g, context);\r
+                    }\r
+                }\r
+            }\r
+\r
+            final Collection<Object> selectedObjects = findElementObjects(g, module);\r
+\r
+            result.add(\r
+                    NavigateToTarget.editorActivator(EDITOR_ID, diagram, model, rvi, new Callback<IEditorPart>() {\r
+                        @Override\r
+                        public void run(IEditorPart part) {\r
+                            final ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);\r
+                            assert openedCanvas != null;\r
+                            // CanvasContext-wide denial of initial zoom-to-fit on diagram open.\r
+                            openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE);\r
+                            ThreadUtils.asyncExec(openedCanvas.getThreadAccess(),\r
+                                    NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false));\r
+                        }\r
+                    }));\r
+            return result;\r
+        }\r
+\r
+        // Nothing to open\r
+        return Collections.emptyList();\r
+    }\r
+\r
+    public static Collection<Object> findElementObjects(ReadGraph g, Resource module) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(g);\r
+        ModelingResources MOD = ModelingResources.getInstance(g);\r
+        final Collection<Object> selectedObjects = new ArrayList<Object>();\r
+        for (Resource element : g.getObjects(module, MOD.ComponentToElement)) {\r
+            if (g.isInstanceOf(element, DIA.Flag) && FlagUtil.isExternal(g, element)) {\r
+                // Use external flag primarily if one exists in the correspondences\r
+                selectedObjects.clear();\r
+                selectedObjects.add(element);\r
+                break;\r
+            } else if (g.isInstanceOf(element, DIA.RouteGraphConnection)) {\r
+                selectedObjects.add(element);\r
+            } else if (g.isInstanceOf(element, DIA.Connection)) {\r
+                // Okay, we need to find a part of the connection\r
+                ConnectionUtil cu = new ConnectionUtil(g);\r
+                cu.gatherConnectionParts(element, selectedObjects);\r
+            } else {\r
+                selectedObjects.add(element);\r
+            }\r
+        }\r
+        for(Resource element : g.getObjects(module, MOD.HasParentComponent_Inverse)) {\r
+            selectedObjects.add(element);\r
+        }\r
+        return selectedObjects;\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..8fe5d1d
--- /dev/null
@@ -0,0 +1,121 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.PlatformUI;\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.modeling.ComponentUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.Activator;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.StructuralVariables;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorInput2;\r
+import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+public class OpenDiagramFromConfigurationAdapter extends AbstractResourceEditorAdapter {\r
+\r
+       private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+\r
+    public OpenDiagramFromConfigurationAdapter() {\r
+        super("Diagram Editor", Activator.COMPOSITE_ICON);\r
+    }\r
+\r
+    protected String getEditorId() {\r
+        return EDITOR_ID;\r
+    }\r
+\r
+    @Override\r
+    public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(g);\r
+               if(g.isInheritedFrom(r, sr.ModuleSymbol)) {\r
+                       ModelingResources mr = ModelingResources.getInstance(g);\r
+                       StructuralResource2 sr2 = StructuralResource2.getInstance(g);\r
+                       Resource componentType = g.getSingleObject(r, mr.SymbolToComponentType);\r
+                       r = g.getSingleObject(componentType, sr2.IsDefinedBy);\r
+               }\r
+               Layer0X L0X = Layer0X.getInstance(g);\r
+               Resource represents = g.getPossibleObject(r, L0X.Represents);\r
+               if(represents != null){\r
+                       if(g.isInstanceOf(represents, sr.Configuration)) {\r
+                               r = represents;\r
+                       }\r
+               }\r
+               return ComponentUtils.compositeHasDiagram(g, r) /*|| ComponentUtils.componentHasDiagram(g, r)*/;\r
+    }\r
+\r
+    @Override\r
+    public void openEditor(final Resource r) throws Exception {\r
+\r
+        SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+            @Override\r
+            public void run(ReadGraph g) throws DatabaseException {\r
+               Resource cr = r;\r
+                               Layer0X L0X = Layer0X.getInstance(g);\r
+                               if(g.isInheritedFrom(r, SysdynResource.getInstance(g).ModuleSymbol)) {\r
+                                       ModelingResources mr = ModelingResources.getInstance(g);\r
+                                       StructuralResource2 sr2 = StructuralResource2.getInstance(g);\r
+                                       Resource componentType = g.getSingleObject(r, mr.SymbolToComponentType);\r
+                                       Resource configuration = g.getSingleObject(componentType, sr2.IsDefinedBy);\r
+                                       cr = configuration;\r
+                               } else {     \r
+                                       Resource represents = g.getPossibleObject(r, L0X.Represents);\r
+                                       if(represents != null && g.isInstanceOf(represents, SysdynResource.getInstance(g).Configuration)){\r
+                                               cr = represents;\r
+                                       } else {\r
+                                               cr = r;\r
+                                       }\r
+                               }\r
+\r
+               \r
+                final Resource diagram = ComponentUtils.getPossibleCompositeDiagram(g, cr);\r
+                if(diagram == null) return;\r
+                final ResourceArray compositePath = StructuralVariables.getCompositeArray(g, cr);\r
+                final ResourceArray variablePath = compositePath.removeFromBeginning(1);\r
+\r
+                final Resource model = StructuralVariables.getModel(g, compositePath.head());\r
+                if(model == null) return;\r
+\r
+                \r
+                \r
+                final String rvi = StructuralVariables.getRVI(g, variablePath);\r
+                if(rvi == null) return;\r
+\r
+                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        try {\r
+                            String editorId = getEditorId();\r
+//                            System.out.println("Activating diagram: model=" + modelURI + " rvi='" + rvi + "'");\r
+                            WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, diagram, model, 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
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..ffcfd38
--- /dev/null
@@ -0,0 +1,149 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.structural2.modelingRules.CPIgnore;\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
+import org.simantics.sysdyn.ui.elements.CloudFactory.CloudSceneGraph;\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
+               // FIXME: this currently allows connections to begin from flags\r
+               // but is rather hackish.\r
+               if(element.getElementClass().containsClass(CloudSceneGraph.class)) {\r
+                       return CPIgnore.NULL_INSTANCE;\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
+                                       if(element1 != null && term1 != null && element2 != null && term2 != null) {\r
+                                               StaticObjectAdapter soa = element1.getElementClass().getSingleItem(StaticObjectAdapter.class);\r
+                                               Resource startElementResource = soa.adapt(Resource.class);\r
+                                               Object r = ElementUtils.getObject(element2);\r
+                                               if(r == null || !(r instanceof Resource))\r
+                                                   return null;\r
+                                               Resource endElementResource = (Resource) r;\r
+                                               \r
+                                               DiagramResource dr = DiagramResource.getInstance(g);\r
+                                               Resource terminal2 = ((ResourceTerminal) term2).getResource();\r
+                                               SysdynResource sr = SysdynResource.getInstance(g);\r
+                                               \r
+                                               \r
+                                               // Chech that end terminal has IsHeadOfTerminal relation\r
+                                               Resource connectionPoint = g.getPossibleObject(terminal2, dr.HasConnectionPoint);\r
+                        if(connectionPoint == null || !g.isSubrelationOf(connectionPoint, sr.IsHeadOfTerminal)) {\r
+                            return null;\r
+                        }\r
+\r
+                                               \r
+                        // If end element is input symbol, allow only one connection and only from a module\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
+\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;\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..6772154
--- /dev/null
@@ -0,0 +1,99 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import gnu.trove.TIntIntHashMap;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+\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.utils.NameUtils;\r
+import org.simantics.db.common.utils.URIStringUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\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.operation.Layer0X;\r
+import org.simantics.project.IProject;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.ShadowVariableReferenceDialogRunnable;\r
+import org.simantics.utils.threads.SWTThread;\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
+        Layer0 l0 = Layer0.getInstance(g);\r
+        Layer0X L0X = Layer0X.getInstance(g);\r
+        \r
+        try {\r
+            \r
+            // Naming strategy\r
+            String proposition = URIStringUtils.escape(ComponentNamingUtil.findFreshInstanceName(g, project, configuration, configuration, componentType));\r
+            Resource result = GraphUtils.create(g,\r
+                    l0.HasName, proposition\r
+            );\r
+            g.claim(result, L0X.Represents, result);\r
+            \r
+            // Add uninitialized tag. The tag is used to start name editing \r
+            SysdynResource SR = SysdynResource.getInstance(g);\r
+            g.claim(result, SR.IndependentVariable_isUninitialized, result);\r
+            \r
+            // Async reference dialog for shadow variables\r
+            if(SR.Shadow.equals(componentType)) {\r
+                Layer0 L0 = Layer0.getInstance(g);\r
+                Collection<Resource> referrableVariables = g.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, SR.IndependentVariable));\r
+                referrableVariables.addAll( g.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, SR.Input)));\r
+                HashMap<String, Resource> names = new  HashMap<String, Resource>();\r
+                for(Resource var : referrableVariables) {\r
+                    String name = NameUtils.getSafeName(g, var);\r
+                    names.put(name, var);\r
+                }\r
+                SWTThread.getThreadAccess().asyncExec(new ShadowVariableReferenceDialogRunnable(result, names));\r
+            }\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/SysdynEditorInput.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorInput.java
new file mode 100644 (file)
index 0000000..7e317c6
--- /dev/null
@@ -0,0 +1,387 @@
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.ui.IMemento;\r
+import org.eclipse.ui.IPersistableElement;\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.common.ResourceArray;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.AdaptionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ResourceNotFoundException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.service.LifecycleSupport;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.icons.ImageDescriptorProvider;\r
+import org.simantics.ui.workbench.ResourceEditorInput2;\r
+import org.simantics.ui.workbench.ResourceEditorInputFactory2;\r
+import org.simantics.ui.workbench.TitleRequest;\r
+import org.simantics.ui.workbench.ToolTipRequest;\r
+import org.simantics.utils.ObjectUtils;\r
+import org.simantics.utils.datastructures.cache.ProvisionException;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.workbench.StringMemento;\r
+\r
+/**\r
+ * TEMPORARY fix to support sysdyn\r
+ * \r
+ * @author tlteemu\r
+ *\r
+ */\r
+public class SysdynEditorInput extends ResourceEditorInput2 {\r
+    \r
+    private final static boolean      DEBUG_UPDATE    = false;\r
+\r
+    private static final String       NO_NAME         =  "(no name)";\r
+\r
+    private final String              editorID;\r
+\r
+    private String                    randomAccessResourceId;\r
+\r
+    private transient Resource        resource;\r
+\r
+    /**\r
+     * Gotten from the editor that needs to initialize this input. Currently\r
+     * needed for two things: {@link #exists()} and {@link #saveState(IMemento)}.\r
+     */\r
+    private transient Session         session;\r
+\r
+    private transient boolean         exists;\r
+\r
+    private transient String          name;\r
+\r
+    private transient String          tooltip;\r
+\r
+    private transient ImageDescriptor imageDesc;\r
+\r
+    /** Persistent memento for external data */\r
+    private final StringMemento       persistentStore = new StringMemento();\r
+\r
+    /**\r
+     * @param editorID\r
+     * @param r\r
+     */\r
+    public SysdynEditorInput(String editorID, Resource r, Resource model, String rvi) {\r
+        super(editorID, r, model, rvi);\r
+        if (editorID == null)\r
+            throw new IllegalArgumentException("null editor id");\r
+        if (r == null)\r
+            throw new IllegalArgumentException("null resource");\r
+\r
+        this.editorID = editorID;\r
+        this.randomAccessResourceId = "";\r
+        this.resource = r;\r
+        this.rvi = rvi;\r
+        this.session = SimanticsUI.getSession();\r
+\r
+        ensureRandomAccessId();\r
+        setNonExistant();\r
+    }\r
+\r
+    void ensureRandomAccessId() {\r
+        if (resource == null)\r
+            throw new IllegalStateException("resource is null, input is disposed");\r
+        // Make sure that the resource has a random access id\r
+        try {\r
+            SerialisationSupport support = session.getService(SerialisationSupport.class);\r
+            randomAccessResourceId = String.valueOf(support.getRandomAccessId(resource));\r
+        } catch (DatabaseException e) {\r
+            throw new RuntimeException(e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void init(IAdaptable adapter) throws DatabaseException {\r
+        if (resource == null && randomAccessResourceId != null) {\r
+            getSession().syncRequest(new ReadRequest() {\r
+                @Override\r
+                public void run(ReadGraph g) throws DatabaseException {\r
+                    try {\r
+                        long id = Long.parseLong(randomAccessResourceId);\r
+                        resource = g.getService(SerialisationSupport.class).getResource(id);\r
+                        update(g);\r
+                    } catch (NumberFormatException e) {\r
+                        setNonExistant();\r
+                    } catch (DatabaseException e) {\r
+                        setNonExistant();\r
+                    }\r
+                }\r
+            });\r
+        } else {\r
+            if (resource != null) {\r
+                updateCaches(getSession(), true);\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        //System.out.println("dispose resource editor input: " + name);\r
+        // NOTE: this has to be done since Eclipse will cache these IEditorInput\r
+        // instances within EditorHistoryItem's that are stored in an EditorHistory\r
+        // instance. They are held by strong reference which means that the session\r
+        // cannot be collected if it is not nulled here.\r
+        session = null;\r
+        resource = null;\r
+    }\r
+\r
+    /**\r
+     * @return a graph instance if it exists and has not yet been disposed,\r
+     *         <code>null</code> otherwise\r
+     */\r
+    public Session getSession() {\r
+        // TODO: also throw an exception if the session is disposed\r
+        if (session == null)\r
+            throw new IllegalStateException("session is disposed");\r
+        return session;\r
+    }\r
+\r
+    @Override\r
+    public boolean exists() {\r
+        return exists;\r
+    }\r
+\r
+    @Override\r
+    public boolean exists(ReadGraph graph) throws DatabaseException {\r
+        try {\r
+            assertExists(graph);\r
+            return true;\r
+        } catch (ResourceNotFoundException e) {\r
+        } catch (Nonexistant e) {\r
+        }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public Resource getResource() {\r
+        return resource;\r
+    }\r
+\r
+    @Override\r
+    @Deprecated\r
+    public ResourceArray getResourceArray() {\r
+        return new ResourceArray(resource);\r
+    }\r
+\r
+    @Override\r
+    public String getRVI() {\r
+        return rvi;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.IEditorInput#getImageDescriptor()\r
+     */\r
+    @Override\r
+    public ImageDescriptor getImageDescriptor() {\r
+        return imageDesc;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.IEditorInput#getName()\r
+     */\r
+    @Override\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.IEditorInput#getToolTipText()\r
+     */\r
+    @Override\r
+    public String getToolTipText() {\r
+        return tooltip;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.IEditorInput#getPersistable()\r
+     */\r
+    @Override\r
+    public IPersistableElement getPersistable() {\r
+        // Don't allow persistability when it's not possible.\r
+        if (!isPersistable())\r
+            return null;\r
+        return this;\r
+    }\r
+\r
+    protected boolean isPersistable() {\r
+        if (session == null)\r
+            return false;\r
+        LifecycleSupport lc = session.peekService(LifecycleSupport.class);\r
+        if (lc == null)\r
+            return false;\r
+        if (lc.isClosed())\r
+            return false;\r
+        return true;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.ui.IPersistableElement#getFactoryId()\r
+     */\r
+    @Override\r
+    public String getFactoryId() {\r
+        return ResourceEditorInputFactory2.getFactoryId();\r
+    }\r
+\r
+    /**\r
+     * Saves the state of the given resource editor input into the given memento.\r
+     *\r
+     * @param memento the storage area for element state\r
+     * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)\r
+     */\r
+    @Override\r
+    public void saveState(IMemento memento) {\r
+//        List<String> ids = randomAccessResourceId;\r
+        if (randomAccessResourceId == null) {\r
+            // Must create a new random access ID.\r
+            ensureRandomAccessId();\r
+        }\r
+        IMemento child = memento.createChild(ResourceEditorInputFactory2.TAG_RESOURCE_ID);\r
+        child.putTextData(randomAccessResourceId);\r
+        memento.putString(ResourceEditorInputFactory2.TAG_EDITOR_ID, editorID);\r
+//        memento.putString(ResourceEditorInputFactory2.TAG_MODEL_URI, modelURI);\r
+        memento.putString(ResourceEditorInputFactory2.TAG_MODEL_ID, modelId);\r
+        memento.putString(ResourceEditorInputFactory2.TAG_RVI, rvi);\r
+        memento.putString(ResourceEditorInputFactory2.TAG_EXTERNAL_MEMENTO_ID, persistentStore.toString());\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)\r
+     */\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        //System.out.println("[ResourceEditorInput] getAdapter: " + adapter.getName());\r
+        return null;\r
+    }\r
+\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result + editorID.hashCode();\r
+        result = prime * result + ObjectUtils.hashCode(modelId);\r
+        result = prime * result + ObjectUtils.hashCode(rvi);\r
+        result = prime * result + ObjectUtils.hashCode(randomAccessResourceId);\r
+        return result;\r
+    }\r
+\r
+    private void updateCaches(RequestProcessor processor, boolean sync) throws DatabaseException {\r
+        ReadRequest req = new ReadRequest() {\r
+            @Override\r
+            public void run(ReadGraph g) throws DatabaseException {\r
+                update(g);\r
+            }\r
+        };\r
+        if (sync) {\r
+            processor.syncRequest(req);\r
+        } else {\r
+            processor.asyncRequest(req);\r
+        }\r
+    }\r
+\r
+    static class Nonexistant extends DatabaseException {\r
+        private static final long serialVersionUID = -7964385375237203651L;\r
+\r
+        @Override\r
+        public synchronized Throwable fillInStackTrace() {\r
+            return this;\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.simantics.ui.workbench.IResourceEditorInput#update(org.simantics.db.Graph)\r
+     */\r
+    @Override\r
+    public void update(ReadGraph g) throws DatabaseException {\r
+        Resource r = getResource();\r
+        if (r == null)\r
+            return;\r
+\r
+        if (DEBUG_UPDATE)\r
+            System.out.println("update(" + this + ")");\r
+\r
+        try {\r
+            assertExists(g);\r
+\r
+            name = g.syncRequest(new TitleRequest(editorID, this));\r
+            if (name == null)\r
+                name = NO_NAME;\r
+\r
+            tooltip = g.syncRequest(new ToolTipRequest(editorID, this));\r
+            if (tooltip == null)\r
+                tooltip = NO_NAME;\r
+\r
+            try {\r
+                ImageDescriptorProvider idp = g.adapt(r, ImageDescriptorProvider.class);\r
+                imageDesc = idp.get();\r
+            } catch (AdaptionException e) {\r
+                imageDesc = ImageDescriptor.getMissingImageDescriptor();\r
+            } catch (ProvisionException e) {\r
+                imageDesc = ImageDescriptor.getMissingImageDescriptor();\r
+                ErrorLogger.defaultLogError(e);\r
+            }\r
+\r
+            if (DEBUG_UPDATE)\r
+                System.out.println("update(" + this + ") finished");\r
+        } catch (DatabaseException e) {\r
+            if (DEBUG_UPDATE)\r
+                e.printStackTrace();\r
+            setNonExistant();\r
+        }\r
+    }\r
+\r
+    private void assertExists(ReadGraph g) throws DatabaseException {\r
+        Resource r = getResource();\r
+        if (r == null)\r
+            throw new Nonexistant();\r
+\r
+        // 1. Check resource existence\r
+        boolean exists = g.hasStatement(r);\r
+        if (!exists)\r
+            throw new Nonexistant();\r
+\r
+        // 2. Validate modelURI\r
+        if (getModel(g) != null && g.getPossibleURI(getModel(g)) != null) {\r
+            Layer0X L0X = Layer0X.getInstance(g);\r
+            \r
+            // 3. Validate RVI\r
+            Resource model = getModel(g);\r
+            Resource baseRealization = g.getPossibleObject(model, L0X.HasBaseRealization);\r
+            Variable modelVariable = Variables.getVariable(g, g.getURI(baseRealization));\r
+            modelVariable.browse(g, getRVI());\r
+        }\r
+\r
+        // Touch the diagram title calculation within this existence\r
+        // checking request.\r
+        g.syncRequest(new TitleRequest(editorID, this));\r
+    }\r
+\r
+    private void setNonExistant() {\r
+        if (DEBUG_UPDATE)\r
+            System.out.println("setNonExistant(" + this + " @ " + System.identityHashCode(this) + ")");\r
+\r
+        exists = false;\r
+        tooltip = name = NO_NAME;\r
+        imageDesc = ImageDescriptor.getMissingImageDescriptor();\r
+    }\r
+\r
+    public IMemento getPersistentStore() {\r
+        return persistentStore;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return getClass().getSimpleName() + " [name=" + getName() + ", resource=" + resource + "]";\r
+    }\r
+    \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynEditorNamingService.java
new file mode 100644 (file)
index 0000000..98f825b
--- /dev/null
@@ -0,0 +1,74 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import org.eclipse.ui.IEditorInput;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.features.EditorNamingService2;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.workbench.IResourceEditorInput2;\r
+\r
+/**\r
+ * SysdynEditorNamingService provides names for diagram viewers. \r
+ * If the viewer shows an instantiated module, the service provides a name of type: "instanceName : instanceOf".\r
+ * Otherwise works as standard EditorNamingService2.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynEditorNamingService extends EditorNamingService2 {\r
+\r
+       @Override\r
+       public String getName(ReadGraph g, String editorId, IEditorInput in) throws DatabaseException {\r
+               if(in instanceof IResourceEditorInput2) {\r
+                       IResourceEditorInput2 input = (IResourceEditorInput2) in;\r
+\r
+                       if(input.getRVI() != null && !input.getRVI().isEmpty()) {\r
+                               Resource model = input.getModel(g);\r
+                               if(model != null) {\r
+                                       Resource configuration = g.getPossibleObject(model, SimulationResource.getInstance(g).HasConfiguration);\r
+                                       String configurationName = NameUtils.getSafeName(g, configuration);\r
+                                       String uri = g.getURI(input.getModel(g)) + "/" + configurationName + input.getRVI();\r
+                                       Variable v = Variables.getPossibleVariable(g, uri);\r
+                                       if(v != null) {\r
+                                               String name = input.getRVI();\r
+                                               if(name.contains("/"))\r
+                                                       name = name.substring(name.lastIndexOf("/") + 1);\r
+\r
+                                               Resource instanceOf = g.getPossibleObject(v.getRepresents(g), Layer0.getInstance(g).InstanceOf);\r
+                                               return name + " : " + NameUtils.getSafeName(g, instanceOf);\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               ModelingResources mr = ModelingResources.getInstance(g);\r
+                               SysdynResource sr = SysdynResource.getInstance(g);\r
+                               Resource composite = g.getPossibleObject(input.getResource(), mr.DiagramToComposite);\r
+                               if(composite != null) {\r
+                                       if(g.isInstanceOf(composite, sr.Configuration))\r
+                                               composite = g.getPossibleObject(composite, Layer0.getInstance(g).PartOf);\r
+                                       if(composite != null) \r
+                                               return NameUtils.getSafeName(g, composite);\r
+                               }\r
+                       }\r
+               }\r
+               return super.getName(g, editorId, in);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/CreateVariablesShortcutParticipant.java
new file mode 100644 (file)
index 0000000..96d6f93
--- /dev/null
@@ -0,0 +1,322 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.Queries;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.g2d.canvas.SGDesignation;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\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.participant.AbstractDiagramParticipant;\r
+import org.simantics.g2d.diagram.participant.ElementPainter;\r
+import org.simantics.g2d.diagram.participant.Selection;\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.participant.MouseUtil;\r
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.KeyEvent;\r
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;\r
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryFactory;\r
+import org.simantics.sysdyn.ui.elements.CloudFactory;\r
+import org.simantics.sysdyn.ui.elements.InputFactory;\r
+import org.simantics.sysdyn.ui.elements.LoopFactory;\r
+import org.simantics.sysdyn.ui.elements.ShadowFactory;\r
+import org.simantics.sysdyn.ui.elements.StockFactory;\r
+import org.simantics.sysdyn.ui.elements.ValveFactory;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class CreateVariablesShortcutParticipant extends AbstractDiagramParticipant {\r
+\r
+       private GraphToDiagramSynchronizer synchronizer;\r
+\r
+       private VariableInformation variableInformation;\r
+\r
+       @Dependency\r
+       MouseUtil mouseUtil;\r
+\r
+       @Dependency\r
+       Selection selection;\r
+\r
+       @Dependency\r
+       ElementPainter diagramPainter;\r
+\r
+       ShapeNode node;\r
+       G2DParentNode parent;\r
+\r
+       private boolean createVar;\r
+       private IDiagram createVarDiagram;\r
+\r
+       @SGInit(designation = SGDesignation.CANVAS)\r
+       public void init(G2DParentNode parent) {\r
+               this.parent = parent;\r
+       }\r
+\r
+       public void removeSG() {\r
+               node.remove();\r
+               node = null;\r
+               setDirty();\r
+       }\r
+\r
+       void updateSG() {\r
+\r
+               if (node == null) {\r
+                       node = variableInformation.node;\r
+               }\r
+\r
+               MouseInfo mi = mouseUtil.getMouseInfo(0);\r
+               if (mi == null)\r
+                       return;\r
+\r
+               Point2D newPos = mi.canvasPosition;\r
+               double x = newPos.getX();\r
+               double y = newPos.getY();\r
+\r
+               AffineTransform origAt = node.getTransform();\r
+               double oldX = origAt.getTranslateX();\r
+               double oldY = origAt.getTranslateY();\r
+               AffineTransform move = new AffineTransform();\r
+               move.setToTranslation(x - oldX, y - oldY);\r
+               AffineTransform at2 = new AffineTransform(origAt);\r
+               at2.preConcatenate(move);\r
+               node.setTransform(at2);\r
+               setDirty();\r
+       }\r
+\r
+       public CreateVariablesShortcutParticipant(GraphToDiagramSynchronizer synchronizer) {\r
+               this.synchronizer = synchronizer;\r
+       }\r
+\r
+       @EventHandler(priority = -10)\r
+       public boolean handleKeyboardEvent(KeyEvent ke) {\r
+\r
+               KeyPressedEvent kpe;\r
+               if (ke instanceof KeyPressedEvent) {\r
+                       \r
+                       kpe = (KeyPressedEvent) ke;\r
+                       \r
+                       if (!kpe.isShiftDown() || isEditing()) \r
+                               return false;\r
+                       \r
+                       if (kpe.keyCode == java.awt.event.KeyEvent.VK_A) {\r
+                               variableInformation = new VariableInformation(\r
+                               java.awt.event.KeyEvent.VK_A,\r
+                               SysdynResource.URIs.AuxiliarySymbol,\r
+                               (ShapeNode)AuxiliaryFactory.AUX_STATIC_IMAGE.init(parent)\r
+                               );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_S) {\r
+                               variableInformation = new VariableInformation(\r
+                                               java.awt.event.KeyEvent.VK_S,\r
+                                               SysdynResource.URIs.StockSymbol,\r
+                                               (ShapeNode)StockFactory.STOCK_IMAGE.init(parent)\r
+                                               );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_C) {\r
+                               variableInformation = new VariableInformation(\r
+                                               java.awt.event.KeyEvent.VK_C,\r
+                                               SysdynResource.URIs.CloudSymbol,\r
+                                               (ShapeNode)CloudFactory.CLOUD_IMAGE.init(parent)\r
+                                               );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_V) {\r
+                               variableInformation = new VariableInformation(\r
+                                               java.awt.event.KeyEvent.VK_V,\r
+                                               SysdynResource.URIs.ValveSymbol,\r
+                                               (ShapeNode)ValveFactory.VALVE_STATIC_IMAGE.init(parent)\r
+                                               );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_I) {\r
+                               variableInformation = new VariableInformation(\r
+                                               java.awt.event.KeyEvent.VK_I,\r
+                                               SysdynResource.URIs.InputSymbol,\r
+                                               (ShapeNode)InputFactory.INPUT_IMAGE.init(parent)\r
+                                               );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_G) {\r
+                variableInformation = new VariableInformation(\r
+                        java.awt.event.KeyEvent.VK_G,\r
+                        SysdynResource.URIs.ShadowSymbol,\r
+                        (ShapeNode)ShadowFactory.GHOST_IMAGE.init(parent)\r
+                        );\r
+                       } else if (kpe.keyCode == java.awt.event.KeyEvent.VK_L) {\r
+                variableInformation = new VariableInformation(\r
+                        java.awt.event.KeyEvent.VK_L,\r
+                        SysdynResource.URIs.LoopSymbol,\r
+                        (ShapeNode)LoopFactory.LOOP_STATIC_IMAGE.init(parent)\r
+                        );\r
+            }\r
+\r
+                       if (variableInformation != null) {\r
+                               updateSG();\r
+                               return true;\r
+                       }\r
+               }\r
+\r
+               KeyReleasedEvent kre;\r
+               if (ke instanceof KeyReleasedEvent) {\r
+                       kre = (KeyReleasedEvent) ke;\r
+                       \r
+                       if (variableInformation != null\r
+                                       && (kre.keyCode == variableInformation.shortcutKey || kre.keyCode == java.awt.event.KeyEvent.VK_SHIFT)) {\r
+                               if (node != null) {\r
+                                       // If there is a variable to be created, do it when a key is released.\r
+                                       if (createVar) {\r
+                                               createVar = false;\r
+                                               createVariableOnDiagram(createVarDiagram);\r
+                                       }\r
+                                       variableInformation = null;\r
+                                       removeSG();\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return false;\r
+\r
+       }\r
+\r
+       @EventHandler(priority = -10)\r
+       public boolean handleMouse(MouseMovedEvent e) {\r
+\r
+               if (variableInformation != null ) {\r
+                       updateSG();\r
+               } else {\r
+                       if (node != null) {\r
+                               removeSG();\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+\r
+       @EventHandler(priority = 100)\r
+       public boolean handleMouseEvent(MouseEvent me) {\r
+\r
+\r
+               MouseEvent.MouseClickEvent mce;\r
+               if (me instanceof MouseEvent.MouseClickEvent) {\r
+                       mce = (MouseEvent.MouseClickEvent) me;\r
+               } else {\r
+                       return false;\r
+               }\r
+\r
+               if (!\r
+                               (\r
+                                               mce.button == MouseEvent.LEFT_BUTTON && \r
+                                               variableInformation != null && \r
+                                               mce.stateMask ==  MouseEvent.SHIFT_MASK\r
+                               )) \r
+               {\r
+                       return false;\r
+               }\r
+               \r
+               final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);\r
+               if (d == null)\r
+                       return false;\r
+               \r
+               // Need to create a new variable, save the diagram to do this later.\r
+               createVar = true;\r
+               createVarDiagram = d;\r
+\r
+               return true;\r
+       }\r
+\r
+\r
+       private void createVariableOnDiagram(IDiagram d) {\r
+               DiagramUtils.mutateDiagram(d, new Callback<DiagramMutator>() {\r
+                       @Override\r
+                       public void run(DiagramMutator m) {\r
+\r
+                               Resource r;\r
+                               try {\r
+                                       r = SimanticsUI\r
+                                       .getSession()\r
+                                       .syncRequest(\r
+                                                       Queries\r
+                                                       .resource(variableInformation.symbolURI));\r
+                                       ElementClass ec = SimanticsUI.getSession().syncRequest(\r
+                                                       DiagramRequests.getElementClass(r, diagram));\r
+\r
+                                       IElement element = m.newElement(ec);\r
+\r
+                                       // MouseUtil mutil = new MouseUtil();\r
+                                       MouseInfo minfo = mouseUtil.getMouseInfo(0);\r
+\r
+                                       //at least when using breakpoints this is possible\r
+                                       if(minfo == null) \r
+                                               return;\r
+\r
+                                       Point2D p = minfo.canvasPosition;\r
+                                       //FIXME - Arto element doesn't know its size at first. Hopefully temp fix.\r
+                                       p.setLocation(p.getX()-5.46, p.getY()+1);\r
+\r
+                                       ElementUtils.setPos(element, p);\r
+\r
+                               } catch (DatabaseException e) {\r
+                                       ExceptionUtils.logAndShowError(e);\r
+                               }\r
+\r
+                       }\r
+               });\r
+\r
+               synchronizer.getCanvasContext().getContentContext().setDirty();\r
+\r
+       }\r
+\r
+       private class VariableInformation {\r
+               public String symbolURI;\r
+               public ShapeNode node;\r
+               public int shortcutKey;\r
+\r
+               public VariableInformation(int shortcutKey, String symbolURI, ShapeNode node) {\r
+                       this.symbolURI = symbolURI;\r
+                       this.node = node;\r
+                       this.shortcutKey = shortcutKey;\r
+               }\r
+       }\r
+       \r
+       private boolean isEditing() {\r
+        int selectionId = 0;\r
+        Set<IElement> ss = selection.getSelection(selectionId);\r
+        if (ss.isEmpty()) {\r
+            return false;\r
+        }\r
+        for (IElement e : ss) {\r
+               for(Object o : e.getHints().values()) {\r
+                       if (o instanceof TextNode) {\r
+                               TextNode tn = (TextNode) o;\r
+                               if(tn.isEditMode())\r
+                                       return true;\r
+                       }\r
+               }\r
+        }\r
+               return false;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SelectionUpdaterParticipant.java
new file mode 100644 (file)
index 0000000..023c78c
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.util.Collection;\r
+\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.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.canvas.impl.HintReflection.HintListener;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\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.IHintObservable;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+\r
+public class SelectionUpdaterParticipant extends AbstractDiagramParticipant {\r
+\r
+    @Dependency Selection selection;\r
+\r
+    @HintListener(Class = Selection.class, Field = "SELECTION0")\r
+    public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+        IDiagram diagram = sender.getHint(DiagramHints.KEY_DIAGRAM);\r
+        Collection<IElement> elements = AdaptionUtils.adaptToCollection(newValue, IElement.class);\r
+        if(diagram != null) {\r
+            Session session = SimanticsUI.getSession();\r
+            session.asyncRequest(new ModifyDiagramSelection(session.getService(VirtualGraph.class), diagram, elements));\r
+        }\r
+    }\r
+    \r
+    @HintListener(Class = Selection.class, Field = "SELECTION0")\r
+    public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
+        IDiagram diagram = sender.getHint(DiagramHints.KEY_DIAGRAM);\r
+        if(diagram != null) {\r
+            Session session = SimanticsUI.getSession();\r
+            session.asyncRequest(new ModifyDiagramSelection(session.getService(VirtualGraph.class), diagram, null));\r
+        }\r
+    }\r
+    \r
+    \r
+    private class ModifyDiagramSelection extends WriteRequest {\r
+        IDiagram diagram;\r
+        Collection<IElement> elements;\r
+        \r
+        public ModifyDiagramSelection(VirtualGraph provider, IDiagram diagram, Collection<IElement> elements) {\r
+            super(provider);\r
+            this.elements = elements;\r
+            this.diagram = diagram;\r
+        }\r
+        \r
+        @Override\r
+        public void perform(WriteGraph graph) throws DatabaseException {\r
+            Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
+            \r
+            if(diagramRuntime == null) {\r
+                return;\r
+            }\r
+            \r
+            SysdynResource SR = SysdynResource.getInstance(graph);\r
+            DiagramResource DR = DiagramResource.getInstance(graph);\r
+\r
+            graph.deny(diagramRuntime, SR.ConfigurationDiagram_selection);\r
+\r
+            if(elements != null) {\r
+                for(IElement e : elements) {\r
+                    Resource object = e.getHint(ElementHints.KEY_OBJECT);\r
+                    if(object != null && graph.isInstanceOf(object, DR.Element)) {\r
+                        graph.claim(diagramRuntime, SR.ConfigurationDiagram_selection, object);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynComponentCopyAdvisor.java
new file mode 100644 (file)
index 0000000..8e61586
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.util.Map;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.diagram.synchronization.ISynchronizationContext;\r
+import org.simantics.diagram.synchronization.StatementEvaluation;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.CopyAdvisorUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ComponentUtils;\r
+import org.simantics.modeling.mapping.ComponentCopyAdvisor;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.BinaryFunction;\r
+\r
+public class SysdynComponentCopyAdvisor extends ComponentCopyAdvisor {\r
+\r
+    private Layer0 L0;\r
+    private StructuralResource2 STR;\r
+    private SysdynResource SYSDYN;\r
+\r
+    @Override\r
+    public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer, Resource targetContainer, Map<Object, Object> map) throws DatabaseException {\r
+//        Object copy = super.copy(context, graph, source, sourceContainer, targetContainer, map);\r
+        \r
+      BinaryFunction<StatementEvaluation, ReadGraph, Statement> tester = new BinaryFunction<StatementEvaluation, ReadGraph, Statement>() {\r
+          @Override\r
+          public StatementEvaluation call(ReadGraph graph, Statement statement) {\r
+              try {\r
+                  if(statement.getPredicate().equals(L0.List_Next) ||\r
+                          statement.getPredicate().equals(L0.List_Previous)) {\r
+                      return StatementEvaluation.INCLUDE_AND_FOLLOW;\r
+                  } else if(statement.getPredicate().equals(L0.List_Element)){\r
+                      if(graph.isInstanceOf(statement.getObject(), SYSDYN.Enumeration))\r
+                          return StatementEvaluation.INCLUDE;\r
+                      else\r
+                          return StatementEvaluation.INCLUDE_AND_FOLLOW;\r
+                  } else if(statement.getPredicate().equals(SYSDYN.Shadow_original))\r
+                      return StatementEvaluation.INCLUDE;\r
+              } catch (ServiceException e) {\r
+                  e.printStackTrace();\r
+              }\r
+              return StatementEvaluation.USE_DEFAULT;\r
+          }\r
+          \r
+      };\r
+        \r
+      SYSDYN = SysdynResource.getInstance(graph);\r
+      L0 = Layer0.getInstance(graph);\r
+        STR = StructuralResource2.getInstance(graph);\r
+        Resource copy = null;\r
+        if (graph.isInstanceOf(source, STR.Connection)) {\r
+            // Configuration connections are not named, can't use TG copy for\r
+            // them at the moment.\r
+            copy = CopyAdvisorUtil.copy2(graph, source, null, map);\r
+        } else {\r
+//            Resource model = graph.syncRequest(new PossibleModel(targetContainer));\r
+//            copy = CopyAdvisorUtil.copy4(graph, source, model);\r
+            copy = CopyAdvisorUtil.copy2(graph, source, tester, map);\r
+        }\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        if (graph.hasStatement(sourceContainer, L0.ConsistsOf, source))\r
+            graph.claim(targetContainer, L0.ConsistsOf, copy);\r
+\r
+        if (context.get(SynchronizationHints.NO_RENAME) == null)\r
+//            renameComponent(context, graph, source, copy, sourceContainer, targetContainer);\r
+            rename(context, graph, source, (Resource)copy, sourceContainer, targetContainer);\r
+        \r
+        return copy;\r
+    }\r
+    \r
+\r
+    public String rename(ISynchronizationContext context, WriteGraph graph, Resource source,\r
+            Resource copy, Resource sourceContainer, Resource targetContainer) throws DatabaseException {\r
+       Layer0 l0 = Layer0.getInstance(graph);\r
+       String copyName = NameUtils.getSafeName(graph, copy);\r
+        Resource configurationRoot = ComponentUtils.getCompositeConfigurationRoot(graph, targetContainer);\r
+       String name =  NameUtils.findFreshName(graph, copyName, configurationRoot, l0.ConsistsOf, "%s%d");\r
+       graph.claimLiteral(copy, l0.HasName, name, Bindings.STRING);\r
+       return name;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectTool.java
new file mode 100644 (file)
index 0000000..72de5cb
--- /dev/null
@@ -0,0 +1,472 @@
+package org.simantics.sysdyn.ui.editor.participant;\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.Point2D;\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.Deque;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\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.diagram.participant.ConnectTool2;\r
+import org.simantics.diagram.participant.ConnectionBuilder;\r
+import org.simantics.diagram.participant.ControlPoint;\r
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;\r
+import org.simantics.g2d.connection.IConnectionAdvisor;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\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.ElementClasses;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.element.impl.Element;\r
+import org.simantics.g2d.elementclass.BranchPointClass;\r
+import org.simantics.g2d.elementclass.FlagClass;\r
+import org.simantics.g2d.routing.Constants;\r
+import org.simantics.g2d.routing.IConnection;\r
+import org.simantics.g2d.routing.IRouter2;\r
+import org.simantics.g2d.routing.TrivialRouter2;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.scenegraph.g2d.snap.ISnapAdvisor;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
+import org.simantics.sysdyn.ui.elements.CloudFactory;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph;\r
+import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SysdynConnectTool extends ConnectTool2 {\r
+\r
+       public SysdynConnectTool(TerminalInfo startTerminal, int mouseId,\r
+                       Point2D startCanvasPos) {\r
+               super(startTerminal, mouseId, startCanvasPos);\r
+       }\r
+\r
+       @Override\r
+       @SGInit\r
+       public void initSG(G2DParentNode parent) {\r
+               ghostNode = parent.addNode(G2DParentNode.class);\r
+               ghostNode.setZIndex(PAINT_PRIORITY);\r
+\r
+               ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);\r
+               pathNode.setColor(Color.BLACK);\r
+               pathNode.setStroke(new BasicStroke(1f));\r
+               pathNode.setScaleStroke(true);\r
+               pathNode.setZIndex(0);\r
+\r
+               G2DParentNode points = ghostNode.getOrCreateNode("points", G2DParentNode.class);\r
+               points.setZIndex(1);\r
+\r
+               updateSG();\r
+       }\r
+\r
+       @Override\r
+       protected TerminalInfo createFlag(EdgeEnd connectionEnd) {\r
+               ElementClass flagClass = elementClassProvider.get(ElementClasses.FLAG);\r
+               IElement e = Element.spawnNew(flagClass);\r
+\r
+               e.setHint(FlagClass.KEY_FLAG_TYPE, endToFlagType(connectionEnd));\r
+               e.setHint(FlagClass.KEY_FLAG_MODE, FlagClass.Mode.Internal);\r
+\r
+               TerminalInfo ti = new TerminalInfo();\r
+               ti.e = e;\r
+\r
+               // start: this part changed to support overlapping terminals\r
+               ArrayList<Terminal> terminals = new ArrayList<Terminal>();\r
+               ElementUtils.getTerminals(e, terminals, false);\r
+               ti.t = terminals.get(0);\r
+               // end\r
+\r
+               ti.posElem = TerminalUtil.getTerminalPosOnElement(e, ti.t);\r
+               ti.posDia = TerminalUtil.getTerminalPosOnDiagram(e, ti.t);\r
+\r
+               return ti;\r
+       }\r
+\r
+       static class Segment {\r
+               public final ControlPoint begin;\r
+               public final ControlPoint end;\r
+               public Path2D             path;\r
+\r
+               public Segment(ControlPoint begin, ControlPoint end) {\r
+                       this.begin = begin;\r
+                       this.end = end;\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       return "Segment[begin=" + begin + ", end=" + end + ", path=" + path + "]";\r
+               }\r
+       }\r
+\r
+       private List<Segment> toSegments(Deque<ControlPoint> points) {\r
+               if (points.isEmpty())\r
+                       return Collections.emptyList();\r
+\r
+               List<Segment> segments = new ArrayList<Segment>();\r
+\r
+               Iterator<ControlPoint> it = points.iterator();\r
+               ControlPoint prev = it.next();\r
+               while (it.hasNext()) {\r
+                       ControlPoint next = it.next();\r
+                       segments.add(new Segment(prev, next));\r
+                       prev = next;\r
+               }\r
+\r
+               return segments;\r
+       }\r
+\r
+       public interface SysdynConnection extends IConnection { }\r
+\r
+       @Override\r
+       protected void updateSG() {\r
+               if (controlPoints.isEmpty())\r
+                       return;\r
+\r
+               // Route connection segments separately\r
+               IRouter2 router = ElementUtils.getHintOrDefault(diagram, DiagramHints.ROUTE_ALGORITHM, TrivialRouter2.INSTANCE);\r
+               final List<Segment> segments = toSegments(controlPoints);\r
+               //System.out.println("controlpoints: " + controlPoints);\r
+               //System.out.println("segments: " + segments);\r
+               router.route(new SysdynConnection() {\r
+                       @Override\r
+                       public Collection<? extends Object> getSegments() {\r
+                               return segments;\r
+                       }\r
+\r
+                       @Override\r
+                       public Connector getBegin(Object seg) {\r
+                               return getConnector(((Segment) seg).begin);\r
+                       }\r
+\r
+                       @Override\r
+                       public Connector getEnd(Object seg) {\r
+                               return getConnector(((Segment) seg).end);\r
+                       }\r
+\r
+                       private Connector getConnector(ControlPoint cp) {\r
+                               Connector c = new Connector();\r
+                               c.x = cp.getPosition().getX();\r
+                               c.y = cp.getPosition().getY();\r
+\r
+                               c.allowedDirections = Constants.EAST_FLAG | Constants.WEST_FLAG\r
+                                               | Constants.NORTH_FLAG | Constants.SOUTH_FLAG;\r
+\r
+                               TerminalInfo ti = cp.getAttachedTerminal();\r
+                               if (ti != null && (ti != startFlag && ti != endFlag)) {\r
+                                       if(ti.e.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                                               Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D();\r
+                                               c.parentObstacle = new Rectangle2D.Double(\r
+                                                               bounds.getCenterX() - FlowRouter.OFFSET,\r
+                                                               bounds.getCenterY() - FlowRouter.OFFSET, \r
+                                                               FlowRouter.OFFSET * 2,\r
+                                                               FlowRouter.OFFSET * 2);\r
+                                       } else {\r
+                                               c.parentObstacle =  ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D();\r
+                                       }\r
+                               } else if (ti != null && ti == startFlag) {\r
+                                       c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y),\r
+                                                       ElementUtils.getElementBoundsOnDiagram(ti.e).getBounds2D());\r
+                               } else if (isEndingInFlag() && ti.e != null) {\r
+                                       c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y),\r
+                                                       CloudFactory.CLOUD_IMAGE.getBounds());\r
+                               } else {\r
+                                       c.parentObstacle = org.simantics.scenegraph.utils.GeometryUtils.transformRectangle(AffineTransform.getTranslateInstance(c.x, c.y),\r
+                                                       BranchPointClass.DEFAULT_IMAGE2.getBounds());\r
+                               }\r
+\r
+                               return c;\r
+                       }\r
+\r
+                       @Override\r
+                       public void setPath(Object seg, Path2D path) {\r
+                               ((Segment) seg).path = (Path2D) path.clone();\r
+                       }\r
+               });\r
+\r
+               // Combine the routed paths\r
+               Path2D path = new Path2D.Double();\r
+               for (Segment seg : segments) {\r
+                       //System.out.println("SEG: " + seg);\r
+                       if (seg.path != null)\r
+                               path.append(seg.path.getPathIterator(null), true);\r
+               }\r
+\r
+               // Create scene graph to visualize the connection.\r
+               ShapeNode pathNode = ghostNode.getOrCreateNode("path", ShapeNode.class);\r
+               pathNode.setShape(path);\r
+\r
+               /*\r
+                * Removed Points\r
+                */\r
+\r
+               setDirty();\r
+       }\r
+\r
+       @Override\r
+       protected Object canConnect(final IConnectionAdvisor advisor, final IElement endElement, final Terminal endTerminal) {\r
+               final IElement se = startTerminal != null ? startTerminal.e : startFlag.e;\r
+               final Terminal st = startTerminal != null ? startTerminal.t : null;\r
+\r
+               if(se.equals(endElement)) return null;\r
+               if(Boolean.FALSE.equals(diagram.getHint(DiagramHints.KEY_USE_CONNECTION_FLAGS)) && endElement == null) {\r
+                       return null;\r
+               }\r
+\r
+               if(endElement == null && endTerminal == null)\r
+                       return advisor.canBeConnected(null, se, st, endElement, endTerminal);\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
+                                       StaticObjectAdapter soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class);\r
+                                       Resource end = soa.adapt(Resource.class);\r
+                                       ElementClass dependency = elementClassProvider.get(ConnectionClasses.DEPENDENCY);\r
+                                       ElementClass flow = elementClassProvider.get(ConnectionClasses.FLOW);\r
+                                       ElementClass currentConnection = elementClassProvider.get(ElementClasses.CONNECTION);\r
+                                       if(currentConnection.equals(dependency)) {\r
+                                               if(end.equals(sr.CloudSymbol)) return null;\r
+                                               soa = se.getElementClass().getSingleItem(StaticObjectAdapter.class);\r
+                                               Resource start = soa.adapt(Resource.class);\r
+                                               if(g.isInheritedFrom(start, sr.ModuleSymbol) && !end.equals(sr.InputSymbol)) return null;\r
+                                               if(end.equals(sr.ShadowSymbol)) return null;\r
+                                       } else if (currentConnection.equals(flow)) {\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
+                                       if (advisor == null)\r
+                                               return Boolean.TRUE;     \r
+                                       return advisor.canBeConnected(g, se, st, endElement, endTerminal);\r
+                               }\r
+\r
+                       });\r
+               } catch(DatabaseException e) {\r
+                       e.printStackTrace();\r
+                       return null;\r
+               }\r
+\r
+       }\r
+\r
+       @Override\r
+       protected boolean processMouseMove(MouseMovedEvent me) {\r
+               mouseHasMoved = true;\r
+\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
+               // Record last snapped canvas position of mouse.\r
+               this.lastMouseCanvasPos.setLocation(mouseCanvasPos);\r
+\r
+               if (isEndingInFlag()) {\r
+                       endFlagNode.setTransform(AffineTransform.getTranslateInstance(mouseCanvasPos.getX(), mouseCanvasPos.getY()));\r
+               }\r
+\r
+               List<TerminalInfo> tiList = ((SysdynPointerInteractor)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
+                               ti = info;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if (ti != null && !isStartTerminal(ti.e, ti.t)) {\r
+                       Pair<ConnectionJudgement, TerminalInfo> canConnect = canConnect(ti.e, ti.t);\r
+                       if (canConnect != null) {\r
+                               connectionJudgment = canConnect.first;\r
+\r
+                               if (!isEndingInFlag() || !TerminalUtil.isSameTerminal(ti, endTerminal)) {\r
+                                       controlPoints.getLast()\r
+                                       .setPosition(ti.posDia)\r
+                                       .setAttachedToTerminal(ti);\r
+\r
+                                       endTerminal = ti;\r
+                               }\r
+\r
+                               // Make sure that we are ending with a flag if ALT is pressed\r
+                               // and no end terminal is defined. If we are in flow creation\r
+                               // mode, we want to show the terminal cloud (or flag) even when\r
+                               // alt is not pressed.\r
+                               if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty())\r
+                                       endWithoutTerminal(lastMouseCanvasPos, true);\r
+                               else\r
+                                       endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));\r
+                               updateSG();\r
+                               return false;\r
+                       }\r
+               }\r
+\r
+               connectionJudgment = null;\r
+               if (isEndTerminalDefined()) {\r
+                       // CASE: Mouse was previously on top of a valid terminal to end\r
+                       // the connection. Now the mouse has been moved where there is\r
+                       // no longer a terminal to connect to.\r
+                       //\r
+                       // => Disconnect the last edge segment from the previous\r
+                       // terminal, mark endElement/endTerminal non-existent\r
+                       // and connect the disconnected edge to a new branch point.\r
+\r
+                       controlPoints.getLast()\r
+                       .setPosition(mouseCanvasPos)\r
+                       .setDirection(calculateCurrentBranchPointDirection())\r
+                       .setAttachedToTerminal(null);\r
+\r
+                       endTerminal = null;\r
+               } else {\r
+                       // CASE: Mouse was not previously on top of a valid ending\r
+                       // element terminal.\r
+                       //\r
+                       // => Move and re-orient last branch point.\r
+\r
+                       controlPoints.getLast()\r
+                       .setPosition(mouseCanvasPos)\r
+                       .setDirection(calculateCurrentBranchPointDirection());\r
+               }\r
+\r
+               // Make sure that we are ending with a flag if ALT is pressed and no end\r
+               // terminal is defined. If we are in flow creation mode, we want to show \r
+               // the terminal cloud (or flag) even when alt is not pressed.\r
+               if (inFlowMode() && flowInProgress() && !startTerminals.isEmpty())\r
+                       endWithoutTerminal(lastMouseCanvasPos, true);\r
+               else\r
+                       endWithoutTerminal(lastMouseCanvasPos, shouldEndWithFlag(me));\r
+               updateSG();\r
+               return false;\r
+       }\r
+\r
+       @Override\r
+       protected boolean processMouseButtonPress(MouseButtonPressedEvent e) {\r
+               MouseButtonEvent me = e;\r
+\r
+               // Do nothing before the mouse has moved at least a little.\r
+        // This prevents the user from ending the connection right where\r
+        // it started.\r
+               if (!mouseHasMoved)\r
+                       return true;\r
+\r
+               if (me.button == MouseEvent.LEFT_BUTTON || \r
+                               (me.button == MouseEvent.RIGHT_BUTTON && flowInProgress() && !inFlowMode())) {\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 an allowed end terminal. End connection & end mode.\r
+                       if (isEndTerminalDefined()) {\r
+                               createConnection();\r
+                               remove();\r
+                               return true;\r
+                       } else {\r
+                               // Finish connection in thin air only if the\r
+                               // connection was started from a valid terminal.\r
+                               \r
+                               // If we are in flow creation mode, we want to be able to\r
+                               // create the terminal cloud (or flag) without having to \r
+                               // press alt.\r
+                               \r
+                               if (!startTerminals.isEmpty() && ((me.stateMask & MouseEvent.ALT_MASK) != 0 || \r
+                                               (inFlowMode() && flowInProgress()))) {\r
+                                       Pair<ConnectionJudgement, TerminalInfo> pair = canConnect(null, null);\r
+                                       if (pair != null) {\r
+                                               connectionJudgment = (ConnectionJudgement) pair.first;\r
+                                               selectedStartTerminal = pair.second;\r
+                                               createConnection();\r
+                                               setDirty();\r
+                                               remove();\r
+                                       } else {\r
+                                               // Inform the user why connection couldn't be created.\r
+                                               ErrorLogger.defaultLogWarning("Can't resolve connection type for new connection.", null);\r
+                                       }\r
+                                       return true;\r
+                               } else if (routePointsAllowed()\r
+                                               && (me.stateMask & (MouseEvent.ALT_MASK | MouseEvent.SHIFT_MASK | MouseEvent.CTRL_MASK)) == 0) {\r
+                                       // Add new connection control point.\r
+                                       controlPoints.add(newControlPointWithCalculatedDirection(mouseCanvasPos));\r
+                                       resetForcedBranchPointDirection();\r
+                                       updateSG();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return true;\r
+       }\r
+       \r
+       private boolean inFlowMode() {\r
+               return SysdynElementHints.FLOW_TOOL.equals(getHint(SysdynElementHints.SYSDYN_KEY_TOOL));\r
+       }\r
+       \r
+       private boolean flowInProgress() {\r
+               return elementClassProvider.get(ElementClasses.CONNECTION).equals(elementClassProvider.get(ConnectionClasses.FLOW));\r
+       }\r
+\r
+       @Override\r
+       protected void createConnection() {\r
+\r
+               if(this.connectionJudgment == null) return;\r
+\r
+               final ConnectionJudgement judgment = this.connectionJudgment;\r
+               // ConnectionBuilder changed to SysdynconnectionBuilder to support overlapping terminals and valve creation\r
+               final ConnectionBuilder builder = new SysdynConnectionBuilder(this.diagram);\r
+               final Deque<ControlPoint> controlPoints = this.controlPoints;\r
+               final TerminalInfo startTerminal = this.startTerminal;\r
+               final TerminalInfo endTerminal = this.endTerminal;\r
+\r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               builder.create(graph, judgment, controlPoints, startTerminal, endTerminal);\r
+                       }\r
+               }, new Callback<DatabaseException>() {\r
+                       @Override\r
+                       public void run(DatabaseException parameter) {\r
+                               if (parameter != null)\r
+                                       ExceptionUtils.logAndShowError(parameter);\r
+                       }\r
+               });\r
+       }    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynConnectionBuilder.java
new file mode 100644 (file)
index 0000000..9f2ebca
--- /dev/null
@@ -0,0 +1,265 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Point2D;\r
+import java.util.ArrayList;\r
+import java.util.Deque;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.content.ConnectionUtil;\r
+import org.simantics.diagram.participant.ConnectionBuilder;\r
+import org.simantics.diagram.participant.ControlPoint;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.graph.AddElement;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\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.ElementClasses;\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.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.impl.Element;\r
+import org.simantics.g2d.elementclass.FlagClass;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementClasses;\r
+import org.simantics.sysdyn.ui.elements.ValveFactory;\r
+import org.simantics.sysdyn.ui.elements.connections.ConnectionClasses;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class SysdynConnectionBuilder extends ConnectionBuilder{\r
+\r
+       public SysdynConnectionBuilder(IDiagram diagram) {\r
+               super(diagram);\r
+       }\r
+\r
+    /**\r
+     * @param graph\r
+     * @param judgment\r
+     * @param controlPoints\r
+     * @param startTerminal\r
+     * @param endTerminal\r
+     * @throws DatabaseException\r
+     */\r
+    public void create(WriteGraph graph, ConnectionJudgement judgment, Deque<ControlPoint> controlPoints,\r
+            TerminalInfo startTerminal, TerminalInfo endTerminal) throws DatabaseException {\r
+\r
+        graph.markUndoPoint();\r
+        \r
+       // If needs a valve, we will create two separate connections\r
+        if(needsValve(startTerminal, endTerminal)) {\r
+               createValveAndConnections(graph, judgment, controlPoints, startTerminal, endTerminal);\r
+        } \r
+        // If no need for valve, just call createConnection with false on createValve parameter\r
+        else {\r
+               createConnection(graph, judgment, controlPoints, startTerminal, endTerminal, false);\r
+        }\r
+        \r
+        \r
+        String startElementName = startTerminal != null ? startTerminal.e.getHint(ElementHints.KEY_TEXT).toString() : "null";\r
+        String endElementName = endTerminal != null ? endTerminal.e.getHint(ElementHints.KEY_TEXT).toString() : "null";\r
+        \r
+        String startElementResource = startTerminal != null ? startTerminal.e.getHint(ElementHints.KEY_OBJECT).toString() : "null";\r
+        String endElementResource = endTerminal != null ? endTerminal.e.getHint(ElementHints.KEY_OBJECT).toString() : "null";\r
+        \r
+        Layer0Utils.addCommentMetadata(graph, "Created dependency starting from " + startElementName + " " + startElementResource + " and ending to " + endElementName + " " + endElementResource);\r
+    }\r
+    /**\r
+     * @param graph\r
+     * @param judgment\r
+     * @param controlPoints\r
+     * @param startTerminal\r
+     * @param endTerminal\r
+     * @throws DatabaseException\r
+     */\r
+    public TerminalInfo createConnection(WriteGraph graph, ConnectionJudgement judgment, Deque<ControlPoint> controlPoints,\r
+            TerminalInfo startTerminal, TerminalInfo endTerminal, boolean createValve) throws DatabaseException {\r
+        TerminalInfo newValve = null;\r
+\r
+       this.cu = new ConnectionUtil(graph);\r
+\r
+        // 1. Get diagram connection to construct.\r
+        Resource connection = getOrCreateConnection(graph, startTerminal, endTerminal);\r
+        \r
+        // 1.1 Give running name to connection and increment the counter attached to the diagram.\r
+        AddElement.claimFreshElementName(graph, diagramResource, connection);\r
+\r
+        // 2. Add branch points\r
+        List<Pair<ControlPoint, Resource>> bps = createBranchPoints(graph, connection, controlPoints);\r
+        \r
+        // 3. Create edges between branch points.\r
+        Resource firstBranchPoint = null;\r
+        Resource lastBranchPoint = null;\r
+        if (!bps.isEmpty()) {\r
+            Iterator<Pair<ControlPoint, Resource>> it = bps.iterator();\r
+            Pair<ControlPoint, Resource> prev = it.next();\r
+            firstBranchPoint = prev.second;\r
+            while (it.hasNext()) {\r
+                Pair<ControlPoint, Resource> next = it.next();\r
+                cu.connect(prev.second, next.second);\r
+                prev = next;\r
+            }\r
+            lastBranchPoint = prev.second;\r
+        }\r
+\r
+        // 4. Connect start/end terminals if those exist.\r
+        // If first/lastBranchPoint != null, connect to those.\r
+        // Otherwise connect the start/end terminals together.\r
+        Connector startConnector = null;\r
+        Connector endConnector = null;\r
+        IElement startFlag = null;\r
+        IElement endFlag = null;\r
+\r
+        if (startTerminal != null) {\r
+            startConnector = createConnectorForNode(graph, connection, startTerminal, EdgeEnd.Begin, judgment);\r
+        } else if (createFlags) {\r
+            startFlag = createFlag(graph, connection, EdgeEnd.Begin, controlPoints.getFirst(), FlagClass.Type.In, "");\r
+                       ArrayList<Terminal> terminals = new ArrayList<Terminal>();\r
+                       ElementUtils.getTerminals(startFlag, terminals, false);\r
+                       Terminal st = terminals.get(1);\r
+            startConnector = createConnectorForNode(graph, connection, (Resource) ElementUtils.getObject(startFlag),\r
+                    st, EdgeEnd.Begin, judgment);\r
+        }\r
+\r
+        if (endTerminal != null) {\r
+            endConnector = createConnectorForNode(graph, connection, endTerminal, EdgeEnd.End, judgment);\r
+        } else if (createFlags) {\r
+               if(createValve)\r
+                endFlag = createValveElement(graph, connection, EdgeEnd.End, controlPoints.getLast());\r
+               else\r
+                       endFlag = createFlag(graph, connection, EdgeEnd.End, controlPoints.getLast(), FlagClass.Type.Out, "");\r
+                       ArrayList<Terminal> terminals = new ArrayList<Terminal>();\r
+                       ElementUtils.getTerminals(endFlag, terminals, false);\r
+                       Terminal et = terminals.get(0);\r
+            endConnector = createConnectorForNode(graph, connection, (Resource) ElementUtils.getObject(endFlag),\r
+                    et, EdgeEnd.End, judgment);\r
+            \r
+            if(createValve) {\r
+               newValve = new TerminalInfo();\r
+               newValve.e = endFlag;\r
+               newValve.t = terminals.get(1);\r
+               newValve.posElem = TerminalUtil.getTerminalPosOnElement(endFlag, newValve.t);\r
+               newValve.posDia = TerminalUtil.getTerminalPosOnDiagram(endFlag, newValve.t);\r
+            }\r
+        }\r
+\r
+        if (firstBranchPoint == null || lastBranchPoint == null) {\r
+            cu.connect(startConnector.getConnector(), endConnector.getConnector());\r
+        } else {\r
+            cu.connect(startConnector.getConnector(), firstBranchPoint);\r
+            cu.connect(lastBranchPoint, endConnector.getConnector());\r
+        }\r
+\r
+        // 5. Finally, set connection type according to modelling rules\r
+        IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);\r
+        if (judgment.connectionType != null && modelingRules != null) {\r
+            modelingRules.setConnectionType(graph, connection, judgment.connectionType);\r
+        }\r
+\r
+        this.cu = null;\r
+        return newValve;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * @param graph\r
+     * @param connection\r
+     * @param end\r
+     * @param cp\r
+     * @param type\r
+     * @return an element describing the new created flag resource\r
+     * @throws DatabaseException\r
+     */\r
+    public IElement createValveElement(WriteGraph graph, Resource connection, EdgeEnd end, ControlPoint cp) throws DatabaseException {\r
+        ElementClass valveClass = elementClassProvider.get(SysdynElementClasses.VALVE);\r
+        IElement valveElement = Element.spawnNew(valveClass);\r
+        Resource valveClassResource = ElementUtils.checkedAdapt(valveClass, Resource.class);\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        G2DResource G2D = G2DResource.getInstance(graph);\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+        Resource valve = graph.newResource();\r
+        graph.claim(valve, L0.InstanceOf, null, valveClassResource);\r
+        graph.claim(valve, L0.PartOf, diagramResource);\r
+        AddElement.claimFreshElementName(graph, diagramResource, valve);\r
+        valveElement.setHint(ElementHints.KEY_OBJECT, valve);\r
+\r
+        OrderedSetUtils.add(graph, diagramResource, valve);\r
+\r
+        AffineTransform at = AffineTransform.getTranslateInstance(cp.getPosition().getX(), cp.getPosition().getY());\r
+        valveElement.setHint(ElementHints.KEY_TRANSFORM, at);\r
+        double[] matrix = new double[6];\r
+        at.getMatrix(matrix);\r
+        graph.claimLiteral(valve, DIA.HasTransform, G2D.Transform, matrix);\r
+\r
+        // Put the element on all the currently active layers if possible.\r
+        if (layerManager != null) {\r
+            layerManager.removeFromAllLayers(graph, valve);\r
+            layerManager.putElementOnVisibleLayers(diagram, graph, valve);\r
+        }\r
+\r
+        return valveElement;\r
+    }\r
+    \r
+    private boolean needsValve(TerminalInfo startTerminal, TerminalInfo endTerminal) {\r
+               if (!elementClassProvider.get(ElementClasses.CONNECTION)\r
+                               .equals(elementClassProvider.get(ConnectionClasses.FLOW))) \r
+                       return false;\r
+               if(startTerminal != null && startTerminal.e != null && startTerminal.e.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) {\r
+                       return false;\r
+               } else if(endTerminal != null && endTerminal.e != null && endTerminal.e.getElementClass().getId().equals(ValveFactory.class.getSimpleName())) {\r
+                       return false;\r
+               }\r
+               return true;\r
+    }\r
+    \r
+    private void createValveAndConnections(WriteGraph graph, ConnectionJudgement judgment, Deque<ControlPoint> controlPoints,\r
+            TerminalInfo startTerminal, TerminalInfo endTerminal) throws DatabaseException {\r
+       \r
+               ControlPoint cpfirst = controlPoints.getFirst();\r
+               ControlPoint cplast = controlPoints.getLast();\r
+\r
+               // Set the position in the middle of the route\r
+               double startX = cpfirst.getPosition().getX();\r
+               double startY = cpfirst.getPosition().getY();\r
+               double x = cplast.getPosition().getX();\r
+               double y = cplast.getPosition().getY();\r
+               Point2D pos = new Point2D.Double(startX - (startX - x) / 2, startY - (startY - y) / 2);\r
+               \r
+               // Replace the last control point with the control point in the middle\r
+        controlPoints.getLast().setPosition(pos);\r
+\r
+        // Create a connection to a new valve and get the new valve\r
+        TerminalInfo newValve = createConnection(graph, judgment, controlPoints, startTerminal, null, true);\r
+        \r
+               // Replace the last control point with the original control point\r
+        controlPoints.getLast().setPosition(x, y);\r
+        \r
+        // Create a connection starting from the new valve\r
+               createConnection(graph, judgment, controlPoints, newValve, endTerminal, false);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynCopyPasteStrategy.java
new file mode 100644 (file)
index 0000000..2c5c0dd
--- /dev/null
@@ -0,0 +1,237 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.Simantics;\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.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.handler.CopyPasteUtil;\r
+import org.simantics.diagram.handler.DefaultCopyPasteStrategy;\r
+import org.simantics.diagram.handler.ElementObjectAssortment;\r
+import org.simantics.diagram.handler.PasteOperation;\r
+import org.simantics.diagram.handler.Paster;\r
+import org.simantics.diagram.handler.Paster.NodeMap;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+/**\r
+ *  A copy-paste-strategy that changes variable names in the equations of copied variables.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SysdynCopyPasteStrategy extends DefaultCopyPasteStrategy {\r
+    \r
+    @Override\r
+    public void paste(final PasteOperation op) {\r
+        try {\r
+            Session session = Simantics.getSession();\r
+            if (op.sameDiagram()) {\r
+               if (op.cut) {\r
+                       CopyPasteUtil.localCutPaste(op);\r
+                       return;\r
+               }\r
+            } else {\r
+                if (CopyPasteUtil.onlyFlagsWithoutCorrespondence(session, op.ea)\r
+                        && CopyPasteUtil.checkFlagExternality(session, op.ea.flags, false)) {\r
+                    CopyPasteUtil.continueFlags(op);\r
+                    return;\r
+                } else {\r
+                       // Deny operation if copying shadow without original.\r
+                       if (copyingShadowWithoutOriginal(session, op.ea)) {\r
+                               PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+                                   public void run() {\r
+                                           Shell activeShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+                                           MessageDialog.openError(\r
+                                                       activeShell, \r
+                                                       "Error in pasting variables", \r
+                                                       "Cannot paste a shadow variable to another diagram without the original variable. " +\r
+                                                       "Shadow variables referring to a variable in another diagram are not supported in " +\r
+                                                       "the current version.");\r
+                                       }\r
+                               });\r
+                               return;\r
+                       }\r
+                       if (op.cut) {\r
+                               // Deny cut if cutting variable which has shadow that is not in the same cut operation. \r
+                               if (cuttingOriginalWithoutAllShadows(session, op.ea)) {\r
+                               PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+                                   public void run() {\r
+                                           Shell activeShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+                                           MessageDialog.openError(\r
+                                                       activeShell, \r
+                                                       "Error in pasting variables", \r
+                                                       "Cannot cut and paste a variable to another diagram without all of its shadows.");\r
+                                       }\r
+                               });\r
+                               return;\r
+                       }\r
+                       }\r
+                }\r
+            }\r
+            Paster paster = new Paster(session, op);\r
+            paster.perform();\r
+\r
+            // Change shadow originals for all shadows of which original is also copied.\r
+               replaceCopiedShadowOriginalsWithCreatedOnes(session, paster.getNodeMap());\r
+\r
+            renameVariablesInEquations(session, paster.getNodeMap());\r
+        } catch (DatabaseException e) {\r
+            ErrorLogger.defaultLogError(e);\r
+        }\r
+    }\r
+    \r
+    private static boolean cuttingOriginalWithoutAllShadows(Session session, final ElementObjectAssortment ea) throws DatabaseException {\r
+        return session.syncRequest(new Read<Boolean>() {\r
+               \r
+               @Override\r
+               public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                               for (Resource r : ea.nodeList) {\r
+                                       ModelingResources MOD = ModelingResources.getInstance(graph); \r
+                                       SysdynResource SR = SysdynResource.getInstance(graph); \r
+                                       if (graph.isInstanceOf(r, SR.StockSymbol)\r
+                                                       || graph.isInstanceOf(r, SR.AuxiliarySymbol)\r
+                                                       || graph.isInstanceOf(r, SR.ValveSymbol)\r
+                                                       || graph.isInstanceOf(r, SR.InputSymbol)) {\r
+                                               Resource component = graph.getPossibleObject(r, MOD.ElementToComponent);\r
+                                               Collection<Resource> shadows = graph.getObjects(component, SR.Shadow_original_Inverse);\r
+                                               for (Resource shadow : shadows) {\r
+                                                       Resource shadowElement = graph.getPossibleObject(shadow, MOD.ComponentToElement);\r
+                                                       if (!ea.nodes.contains(shadowElement))\r
+                                                               return true;\r
+                                               }\r
+                                               \r
+                                       }\r
+                           }\r
+                               return false;\r
+            }\r
+               });\r
+    }\r
+    \r
+    private static boolean copyingShadowWithoutOriginal(Session session, final ElementObjectAssortment ea) throws DatabaseException {\r
+        return session.syncRequest(new Read<Boolean>() {\r
+               \r
+               @Override\r
+               public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                               for (Resource r : ea.nodeList) {\r
+                                       ModelingResources MOD = ModelingResources.getInstance(graph); \r
+                                       SysdynResource SR = SysdynResource.getInstance(graph); \r
+                                       if (graph.isInstanceOf(r, SR.ShadowSymbol)) {\r
+                                               Resource component = graph.getPossibleObject(r, MOD.ElementToComponent);\r
+                                               Resource original = graph.getPossibleObject(component, SR.Shadow_original);\r
+                                               Resource originalElement = graph.getPossibleObject(original, MOD.ComponentToElement);\r
+                                               if (!ea.nodes.contains(originalElement))\r
+                                                       return true;\r
+                                       }\r
+                           }\r
+                               return false;\r
+            }\r
+               });\r
+    }\r
+    \r
+    private void replaceCopiedShadowOriginalsWithCreatedOnes(Session session, final NodeMap nodeMap) {\r
+       session.asyncRequest(new WriteRequest() {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+               ModelingResources MOD = ModelingResources.getInstance(graph); \r
+                               SysdynResource SR = SysdynResource.getInstance(graph); \r
+                               if (nodeMap == null)\r
+                                       return;\r
+                               Set<Resource> allResources = nodeMap.allResources();\r
+               for (Resource r : allResources) {\r
+                       // Go through all shadows\r
+                       if (graph.isInstanceOf(r, SR.ShadowSymbol)) {\r
+                               // See if the original of the shadow is copied\r
+                               Resource shadowComponent = graph.getPossibleObject(r, MOD.ElementToComponent);\r
+                                               Resource original = graph.getPossibleObject(shadowComponent, SR.Shadow_original);\r
+                                               Resource originalElement = graph.getPossibleObject(original, MOD.ComponentToElement);\r
+                                               Resource copiedOriginal = nodeMap.getResource(originalElement);\r
+                                               \r
+                               // If original is copied, change the copy shadow original to point to the new variable.\r
+                                               if (copiedOriginal != null) {\r
+                                                       Resource copiedShadow = nodeMap.getResource(r);\r
+                                                       Resource copiedShadowComponent = graph.getPossibleObject(copiedShadow, MOD.ElementToComponent);\r
+                                                       graph.deny(copiedShadowComponent, SR.Shadow_original);\r
+                                                       Resource copiedOriginalComponent = graph.getPossibleObject(copiedOriginal, MOD.ElementToComponent);;\r
+                                                       graph.claim(copiedShadowComponent, SR.Shadow_original, copiedOriginalComponent);\r
+                                               }\r
+                       }\r
+               }\r
+            }\r
+        });\r
+    }\r
+\r
+    \r
+    /**\r
+     * Rename variables in equations that need to be renamed.\r
+     * \r
+     * 1. Find the original variables and their names that were copied\r
+     * 2. For each copied variables, modify its equations. If equation had a reference\r
+     * to another copied variable, it needs to be modified. \r
+     * @param session\r
+     * @param nodeMap\r
+     */\r
+    private void renameVariablesInEquations(Session session, final NodeMap nodeMap) {\r
+        session.asyncRequest(new WriteRequest() {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Set<Resource> copies = new HashSet<Resource>();\r
+                HashMap<String, String> names = new HashMap<String, String>();\r
+                \r
+                ModelingResources MOD = ModelingResources.getInstance(graph);\r
+                // Collect copied variables and their names\r
+                if (nodeMap == null)\r
+                       return;\r
+                for(Resource var : nodeMap.allResources()) {\r
+                    Resource comp = graph.getPossibleObject(var, MOD.ElementToComponent);\r
+                    \r
+                    Resource r = nodeMap.getResource(var);\r
+                    Resource copy = graph.getPossibleObject(r, MOD.ElementToComponent);\r
+\r
+                    if(comp != null && copy != null) {\r
+                        names.put(NameUtils.getSafeName(graph, comp), NameUtils.getSafeName(graph, copy));\r
+                        copies.add(copy);\r
+                    }\r
+                }\r
+                \r
+                // Change equations only from copied variables\r
+                for(Resource copy : copies) {\r
+                    // Check for each name individually\r
+                    for(String originalName : names.keySet()) {\r
+                        String newName = names.get(originalName);\r
+                        new VariableNameValidator().renameInEquations(graph, copy, originalName, newName);\r
+                    }\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynElementClassProviders.java
new file mode 100644 (file)
index 0000000..93c5675
--- /dev/null
@@ -0,0 +1,69 @@
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementClassProviders;\r
+import org.simantics.g2d.element.IElementClassProvider;\r
+\r
+public class SysdynElementClassProviders extends ElementClassProviders {\r
+       \r
+    /**\r
+     * Create an element class provider that based on the specified map. The\r
+     * provider will directly access the map with the received keys. The\r
+     * argument map will be copied.\r
+     * \r
+     * @param map the map to use for element class provision\r
+     * @return <code>null</code> if there is no provider for the specified key\r
+     */\r
+    public static IElementClassProvider mappedProvider(Map<Object, ElementClass> map) {\r
+        // Copy the map as a safety measure\r
+        final Map<Object, ElementClass> copy = new HashMap<Object, ElementClass>(map);\r
+        return new ISysdynElementClassProvider() {\r
+            @Override\r
+            public ElementClass get(Object key) {\r
+                return copy.get(key);\r
+            }\r
+\r
+                       @Override\r
+                       public void put(Object key, ElementClass value) {\r
+                               copy.put(key, value);\r
+                       }\r
+\r
+        };\r
+    }\r
+    \r
+    /**\r
+     * Does the same as {@link #mappedProvider(Map)}, the map is simply provided\r
+     * differently. The specified array must contain\r
+     * <code>[key, ElementClass, key, ElementClass, ...]</code>.\r
+     * \r
+     * @param map the map to use for element class provision\r
+     * @return <code>null</code> if there is no provider for the specified key\r
+     */\r
+    public static IElementClassProvider mappedProvider(Object... keyClassPairs) {\r
+        if (keyClassPairs.length % 2 != 0)\r
+            throw new IllegalArgumentException();\r
+        Map<Object, ElementClass> map = new HashMap<Object, ElementClass>();\r
+        int n = keyClassPairs.length / 2;\r
+        for (int i = 0; i < n; ++i) {\r
+            Object key = keyClassPairs[i * 2];\r
+            Object elementClass = keyClassPairs[i*2+1];\r
+            if (!(elementClass instanceof ElementClass))\r
+                throw new IllegalArgumentException("not an ElementClass instance: "  + elementClass);\r
+            map.put(key, (ElementClass) elementClass);\r
+        }\r
+        return mappedProvider(map);\r
+    }\r
+\r
+\r
+       public interface ISysdynElementClassProvider extends IElementClassProvider {\r
+               \r
+               /**\r
+                * Update a value in an IElementClassProvider\r
+                */\r
+           void put(Object key, ElementClass value);\r
+           \r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPointerInteractor.java
new file mode 100644 (file)
index 0000000..ef74d7b
--- /dev/null
@@ -0,0 +1,186 @@
+package org.simantics.sysdyn.ui.editor.participant;\r
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+\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.ICanvasParticipant;\r
+import org.simantics.g2d.canvas.IToolMode;\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.handler.PickRequest.PickSorter;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.diagram.participant.TerminalPainter;\r
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\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.ElementClasses;\r
+import org.simantics.g2d.element.IElementClassProvider;\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.utils.GeometryUtils;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynElementClassProviders.ISysdynElementClassProvider;\r
+import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
+import org.simantics.sysdyn.ui.editor.routing.FlowRouter;\r
+import org.simantics.sysdyn.ui.elements.AuxiliaryFactory;\r
+import org.simantics.sysdyn.ui.elements.CloudFactory;\r
+import org.simantics.sysdyn.ui.elements.InputFactory;\r
+import org.simantics.sysdyn.ui.elements.ModuleFactory;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.sysdyn.ui.elements.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
+ * 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 SysdynPointerInteractor extends 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 SysdynPointerInteractor(boolean clickSelect, boolean boxSelect, boolean dragElement, boolean dndDragElement, boolean connect, boolean doubleClickEdit, IElementClassProvider newConnectionClassProvider, PickSorter pickSorter) {\r
+               super(clickSelect, boxSelect, dragElement, dndDragElement, connect, doubleClickEdit, newConnectionClassProvider, pickSorter);\r
+       }\r
+\r
+       @Override\r
+       @EventHandler(priority = TOOL_PRIORITY)\r
+       public boolean handlePress(MouseButtonPressedEvent me) {\r
+               if (!connects()) \r
+                       return false;\r
+               if (elementClassProvider == null)\r
+                       return false;\r
+               \r
+               // There should (maybe) be only one sysdynConnectTool associated with \r
+               // the canvas context at a time. If this is not the case, right-clicks\r
+               // are not always handled correctly mid-connection as they are instead \r
+               // treated as commands to create a new cloud and a new flow. There\r
+               // might be a more sensible way to fix this.\r
+               if (getContext().containsItemByClass(SysdynConnectTool.class)) {\r
+                       return false;\r
+               }\r
+               \r
+               IToolMode mode = getHint(Hints.KEY_TOOL);\r
+               if (!Hints.CONNECTTOOL.equals(mode))\r
+                       return false;\r
+               \r
+               IToolMode sysdynMode = getHint(SysdynElementHints.SYSDYN_KEY_TOOL);\r
+               \r
+               assertDependencies();\r
+               \r
+               TerminalInfo ti = pickTerminal(me.controlPosition);\r
+               Point2D curCanvasPos = util.controlToCanvas(me.controlPosition, null);\r
+               \r
+               ICanvasParticipant bsi = null;\r
+               \r
+               if (me.button == MouseEvent.LEFT_BUTTON) {\r
+                       if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode))\r
+                               // Do nothing.\r
+                               return false;\r
+                       else if (SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode))\r
+                               bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos);\r
+                       else if (SysdynElementHints.FLOW_TOOL.equals(sysdynMode))\r
+                               bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos);\r
+                       else\r
+                               bsi = getDependencyConnectTool(ti, me.mouseId, curCanvasPos);\r
+               }\r
+               else if (me.button == MouseEvent.RIGHT_BUTTON) {\r
+                       if (SysdynElementHints.LOCK_TOOL.equals(sysdynMode) ||\r
+                                       SysdynElementHints.DEPENDENCY_TOOL.equals(sysdynMode) ||\r
+                                       SysdynElementHints.FLOW_TOOL.equals(sysdynMode))\r
+                               return false;\r
+                       else\r
+                               bsi = getFlowConnectTool(ti, me.mouseId, curCanvasPos);\r
+               }\r
+               \r
+               if (bsi != null) {\r
+                       getContext().add(bsi);\r
+                       return true;\r
+               }\r
+               \r
+               return false;\r
+       }\r
+       \r
+       private ICanvasParticipant getDependencyConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) {\r
+               // can not have dependencies that start from thin air\r
+               if (ti == null)\r
+                       return null;\r
+               // can not have dependencies that start from clouds\r
+               if (ti.e.getElementClass().getId().equals(CloudFactory.class.getSimpleName())) \r
+                       return null;\r
+               \r
+               diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new DependencyRouter());\r
+               diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, false);\r
+               ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
+               secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.DEPENDENCY));\r
+\r
+               // not sure if this is necessary\r
+               IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
+               if (advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) {\r
+                       return new SysdynConnectTool(ti, mouseId, curCanvasPos);\r
+               }\r
+               \r
+               return null;\r
+       }\r
+       \r
+       private ICanvasParticipant getFlowConnectTool(TerminalInfo ti, int mouseId, Point2D curCanvasPos) {\r
+               // flows must not start from auxiliaries, inputs or modules\r
+               if (ti != null && (ti.e.getElementClass().getId().equals(AuxiliaryFactory.class.getSimpleName()) || \r
+                               ti.e.getElementClass().getId().equals(InputFactory.class.getSimpleName()) || \r
+                               ti.e.getElementClass().getId().equals(ModuleFactory.class.getSimpleName()))) \r
+                       return null;\r
+               \r
+               diagram.setHint(DiagramHints.ROUTE_ALGORITHM, new FlowRouter());\r
+               diagram.setHint(DiagramHints.KEY_USE_CONNECTION_FLAGS, true);\r
+               ISysdynElementClassProvider secp = (ISysdynElementClassProvider)elementClassProvider;\r
+               secp.put(ElementClasses.CONNECTION, elementClassProvider.get(ConnectionClasses.FLOW));\r
+               \r
+               // not sure if this is necessary\r
+               IConnectionAdvisor advisor = diagram.getHint(DiagramHints.CONNECTION_ADVISOR);\r
+               if (ti == null || advisor == null || advisor.canBeginConnection(null, ti.e, ti.t)) {\r
+                       return new SysdynConnectTool(ti, mouseId, curCanvasPos);\r
+               }\r
+               \r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public List<TerminalInfo> pickTerminals(Point2D controlPos) {\r
+               Rectangle2D controlPickRect = new Rectangle2D.Double(controlPos.getX()-SysdynPointerInteractor.PICK_DIST, controlPos.getY()-SysdynPointerInteractor.PICK_DIST, SysdynPointerInteractor.PICK_DIST*2+1, SysdynPointerInteractor.PICK_DIST*2+1);\r
+               Shape       canvasPickRect  = GeometryUtils.transformShape(controlPickRect, util.getInverseTransform());\r
+               return TerminalUtil.pickTerminals(diagram, canvasPickRect, false, true);\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynPopulateElementDropParticipant.java
new file mode 100644 (file)
index 0000000..f15307c
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import java.awt.dnd.DropTargetDragEvent;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\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.diagram.adapter.GraphToDiagramSynchronizer;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.dnd.ElementClassDragItem;\r
+import org.simantics.g2d.dnd.IDnDContext;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.diagramEditor.PopulateElementDropParticipant;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class SysdynPopulateElementDropParticipant extends PopulateElementDropParticipant {\r
+\r
+       public SysdynPopulateElementDropParticipant(GraphToDiagramSynchronizer synchronizer) {\r
+               super(synchronizer);\r
+       }\r
+\r
+    @Override\r
+    public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) {\r
+        super.dragEnter(dtde, dp);\r
+        \r
+        // Check that user is not trying to populate a module to itself. \r
+        // This doesn't prevent infinite recursion if there is one module between two exactly the same modules.\r
+        // e.g. WorkModule -> WokrforceModule -> WorkModule creates an infinite recursion\r
+        final Collection<ElementClassDragItem> items = dp.getItemsByClass(ElementClassDragItem.class);\r
+        if(!items.isEmpty()) {\r
+                Collection<ElementClassDragItem> unvalidModules = null;\r
+               try {\r
+                       unvalidModules = synchronizer.getSession().syncRequest(new Read<Collection<ElementClassDragItem>>() {\r
+\r
+                                       @Override\r
+                                       public Collection<ElementClassDragItem> perform(ReadGraph graph)\r
+                                                       throws DatabaseException {\r
+                                                Collection<ElementClassDragItem> unvalidModules = new ArrayList<ElementClassDragItem>();\r
+                                               for(ElementClassDragItem item : items) {\r
+                                                       StaticObjectAdapter soa = item.getElementClass().getSingleItem(StaticObjectAdapter.class);\r
+                                                       Resource type = soa.adapt(Resource.class);\r
+                                                       \r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       if(graph.isInheritedFrom(type, sr.ModuleSymbol)) {\r
+                                               Resource module = graph.getSingleObject(type, ModelingResources.getInstance(graph).SymbolToComponentType);\r
+                                               Resource configuration = graph.getSingleObject(module, StructuralResource2.getInstance(graph).IsDefinedBy);\r
+                                               Resource dia = graph.getSingleObject(configuration, ModelingResources.getInstance(graph).CompositeToDiagram);\r
+                                               Resource editorDia = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
+                                               if(dia.equals(editorDia))\r
+                                                       unvalidModules.add(item);\r
+                                       }\r
+                                               }\r
+                                               return unvalidModules;\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       if(!unvalidModules.isEmpty()) {\r
+                               for(ElementClassDragItem item : unvalidModules) {\r
+                                       dp.remove(item);\r
+                               }\r
+                       }\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/SysdynSpecialComponentCopyAdvisor.java
new file mode 100644 (file)
index 0000000..40c3835
--- /dev/null
@@ -0,0 +1,44 @@
+package org.simantics.sysdyn.ui.editor.participant;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.synchronization.ISynchronizationContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ComponentUtils;\r
+\r
+/**\r
+ * Copy advisor for copying sysdyn elements with custom prefix and/or suffix\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynSpecialComponentCopyAdvisor extends SysdynComponentCopyAdvisor {\r
+    \r
+    private String prefix = "";\r
+    private String suffix = "";\r
+    \r
+    public SysdynSpecialComponentCopyAdvisor(String prefix, String suffix) {\r
+        this.prefix = prefix;\r
+        this.suffix = suffix;\r
+    }\r
+    \r
+    @Override\r
+    public String rename(ISynchronizationContext context, WriteGraph graph, Resource source,\r
+            Resource copy, Resource sourceContainer, Resource targetContainer) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        String copyName = NameUtils.getSafeName(graph, copy);\r
+        Resource configurationRoot = ComponentUtils.getCompositeConfigurationRoot(graph, targetContainer);\r
+        \r
+        if(prefix == null)\r
+            prefix = "";\r
+        if(suffix == null)\r
+            suffix = "";\r
+        \r
+        String name =  NameUtils.findFreshName(graph, prefix + copyName + suffix, configurationRoot, l0.ConsistsOf, "%s%d");\r
+        graph.claimLiteral(copy, l0.HasName, name, Bindings.STRING);\r
+        return name;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/DependencyRouter.java
new file mode 100644 (file)
index 0000000..2cab67e
--- /dev/null
@@ -0,0 +1,189 @@
+package org.simantics.sysdyn.ui.editor.routing;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\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.g2d.routing.IConnection;\r
+import org.simantics.g2d.routing.IConnection.Connector;\r
+import org.simantics.g2d.routing.IRouter2;\r
+import org.simantics.sysdyn.ui.elements.connections.Arcs;\r
+import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+public class DependencyRouter implements IRouter2 {\r
+    \r
+    public static DependencyRouter INSTANCE = new DependencyRouter();\r
+\r
+       @Override\r
+       public void route(IConnection connection) {\r
+               if(connection.getSegments().isEmpty())\r
+                       return;\r
+               Object seg = connection.getSegments().iterator().next();\r
+        Connector begin = connection.getBegin(seg);\r
+        Connector end = connection.getEnd(seg);\r
+        \r
+        Triple<Arc2D, Path2D, Path2D> shapes = new Triple<Arc2D, Path2D, Path2D>(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double());\r
+        createArrowShape(shapes,\r
+                       begin.parentObstacle,\r
+                       end.parentObstacle,\r
+                       0.3,\r
+                       null);\r
+        \r
+        Path2D path = new Path2D.Double();\r
+        path.append(shapes.first, false);\r
+        path.append(shapes.second, false);\r
+        connection.setPath(seg, path);\r
+       }\r
+\r
+       \r
+       /*\r
+        * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2\r
+        */\r
+    public static double ARROW_LENGTH1 = 0.1;\r
+    public static double ARROW_LENGTH2 = 1.9;\r
+    public static double ARROW_WIDTH = 0.7;\r
+    public static double DELAYMARK_LENGTH = 6;\r
+    public static double DELAYMARK_GAP = 0.4;\r
+    \r
+\r
+       private static Path2D createArrow(Path2D shape, double x, double y, double dx, double dy) {\r
+               if(shape == null)\r
+                       shape = new Path2D.Double();\r
+               else\r
+                       shape.reset();\r
+               \r
+        shape.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy);\r
+        x -= ARROW_LENGTH2*dx;\r
+        y -= ARROW_LENGTH2*dy;\r
+        shape.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx);\r
+        shape.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx);\r
+        shape.closePath();\r
+        return shape;\r
+    }\r
+       \r
+       public static Arc2D createArc(Arc2D arc, Shape beginBounds, Shape endBounds, double angle) {\r
+               if (beginBounds == null || endBounds == null)\r
+                       return new Arc2D.Double();\r
+               double x0 = beginBounds.getBounds2D().getCenterX();\r
+        double y0 = beginBounds.getBounds2D().getCenterY();\r
+        double x1 = endBounds.getBounds2D().getCenterX();\r
+        double y1 = endBounds.getBounds2D().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), beginBounds, angle < 0.0);\r
+//        head.getBounds(bounds);\r
+        double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, \r
+            Math.atan2(-dy1, dx1), endBounds, 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
+        if(arc == null)\r
+               arc = new Arc2D.Double();\r
+        arc.setArc(cx-r, cy-r, 2*r, 2*r, \r
+            Math.toDegrees(angle0), \r
+            Math.toDegrees(extent), \r
+            Arc2D.OPEN);\r
+//        \r
+               return arc;\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
+\r
+       public static Path2D createDelayMark(Path2D shape, double x, double y, double angle, BasicStroke stroke) {\r
+               if(shape == null)\r
+                       shape = new Path2D.Double();\r
+               else\r
+                       shape.reset();\r
+               \r
+               float strokeWidth = stroke != null ? stroke.getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH;\r
+               \r
+               double dx = Math.cos(angle) * (DELAYMARK_LENGTH + strokeWidth) / 2; \r
+               double dy = -Math.sin(angle) * (DELAYMARK_LENGTH + strokeWidth) / 2; \r
+               double dxGap = Math.cos(angle + Math.PI / 2) * (DELAYMARK_GAP / 2 + strokeWidth); \r
+               double dyGap = -Math.sin(angle + Math.PI / 2) * (DELAYMARK_GAP / 2 + strokeWidth);\r
+        shape.moveTo(x - dx - dxGap, y - dy - dyGap);\r
+        shape.lineTo(x + dx - dxGap, y + dy - dyGap);\r
+        shape.moveTo(x - dx + dxGap, y - dy + dyGap);\r
+        shape.lineTo(x + dx + dxGap, y + dy + dyGap);\r
+        return shape;\r
+       }\r
+       \r
+       public static Triple<Arc2D, Path2D, Path2D> createArrowShape(Triple<Arc2D, Path2D, Path2D> shapes, Shape beginBounds, Shape endBounds, double angle, Stroke stroke) {\r
+               if(shapes == null || shapes.first == null || shapes.second == null || shapes.third == null) {\r
+                       shapes = new Triple<Arc2D, Path2D, Path2D>(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double());\r
+               }\r
+               createArc(shapes.first, beginBounds, endBounds, angle);\r
+               \r
+        double angle0 =  Math.toRadians(shapes.first.getAngleStart());\r
+        double angle1 = Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent());\r
+        double x = Math.cos(angle > 0.0 ? angle1 : angle0);\r
+        double y = -Math.sin(angle > 0.0 ? angle1 : angle0);\r
+        double r = shapes.first.getHeight() / 2;\r
+        \r
+        createArrow(shapes.second, shapes.first.getCenterX() + r*x, shapes.first.getCenterY() + r*y, \r
+            angle < 0.0 ? -y : y, \r
+            angle > 0.0 ? -x : x);\r
+\r
+        double angleCenter = Math.toRadians(shapes.first.getAngleStart() + (shapes.first.getAngleExtent() / 2));\r
+        double arcCenterX = shapes.first.getCenterX() + r * Math.cos(angleCenter);\r
+        double arcCenterY = shapes.first.getCenterY() - r * Math.sin(angleCenter);\r
+        createDelayMark(shapes.third, arcCenterX, arcCenterY, angleCenter, \r
+                       stroke instanceof BasicStroke ? (BasicStroke)stroke : null);\r
+        \r
+        return shapes;\r
+        \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/FlowRouter.java
new file mode 100644 (file)
index 0000000..fc64625
--- /dev/null
@@ -0,0 +1,139 @@
+package org.simantics.sysdyn.ui.editor.routing;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.PathIterator;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\r
+import org.simantics.g2d.routing.Constants;\r
+import org.simantics.g2d.routing.IConnection;\r
+import org.simantics.g2d.routing.IConnection.Connector;\r
+import org.simantics.g2d.routing.IRouter2;\r
+import org.simantics.sysdyn.ui.elements.connections.Flows;\r
+\r
+public class FlowRouter implements IRouter2{\r
+\r
+       SysdynLocalRouter localRouter;\r
+       \r
+       public static final float OFFSET = 0.5f;\r
+\r
+    public FlowRouter() {\r
+        this(false);\r
+    }\r
+\r
+    public FlowRouter(boolean roundCorners) {\r
+        this.localRouter = new SysdynLocalRouter();\r
+    }\r
+\r
+    private Path2D route(double beginX, double beginY, int sDir, Rectangle2D beginObstacle,\r
+            double endX, double endY, int tDir, Rectangle2D endObstacle) {\r
+        localRouter.sx = beginX;\r
+        localRouter.sy = beginY;\r
+        if(beginObstacle == null) {\r
+            localRouter.aMinX = beginX;\r
+            localRouter.aMinY = beginY;\r
+            localRouter.aMaxX = beginX;\r
+            localRouter.aMaxY = beginY;\r
+        }\r
+        else {\r
+            localRouter.aMinX = beginObstacle.getMinX();\r
+            localRouter.aMinY = beginObstacle.getMinY();\r
+            localRouter.aMaxX = beginObstacle.getMaxX();\r
+            localRouter.aMaxY = beginObstacle.getMaxY();\r
+        }\r
+        localRouter.sourceDirection = sDir;\r
+\r
+        localRouter.tx = endX;\r
+        localRouter.ty = endY;\r
+        if(endObstacle == null) {\r
+            localRouter.bMinX = endX;\r
+            localRouter.bMinY = endY;\r
+            localRouter.bMaxX = endX;\r
+            localRouter.bMaxY = endY;\r
+        }\r
+        else {\r
+            localRouter.bMinX = endObstacle.getMinX();\r
+            localRouter.bMinY = endObstacle.getMinY();\r
+            localRouter.bMaxX = endObstacle.getMaxX();\r
+            localRouter.bMaxY = endObstacle.getMaxY();\r
+        }\r
+        localRouter.targetDirection = tDir;\r
+        \r
+        // adjust flows to start and stop within the obstacle\r
+        if(sDir == Constants.EAST || sDir == Constants.WEST) {\r
+               localRouter.aMinY = localRouter.aMinY + OFFSET;\r
+               localRouter.aMaxY = localRouter.aMaxY - OFFSET;\r
+        }\r
+        if(tDir == Constants.EAST || tDir == Constants.WEST) {\r
+               localRouter.bMinY = localRouter.bMinY + OFFSET;\r
+               localRouter.bMaxY = localRouter.bMaxY - OFFSET;\r
+        }\r
+        if(sDir == Constants.SOUTH || sDir == Constants.NORTH) {\r
+               localRouter.aMinX = localRouter.aMinX + OFFSET;\r
+               localRouter.aMaxX = localRouter.aMaxX - OFFSET;\r
+        }\r
+        if(tDir == Constants.SOUTH || tDir == Constants.NORTH) {\r
+               localRouter.bMinX = localRouter.bMinX + OFFSET;\r
+               localRouter.bMaxX = localRouter.bMaxX - OFFSET;\r
+        }\r
+\r
+        localRouter.route();\r
+        \r
+        Path2D completePath = new Path2D.Double();\r
+        \r
+        completePath = Flows.createOffsetPath(localRouter.path, OFFSET);\r
+        completePath.append(Flows.createOffsetPath(localRouter.path, -OFFSET), false);\r
+        \r
+        return completePath;\r
+    }\r
+    \r
+    @Override\r
+    public void route(IConnection connection) {\r
+        Collection<?> segments = connection.getSegments();\r
+        if(segments.size() == 1)\r
+            for(Object seg : segments) {\r
+                Connector begin = connection.getBegin(seg);\r
+                Connector end = connection.getEnd(seg);\r
+\r
+                double bestLength = Double.POSITIVE_INFINITY;\r
+                Path2D bestPath = null;\r
+                \r
+                for(int sDir : Constants.POSSIBLE_DIRECTIONS[begin.allowedDirections])\r
+                    for(int tDir : Constants.POSSIBLE_DIRECTIONS[end.allowedDirections]) {\r
+                        Path2D path = route(begin.x, begin.y, sDir, begin.parentObstacle,\r
+                                end.x, end.y, tDir, end.parentObstacle);\r
+\r
+                        double length = pathCost(path);\r
+                        if(length < bestLength) {\r
+                            bestLength = length;\r
+                            bestPath = path;\r
+                        }\r
+                    }\r
+\r
+                if(bestPath != null)\r
+                    connection.setPath(seg, bestPath);\r
+            }\r
+    }\r
+    \r
+\r
+    final static AffineTransform IDENTITY = new AffineTransform();\r
+\r
+    static double pathCost(Path2D path) {\r
+        double length = 0.0;\r
+        PathIterator it = path.getPathIterator(IDENTITY);\r
+        double[] temp = new double[6];\r
+        double x=0.0, y=0.0;\r
+        double bendCount = 0.0;\r
+        while(!it.isDone()) {\r
+            bendCount += 1.0;\r
+            if(it.currentSegment(temp) != PathIterator.SEG_MOVETO)\r
+                length += Math.abs(x - temp[0] + y - temp[1]);\r
+            x = temp[0];\r
+            y = temp[1];\r
+            it.next();\r
+        }\r
+        return bendCount - 1.0 / length;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/routing/SysdynLocalRouter.java
new file mode 100644 (file)
index 0000000..253e6a1
--- /dev/null
@@ -0,0 +1,477 @@
+package org.simantics.sysdyn.ui.editor.routing;\r
+\r
+import java.awt.geom.Path2D;\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.g2d.routing.Constants;\r
+\r
+public class SysdynLocalRouter {\r
+\r
+       static final double OFFSET = 1.0;\r
+       \r
+       double aMinX;\r
+       double aMinY;\r
+       double aMaxX;\r
+       double aMaxY;\r
+\r
+       double bMinX;\r
+       double bMinY;\r
+       double bMaxX;\r
+       double bMaxY;\r
+\r
+       double sx;\r
+       double sy;\r
+\r
+       double tx;\r
+       double ty;\r
+\r
+       int sourceDirection;\r
+       int targetDirection;\r
+\r
+       ArrayList<Double> points;\r
+       Path2D path;\r
+\r
+       public SysdynLocalRouter() {\r
+       }\r
+\r
+       /**\r
+        * Case where both source and target connection directions are to east.\r
+        */\r
+       void routeEast() {\r
+               if (bMinX >= aMaxX || tx >= 0 && !(bMaxY < aMinY || aMaxY < bMinY)) {\r
+                       if (ty != 0.0) {\r
+                /*  ______           ______\r
+                 * |      |         |      |\r
+                 * |      |----\    |      |\r
+                 * |      |    \--->|      |\r
+                 * |______|         |______|\r
+                 */\r
+                               double mx = 0.5 * (aMaxX + bMinX);\r
+                               point(mx, 0.0);\r
+                               point(mx, ty);\r
+                       } else\r
+                               ; // Just a straight line\r
+               } else {\r
+                       double x0 = bMinX;\r
+                       double x1 = aMaxX;\r
+                       double my;\r
+            /*      ______\r
+             *     |      |\r
+             *     |      |\r
+             *  /->|      |\r
+             *  |  |______|\r
+             *  |\r
+             *  \-------------\\r
+             *        ______  |\r
+             *       |      | |\r
+             *       |      |-/\r
+             *       |      |\r
+             *       |______|\r
+             * \r
+             * If the elements are separated in Y-direction,\r
+             * route between the elements (this is always the shortest path).\r
+             */\r
+                       if (bMaxY < aMinY)\r
+                               my = 0.5 * (aMinY + bMaxY);\r
+                       else if (aMaxY < bMinY)\r
+                               my = 0.5 * (aMaxY + bMinY);\r
+                       else {\r
+                /*\r
+                 *  /------------------------\\r
+                 *  |   ______      ______   |\r
+                 *  |  |      |    |      |  |\r
+                 *  |  |      |    |      |--+\r
+                 *  +->|      |    |      |  |\r
+                 *  |  |______|    |______|  |\r
+                 *  |                        |\r
+                 *  \------------------------/\r
+                 * \r
+                 * or\r
+                 * \r
+                 *    /-----------\\r
+                 *    |   ______  |\r
+                 *    |  |      | |\r
+                 *    |  |      | |\r
+                 * /--+->|      | |\r
+                 * |  ___|______| |\r
+                 * | |      |     |\r
+                 * | |      |-+---/\r
+                 * | |      | |\r
+                 * | |______| |\r
+                 * |          |\r
+                 * \----------/\r
+                 * \r
+                 * We may choose either lower or upper path.\r
+                 */\r
+                               double upperX0 = bMinX;\r
+                               double upperX1 = aMaxX;\r
+                               double lowerX0 = bMinX;\r
+                               double lowerX1 = aMaxX;\r
+                               double upperY = Math.min(aMinY, bMinY);\r
+                               double lowerY = Math.max(aMaxY, bMaxY);\r
+\r
+                               if (aMinX < bMinX) {\r
+                                       if (ty < 0.5 * (aMinY + aMaxY))\r
+                                               lowerX0 = aMinX;\r
+                                       else\r
+                                               upperX0 = aMinX;\r
+                               }\r
+\r
+                               if (bMaxX > aMaxX) {\r
+                                       if (ty < 0.5 * (aMinY + aMaxY))\r
+                                               upperX1 = bMaxX;\r
+                                       else\r
+                                               lowerX1 = bMaxX;\r
+                               }\r
+\r
+                               double upperLength = upperX1 - upperY + (upperX1 - upperX0)\r
+                                               + (ty - upperY) + (tx - upperX0);\r
+                               double lowerLength = lowerX1 + lowerY + (lowerX1 - lowerX0)\r
+                                               + (lowerY - ty) + (tx - lowerX0);\r
+\r
+                               if (upperLength < lowerLength) {\r
+                                       x0 = upperX0;\r
+                                       x1 = upperX1;\r
+                                       my = upperY;\r
+                               } else {\r
+                                       x0 = lowerX0;\r
+                                       x1 = lowerX1;\r
+                                       my = lowerY;\r
+                               }\r
+                       }\r
+                       point(x1, 0.0);\r
+                       point(x1, my);\r
+                       point(x0, my);\r
+                       point(x0, ty);\r
+               }\r
+       }\r
+\r
+       void routeWest() {\r
+               if (tx >= 0.0) {\r
+                       double fx = Math.max(aMaxX, bMaxX);\r
+                       double mx = 0.5 * (aMaxX + bMinX);\r
+                       if (bMinY >= 0.0 || bMaxY <= 0.0 || mx < 0.0) {\r
+                /*                   ______\r
+                 *                  |      |\r
+                 *                  |      |\r
+                 *                  |      |<-\\r
+                 *  ______          |______|  |\r
+                 * |      |                   |\r
+                 * |      |-------------------/\r
+                 * |      |\r
+                 * |______|\r
+                 */\r
+                point(fx, 0.0);\r
+            }\r
+            else {\r
+                /*             /-------------\\r
+                 *             |    ______   |\r
+                 *             |   |      |  |\r
+                 *  ______     |   |      |  |\r
+                 * |      |    |   |      |<-+\r
+                 * |      |----+   |______|  |\r
+                 * |      |    |             |\r
+                 * |______|    \-------------/\r
+                 * \r
+                 * We may choose either upper or lower path\r
+                 * by the path length.\r
+                 */\r
+                               double my = Math.abs(bMinY) + Math.abs(ty - bMinY) < Math\r
+                                               .abs(bMaxY) + Math.abs(ty - bMaxY) ? bMinY : bMaxY;\r
+                               point(mx, 0.0);\r
+                               point(mx, my);\r
+                               point(fx, my);\r
+                       }\r
+                       point(fx, ty);\r
+               } else {\r
+                       double fx = Math.max(aMaxX, bMaxX);\r
+                       double mx = 0.5 * (aMinX + bMaxX);\r
+                       point(fx, 0.0);\r
+                       if (ty <= aMinY || ty >= aMaxY\r
+                                       || (tx >= mx && ty >= aMinY && ty <= aMaxY)) {\r
+                /*                   ______\r
+                 *                  |      |\r
+                 *                  |      |\r
+                 *                  |      |--\\r
+                 *  ______          |______|  |\r
+                 * |      |                   |\r
+                 * |      |<------------------/\r
+                 * |      |\r
+                 * |______|\r
+                 */\r
+                point(fx, ty);\r
+            }\r
+            else {\r
+                /*             /-------------\\r
+                 *             |    ______   |\r
+                 *             |   |      |  |\r
+                 *  ______     |   |      |  |\r
+                 * |      |    |   |      |--+\r
+                 * |      |<---+   |______|  |\r
+                 * |      |    |             |\r
+                 * |______|    \-------------/\r
+                 * \r
+                 * We may choose either upper or lower path\r
+                 * by the path length.\r
+                 */\r
+                               double my = Math.abs(aMinY) + Math.abs(ty - aMinY) < Math\r
+                                               .abs(aMaxY) + Math.abs(ty - aMaxY) ? aMinY : aMaxY;\r
+                               point(fx, my);\r
+                               point(mx, my);\r
+                               point(mx, ty);\r
+                       }\r
+               }\r
+       }\r
+\r
+       void routeSouth() {\r
+               if (tx > 0.0 && (bMinY >= 0.0 || (ty > 0.0 && bMinX <= aMaxX)))\r
+                       point(tx, 0.0);\r
+               else if (bMinX > aMaxX) {\r
+                       double mx = 0.5 * (aMaxX + bMinX);\r
+                       point(mx, 0.0);\r
+                       point(mx, bMinY);\r
+                       point(tx, bMinY);\r
+               } else {\r
+                       double fx = aMaxX;\r
+                       double my = 0.5 * (aMaxY + bMinY);\r
+                       if (my < aMaxY && (tx < aMinX || ty < aMinY)) {\r
+                               my = Math.min(aMinY, bMinY);\r
+                               if (bMaxX > aMaxX)\r
+                                       fx = bMaxX;\r
+                       }\r
+                       point(fx, 0.0);\r
+                       point(fx, my);\r
+                       point(tx, my);\r
+               }\r
+       }\r
+\r
+       double xx, xy, yx, yy;\r
+\r
+       void point(double x, double y) {\r
+               lineTo(x * xx + y * yx + sx, x * xy + y * yy + sy);\r
+       }\r
+\r
+       /*\r
+        * should draw only horizontal or vertical lines. Determine the offset and\r
+        * draw both lines.\r
+        */\r
+       void lineTo(double x, double y) {\r
+               double cx = path.getCurrentPoint().getX();\r
+               double cy = path.getCurrentPoint().getY();\r
+               \r
+               if (Math.abs(cx - x) < 1e-5) {\r
+                       // Vertical line\r
+                       if(points.size() % 2 == 0) {\r
+                               points.add(points.get(points.size()-2));\r
+                       }\r
+                       points.add(y);\r
+               } else if (Math.abs(cy - y) < 1e-5) {\r
+                       // Horizontal line\r
+                       if(points.size() % 2 != 0) {\r
+                               points.add(cy);\r
+                       }\r
+                       points.add(x);\r
+               }\r
+               path.lineTo(x, y);\r
+       }\r
+       void rotate() {\r
+               double temp;\r
+\r
+               temp = tx;\r
+               tx = ty;\r
+               ty = -temp;\r
+\r
+               temp = aMinX;\r
+               aMinX = aMinY;\r
+               aMinY = -aMaxX;\r
+               aMaxX = aMaxY;\r
+               aMaxY = -temp;\r
+\r
+               temp = bMinX;\r
+               bMinX = bMinY;\r
+               bMinY = -bMaxX;\r
+               bMaxX = bMaxY;\r
+               bMaxY = -temp;\r
+\r
+               temp = xx;\r
+               xx = -xy;\r
+               xy = temp;\r
+\r
+               temp = yx;\r
+               yx = -yy;\r
+               yy = temp;\r
+\r
+               --targetDirection;\r
+               if (targetDirection < 0)\r
+                       targetDirection += 4;\r
+               --sourceDirection;\r
+       }\r
+\r
+       void flip() {\r
+               double temp;\r
+\r
+               ty = -ty;\r
+\r
+               temp = aMinY;\r
+               aMinY = -aMaxY;\r
+               aMaxY = -temp;\r
+\r
+               temp = bMinY;\r
+               bMinY = -bMaxY;\r
+               bMaxY = -temp;\r
+\r
+               yx = -yx;\r
+               yy = -yy;\r
+\r
+               targetDirection = (targetDirection + 2) % 4;\r
+       }\r
+\r
+       /*\r
+        * Puts source terminal to origo and rotates the situation so that the\r
+        * connection leaves to east. Finally, the case where target direction is to\r
+        * south is eliminated by optionally flipping the situation.\r
+        */\r
+       void canonicalize() {\r
+               aMinX -= sx;\r
+               aMinY -= sy;\r
+               aMaxX -= sx;\r
+               aMaxY -= sy;\r
+               bMinX -= sx;\r
+               bMinY -= sy;\r
+               bMaxX -= sx;\r
+               bMaxY -= sy;\r
+               tx -= sx;\r
+               ty -= sy;\r
+               xx = yy = 1.0;\r
+               xy = yx = 0.0;\r
+               while (sourceDirection > 0)\r
+                       rotate();\r
+\r
+               if (targetDirection == Constants.SOUTH)\r
+                       flip();\r
+       }\r
+\r
+       public void route() {\r
+               /*\r
+                * Three cases: 1. Obstacles share X-axis at some point 2. Obstacles\r
+                * share Y-Axis at some point 3. Obstacles don't share axis => Have to\r
+                * make corners.\r
+                */             \r
+//             if (\r
+//                             aMinX > bMinX && aMinX < bMaxX ||\r
+//                             aMaxX > bMinX && aMaxX < bMaxX ||\r
+//                             aMinX < bMinX && aMaxX > bMaxX) {\r
+//                     // Obstacles share x-axis => no corner\r
+//                     double minX = aMinX > bMinX ? aMinX : bMinX;\r
+//                     double maxX = aMaxX < bMaxX ? aMaxX : bMaxX;\r
+//                     double middle = minX + (maxX - minX) / 2;\r
+//                     sx = middle;\r
+//                     tx = middle;\r
+//                     if (sy > ty) {\r
+//                             sy = aMinY;\r
+//                             ty = bMaxY;\r
+//                     } else {\r
+//                             sy = aMaxY;\r
+//                             ty = bMinY;\r
+//                     }\r
+//             } else if (\r
+//                             aMinY > bMinY && aMinY < bMaxY || \r
+//                             aMaxY > bMinY && aMaxY < bMaxY ||\r
+//                             aMinY < bMinY && aMaxY > bMaxY) {\r
+//                     // Obstacles share y-axis => no corner\r
+//                     double minY = aMinY > bMinY ? aMinY : bMinY;\r
+//                     double maxY = aMaxY < bMaxY ? aMaxY : bMaxY;\r
+//                     double middle = minY + (maxY - minY) / 2;\r
+//                     sy = middle;\r
+//                     ty = middle;\r
+//                     if (sx > tx) {\r
+//                             sx = aMinX;\r
+//                             tx = bMaxX;\r
+//                     } else {\r
+//                             sx = aMaxX;\r
+//                             tx = bMinX;\r
+//                     }\r
+//             } else {\r
+                       sx = aMinX + (aMaxX - aMinX) / 2;\r
+                       sy = aMinY + (aMaxY - aMinY) / 2;\r
+                       tx = bMinX + (bMaxX - bMinX) / 2;\r
+                       ty = bMinY + (bMaxY - bMinY) / 2;\r
+                       // Move starting point to the edge of the start element\r
+                       switch (sourceDirection) {\r
+                       case Constants.WEST:\r
+                               sx = aMinX;\r
+                               break;\r
+                       case Constants.EAST:\r
+                               sx = aMaxX;\r
+                               break;\r
+                       case Constants.NORTH:\r
+                               sy = aMinY;\r
+                               break;\r
+                       case Constants.SOUTH:\r
+                               sy = aMaxY;\r
+                               break;\r
+                       }\r
+\r
+                       // Move target point to the edge of the ending element\r
+                       switch (targetDirection) {\r
+                       case Constants.EAST:\r
+                               tx = bMaxX;\r
+                               break;\r
+                       case Constants.WEST:\r
+                               tx = bMinX;\r
+                               break;\r
+                       case Constants.NORTH:\r
+                               ty = bMinY;\r
+                               break;\r
+                       case Constants.SOUTH:\r
+                               ty = bMaxY;\r
+                               break;\r
+                       }\r
+//             }\r
+\r
+               path = new Path2D.Double();\r
+               points = new ArrayList<Double>();\r
+\r
+               path.moveTo(sx, sy);\r
+               points.add(sx);\r
+               points.add(sy);\r
+\r
+               // Vertical and horizontal cases\r
+               if ((Math.abs(sx - tx) < 1e-5 && isVertical())\r
+                       || (Math.abs(sy - ty) < 1e-5 && isHorizontal())) {\r
+                       lineTo(tx, ty);\r
+                       return;\r
+               }\r
+               \r
+\r
+               canonicalize();\r
+               switch (targetDirection) {\r
+               case Constants.EAST:\r
+                       routeWest();\r
+                       break;\r
+               case Constants.WEST:\r
+                       routeEast();\r
+                       break;\r
+               case Constants.NORTH:\r
+                       routeSouth();\r
+                       break;\r
+               }\r
+\r
+               point(tx, ty);\r
+\r
+       }\r
+       \r
+       private boolean isVertical() {\r
+               return\r
+               (sourceDirection == Constants.SOUTH && targetDirection == Constants.SOUTH)\r
+               ||\r
+               (sourceDirection == Constants.NORTH && targetDirection == Constants.NORTH);\r
+       }\r
+       \r
+       private boolean isHorizontal() {\r
+               return\r
+               (sourceDirection == Constants.EAST && targetDirection == Constants.EAST)\r
+               ||\r
+               (sourceDirection == Constants.WEST && targetDirection == Constants.WEST);\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/AuxiliaryFactory.java
new file mode 100644 (file)
index 0000000..ab3bbd3
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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.diagram.elements.ResizeRectangularSceneGraph;\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
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class AuxiliaryFactory extends SysdynElementFactory {\r
+\r
+    public 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
+                new SysdynTextElementHandler(0, 0, Alignment.CENTER, 0, 1.5, 1.5, true),\r
+                BoundsOutline.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,   \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/elements/BorderSceneGraph.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/BorderSceneGraph.java
new file mode 100644 (file)
index 0000000..2126e9c
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.geom.AffineTransform;\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.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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/CloudFactory.java
new file mode 100644 (file)
index 0000000..6489501
--- /dev/null
@@ -0,0 +1,193 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\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.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.BorderColorImpl;\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.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+\r
+public class CloudFactory extends SysdynElementFactory {\r
+\r
+    public static final double       CLOUD_SIZE_X  = 2.5;\r
+    public static final double       CLOUD_SIZE_Y  = 1.7;\r
+    public static final double       CLOUD_CURVES  = 7;\r
+\r
+    private static final BasicStroke    STROKE           = new BasicStroke(1f);\r
+    public static final Image       CLOUD_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
+    public static ElementClass createElementClass(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(CLOUD_IMAGE),\r
+                StaticSymbolImageInitializer.INSTANCE,\r
+                CloudSceneGraph.INSTANCE,\r
+                HoverImpl.INSTANCE,\r
+                BoundsOutline.INSTANCE,\r
+                new BorderColorImpl(Color.BLACK),\r
+                new WholeElementTerminals(terminals)\r
+        ).setId(CloudFactory.class.getSimpleName());\r
+    }\r
+    \r
+    @Override\r
+    public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e)\r
+            throws DatabaseException {\r
+        super.load(graph, canvas, diagram, element, e);\r
+        e.setHint(ElementHints.KEY_BORDER_COLOR, e.getHint(ElementHints.KEY_TEXT_COLOR));\r
+    }\r
+\r
+    @Override\r
+    protected ElementClass compileElementClass(Resource elementType, Collection<ObjectTerminal> terminals) {\r
+        return createElementClass(elementType, terminals);\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, "CLOUD_NODE");\r
+        \r
+        private IHintListener hoverHintListener;\r
+\r
+        @Override\r
+        public void init(IElement e, G2DParentNode parent) {\r
+            \r
+            HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "cloud", HoverShapeNode.class);\r
+            \r
+            AffineTransform at = ElementUtils.getTransform(e);\r
+            \r
+            node.setStroke(STROKE);\r
+            node.setScaleStroke(true);\r
+            node.setColor(ElementUtils.getBorderColor(e, Color.BLACK));\r
+            node.setShape(getCloudShape());\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
+                    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(CLOUD_IMAGE.getBounds());\r
+            return size;\r
+        }\r
+\r
+        @Override\r
+        public boolean handleMouseEvent(IElement e, ICanvasContext ctx, MouseEvent me) {\r
+            if (me instanceof MouseEnterEvent) {\r
+               e.setHint(ElementHints.KEY_HOVER, true);\r
+                return false;\r
+            } else if (me instanceof MouseExitEvent) {\r
+               e.setHint(ElementHints.KEY_HOVER, 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/elements/ComponentNameSynchronizer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ComponentNameSynchronizer.java
new file mode 100644 (file)
index 0000000..0e47ca9
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.exception.DatabaseException;\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.layer0.Layer0;\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
+            Layer0 l0;\r
+                       try {\r
+                               l0 = Layer0.getInstance(session);\r
+                   ModelingResources mr = session.getService(ModelingResources.class);\r
+                   return queue.offer(new RelatedPropertyModification(object, mr.ElementToComponent, l0.HasName, l0.String, newValue, Bindings.STRING), null);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+        }\r
+        return false;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ConfigurationDiagramClassAdapter.java
new file mode 100644 (file)
index 0000000..e562ff3
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.adaption.ResourceAdapter;\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 ResourceAdapter<DiagramClass> {\r
+\r
+    @Override\r
+    public void adapt(AsyncReadGraph g, Resource source, 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/elements/HoverShapeNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/HoverShapeNode.java
new file mode 100644 (file)
index 0000000..3cc5b2f
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.AlphaComposite;\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Composite;\r
+import java.awt.Graphics2D;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\r
+\r
+import org.simantics.scenegraph.ISelectionPainterNode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+\r
+public class HoverShapeNode extends ShapeNode implements ISelectionPainterNode {\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
+        Color oldColor = g2d.getColor();\r
+        BasicStroke oldStroke = (BasicStroke)g2d.getStroke();\r
+        Composite oldComposite = g2d.getComposite();\r
+        \r
+        boolean selected = NodeUtil.isSelected(this, 1);\r
+        if (selected) {\r
+            float lineWidth = oldStroke.getLineWidth() * 5;\r
+            g2d.setStroke(new BasicStroke(lineWidth < 1.0f ? lineWidth : 1.0f));\r
+               g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));\r
+               g2d.setColor(Color.RED);\r
+            g2d.draw(s);\r
+            g2d.setColor(oldColor);\r
+        }\r
+        \r
+        if(!selected && hover) {\r
+            g2d.setColor(Color.LIGHT_GRAY);\r
+            float lineWidth = oldStroke.getLineWidth() * 5;\r
+            g2d.setStroke(new BasicStroke(lineWidth < 1.0f ? lineWidth : 1.0f));\r
+            g2d.draw(s);\r
+\r
+        }\r
+\r
+        g2d.setColor(oldColor);\r
+        g2d.setStroke(oldStroke);\r
+        g2d.setComposite(oldComposite);\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/elements/Input.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Input.java
new file mode 100644 (file)
index 0000000..54f83d4
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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/elements/InputFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/InputFactory.java
new file mode 100644 (file)
index 0000000..b19f43d
--- /dev/null
@@ -0,0 +1,239 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\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.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.layer0.Layer0;\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
+    public 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(-6, -1);\r
+        path.lineTo(-1, -1);\r
+        path.lineTo(-1, -2.5);\r
+        path.lineTo(1.5, 0);\r
+        path.curveTo(1.5, -2.5, 6.5, -2.5, 6.5, 0);\r
+        path.curveTo(6.5, 2.5, 1.5, 2.5, 1.5, 0);\r
+        path.lineTo(-1, 2.5);\r
+        path.lineTo(-1, 1);\r
+        path.lineTo(-6, 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.CENTER, 0, 1.5, 1.5, true),\r
+                BoundsOutline.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,                    \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
+        Layer0 l0 = Layer0.getInstance(graph);\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.Variable_isHeadOf);\r
+        if(dependency != null) {\r
+            refersTo = graph.getPossibleObject(dependency, sr.Dependency_refersTo);\r
+            if(refersTo != null) {\r
+                referenceName = (String) graph.getPossibleRelatedValue(refersTo, l0.HasName);\r
+                module = graph.getPossibleObject(dependency, sr.Variable_HasTail);\r
+                moduleName = (String) graph.getPossibleRelatedValue(module, l0.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.getPossibleRelatedValue(runtime, dr.RuntimeDiagram_HasVariable);\r
+            if(variable == null)\r
+               return;\r
+            \r
+            \r
+            try {\r
+               Variable v = Variables.getVariable(graph, variable);\r
+               if(v != null) {\r
+                       module = v.getRepresents(graph);\r
+               }\r
+               if(module != null)\r
+                       for(Resource dep : graph.getObjects(module, sr.Variable_isHeadOf)) {\r
+                               Resource reference = graph.getPossibleObject(dep, sr.Dependency_refersTo);\r
+                               if(reference!= null && reference.equals(component)) {\r
+                                       refersTo = graph.getSingleObject(dep, sr.Variable_HasTail);\r
+                                       referenceName = (String) graph.getPossibleRelatedValue(refersTo, l0.HasName);\r
+                                       Variable parent = null;\r
+                                       parent = v.getParent(graph);\r
+                                       Resource represents = parent.getRepresents(graph);\r
+                                       if(parent != null && !graph.isInstanceOf(represents, sr.Configuration) && !graph.isInstanceOf(represents, sr.Experiment_Run)) {\r
+                                               moduleName = parent.getName(graph);\r
+                                       }\r
+                                       break;\r
+                               }\r
+                       }\r
+            } catch (MissingVariableException mve) {\r
+               // DO nothing.\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());\r
+        ElementUtils.setTextFont(e, font);\r
+    }\r
+\r
+\r
+    public static class InputSceneGraph extends SysdynTextElementNoBounds 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, double borderWidth, double paddingX, double paddingY, boolean editable) {\r
+            super(originX, originY, horizontalAlignment, borderWidth, paddingX, paddingY, editable);\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, originY, 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
+                // Use affinetransform to move the name of the valve below the valve symbol\r
+                AffineTransform at2 = (AffineTransform) at.clone();\r
+                at2.translate(0, font.getSize2D() * scale);\r
+                node.setTransform(at2);\r
+            }\r
+            \r
+            unflipText(e);\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
+            \r
+            if(reference != null) {\r
+               /* Only the main text box as bounds\r
+                if (reference.getBoundsInLocal().getWidth() > size.getWidth())\r
+                    size.setRect(size.getX(), size.getY(), reference.getBoundsInLocal().getWidth(), size.getHeight());\r
+                */\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/elements/LoopClockwise.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopClockwise.java
new file mode 100644 (file)
index 0000000..19cf448
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+\r
+public class LoopClockwise implements ElementHandler {\r
+\r
+       private static final long serialVersionUID = -5104770127548577905L;\r
+       \r
+       public static final LoopClockwise INSTANCE = new LoopClockwise();\r
+    \r
+    public String getTextLocation(IElement e) {\r
+        return e.getHint(SysdynElementHints.KEY_LOOP_CLOCKWISE);\r
+    }\r
+\r
+    \r
+    public void setTextLocation(IElement e, Boolean clockwise) {\r
+        if (clockwise != null)\r
+            e.setHint(SysdynElementHints.KEY_LOOP_CLOCKWISE, clockwise);\r
+        else\r
+            e.removeHint(SysdynElementHints.KEY_LOOP_CLOCKWISE);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopFactory.java
new file mode 100644 (file)
index 0000000..2498e4a
--- /dev/null
@@ -0,0 +1,384 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Paint;\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Arc2D;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Point2D;\r
+import java.awt.geom.RectangularShape;\r
+import java.util.Collection;\r
+\r
+import org.simantics.databoard.Bindings;\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.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.ITextListener;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.DiagramUtils;\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.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.HandleMouseEvent;\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.elementclass.ImageClass.StaticImageElementHandler;\r
+import org.simantics.g2d.image.DefaultImages;\r
+import org.simantics.g2d.image.Image;\r
+import org.simantics.g2d.image.impl.ShapeImage;\r
+import org.simantics.g2d.svg.SVGImage;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
+import org.simantics.scenegraph.g2d.nodes.SVGNode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.LoopTab;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.sysdyn.utils.LoopUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+\r
+/**\r
+ * Factory for loops.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ */\r
+public class LoopFactory extends SysdynElementFactory {\r
+\r
+       public static final Image LOOP_STATIC_IMAGE = new ShapeImage(getLoopShape(), null, new BasicStroke(1), true);\r
+       private static Image image = null;\r
+\r
+       @Override\r
+       public ElementClass create(ReadGraph graph, ICanvasContext canvas,\r
+                       IDiagram diagram, Resource elementType) throws DatabaseException {\r
+\r
+               // Create the loop symbol svg image\r
+               G2DResource g2d = G2DResource.getInstance(graph);\r
+               String svgDoc = graph.getPossibleRelatedValue(elementType, g2d.HasSVGDocument);\r
+               String id = "TextElement: " + NameUtils.getSafeName(graph, elementType);\r
+               if (svgDoc != null)\r
+                       image = new SVGImage(id+".svg", svgDoc);\r
+               else\r
+                       image = DefaultImages.ERROR_DECORATOR.get();\r
+\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(image),\r
+                               StaticSymbolImageInitializer.INSTANCE,\r
+                               LoopSceneGraph.INSTANCE,\r
+                               new LoopImageSceneGraph(image),\r
+                               HoverImpl.INSTANCE,\r
+                               BoundsOutline.INSTANCE,\r
+                               LoopClockwise.INSTANCE\r
+        ).setId(LoopFactory.class.getSimpleName());\r
+       }\r
+\r
+       static Shape getLoopShape() {\r
+               // Used in shortcut.\r
+               double x0 = 5, y0 = 2;\r
+               Path2D loop = new Path2D.Double();\r
+               loop.moveTo(x0 + 1, y0 + 2);\r
+               loop.lineTo(x0 + 0, y0 + 0);\r
+               loop.lineTo(x0  -1, y0 + 2);\r
+               loop.closePath();\r
+\r
+               loop.append(new Arc2D.Double(x0 -10, y0 -3, 10, 10, 0, -270, Arc2D.OPEN), false);\r
+               return loop;\r
+       }\r
+\r
+       @Override\r
+       protected String getText(ReadGraph graph, Resource element) throws DatabaseException {\r
+               // Get loop comment instead of loop name.\r
+               SysdynResource sr = SysdynResource.getInstance(graph); \r
+               ModelingResources mr = ModelingResources.getInstance(graph);\r
+               Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+               String text = null;\r
+               if (component != null) {\r
+                       text = (String) graph.getPossibleRelatedValue(component, sr.Loop_Comment);\r
+               }\r
+               if (text == null)\r
+                       text = "";\r
+               else if (LoopTab.AUTO.equals(text)) {\r
+                       switch (LoopUtils.getLoopType(graph, component)) {\r
+                       case BALANCING:\r
+                               text = "B";\r
+                               break;\r
+                       case REINFORCING:\r
+                               text = "R";\r
+                               break;\r
+                       default:\r
+                               text = "";\r
+                       }\r
+               }\r
+               return text;\r
+       }\r
+\r
+       @Override\r
+       protected ElementClass compileElementClass(Resource elementType,\r
+                       Collection<ObjectTerminal> terminals) {\r
+               return null;\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
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Boolean clockwise = graph.getPossibleRelatedValue(element, sr.LoopSymbol_Clockwise, Bindings.BOOLEAN);\r
+        if(clockwise == null) {\r
+            clockwise = Boolean.TRUE;\r
+        }\r
+        SysdynElementUtils.setLoopClockwise(e, clockwise);\r
+    }\r
+    \r
+    \r
+\r
+       /**\r
+        * Handling for the loop image on diagram.\r
+        * @author Tuomas Miettinen\r
+        *\r
+        */\r
+       public static class LoopImageSceneGraph extends StaticImageElementHandler {\r
+\r
+               private static final long serialVersionUID = -185893525553743589L;\r
+               \r
+               private IHintListener hoverHintListener;\r
+               \r
+               private static final Key            NODE             = new SceneGraphNodeKey(LoopNode.class, "LOOP_NODE");\r
+\r
+               public LoopImageSceneGraph(Image i) {\r
+                       super(i);\r
+               }\r
+\r
+               @Override\r
+               public void init(IElement e, G2DParentNode parent) {\r
+                       super.init(e, parent);\r
+\r
+                       // Create new hover shape node for the loop image\r
+                       final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopHover", LoopNode.class);\r
+                       \r
+                       // Mirror the image if clockwise is selected.\r
+                       Boolean clockwise = e.getHint(SysdynElementHints.KEY_LOOP_CLOCKWISE);\r
+                       SVGNode image = e.getHint(getNodeKey());\r
+                       if (clockwise != null && clockwise) {\r
+               Point2D imageParent = (Point2D) image.localToParent(new Point2D.Double(0.0,0.0)).clone();\r
+               AffineTransform at = new AffineTransform(-1.0, 0.0, 0.0, 1.0, imageParent.getX()+12.34, imageParent.getY());\r
+               image.setTransform(at);\r
+                       }\r
+                       \r
+                       // Set the shape of the shape node to match the shape of the image\r
+                       RectangularShape bounds = (RectangularShape)image.getBounds().clone();\r
+                       node.setShape(bounds);\r
+                                               \r
+                       // Set the shape node transparent\r
+                       Paint paint = new Color(0,0,0,0);\r
+                       node.setColor(paint);\r
+                       \r
+                       // Handle hover\r
+                       Boolean hover = e.getHint(ElementHints.KEY_HOVER); \r
+                       node.setHover(hover != null ? hover : false);\r
+                       hoverHintListener = new IHintListener() {\r
+\r
+                               @Override\r
+                               public void hintRemoved(IHintObservable sender, Key key, Object oldValue) {\r
+                               }\r
+\r
+                               @Override\r
+                               public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+                                       IElement e = (IElement)sender;\r
+                                       LoopNode shape = (LoopNode) 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
+                       super.cleanup(e);\r
+                       e.removeHintListener(hoverHintListener);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Handling for the text box of loop in diagram.\r
+        * @author Tuomas Miettinen\r
+        *\r
+        */\r
+       public static class LoopSceneGraph extends SysdynTextElementNoBounds  implements HandleMouseEvent {\r
+\r
+               private static final long serialVersionUID = -5093461687773246286L;\r
+\r
+               public static final LoopSceneGraph INSTANCE         = new LoopSceneGraph();\r
+               \r
+               private static final Key            NODE             = new SceneGraphNodeKey(ShapeNode.class, "LOOP_COMMENT_NODE");\r
+        \r
+               public LoopSceneGraph() {\r
+                       super(0, 0, Alignment.CENTER, 0, 1, 1, true);\r
+               }\r
+               \r
+               @Override\r
+               public void init(IElement e, G2DParentNode parent) {\r
+                       super.init(e, parent);\r
+                       \r
+                       // Move the text box into (around) the middle of the loop image\r
+                       AffineTransform at = ElementUtils.getTransform(e);\r
+                       final LoopNode node = ElementUtils.getOrCreateNode(e, parent, NODE, "loopComment", LoopNode.class);\r
+\r
+                       // Unflip the text and image\r
+                       unflipText(e);\r
+\r
+                       if(at != null) {\r
+                               node.setTransform(at);\r
+\r
+                               TextNode name = (TextNode) e.getHint(SG_NODE);\r
+                               if(name != null) {\r
+                                       AffineTransform at2 = (AffineTransform) at.clone();\r
+                                       at2.translate(getXCoordShift(e), getYCoordShift(e));\r
+\r
+                                       Alignment alignment = Alignment.CENTER;\r
+\r
+                                       name.setTransform(at2);\r
+                                       if(alignment != null) {\r
+                                               name.setHorizontalAlignment((byte) alignment.ordinal());\r
+                                               name.setVerticalAlignment((byte) alignment.ordinal());\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               private static double getXCoordShift(IElement e) {\r
+                       //String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+                       return 6.3;\r
+               }\r
+\r
+               private static double getYCoordShift(IElement e) {\r
+                       //String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+                       return -0.3;\r
+               }\r
+\r
+               @Override\r
+               protected <T extends SysdynTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
+                       return new Callback<T>() {\r
+                               @Override\r
+                               public void run(T node) {\r
+                                       node.setTextListener(new ITextListener() {\r
+\r
+                                               Resource component;\r
+\r
+                                               @Override\r
+                                               public void textChanged() {\r
+                                               }\r
+\r
+                                               @Override\r
+                                               public void textEditingStarted() {\r
+                                                       if(component != null) return;\r
+\r
+                                                       Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+                                                       if(o != null && o instanceof Resource) {\r
+                                                               final Resource element = (Resource)o;\r
+                                                               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                                                                       @Override\r
+                                                                       public void run(ReadGraph graph) throws DatabaseException {\r
+                                                                               component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent);\r
+                                                                       }\r
+                                                               });\r
+                                                       }\r
+                                               }\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
+\r
+                                               @Override\r
+                                               public void textEditingEnded() {\r
+                                                       TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                                                       if (node == null)\r
+                                                               return;\r
+\r
+                                                       // Write the changed comment of the loop\r
+                                                       final String text = node.getText();\r
+                                                       try {\r
+                                                               SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                                                       @Override\r
+                                                                       public void perform(WriteGraph graph)\r
+                                                                                       throws DatabaseException {\r
+                                                                               if (component != null) {\r
+                                                                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                                                       graph.deny(component, sr.Loop_Comment);\r
+                                                                                       graph.claimLiteral(component, sr.Loop_Comment, text);\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                               });\r
+                                                       } catch (DatabaseException e1) {\r
+                                                               e1.printStackTrace();\r
+                                                       }\r
+\r
+                                                       IDiagram diagram = ElementUtils.getDiagram(e);\r
+                                                       DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
+                                                       endEdit(node);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       };\r
+               }\r
+\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/LoopNode.java
new file mode 100644 (file)
index 0000000..865ddf6
--- /dev/null
@@ -0,0 +1,241 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 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.Graphics2D;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.elements.DiagramNodeUtil;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.ParentNode;\r
+import org.simantics.scenegraph.g2d.IG2DNode;\r
+import org.simantics.scenegraph.g2d.nodes.ConnectionNode;\r
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Node for Sysdyn loop elements.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class LoopNode extends HoverShapeNode {\r
+\r
+       /**\r
+        * Interface for nodes that can be part of loops\r
+        * @author Tuomas Miettinen\r
+        *\r
+        */\r
+       public interface ILoopComponentNode {\r
+               \r
+               /**\r
+                * Sets or resets the loop selected status\r
+                * @param loop The loop which has been selected\r
+                * @param selected true iff the loop is selected\r
+                */\r
+               public void setLoopSelected(LoopNode loop, boolean selected);\r
+               \r
+       }\r
+       \r
+       public static Color HIGHLIGHT_COLOR = Color.decode("#ff5fbf");\r
+       \r
+       private boolean selected = false;\r
+       \r
+       private static final long serialVersionUID = 6173159124691715569L;\r
+       \r
+       @Override\r
+    public void render(Graphics2D g2d) {\r
+               super.render(g2d);\r
+               \r
+               // If the loop is selected, highlight also the elements that belong to the loop.\r
+               boolean selected = NodeUtil.isSelected(this, 1);\r
+               // Do nothing if the selection is and was off.\r
+               if (selected || this.selected != selected) {\r
+                       this.selected = selected; \r
+                       // Tell all items belonging to the loop that the loop is selected.\r
+                       setLoopItemsSelected();\r
+               }\r
+       }\r
+       \r
+       private void setLoopItemsSelected() {\r
+               // Get all variables and dependencies in the loop.\r
+               List<Resource> loopItems = getAllLoopItems();\r
+               \r
+               // Get the diagram where this loop is.\r
+               RTreeNode diagramNode = (RTreeNode)NodeUtil.getNearestParentOfType(this, RTreeNode.class);\r
+               if (diagramNode == null)\r
+                       return;\r
+               \r
+               // Go through all elements on the diagram where this loop is.\r
+               Collection<IG2DNode> children = diagramNode.getNodes();\r
+               Iterator<IG2DNode> it = children.iterator();\r
+               while (it.hasNext()) {\r
+                       IG2DNode n = it.next();\r
+                       \r
+                       // Get the respective node \r
+                       INode child = getNodeOfPossibleLoopComponentNode(n);\r
+                       if (child instanceof ILoopComponentNode) {\r
+                               ILoopComponentNode ln = (ILoopComponentNode)child;\r
+                               // Get the respective element \r
+                               IElement e = DiagramNodeUtil.getElement((IG2DNode)child.getParent());\r
+                               // Get the respective resource \r
+                               Resource r = e.getHint(ElementHints.KEY_OBJECT);\r
+                               // If the node belongs to the loop, tell it that whether the loop is selected or not.\r
+                               ln.setLoopSelected(this, NodeUtil.isSelected(this, 1) && loopItems.contains(r));\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the ILoopComponentNode under the variable, dependency, or flow. \r
+        * @param n node under which the ILoopComponentNode is sought\r
+        * @return ILoopComponentNode or null, if there is not any.\r
+        */\r
+       private static INode getNodeOfPossibleLoopComponentNode(IG2DNode n) {\r
+               // Get all nodeIds of n's children.\r
+               Collection<String> nodeIds = ((ParentNode<?>)n).getNodeIds();\r
+\r
+               // Flows and SysdynTextNodes\r
+               for (String id : nodeIds) {\r
+                       if ("text".equals(id)\r
+                                       || id.startsWith("flow_")) \r
+                               return ((ParentNode<?>)n).getNode(id);\r
+               }\r
+\r
+               // Dependencies\r
+               if (n instanceof ConnectionNode) {\r
+                       // See the if a child of n has a DependencyNode as a child.\r
+                       Iterator<IG2DNode> it = ((ConnectionNode) n).getNodes().iterator();\r
+                       while (it.hasNext()) {\r
+                               n = it.next();\r
+                               if (n instanceof ParentNode<?>) {\r
+                                       nodeIds = ((ParentNode<?>)n).getNodeIds();\r
+                                       for (String id : nodeIds) {\r
+                                               if (id.startsWith("edge_"))\r
+                                                       return ((ParentNode<?>)n).getNode(id);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               return null; // n was no variable, dependency, or flow\r
+\r
+       }\r
+\r
+       /**\r
+        * Get all variables and dependencies in the loop.\r
+        * @return A list where the items are, in unspecified order.\r
+        */\r
+       private List<Resource> getAllLoopItems() {\r
+               IElement loopElement = DiagramNodeUtil.getElement(this);\r
+               final Resource loopSymbolResource = loopElement.getHint(ElementHints.KEY_OBJECT);\r
+               List<Resource> loopItems = Collections.emptyList();\r
+               \r
+               try {\r
+                       loopItems = SimanticsUI.getSession().syncRequest(new Read<List<Resource>>(){\r
+\r
+                               @Override\r
+                               public List<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                                       ModelingResources mod = ModelingResources.getInstance(graph);\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Resource loopComponentResource = graph.getPossibleObject(loopSymbolResource, mod.ElementToComponent);\r
+                                       if (loopComponentResource == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       Resource loopResource = graph.getPossibleObject(loopComponentResource, sr.Loop_Items);\r
+                                       if (loopResource == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       List<Resource> loopItems = ListUtils.toPossibleList(graph, loopResource);\r
+                                       if (loopItems == null)\r
+                                               return Collections.emptyList();\r
+                                       \r
+                                       ArrayList<Resource> dependencyItems = new ArrayList<Resource>();\r
+                                       \r
+                                       // Add dependencies and flows.\r
+                                       for (int i = 0; i < loopItems.size(); ++i) {\r
+                                       boolean skipBackwardFlows = false;\r
+                                       \r
+                                       // Go through forward dependencies and flows\r
+                                       Collection<Resource> forwardDependencies = graph.getObjects(loopItems.get(i), sr.Variable_isTailOf);\r
+                                       \r
+                                       // And also through the forward dependencies of possible shadows.\r
+                                       Collection<Resource> shadows = graph.getObjects(loopItems.get(i), sr.Shadow_original_Inverse);\r
+                                       for (Resource shadow : shadows)\r
+                                               forwardDependencies.addAll(graph.getObjects(shadow, sr.Variable_isTailOf));\r
+                                               \r
+                                       for (Resource dependency : forwardDependencies) {\r
+                                               Resource dependingVariable = graph.getSingleObject(dependency, sr.Variable_HasHead);\r
+                                               if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size()))) {\r
+                                                       if (graph.isInstanceOf(dependency, sr.Flow)\r
+                                                                       && graph.isInstanceOf(loopItems.get(i), sr.Stock)) {\r
+                                                               // Flows from stocks don't count. \r
+                                                               continue;\r
+                                                       }\r
+                                                       skipBackwardFlows = true;\r
+                                                       dependencyItems.add(graph.getSingleObject(dependency, mod.ConnectionToDiagramConnection));\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       if (skipBackwardFlows)\r
+                                               continue;\r
+                                       \r
+                                       // Backward flows from stocks.\r
+                                       Collection<Resource> backwardFlows = graph.getObjects(loopItems.get(i), sr.Variable_isHeadOf);\r
+                                               for (Resource flow : backwardFlows) {\r
+                                                       if (graph.isInstanceOf(flow, sr.Flow)) {\r
+                                                               Resource dependingVariable = graph.getSingleObject(flow, sr.Variable_HasTail);\r
+                                                               if (dependingVariable.equals(loopItems.get((i + 1) % loopItems.size()))\r
+                                                                               && graph.isInstanceOf(dependingVariable, sr.Stock)) {\r
+                                                                       dependencyItems.add(graph.getSingleObject(flow, mod.ConnectionToDiagramConnection));\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                               }\r
+                                       \r
+                                       // Convert variables from component to element.\r
+                                       for (int i = 0; i < loopItems.size(); ++i) {\r
+                                               loopItems.set(i, graph.getPossibleObject(loopItems.get(i), mod.ComponentToElement));\r
+                                       }\r
+                                       // Merge the two lists.\r
+                                       loopItems.addAll(dependencyItems);\r
+                                       \r
+                                       return loopItems;\r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       // TODO Auto-generated catch block\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+               return loopItems;\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleFactory.java
new file mode 100644 (file)
index 0000000..175a95d
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\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.diagram.elements.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextNode;\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.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.impl.BorderColorImpl;\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
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+\r
+public class ModuleFactory extends SysdynElementFactory {\r
+\r
+    private static final BasicStroke    STROKE           = new BasicStroke(2.0f);\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 ModuleSceneGraph(0, 0, Alignment.CENTER, 1f , 2, 3, true),\r
+                BoundsOutline.INSTANCE,\r
+                new BorderColorImpl(Color.BLACK),\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,                   \r
+                new WholeElementTerminals(terminals)\r
+        ).setId(ModuleFactory.class.getSimpleName());\r
+    }\r
+    \r
+    \r
+    public static class ModuleSceneGraph extends SysdynTextElementHandler implements InternalSize {\r
+\r
+               private static final long       serialVersionUID = 2367230056477661273L;\r
+        \r
+               public ModuleSceneGraph(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
+               \r
+               \r
+               @Override\r
+               protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {\r
+            return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", ModuleNode.class, getCallback(e, parent, ModuleNode.class));\r
+               }\r
+\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ModuleNode.java
new file mode 100644 (file)
index 0000000..f2431be
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.AlphaComposite;\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Composite;\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.scenegraph.utils.GeometryUtils;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+\r
+public class ModuleNode extends SysdynTextNode {\r
+\r
+       private static final long serialVersionUID = 8535695797227320496L;\r
+    private static double              CORNER_LENGTH    = 2.0; \r
+    private static double              CORNER_PADDING   = 0.8; \r
+    \r
+    \r
+    @Override\r
+    public void render(Graphics2D g) {\r
+       super.render(g);\r
+       \r
+        BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+        Color oldColor = g.getColor();\r
+\r
+        Rectangle2D bounds = getBounds();\r
+\r
+        \r
+        Path2D path = new Path2D.Double();\r
+        // LEFT TOP\r
+        path.moveTo(bounds.getMinX() + CORNER_LENGTH, bounds.getMinY() - CORNER_PADDING);\r
+        path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMinY() - CORNER_PADDING);\r
+        path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMinY() + CORNER_LENGTH);\r
+        \r
+        // LEFT BOTTOM\r
+        path.moveTo(bounds.getMinX() + CORNER_LENGTH, bounds.getMaxY() + CORNER_PADDING);\r
+        path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMaxY() + CORNER_PADDING);\r
+        path.lineTo(bounds.getMinX() - CORNER_PADDING, bounds.getMaxY() - CORNER_LENGTH);\r
+        \r
+        // RIGHT TOP\r
+        path.moveTo(bounds.getMaxX() - CORNER_LENGTH, bounds.getMinY() - CORNER_PADDING);\r
+        path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMinY() - CORNER_PADDING);\r
+        path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMinY() + CORNER_LENGTH);\r
+        \r
+        // RIGHT BOTTOM\r
+        path.moveTo(bounds.getMaxX() - CORNER_LENGTH, bounds.getMaxY() + CORNER_PADDING);\r
+        path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() + CORNER_PADDING);\r
+        path.lineTo(bounds.getMaxX() + CORNER_PADDING, bounds.getMaxY() - CORNER_LENGTH);\r
+        \r
+        g.setStroke(new BasicStroke((float) (/*scale**/scale*borderWidth)));       \r
+        g.setColor(borderColor);\r
+        g.draw(path);   \r
+        \r
+        \r
+        boolean selected = NodeUtil.isSelected(this, 1);\r
+        if (selected && showsSelection()) {\r
+            Composite oc = g.getComposite();\r
+            g.setComposite(AlphaComposite.SrcOver.derive(0.5f));\r
+\r
+            g.setColor(Color.RED);\r
+            float bw = borderWidth;\r
+            double s = GeometryUtils.getScale(g.getTransform());\r
+            if (bw <= 0f) {\r
+                bw = (float) (1f / s);\r
+            } else {\r
+                bw *= 3f * scale;\r
+            }\r
+            g.setStroke(new BasicStroke(bw));\r
+            g.draw(path);\r
+\r
+            g.setComposite(oc);\r
+        }\r
+\r
+        g.setColor(oldColor);\r
+        g.setStroke(oldStroke);\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/MultilineTextElementFactory.java
new file mode 100644 (file)
index 0000000..d6b56d0
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.adapter.TextElementClassFactory;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+\r
+/**\r
+ * Multi-line text element used in comment in sysdyn diagrams\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class MultilineTextElementFactory extends TextElementClassFactory {\r
+\r
+    @Override\r
+    public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource element, IElement e)\r
+            throws DatabaseException {\r
+        super.load(graph, canvas, diagram, element, e);\r
+        e.setHint(ElementHints.KEY_RESIZABLE, true);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Orientation.java
new file mode 100644 (file)
index 0000000..dbf3257
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+\r
+public class Orientation implements ElementHandler {\r
+\r
+    private static final long serialVersionUID = 958120463924210936L;\r
+    \r
+    public static final Orientation INSTANCE = new Orientation();\r
+    \r
+    public String getOrientation(IElement e) {\r
+        return e.getHint(SysdynElementHints.KEY_ORIENTATION);\r
+    }\r
+\r
+    \r
+    public void setOrientation(IElement e, String orientation) {\r
+        if (orientation != null)\r
+            e.setHint(SysdynElementHints.KEY_ORIENTATION, orientation);\r
+        else\r
+            e.removeHint(SysdynElementHints.KEY_ORIENTATION);\r
+    }\r
+}\r
+    \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/RectangleNode.java
new file mode 100644 (file)
index 0000000..1f05f54
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import org.simantics.scenegraph.g2d.G2DNode;\r
+\r
+public class RectangleNode extends G2DNode {\r
+       \r
+       private static final long serialVersionUID = 654692698101485672L;\r
+\r
+    protected Rectangle2D bounds = null;\r
+\r
+    @SyncField("bounds")\r
+    public void init(Rectangle2D bounds) {\r
+        this.bounds = bounds;\r
+    }\r
+\r
+    @Override\r
+    public void render(Graphics2D g) {\r
+        if(bounds == null) return;\r
+        AffineTransform ot = g.getTransform();\r
+        \r
+        g.transform(transform);\r
+        g.setColor(Color.BLACK);\r
+        double scale = g.getTransform().getScaleX();\r
+        g.setStroke(new BasicStroke( (float)(1.0 / scale) ));\r
+\r
+        g.draw(bounds);\r
+        g.setTransform(ot);\r
+    }\r
+\r
+       @Override\r
+       public Rectangle2D getBoundsInLocal() {\r
+               return bounds;\r
+       }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowFactory.java
new file mode 100644 (file)
index 0000000..726cae6
--- /dev/null
@@ -0,0 +1,129 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - 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.AffineTransform;\r
+import java.awt.geom.Ellipse2D;\r
+import java.awt.geom.Path2D;\r
+import java.util.Collection;\r
+\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.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextElementHandler;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\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.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
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ShadowFactory extends SysdynElementFactory {\r
+\r
+    private static TextElementHandler shadowHandler = new TextElementHandler(0, 0, Alignment.LEADING, 0.0, 2.0, 2.0, false); \r
+    private static final TextColorImpl GRAY = new TextColorImpl(java.awt.Color.GRAY);\r
+    private static final BasicStroke    STROKE          = new BasicStroke(1f);\r
+    public static final Image          GHOST_IMAGE     = new ShapeImage(getGhostShape(), null, STROKE, true);\r
+\r
+    static Shape getGhostShape() {\r
+        \r
+        Path2D path = new Path2D.Double();\r
+        \r
+        // Body\r
+        path.moveTo(-3, 3);\r
+        path.quadTo(-3, -3, 0, -3);\r
+        path.quadTo(3, -3, 3, 3);\r
+        path.lineTo(2, 2);\r
+        path.lineTo(1, 3);\r
+        path.lineTo(0, 2);\r
+        path.lineTo(-1, 3);\r
+        path.lineTo(-2, 2);\r
+        path.closePath();\r
+        \r
+        // Eyes\r
+        path.append(new Ellipse2D.Double(-1.25, -1.25, 0.5, 0.5), false);\r
+        path.append(new Ellipse2D.Double(0.75, -1.25, 0.5, 0.5), false);\r
+        return path;\r
+    }\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
+                GRAY,\r
+                TextFontImpl.DEFAULT,\r
+                DefaultTransform.INSTANCE,\r
+                new StaticObjectAdapter(elementType),\r
+                new StaticSymbolImpl(GHOST_IMAGE),\r
+                StaticSymbolImageInitializer.INSTANCE,\r
+                shadowHandler,\r
+                BoundsOutline.INSTANCE,\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,    \r
+                new WholeElementTerminals(terminals)\r
+        ).setId(ShadowFactory.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
+        Layer0 l0 = Layer0.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
+            SysdynResource SR = SysdynResource.getInstance(graph);\r
+            Resource original = graph.getPossibleObject(component, SR.Shadow_original);\r
+            if(original != null)\r
+                text = "< " + (String) graph.getPossibleRelatedValue(original, l0.HasName) + " >";\r
+        }\r
+        if (text == null)\r
+            text = "< --- >";\r
+\r
+        ElementUtils.setText(e, text);\r
+        \r
+        super.getVisualProperties(graph, element, e);\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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceDialogRunnable.java
new file mode 100644 (file)
index 0000000..6e1f7de
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.viewers.LabelProvider;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;\r
+import org.simantics.db.Resource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ShadowVariableReferenceDialogRunnable implements Runnable {\r
+\r
+    private Resource shadow;\r
+    private HashMap<String, Resource> possibleReferences;\r
\r
+    public ShadowVariableReferenceDialogRunnable(Resource shadow, HashMap<String, Resource> possibleReferences) {\r
+        this.shadow = shadow;\r
+        this.possibleReferences = possibleReferences;\r
+    }\r
+    \r
+    @Override\r
+    public void run() {\r
+        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+        \r
+        ElementListSelectionDialog dialog = \r
+                new ElementListSelectionDialog(shell, new LabelProvider());\r
+        dialog.setElements(possibleReferences.keySet().toArray(new String[possibleReferences.keySet().size()]));\r
+        dialog.setTitle("Select referred variable");\r
+        dialog.setMultipleSelection(false);\r
+        \r
+        dialog.open();\r
+        \r
+        Object[] result = dialog.getResult(); \r
+        \r
+        Resource resource = null;\r
+        if(result != null && result.length == 1)\r
+            resource = possibleReferences.get(result[0]);\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new ShadowVariableReferenceRequest(shadow, resource));\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ShadowVariableReferenceRequest.java
new file mode 100644 (file)
index 0000000..7fb80e8
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\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.layer0.util.RemoverUtil;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ShadowVariableReferenceRequest extends WriteRequest {\r
+    \r
+    Resource shadow;\r
+    Resource original;\r
+    \r
+    public ShadowVariableReferenceRequest(Resource shadow, Resource original) {\r
+        this.shadow = shadow;\r
+        this.original = original;\r
+    }\r
+\r
+    @Override\r
+    public void perform(WriteGraph graph) throws DatabaseException {\r
+        if(shadow == null)\r
+            return;\r
+        \r
+        if(shadow != null && original == null) {\r
+            Resource element = graph.getPossibleObject(shadow, ModelingResources.getInstance(graph).ComponentToElement);\r
+            RemoverUtil.remove(graph, element);\r
+        } else { \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        graph.claim(shadow, SR.Shadow_original, original);\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/Size.java
new file mode 100644 (file)
index 0000000..00b0d2f
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.element.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.LifeCycle;\r
+\r
+/**\r
+ * Class for internal size and setting default bounds when element is created. \r
+ * Used especially with comment elements (resizeable text elements)\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Size implements  InternalSize, LifeCycle {\r
+    private static final long serialVersionUID = -7459941323196171227L;\r
+    private Rectangle2D defaultBounds;\r
+    \r
+    public Size(Rectangle2D defaultSize) {\r
+        this.defaultBounds = defaultSize;\r
+    }\r
+    \r
+    /**\r
+     * Set default bounds for the created element\r
+     * @param e Element\r
+     */\r
+    @Override\r
+    public void onElementCreated(IElement e) {\r
+        e.setHint(ElementHints.KEY_BOUNDS, defaultBounds);\r
+    }\r
+    \r
+    /**\r
+     * Returns bounds of the element\r
+     */\r
+    @Override\r
+    public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+        if (size==null) size = new Rectangle2D.Double();\r
+        size.setFrame((Rectangle2D)e.getHint(ElementHints.KEY_BOUNDS));\r
+        return size;\r
+    }\r
+\r
+    @Override\r
+    public void onElementDestroyed(IElement e) {}\r
+    @Override\r
+    public void onElementActivated(IDiagram d, IElement e) {}\r
+    @Override\r
+    public void onElementDeactivated(IDiagram d, IElement e) {}\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        final int prime = 31;\r
+        int result = 1;\r
+        result = prime * result\r
+                + ((defaultBounds == null) ? 0 : defaultBounds.hashCode());\r
+        return result;\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
+        Size other = (Size) obj;\r
+        if (defaultBounds == null) {\r
+            if (other.defaultBounds != null)\r
+                return false;\r
+        } else if (!defaultBounds.equals(other.defaultBounds))\r
+            return false;\r
+        return true;\r
+    }    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/StockFactory.java
new file mode 100644 (file)
index 0000000..96b6895
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\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.ResizeRectangularSceneGraph;\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.IElement;\r
+import org.simantics.g2d.element.handler.impl.BorderColorImpl;\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
+    public static final Image STOCK_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(STOCK_IMAGE),\r
+                StaticSymbolImageInitializer.INSTANCE,\r
+                new SysdynTextElementHandler(0, 0, Alignment.CENTER, 1f, 1.0, 1.0, true),\r
+                BoundsOutline.INSTANCE,\r
+                new BorderColorImpl(Color.BLACK),\r
+                ResizeRectangularSceneGraph.INSTANCE,\r
+                RESIZE_PROPERTY_SETTER,    \r
+                new WholeElementTerminals(terminals)\r
+        ).setId(StockFactory.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
+        e.setHint(ElementHints.KEY_BORDER_COLOR, e.getHint(ElementHints.KEY_TEXT_COLOR));\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementClasses.java
new file mode 100644 (file)
index 0000000..a2cb04a
--- /dev/null
@@ -0,0 +1,8 @@
+package org.simantics.sysdyn.ui.elements;\r
+\r
+public class SysdynElementClasses {\r
+\r
+    public static final Object VALVE = new Object() {\r
+        public String toString() { return "VALVE"; }\r
+    };\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementFactory.java
new file mode 100644 (file)
index 0000000..a3c3be2
--- /dev/null
@@ -0,0 +1,211 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.eclipse.jface.preference.PreferenceConverter;\r
+import org.eclipse.jface.resource.StringConverter;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\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.elements.ElementPropertySetter;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPropertyExternalRead;\r
+import org.simantics.utils.datastructures.Pair;\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
+    public static final ElementPropertySetter RESIZE_PROPERTY_SETTER =\r
+            new ElementPropertySetter(ResizeRectangularSceneGraph.KEY_SG_NODE);\r
+    \r
+    protected String getText(ReadGraph graph, Resource element) throws DatabaseException {\r
+       Layer0 l0 = Layer0.getInstance(graph);\r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+        Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+        String text = null;\r
+        if (component != null) {\r
+            text = (String) graph.getPossibleRelatedValue(component, l0.HasName);\r
+        }\r
+        if (text == null)\r
+            text = "[empty]";\r
+               return text;\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
+        e.setHint(ElementHints.KEY_RESIZABLE, true);\r
+       ElementUtils.setText(e, getText(graph, element));\r
+       // Just testing loop finding.\r
+       //ModelingResources mr = ModelingResources.getInstance(graph);\r
+        //Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+        //ConfigurationUtils.getLoops(graph, component);\r
+        getVisualProperties(graph, element, e);\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
+    /**\r
+     * Reads a collection of visualization properties e.g. colour and font.\r
+     * @param graph ReadGraph\r
+     * @param element Element resource\r
+     * @param e Diagram element\r
+     * @throws DatabaseException\r
+     */\r
+    protected void getVisualProperties(ReadGraph graph, Resource element, IElement e) throws DatabaseException {\r
+        G2DResource g2d = G2DResource.getInstance(graph);\r
+        DiagramResource dr = DiagramResource.getInstance(graph);\r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+        \r
+        if (graph.isInstanceOf(element, dr.FontProvider)) {\r
+            Statement fontStatement = graph.getPossibleStatement(element, g2d.HasFont);\r
+            if(fontStatement != null && !fontStatement.isAsserted(element)) {\r
+                ElementUtils.setTextFont(e, G2DUtils.getFont(graph, fontStatement.getObject()));\r
+            } else {\r
+                String fontdata = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(element, SysdynDiagramPreferences.getFontPreferenceName(graph, element))));\r
+                if(fontdata != null) {\r
+                    FontData[] fdArray = PreferenceConverter.basicGetFontData(fontdata);\r
+                    if(fdArray != null) {\r
+                        if(fdArray.length == 1) {\r
+                            FontData fd = fdArray[0];\r
+                            if(fd != null) {\r
+                                Font font = new Font(fd.getName(), fd.getStyle(), fd.getHeight());\r
+                                e.setHint(ElementHints.KEY_FONT, font);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        if (graph.isInstanceOf(element, dr.ColorProvider)) {\r
+            Statement colorStatement = graph.getPossibleStatement(element, g2d.HasColor);\r
+            if(colorStatement != null && !colorStatement.isAsserted(element)) {\r
+                e.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, colorStatement.getObject()));\r
+            } else {\r
+                String color = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(element, SysdynDiagramPreferences.getColorPreferenceName(graph, element))));\r
+                if(color != null) {\r
+                    RGB rgb = StringConverter.asRGB(color, null);\r
+                    if(rgb != null) {\r
+                        Color c = new Color(rgb.red, rgb.green, rgb.blue);\r
+                        e.setHint(ElementHints.KEY_TEXT_COLOR, c);\r
+                        e.setHint(ElementHints.KEY_BORDER_COLOR, c);\r
+                    }\r
+                }\r
+\r
+            }\r
+        }\r
+\r
+        Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+        if (component != null && graph.hasStatement(component, SysdynResource.getInstance(graph).IsOutput)) {\r
+            Font font = ElementUtils.getTextFont(e);\r
+            font = font.deriveFont(font.isItalic() ? Font.ITALIC | Font.BOLD : Font.BOLD);\r
+            ElementUtils.setTextFont(e, font);\r
+        }\r
+        \r
+        double bounds[] = DiagramGraphUtil.getPossibleRelatedDoubleArray(graph, element, G2DResource.getInstance(graph).HasBounds);\r
+        if (bounds != null) {\r
+            e.setHint(ElementHints.KEY_BOUNDS, new Rectangle2D.Double(bounds[0], bounds[1], bounds[2], bounds[3]));\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public ElementClass create(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType)\r
+    throws DatabaseException {\r
+        return compileElementClass(elementType, createTerminals(graph, elementType));\r
+    }\r
+    \r
+    public static Collection<ObjectTerminal> createTerminals(ReadGraph graph, Resource elementType) {\r
+\r
+               try {\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
+               return terminals;\r
+               } catch (ManyObjectsForFunctionalRelationException e) {\r
+                       e.printStackTrace();\r
+               } catch (ServiceException e) {\r
+                       e.printStackTrace();\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\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/elements/SysdynElementHints.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementHints.java
new file mode 100644 (file)
index 0000000..fdd74d4
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.g2d.canvas.IToolMode;\r
+import org.simantics.g2d.canvas.impl.ToolMode;\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
+    public static final Key KEY_ORIENTATION = new KeyOf(String.class, "ORIENTATION");   \r
+    public static final Key KEY_LOCATION = new KeyOf(String.class, "LOCATION");     \r
+    public static final Key KEY_LOOP_CLOCKWISE = new KeyOf(Boolean.class, "LOOP_CLOCKWISE");     \r
+    \r
+    public static final Key       SYSDYN_KEY_TOOL = new KeyOf(ToolMode.class, "SysdynKeyTool");\r
+    public static final IToolMode DEPENDENCY_TOOL = new ToolMode("DependencyTool");\r
+    public static final IToolMode FLOW_TOOL       = new ToolMode("FlowTool");\r
+    public static final IToolMode LOCK_TOOL       = new ToolMode("LockTool");\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynElementUtils.java
new file mode 100644 (file)
index 0000000..f912495
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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
+        if(i != null)\r
+            i.setInputReference(e, inputReference);\r
+    }\r
+\r
+    public static String getInputReference(IElement e)\r
+    {\r
+        Input i = e.getElementClass().getSingleItem(Input.class);\r
+        if(i != null)\r
+            return i.getInputReference(e);\r
+        else\r
+            return null;\r
+    }\r
+\r
+    public static void setOrientation(IElement e, String orientation)\r
+    {\r
+        Orientation o = e.getElementClass().getSingleItem(Orientation.class);\r
+        if(o != null)\r
+            o.setOrientation(e, orientation);\r
+    }\r
+\r
+    public static String getOrientation(IElement e)\r
+    {\r
+        Orientation o = e.getElementClass().getSingleItem(Orientation.class);\r
+        if(o != null)\r
+            return o.getOrientation(e);\r
+        else\r
+            return null;\r
+    }\r
+    \r
+    public static void setValveTextLocation(IElement e, String location)\r
+    {\r
+        ValveTextLocation v = e.getElementClass().getSingleItem(ValveTextLocation.class);\r
+        if(v != null)\r
+            v.setTextLocation(e, location);\r
+    }\r
+\r
+    public static String getValveTextLocation(IElement e)\r
+    {\r
+        ValveTextLocation v = e.getElementClass().getSingleItem(ValveTextLocation.class);\r
+        if(v != null)\r
+            return v.getTextLocation(e);\r
+        else\r
+            return null;\r
+    }\r
+\r
+       public static void setLoopClockwise(IElement e, Boolean clockwise) {\r
+        LoopClockwise l = e.getElementClass().getSingleItem(LoopClockwise.class);\r
+        if(l != null)\r
+            l.setTextLocation(e, clockwise);\r
+       }\r
+\r
+    public static String getLoopClockwise(IElement e)\r
+    {\r
+       LoopClockwise l = e.getElementClass().getSingleItem(LoopClockwise.class);\r
+        if(l != null)\r
+            return l.getTextLocation(e);\r
+        else\r
+            return null;\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementHandler.java
new file mode 100644 (file)
index 0000000..408ff09
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT - initial API and implementation\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.diagram.elements.TextElementHandler;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.utils.Alignment;\r
+\r
+/**\r
+ * Version of {@link SysdynTextElementNoBounds} that supports InternalSize\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynTextElementHandler extends SysdynTextElementNoBounds implements InternalSize {\r
+    private static final long serialVersionUID = -1307413505370441178L;\r
+\r
+    public static SysdynTextElementHandler INSTANCE = new SysdynTextElementHandler();\r
+    \r
+    public SysdynTextElementHandler() {\r
+        super();\r
+    }\r
+\r
+    public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment) {\r
+        super(originX, originY, horizontalAlignment);\r
+    }\r
+\r
+    public SysdynTextElementHandler(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+        super(originX, originY, horizontalAlignment, borderWidth);\r
+    }\r
+\r
+    public SysdynTextElementHandler(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
+        Rectangle2D bounds = TextElementHandler.calculateBounds(e, size, horizontalAlignment, SCALE, paddingX, paddingX);\r
+        return bounds;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextElementNoBounds.java
new file mode 100644 (file)
index 0000000..3e2f4f5
--- /dev/null
@@ -0,0 +1,318 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT - initial API and implementation\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.Color;\r
+import java.awt.geom.AffineTransform;\r
+\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.ui.IWorkbenchPage;\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.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.elements.DiagramNodeUtil;\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.diagram.participant.SGFocusParticipant;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.chassis.SWTChassis;\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.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramViewer;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+\r
+/**\r
+ * TextElement for variables in Siamntics System Dynamics\r
+ * \r
+ * The main differences for the basic TextElementNoBounds are:\r
+ * 1. Text is never mirrored\r
+ * 2. Edit mode is activated when the variable is created\r
+ *  \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynTextElementNoBounds extends TextElementNoBounds {\r
+\r
+    private static final long serialVersionUID = -148784588840819612L;\r
+    \r
+    public static final Key ELEMENT_INITIALIZED = new KeyOf(Boolean.class, "SYSDYN_TEXT_ELEMENT_INITIALIZED");\r
+\r
+    // Constructors \r
+    public SysdynTextElementNoBounds() {\r
+        super(0, 0, Alignment.LEADING, 0);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment) {\r
+        super(originX, originY, horizontalAlignment, 0);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(double originX, double originY, Alignment horizontalAlignment, double borderWidth) {\r
+        super(originX, originY, horizontalAlignment, borderWidth);\r
+    }\r
+\r
+    public SysdynTextElementNoBounds(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
+    // End constructors\r
+\r
+    protected <T extends SysdynTextNode> Callback<T> getCallback(final IElement e, G2DParentNode parent, Class<T> nodeClass) {\r
+        return new Callback<T>() {\r
+            @Override\r
+            public void run(T node) {\r
+                node.setTextListener(new ITextListener() {\r
+\r
+                    String textBeforeEdit;\r
+                    Resource component;\r
+\r
+                    @Override\r
+                    public void textChanged() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if(!new VariableNameValidator().isValid(component, node.getText(), false)) {\r
+                            node.setColor(Color.RED);\r
+                        } else {\r
+                            node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                        }\r
+\r
+\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingStarted() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if (node == null)\r
+                               return;\r
+                        textBeforeEdit = node.getText();\r
+\r
+                        if(component != null) return;\r
+                        \r
+                        Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+                        if(o != null && o instanceof Resource) {\r
+                            final Resource element = (Resource)o;\r
+                            SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                                @Override\r
+                                public void run(ReadGraph graph) throws DatabaseException {\r
+                                    component = graph.getPossibleObject(element, ModelingResources.getInstance(graph).ElementToComponent);\r
+                                }\r
+                            });\r
+                        }\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingCancelled() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if (node != null) {\r
+                            if(new VariableNameValidator().isValid(component, node.getText(), false))\r
+                                node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                            endEdit(node);\r
+                        }\r
+                    }\r
+\r
+                    @Override\r
+                    public void textEditingEnded() {\r
+                        TextNode node = (TextNode) e.getHint(SG_NODE);\r
+                        if (node == null)\r
+                            return;\r
+                        String text = node.getText();\r
+                        if(!new VariableNameValidator().isValid(component, text, false)) {\r
+                            text = textBeforeEdit;\r
+                            node.setEditMode(false);\r
+                            node.setText(text);\r
+                            if(new VariableNameValidator().isValid(component, text, false))\r
+                                node.setColor(ElementUtils.getTextColor(e, Color.BLACK));\r
+                        } else {\r
+                            Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+                            final String textAfterEdit = text;\r
+                            if(o != null && o instanceof Resource) {\r
+                                SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                                    @Override\r
+                                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                                        Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf);\r
+                                        new VariableNameValidator().renameInAllEquations(graph, configuration, textBeforeEdit, textAfterEdit);\r
+                                    }\r
+                                });\r
+                            }\r
+                        }\r
+                        ElementUtils.setText(e, text);\r
+                        IDiagram diagram = ElementUtils.getDiagram(e);\r
+                        DiagramUtils.synchronizeHintsToBackend(diagram, e);\r
+                        endEdit(node);\r
+                    }\r
+                });\r
+            }\r
+        };\r
+    }\r
+    \r
+    /**\r
+     * Reverts any rotations that are assigned to the text element\r
+     * @param e\r
+     */\r
+    public static void unflipText(IElement e) {\r
+        Object o = e.getHint(SG_NODE);\r
+        if (o instanceof TextNode) {\r
+            TextNode text = (TextNode)o;\r
+            AffineTransform at = text.getTransform();\r
+            double x = at.getTranslateX();\r
+            double y = at.getTranslateY();\r
+            at.setToRotation(0);\r
+            at.setToTranslation(x, y);\r
+            at.setTransform(at);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Activates edit mode for a newly created variable. \r
+     * \r
+     * Sets focus for diagram if the variable was created by dragging from model browser.\r
+     * \r
+     * @param e\r
+     */\r
+    protected void activateEdit(final IElement e) {\r
+        final SysdynTextNode node = e.getHint(SG_NODE);\r
+        if(node == null)\r
+            return;\r
+        \r
+        final ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);\r
+        // FIXME: needed only because eventdelegator registrations are done before adding node to scene graph.\r
+        if (ctx == null)\r
+            return;\r
+        if (!node.isEditMode()) {\r
+            \r
+            // Get the active editor\r
+            IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+            final DiagramEditor editor = (DiagramEditor)page.getActiveEditor();\r
+            final ICanvasContext editorCtx = (ICanvasContext) editor.getViewer().getAdapter(ICanvasContext.class);\r
+\r
+            editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
+                    \r
+                @Override\r
+                public void run() {\r
+                    Control c = editor.getViewer().getComposite().getDisplay().getFocusControl();\r
+                    if (c == null || "BasicSymbols".equals(c.getParent().getToolTipText())) {\r
+                        // If the variable has been drag and dropped, set focus to diagram and then activate edit.\r
+                        \r
+                        editorCtx.add(new SGFocusParticipant((SWTChassis)editor.getViewer().getComposite(), DiagramViewer.DIAGRAMMING_CONTEXT) {\r
+                \r
+                            @Override\r
+                            public void focusGained(java.awt.event.FocusEvent event) {\r
+                                \r
+                                // When focus has been gained, acticate edit and destroy the listener.\r
+                                editor.getViewer().getComposite().getDisplay().asyncExec(new Runnable() {\r
+                                    \r
+                                    @Override\r
+                                    public void run() {\r
+                                        if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
+                                            node.activateEdit(0, e, ctx, true);\r
+                                            node.repaint();\r
+                                        }\r
+                                    }\r
+                                });\r
+                                ctx.remove(this);\r
+                            }\r
+                            \r
+                            @Override\r
+                            public void focusLost(java.awt.event.FocusEvent e) {\r
+                            }\r
+                        });\r
+                    \r
+                        editor.setFocus();\r
+                    } else {\r
+                        // If the variable has been created with shortcut key, just activate the edit.\r
+                        if (Boolean.TRUE.equals(node.setEditMode(true))) {\r
+                            node.activateEdit(0, e, ctx, true);\r
+                            node.repaint();\r
+                        }\r
+                    }\r
+                }\r
+            }); \r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected TextNode getOrCreateTextNode(IElement e, G2DParentNode parent) {\r
+        return ElementUtils.getOrCreateNode(e, parent, SG_NODE, "text", SysdynTextNode.class, getCallback(e, parent, SysdynTextNode.class));\r
+    }\r
+    \r
+    @Override\r
+    public void init(final IElement e, G2DParentNode parent) {\r
+        super.init(e, parent);\r
+\r
+        \r
+        // Add handling for activating text edit for new variables\r
+     // Store initialization status to hints to prevent unnecessary graph queries\r
+        Boolean isInitialized = e.getHint(ELEMENT_INITIALIZED);  \r
+        Object o = e.getHint(ElementHints.KEY_OBJECT);\r
+        if (o instanceof Resource && !Boolean.TRUE.equals(isInitialized)) {\r
+            final Resource element = (Resource)o;\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
+                        ModelingResources MR = ModelingResources.getInstance(graph);\r
+                        Resource component = graph.getPossibleObject(element, MR.ElementToComponent);\r
+                        if (component == null)\r
+                            return;\r
+                        \r
+                        // See if the resource of the element has just been created. \r
+                        Resource r = graph.getPossibleObject(component, SR.IndependentVariable_isUninitialized);\r
+                        if (r == null){\r
+                            return;\r
+                        }\r
+                        \r
+                        // If the resource is just been created, activate editing its name.\r
+                        if (!graph.isInstanceOf(r, SR.Loop)) {\r
+                            activateEdit(e);\r
+                        }\r
+                        graph.deny(component, SR.IndependentVariable_isUninitialized, r);\r
+                    }\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+            e.setHint(ELEMENT_INITIALIZED, Boolean.TRUE);\r
+        }\r
+        \r
+        unflipText(e);\r
+    }\r
+    \r
+    @Override\r
+    public boolean handleMouseEvent(IElement e, final ICanvasContext ctx, MouseEvent me) {\r
+       //if (!(me instanceof MouseEnterEvent) && !(me instanceof MouseMovedEvent) && !(me instanceof MouseExitEvent))\r
+               //System.out.println(me instanceof MouseDragBegin ? "drag begin" : "no drag begin");\r
+       //SysdynWorkbenchUtils.setHoveringHint(ctx, me, SysdynTextElementNoBounds.this);\r
+        return super.handleMouseEvent(e, ctx, me);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/SysdynTextNode.java
new file mode 100644 (file)
index 0000000..1d593a3
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013-2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT - initial API and implementation\r
+ *     Semantum Oy - 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.Graphics2D;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.diagram.elements.TextEditActivation;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.scenegraph.g2d.events.EventTypes;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+\r
+/**\r
+ * Text node for Sysdyn elements.\r
+ * \r
+ *  Additions to the basic node:\r
+ *  1. Draw borders when hovering\r
+ *  2. Support Sysdyn's diagram locking\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SysdynTextNode extends TextNode implements ILoopComponentNode {\r
+\r
+    private static final long serialVersionUID = 5235077104121753251L;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
+\r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
+\r
+    @Override\r
+    public int getEventMask(){\r
+        return EventTypes.FocusLostMask | super.getEventMask();\r
+    }\r
+    \r
+    @Override\r
+    protected boolean mouseDragged(MouseDragBegin e) {\r
+        // Disable dragging if LockSketch is ON\r
+        if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode())){\r
+            super.mouseDragged(e);\r
+            return true;}\r
+        else\r
+            return super.mouseDragged(e);\r
+    }\r
+    \r
+    \r
+    @Override\r
+    protected void renderSelectedHover(Graphics2D g, boolean isSelected, boolean isHovering) {\r
+        \r
+        if (!isSelected && isHovering) {\r
+            BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+            Color oldColor = g.getColor();\r
+            g.setColor(Color.LIGHT_GRAY);\r
+            g.setStroke(new BasicStroke((float)(2.0*scale)));\r
+            g.draw(getBoundsInLocal());\r
+            g.setColor(oldColor);\r
+            g.setStroke(oldStroke);\r
+            \r
+        } else if (isLoopSelected()) {\r
+            BasicStroke oldStroke = (BasicStroke)g.getStroke();\r
+            Color oldColor = g.getColor();\r
+            g.setColor(LoopNode.HIGHLIGHT_COLOR);\r
+            g.setStroke(new BasicStroke((float)(2.0*scale)));\r
+            g.draw(getBoundsInLocal());\r
+            g.setColor(oldColor);\r
+            g.setStroke(oldStroke);\r
+            \r
+        }\r
+    }\r
+    \r
+    public TextEditActivation activateEdit(int mouseId, IElement e, ICanvasContext ctx, boolean save) {\r
+        if (save)\r
+            return editActivation = super.activateEdit(mouseId, e, ctx);\r
+        return super.activateEdit(mouseId, e, ctx);\r
+    }\r
+    \r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       repaint();\r
+               }\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveFactory.java
new file mode 100644 (file)
index 0000000..200ce9e
--- /dev/null
@@ -0,0 +1,338 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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.NoninvertibleTransformException;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\r
+\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.ResizeNode.TranslateEdge;\r
+import org.simantics.diagram.elements.ResizeRectangularSceneGraph;\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\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.SceneGraphNodeKey;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.SceneGraph;\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.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\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         = 1.5;\r
+\r
+    private static final BasicStroke    STROKE             = new BasicStroke(1f);\r
+    public 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.elements.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
+                Orientation.INSTANCE,\r
+                ValveTextLocation.INSTANCE,\r
+                ValveSceneGraph.INSTANCE,\r
+                ValveText.INSTANCE,\r
+                new ResizeRectangularSceneGraph(TextElementNoBounds.SG_NODE),\r
+                RESIZE_PROPERTY_SETTER,          \r
+                ValveBounds.INSTANCE,\r
+                ValveOutline.INSTANCE,\r
+                new WholeElementTerminals(terminals)\r
+        ).setId(ValveFactory.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
+        \r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        Resource orientation = graph.getPossibleObject(element, sr.ValveSymbol_orientation);\r
+        \r
+        String orientationText;\r
+        if(orientation != null && sr.Vertical.equals(orientation)) {\r
+            orientationText = "Vertical";\r
+        } else {\r
+            orientationText = "Horizontal";\r
+        } \r
+        SysdynElementUtils.setOrientation(e, orientationText);\r
+\r
+        Resource location = graph.getPossibleObject(element, sr.ValveSymbol_textLocation);\r
+        String locationText;\r
+        if(location == null || sr.Bottom.equals(location)) {\r
+            locationText = "Bottom";\r
+        } else if(sr.Top.equals(location)) {\r
+            locationText = "Top";\r
+        } else if(sr.Left.equals(location)) {\r
+            locationText = "Left";\r
+        } else {\r
+            locationText = "Right";\r
+        }\r
+        SysdynElementUtils.setValveTextLocation(e, locationText);    \r
+        \r
+        \r
+        ResizeRectangularSceneGraph resize = e.getElementClass().getSingleItem(ResizeRectangularSceneGraph.class);\r
+        if(resize != null) {\r
+            \r
+            if(location == null || sr.Bottom.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.NORTH);\r
+                resize.setXTranslateEdge(TranslateEdge.NONE);\r
+            } else if(sr.Top.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.SOUTH);\r
+                resize.setXTranslateEdge(TranslateEdge.NONE);\r
+            } else if(sr.Left.equals(location)) {\r
+                resize.setYTranslateEdge(TranslateEdge.NONE);\r
+                resize.setXTranslateEdge(TranslateEdge.EAST);\r
+            } else {\r
+                resize.setYTranslateEdge(TranslateEdge.NONE);\r
+                resize.setXTranslateEdge(TranslateEdge.WEST);\r
+            }\r
+        }\r
+        \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 ValveText extends SysdynTextElementNoBounds {\r
+        private static final long serialVersionUID = -5354779831383095960L;\r
+     \r
+        public static ValveText INSTANCE = new ValveText();\r
+        \r
+        public ValveText() {\r
+            super(0, 0, Alignment.CENTER, 0, 1, 1, true);\r
+        }\r
+        \r
+        @Override\r
+        public void init(IElement e, G2DParentNode parent) {\r
+            super.init(e, parent);\r
+            \r
+            TextNode text = e.getHint(TextElementNoBounds.SG_NODE);\r
+            HoverShapeNode valve = e.getHint(ValveSceneGraph.VALVE_SG_NODE);\r
+            if(valve != null && text != null) {\r
+                Rectangle2D textBounds = text.getBoundsInLocal();\r
+                Rectangle2D valveBounds = valve.getBoundsInLocal();\r
+                AffineTransform at = (AffineTransform) text.getTransform().clone();\r
+                at.translate(\r
+                        getTextXTranslate(e, textBounds, valveBounds), \r
+                        getTextYTranslate(e, textBounds, valveBounds));\r
+                text.setTransform(at);\r
+            }\r
+            \r
+        }\r
+        \r
+        private static double getTextXTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) {\r
+            String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+            if(location.equals("Bottom")) {\r
+                return -textBounds.getCenterX();\r
+            } else if(location.equals("Top")) {\r
+                return -textBounds.getCenterX();\r
+            } else if(location.equals("Left")) {\r
+                return -textBounds.getMaxX() - valveBounds.getWidth() / 2;\r
+            } else {\r
+                return valveBounds.getMaxX() - textBounds.getMinX();\r
+            }\r
+        }\r
+        \r
+        private static double getTextYTranslate(IElement e, Rectangle2D textBounds, Rectangle2D valveBounds) {\r
+            String location = e.getHint(SysdynElementHints.KEY_LOCATION);\r
+            if(location.equals("Bottom")) {\r
+                return valveBounds.getMaxY() - textBounds.getMinY();\r
+            } else if(location.equals("Top")) {\r
+                return valveBounds.getMinY() - textBounds.getMaxY();\r
+            } else if(location.equals("Left")) {\r
+                return -textBounds.getCenterY();\r
+            } else {\r
+                return -textBounds.getCenterY();\r
+            }\r
+        }\r
+    }\r
+    \r
+    public static class ValveBounds implements InternalSize {\r
+        private static final long serialVersionUID = -666692270776359301L;\r
+\r
+        public static final ValveBounds INSTANCE         = new ValveBounds();\r
+\r
+        @Override\r
+        public Rectangle2D getBounds(IElement e, Rectangle2D size) {\r
+            TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE);\r
+            ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+\r
+            if(textNode != null && valveSG != null) {\r
+                try {\r
+                    AffineTransform elementTransform = ElementUtils.getTransform(e);\r
+                    AffineTransform nodeTransform = textNode.getTransform();\r
+\r
+                    AffineTransform elementTransformInverse = elementTransform.createInverse();\r
+                    elementTransformInverse.concatenate(nodeTransform);\r
+\r
+                    Rectangle2D text = textNode.getBoundsInLocal();\r
+                    Shape textShape = elementTransformInverse.createTransformedShape(text);\r
+\r
+                    Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double());\r
+\r
+                    size.setRect(textShape.getBounds2D());\r
+                    size.add(valve);\r
+                    return size;\r
+                } catch (NoninvertibleTransformException e1) {\r
+                    e1.printStackTrace();\r
+                }\r
+            }\r
+            // FallBack\r
+            Path2D path = createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED)));\r
+            return path.getBounds2D();\r
+        }\r
+\r
+    }\r
+    \r
+    public static class ValveSceneGraph implements SceneGraph {\r
+        private static final long serialVersionUID = 7987939328158347639L;\r
+\r
+        public static final ValveSceneGraph INSTANCE         = new ValveSceneGraph();\r
+\r
+        private static final Key            VALVE_SG_NODE             = new SceneGraphNodeKey(ShapeNode.class, "VALVE_SHAPE_NODE");\r
+        \r
+        private IHintListener hoverHintListener;\r
+\r
+        @Override\r
+        public void init(IElement e, G2DParentNode parent) {\r
+            final HoverShapeNode node = ElementUtils.getOrCreateNode(e, parent, VALVE_SG_NODE, "valveShape", HoverShapeNode.class);\r
+\r
+            // Calculate borders from text node bounds.\r
+            node.setStroke(STROKE);\r
+            node.setScaleStroke(true);\r
+            Color color = e.getHint(ElementHints.KEY_TEXT_COLOR);\r
+            node.setColor(color != null ? color : Color.BLACK);\r
+            boolean rotated = false;\r
+            String orientation = SysdynElementUtils.getOrientation(e);\r
+            if(orientation != null && orientation.equals("Vertical"))\r
+                rotated = true;\r
+            node.setShape(createShape(VALVE_SIZE, Boolean.TRUE.equals(rotated)));\r
+            Boolean hover = e.getHint(ElementHints.KEY_HOVER); \r
+            node.setHover(hover != null ? hover : false);\r
+            \r
+            AffineTransform at = ElementUtils.getTransform(e);\r
+            if(at != null)\r
+                node.setTransform(at);\r
+            \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(VALVE_SG_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, VALVE_SG_NODE);            \r
+        }\r
+        \r
+        \r
+        public Rectangle2D getValveBounds(IElement e, Rectangle2D size) {\r
+            if (size == null)\r
+                size = new Rectangle2D.Double();\r
+            \r
+            HoverShapeNode node = e.getHint(VALVE_SG_NODE);\r
+            if(node != null) {\r
+                size.setFrame(node.getBoundsInLocal());\r
+            } else {\r
+                size.setFrame(createShape(VALVE_SIZE, Boolean.TRUE.equals(e.getHint(KEY_ROTATED))).getBounds2D());\r
+            }\r
+            \r
+            // Add some padding to the valve\r
+            double padding = 1;\r
+            size.setFrame(size.getX() - padding, size.getY() - padding, size.getWidth() + padding * 2, size.getHeight() + padding * 2);\r
+            return size;\r
+        }\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveOutline.java
new file mode 100644 (file)
index 0000000..afac8e4
--- /dev/null
@@ -0,0 +1,57 @@
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import java.awt.Shape;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.NoninvertibleTransformException;\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.Rectangle2D;\r
+\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.InternalSize;\r
+import org.simantics.g2d.element.handler.impl.BoundsOutline;\r
+import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph;\r
+\r
+public class ValveOutline extends BoundsOutline {\r
+\r
+    public static final BoundsOutline INSTANCE         = new ValveOutline();\r
+\r
+    private static final long         serialVersionUID = 5544256245734478634L;\r
+\r
+    public ValveOutline() {\r
+        super();\r
+    }\r
+\r
+    @Override\r
+    public Shape getElementShape(IElement e) {\r
+        TextNode textNode = e.getHint(TextElementNoBounds.SG_NODE);\r
+        ValveSceneGraph valveSG = e.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+\r
+        if(textNode != null && valveSG != null) {\r
+            try {\r
+                AffineTransform elementTransform = ElementUtils.getTransform(e);\r
+                AffineTransform nodeTransform = textNode.getTransform();\r
+\r
+                AffineTransform elementTransformInverse = elementTransform.createInverse();\r
+                elementTransformInverse.concatenate(nodeTransform);\r
+\r
+                Rectangle2D text = textNode.getBoundsInLocal();\r
+                Shape textShape = elementTransformInverse.createTransformedShape(text);\r
+\r
+                Rectangle2D valve = valveSG.getValveBounds(e, new Rectangle2D.Double());\r
+\r
+                Path2D path = new Path2D.Double(textShape);\r
+                path.append(valve, false);\r
+\r
+                return path;\r
+            } catch (NoninvertibleTransformException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+        }\r
+\r
+        InternalSize b = e.getElementClass().getSingleItem(InternalSize.class);\r
+        return b.getBounds(e, new Rectangle2D.Double());\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/ValveTextLocation.java
new file mode 100644 (file)
index 0000000..8957e43
--- /dev/null
@@ -0,0 +1,35 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\r
+\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.ElementHandler;\r
+\r
+public class ValveTextLocation implements ElementHandler {\r
+\r
+    private static final long serialVersionUID = 7123851901569461658L;\r
+    \r
+    public static final ValveTextLocation INSTANCE = new ValveTextLocation();\r
+    \r
+    public String getTextLocation(IElement e) {\r
+        return e.getHint(SysdynElementHints.KEY_LOCATION);\r
+    }\r
+\r
+    \r
+    public void setTextLocation(IElement e, String location) {\r
+        if (location != null)\r
+            e.setHint(SysdynElementHints.KEY_LOCATION, location);\r
+        else\r
+            e.removeHint(SysdynElementHints.KEY_LOCATION);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/WholeElementTerminals.java
new file mode 100644 (file)
index 0000000..ff409fe
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements;\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/elements/connections/Arcs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Arcs.java
new file mode 100644 (file)
index 0000000..c054d41
--- /dev/null
@@ -0,0 +1,232 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.Shape;\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
+    /**\r
+     * \r
+     * @param startX Start point x coord\r
+     * @param startY Start point y coord\r
+     * @param cx Center of the circle x coord\r
+     * @param cy Center of the circle y coord\r
+     * @param r Radius of the circle\r
+     * @param curAngle Start angle\r
+     * @param endBounds Shape\r
+     * @param dir direction to which is iterated\r
+     * @param move amount of which is iterated\r
+     * @param noOfIteration current number of itartion\r
+     * @param turn true iff we are increasing the angle\r
+     * @param crossed true if we have crossed the boundary we're targeting\r
+     * @return new angle\r
+     */\r
+    private static double iterateAngle(double startX, double startY, \r
+               double cx, double cy, double r,\r
+            double curAngle, Shape endBounds, boolean dir, double move,\r
+            int noOfIteration, boolean turn, boolean crossed) {\r
+       // Do this many steps\r
+       if (noOfIteration > 16)\r
+               return normalizeAngle(curAngle);\r
+       \r
+       if (crossed) // When we have crossed the boundary, start split half method\r
+               move *= 0.5;\r
+       double x_rad, y_rad;\r
+       if (dir != turn) { // The direction of iteration is based on dir and turn bits\r
+               x_rad = startX + (move * Math.sin(curAngle));\r
+               y_rad = startY + (move * Math.cos(curAngle));\r
+       } else {\r
+               x_rad = startX - (move * Math.sin(curAngle));\r
+               y_rad = startY - (move * Math.cos(curAngle));\r
+       }\r
+       curAngle = -Math.atan((y_rad-cy)/(x_rad-cx));\r
+               if (x_rad-cx < 0)\r
+                       curAngle += Math.PI;\r
+       curAngle = normalizeAngle(curAngle);\r
+               \r
+               if (endBounds.contains(x_rad, y_rad)) {\r
+                       return iterateAngle(x_rad, y_rad,\r
+                                       cx,cy,r,curAngle,endBounds,dir, move, noOfIteration+1, false, crossed);\r
+       }\r
+       else {\r
+               // Crossed is hereafter true\r
+               return iterateAngle(x_rad, y_rad,\r
+                                       cx,cy,r,curAngle,endBounds,dir, move, noOfIteration+1, true, true);\r
+       }\r
+    }\r
+    \r
+    /**\r
+     * \r
+     * @param cx x coord of the center point of the circle \r
+     * @param cy y coord of the center point of the circle\r
+     * @param r radius of the circle\r
+     * @param curAngle angle of the arc\r
+     * @param endBounds bounding shape\r
+     * @param dir direction of the arc\r
+     * @return\r
+     */\r
+    public static double nextIntersectingAngle(double cx, double cy, double r,\r
+        double curAngle, Shape endBounds, boolean dir) {\r
+       // Move this much per iteration till the border is crossed.\r
+       double move = 3.0;\r
+        return iterateAngle(endBounds.getBounds2D().getCenterX(),\r
+                                               endBounds.getBounds2D().getCenterY(),\r
+                                               cx,cy,r,curAngle,endBounds,dir,move, 0, false, false);\r
+    }\r
+    \r
+       public static boolean hitTest(Shape beginBounds, Shape endBounds, double angle, double x, double y, double tolerance) {\r
+               \r
+               boolean clockWise = angle > 0;\r
+               \r
+               double x0 = beginBounds.getBounds2D().getCenterX();\r
+        double y0 = beginBounds.getBounds2D().getCenterY();\r
+        double x1 = endBounds.getBounds2D().getCenterX();\r
+        double y1 = endBounds.getBounds2D().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
+        double tolerance2 = tolerance * tolerance;\r
+        if(dist < (r+tolerance2)*(r+tolerance2) &&\r
+            dist > (r-tolerance2)*(r-tolerance2)) {\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
+        * Calculates the radial distance between an arc and a point\r
+        * @param beginBounds Begin coordinate of the arc\r
+        * @param endBounds End coordinate of the arc\r
+        * @param angle The central angle of the arc\r
+        * @param x x coordinate of the measured point\r
+        * @param y x coordinate of the measured point \r
+        * @return The radial distance between the the arc and (x,y); Double.NaN if the\r
+        *  distance is not real.\r
+        */\r
+       public static double getRadialDistance(Shape beginBounds,\r
+                       Shape endBounds, double angle, double x, double y) {\r
+\r
+               boolean clockWise = angle > 0;\r
+               \r
+               double x0 = beginBounds.getBounds2D().getCenterX();\r
+        double y0 = beginBounds.getBounds2D().getCenterY();\r
+        double x1 = endBounds.getBounds2D().getCenterX();\r
+        double y1 = endBounds.getBounds2D().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 dist2 = dx*dx + dy*dy;\r
+               \r
+           double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx));\r
+               if(!Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) {\r
+               return Double.NaN;\r
+           }\r
+           return  Math.abs(Math.sqrt(dist2) - r);\r
+       }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/ConnectionClasses.java
new file mode 100644 (file)
index 0000000..310c59f
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.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/elements/connections/DependencyConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyConnectionFactory.java
new file mode 100644 (file)
index 0000000..6316eec
--- /dev/null
@@ -0,0 +1,319 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.io.StringReader;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.concurrent.ConcurrentSkipListMap;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import org.eclipse.jface.preference.PreferenceConverter;\r
+import org.eclipse.jface.resource.StringConverter;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.AsyncMultiProcedure;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.db.procedure.SyncProcedure;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.diagram.adapter.ElementFactoryAdapter;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\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.ElementHints;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
+import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPropertyExternalRead;\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
+ * @author Tuomas Miettinen\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
+        procedure.execute(graph, SysdynConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(elementType)));\r
+    }\r
+\r
+    @Override\r
+    protected Resource getElementClassBaseType(AsyncReadGraph graph) {\r
+        return graph.getService(DiagramResource.class).Connection;\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, DependencyRouter.INSTANCE);\r
+\r
+        G2DResource G2D;\r
+        try {\r
+            G2D = G2DResource.getInstance(graph.getSession());\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+            return;\r
+        }\r
+\r
+        // Find possible font\r
+        graph.forPossibleStatement(elementResource, G2D.HasFont, new SyncProcedure<Statement>() {\r
+\r
+            @Override\r
+            public void execute(ReadGraph graph, Statement result) throws DatabaseException {\r
+                if(result != null && !result.isAsserted(elementResource)) {\r
+                    element.setHint(ElementHints.KEY_FONT, G2DUtils.getFont(graph, result.getObject()));\r
+                } else {\r
+                    String fontdata = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(elementResource, SysdynDiagramPreferences.ARROW_FONT)));\r
+                    if(fontdata != null) {\r
+                        FontData[] fdArray = PreferenceConverter.basicGetFontData(fontdata);\r
+                        if(fdArray != null) {\r
+                            if(fdArray.length == 1) {\r
+                                FontData fd = fdArray[0];\r
+                                if(fd != null) {\r
+                                    Font font = new Font(fd.getName(), fd.getStyle(), fd.getHeight());\r
+                                    element.setHint(ElementHints.KEY_FONT, font);\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {\r
+                throwable.printStackTrace();\r
+            }\r
+        });\r
+\r
+        // Find possible color\r
+        graph.forPossibleStatement(elementResource, G2D.HasColor, new SyncProcedure<Statement>() {\r
+\r
+            @Override\r
+            public void execute(ReadGraph graph, Statement result) throws DatabaseException {\r
+                if(result != null && !result.isAsserted(elementResource)) {\r
+                    element.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, result.getObject()));\r
+                } else {\r
+                       String color;\r
+                       if (isForStockInitialOnly(graph, elementResource)) {\r
+                               color = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(elementResource, SysdynDiagramPreferences.ARROW_STOCK_INITIAL_COLOR)));\r
+                       } else {\r
+                               color = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(elementResource, SysdynDiagramPreferences.ARROW_COLOR)));\r
+                       }\r
+                       if(color != null) {\r
+                        RGB rgb = StringConverter.asRGB(color, null);\r
+                        if(rgb != null) {\r
+                            Color c = new Color(rgb.red, rgb.green, rgb.blue);\r
+                            element.setHint(ElementHints.KEY_TEXT_COLOR, c);\r
+                        }\r
+                    }\r
+\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void exception(ReadGraph graph, Throwable throwable) throws DatabaseException {\r
+                throwable.printStackTrace();\r
+            }\r
+        });\r
+\r
+\r
+        // A complicated-looking procedure for obtaining all HasProperties to properties map\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
+                Layer0 l0;\r
+                try {\r
+                    l0 = Layer0.getInstance(graph.getSession());\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                    return;\r
+                }\r
+\r
+                graph.forIsSubrelationOf(property, l0.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
+                                    Layer0 l0;\r
+                                    try {\r
+                                        l0 = Layer0.getInstance(graph.getSession());\r
+                                    } catch (DatabaseException e) {\r
+                                        e.printStackTrace();\r
+                                        return;\r
+                                    }\r
+\r
+                                    graph.forPossibleRelatedValue(property, l0.HasName, Bindings.STRING, 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
+                                            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
+            @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
+       protected static boolean isForStockInitialOnly(ReadGraph graph,\r
+                       Resource elementResource) throws DatabaseException {\r
+               SysdynResource SR = SysdynResource.getInstance(graph);\r
+       ModelingResources MO = ModelingResources.getInstance(graph);\r
+       Layer0 L0 = Layer0.getInstance(graph);\r
+       Resource connection = graph.getPossibleObject(elementResource, MO.DiagramConnectionToConnection);\r
+       Resource tail = graph.getPossibleObject(connection, SR.Variable_HasTail);\r
+       if (tail == null)\r
+               return false;\r
+       \r
+       if (graph.isInstanceOf(tail, SR.Shadow))\r
+               tail = graph.getPossibleObject(tail, SR.Shadow_original);\r
+               \r
+       Resource head = graph.getPossibleObject(connection, SR.Variable_HasHead);\r
+       if (head == null || !graph.isInstanceOf(head, SR.Stock) || tail == null)\r
+               return false;\r
+       \r
+       Resource expressionListResource = graph.getPossibleObject(head, SR.Variable_expressionList);\r
+       List<Resource> expressionList = ListUtils.toPossibleList(graph, expressionListResource);\r
+       \r
+       // Keep track on whether at least one initial equation contains the variable\r
+       boolean initialContainsVariable = false;\r
+       // Go through all expressions\r
+       for (Resource expression : expressionList) {\r
+               if (!graph.isInstanceOf(expression, SR.StockExpression))\r
+                       return false;\r
+               \r
+               String tailStr = graph.getPossibleRelatedValue(tail, L0.HasName, Bindings.STRING);\r
+               String integral = graph.getPossibleRelatedValue(expression, SR.StockExpression_integralEquation, Bindings.STRING);\r
+               if (equationContainsVariable(graph, integral, tailStr))\r
+                       // At least one integral equation contains the variable\r
+                       return false;\r
+               String initial = graph.getPossibleRelatedValue(expression, SR.StockExpression_initialEquation, Bindings.STRING);\r
+               if (!initialContainsVariable && equationContainsVariable(graph, initial, tailStr))\r
+                       // At least one initial equation contains the variable\r
+                       initialContainsVariable = true;\r
+       }\r
+       \r
+       // No integral equation contains the variable.\r
+               return initialContainsVariable;\r
+       }\r
+\r
+       private static boolean equationContainsVariable(ReadGraph graph,\r
+                       String equation, String variable) {\r
+               ExpressionParser parser = new ExpressionParser(new StringReader(equation));\r
+               try {\r
+                       parser.expr();\r
+               } catch (Throwable t) {\r
+                       return false;\r
+               }\r
+               \r
+               // Collect references\r
+        Set<String> references = parser.getReferences().keySet();\r
+        \r
+        // See if the equation contains variable\r
+        return references.contains(variable);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeClass.java
new file mode 100644 (file)
index 0000000..5b86bd9
--- /dev/null
@@ -0,0 +1,273 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\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.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.HashMap;\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.PickRequest.PickPolicy;\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.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.EdgeVisuals;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType;\r
+import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\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.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.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.elementclass.connection.EdgeClass.EdgeHandler;\r
+import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\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 final float DEFAULT_STROKE_WIDTH = 0.3f;\r
+\r
+       private static class NodePick implements Pick {\r
+\r
+           private static final long serialVersionUID = 1L;\r
+           \r
+           public static NodePick INSTANCE = new NodePick();\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
+               return false;\r
+            }\r
+            return Arcs.hitTest(node.getBeginBounds(), node.getEndBounds(), node.getAngle(), pickRect.getCenterX(), pickRect.getCenterY(), 1.7);\r
+            \r
+           }\r
+\r
+       }\r
+       \r
+    public static final ElementClass CLASS =\r
+        ElementClass.compile(\r
+                SysdynEdgeSceneGraph.INSTANCE,\r
+                EdgeHandler.INSTANCE,\r
+                new ConfigurableEdgeVisuals(\r
+                        ArrowType.None, ArrowType.Fill, \r
+                        new BasicStroke(DEFAULT_STROKE_WIDTH,\r
+                                BasicStroke.CAP_BUTT,\r
+                                BasicStroke.JOIN_ROUND,\r
+                                10.0f, null, 0.0f)\r
+                        , 1.0, 1.0),\r
+                FillColorImpl.BLACK,\r
+                FixedTransform.INSTANCE,\r
+                TextImpl.INSTANCE,\r
+                TextColorImpl.BLACK,\r
+                TextFontImpl.DEFAULT,\r
+                NodePick.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(DependencyNode.class, "EDGE_NODE");\r
+        \r
+        @Override\r
+        public void init(IElement e, G2DParentNode parent) {\r
+            DependencyNode node = ElementUtils.getOrCreateNode(e, parent, KEY_SG_NODE, "edge_" + e.hashCode(), DependencyNode.class);\r
+            \r
+            Font font = ElementUtils.getTextFont(e);\r
+            Color color = ElementUtils.getTextColor(e);\r
+            \r
+            HashMap<String, Object> properties = e.getHint(DiagramHints.PROPERTIES);\r
+            Pair<?, ?> polarityPair =  (Pair<?, ?>)properties.get("polarity");\r
+            Pair<?, ?> polarityLocationPair =  (Pair<?, ?>)properties.get("polarityLocation");\r
+            boolean delayMark = properties.containsKey("delayMark");\r
+            boolean arrowHead = !properties.containsKey("hideArrow");\r
+            \r
+            String location;\r
+            if(polarityLocationPair == null)\r
+                location = DependencyNode.INSIDE;\r
+            else\r
+                location = (String) polarityLocationPair.second;\r
+\r
+            String text = polarityPair != null ? (String)  polarityPair.second : "";\r
+            node.init(text, location, delayMark, arrowHead, font, color, 0, 0, 0.235);\r
+            \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
+            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
+\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
+            EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class);\r
+            Map<String, Pair<Resource, Object>> properties = e.getHint(DiagramHints.PROPERTIES);\r
+            Pair<Resource, Object> strokeWidthPair = properties.get("strokeWidth");\r
+            \r
+            float strokeWidth;\r
+            if(strokeWidthPair == null)\r
+               strokeWidth = DEFAULT_STROKE_WIDTH;\r
+            else\r
+               strokeWidth = (Float)strokeWidthPair.second;\r
+\r
+            vh.setStroke(e, new BasicStroke(strokeWidth,\r
+                                BasicStroke.CAP_BUTT,\r
+                                BasicStroke.JOIN_MITER,\r
+                                10.0f, null, 0.0f));\r
+            Stroke stroke = vh.getStroke(e);\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
+            Alignment hAlign = ElementUtils.getHintOrDefault(e, ElementHints.KEY_HORIZONTAL_ALIGN, Alignment.CENTER);\r
+            node.setBackgroundColor(null);\r
+            node.setBorderColor(borderColor);\r
+            node.setHorizontalAlignment((byte) hAlign.ordinal());\r
+            node.setPadding(0, 0);\r
+            node.setBorderWidth((float) 0);\r
+            node.setEditable(false);\r
+            node.setFont(font);\r
+            \r
+            node.setBeginBounds(beginTerminalShape);\r
+            node.setEndBounds(endTerminalShape);\r
+            node.setStroke(stroke);\r
+            node.setColor(color);\r
+            node.setShapes(DependencyRouter.createArrowShape(node.getShapes(), node.getBeginBounds(), node.getEndBounds(), node.getAngle(), node.getStroke()));\r
+\r
+            if(properties != null) {\r
+                       for(Map.Entry<String, Pair<Resource, Object>> entry : properties.entrySet()) {\r
+                               NodeUtil.setPropertyIfSupported(entry.getKey(), entry.getValue().second, node);                         \r
+//                             node.setProperty(entry.getKey(), entry.getValue().second);\r
+//                             System.out.println("setProperty " + entry.getKey() + " => " + entry.getValue().second);\r
+                       }\r
+            }\r
+            EdgeHandler eh = e.getElementClass().getAtMostOneItemOfClass(EdgeHandler.class);\r
+            Path2D path = eh.getPath(e);\r
+            if(path == null)\r
+               path = new Path2D.Double();\r
+            else\r
+               path.reset();\r
+            path.append(node.getShapes().first, false);\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/elements/connections/DependencyEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyEdgeFactory.java
new file mode 100644 (file)
index 0000000..e8f1b89
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.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
+        procedure.execute(graph, CLASS);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/DependencyNode.java
new file mode 100644 (file)
index 0000000..2bd3a51
--- /dev/null
@@ -0,0 +1,409 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.awt.Graphics2D;\r
+import java.awt.Shape;\r
+import java.awt.Stroke;\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
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.g2d.utils.Alignment;\r
+import org.simantics.scenegraph.ISelectionPainterNode;\r
+import org.simantics.scenegraph.g2d.IG2DNode;\r
+import org.simantics.scenegraph.g2d.events.EventTypes;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
+import org.simantics.scenegraph.g2d.nodes.ConnectionNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.ui.editor.routing.DependencyRouter;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+/**\r
+ * Node for dependency arrows and polarity text\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class DependencyNode extends TextNode implements ISelectionPainterNode, ILoopComponentNode {\r
+\r
+    public static final String INSIDE = "Inside";\r
+    public static final String OUTSIDE = "Outside";\r
+\r
+    public static final double HITMARGIN = 1.7;\r
+    \r
+    private static final long serialVersionUID = 1294351381209071074L;\r
+\r
+    private Color color;\r
+    private Stroke stroke;\r
+    private Shape beginBounds;\r
+    private Shape endBounds;\r
+    private double angle = 0.3;\r
+    private String side;\r
+    private boolean delayMark = false;\r
+    private boolean arrowHead = true;\r
+    private transient Triple<Arc2D, Path2D, Path2D> shapes = new Triple<Arc2D, Path2D, Path2D>(new Arc2D.Double(), new Path2D.Double(), new Path2D.Double());\r
+\r
+    transient public boolean hover = false;\r
+    private boolean dragging = false;\r
+\r
+    private transient PropertyChangeListener fieldListener = null;\r
+       \r
+    @Override\r
+    public void init() {\r
+        super.init();\r
+        addEventHandler(this);\r
+\r
+    }\r
+\r
+\r
+    /**\r
+     * Inits the dependency node with a text\r
+     * @param text Polarity\r
+     * @param side Polarity Location\r
+     * @param font Font\r
+     * @param color Color\r
+     * @param x Text initial location x\r
+     * @param y Text initial location y\r
+     * @param scale Scale\r
+     */\r
+    public void init(String text, String side, boolean delayMark, boolean arrowHead, Font font, Color color, double x, double y, double scale) {\r
+        super.init(text, font, color, x, y, scale);\r
+        this.side = side;\r
+        this.delayMark = delayMark;\r
+        this.arrowHead = arrowHead;\r
+        setHorizontalAlignment((byte) Alignment.CENTER.ordinal());\r
+        setVerticalAlignment((byte) Alignment.CENTER.ordinal());\r
+    }\r
+\r
+    @Override\r
+    public void cleanup() {\r
+        super.cleanup();\r
+    }\r
+\r
+    public void setFieldListener(PropertyChangeListener listener) {\r
+        this.fieldListener = listener;\r
+    }\r
+\r
+    @ServerSide\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
+    @PropertySetter("color")\r
+    @SyncField("color")\r
+    public void setColor(Color color) {\r
+        this.color = color;\r
+    }\r
+\r
+    @PropertySetter("stroke")\r
+    @SyncField("stroke")\r
+    public void setStroke(Stroke stroke) {\r
+        this.stroke = stroke;\r
+    }\r
+\r
+    @PropertySetter("beginBounds")\r
+    @SyncField("beginBounds")\r
+    public void setBeginBounds(Shape beginBounds) {\r
+        this.beginBounds = beginBounds;\r
+    }\r
+\r
+    @PropertySetter("endBounds")\r
+    @SyncField("endBounds")\r
+    public void setEndBounds(Shape endBounds) {\r
+        this.endBounds = endBounds;\r
+    }\r
+\r
+    @PropertySetter("angle")\r
+    @SyncField("angle")\r
+    public void setAngle(Double angle) {\r
+        this.angle = angle.doubleValue();\r
+        if(this.beginBounds != null && this.endBounds != null)\r
+            this.shapes = DependencyRouter.createArrowShape(this.shapes, this.beginBounds, this.endBounds, this.angle, this.stroke);\r
+    }\r
+\r
+    @PropertySetter("shapes")\r
+    @SyncField("shapes")\r
+    public void setShapes(Triple<Arc2D, Path2D, Path2D> shapes) {\r
+        this.shapes = shapes;\r
+    }\r
+\r
+    public Color getColor() {\r
+        return color;\r
+    }\r
+\r
+    public Stroke getStroke() {\r
+        return stroke;\r
+    }\r
+\r
+    public Shape getBeginBounds() {\r
+        return beginBounds;\r
+    }\r
+\r
+    public Shape getEndBounds() {\r
+        return endBounds;\r
+    }\r
+\r
+    public double getAngle() {\r
+        return angle;\r
+    }\r
+\r
+    public Triple<Arc2D, Path2D, Path2D> getShapes() {\r
+        return shapes;\r
+    }\r
+\r
+\r
+\r
+    @Override\r
+    public void render(Graphics2D g) {\r
+        if(beginBounds == null || endBounds == null) return;\r
+\r
+        // Removed to let the global control handle rendering quality issues.\r
+        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+\r
+        boolean selected = NodeUtil.isSelected(this, 2);\r
+        if(font != null) g.setFont(font);\r
+        if(selected) {\r
+            g.setColor(Color.PINK);\r
+            float strokeWidth = 1.4f + 2 * (stroke instanceof BasicStroke ? ((BasicStroke)stroke).getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH); \r
+            g.setStroke(new BasicStroke(strokeWidth));\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
+            if (arrowHead) {\r
+               g.draw(shapes.second);\r
+                g.fill(shapes.second);\r
+            }\r
+            if (delayMark) g.draw(shapes.third);\r
+        } else if (hover){\r
+            g.setColor(Color.LIGHT_GRAY);\r
+            float strokeWidth = 1.4f + 2 * (stroke instanceof BasicStroke ? ((BasicStroke)stroke).getLineWidth() : DependencyEdgeClass.DEFAULT_STROKE_WIDTH); \r
+            g.setStroke(new BasicStroke(strokeWidth));\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
+            if (arrowHead) {\r
+               g.draw(shapes.second);\r
+                g.fill(shapes.second);\r
+            }\r
+            if (delayMark) g.draw(shapes.third);\r
+        } else if (isLoopSelected()) {\r
+            g.setColor(LoopNode.HIGHLIGHT_COLOR);\r
+            if(stroke != null) g.setStroke(stroke);\r
+            g.draw(shapes.first);\r
+            if (arrowHead) {\r
+               g.draw(shapes.second);\r
+                g.fill(shapes.second);\r
+            }\r
+            if (delayMark) g.draw(shapes.third);\r
+        } else {\r
+            if(color != null) g.setColor(color);\r
+            if(stroke != null) g.setStroke(stroke);\r
+            g.draw(shapes.first);\r
+            if (arrowHead) {\r
+               g.draw(shapes.second);\r
+                g.fill(shapes.second);\r
+            }\r
+            if (delayMark) g.draw(shapes.third);\r
+        }\r
+\r
+        double angleRad = angle > 0 ? \r
+                Math.toRadians(shapes.first.getAngleStart() + shapes.first.getAngleExtent()) : \r
+                    Math.toRadians(shapes.first.getAngleStart());\r
+                Point2D point = angle > 0 ? shapes.first.getEndPoint() : shapes.first.getStartPoint();\r
+\r
+                int angle1 = 220;\r
+                int angle2 = -40;\r
+                if(OUTSIDE.equals(side)) {\r
+                    angle1 *= -1;\r
+                    angle2 *= -1;\r
+                }\r
+                double a = Math.toRadians(angle < 0 ? angle1 : angle2);\r
+                double s = Math.sin(a) * 3;\r
+                double c = Math.cos(a) * 4;\r
+\r
+                g.translate(point.getX(), point.getY());\r
+                g.rotate(-angleRad);\r
+                g.translate(s, c);\r
+                g.rotate(angleRad);\r
+                super.render(g);\r
+                g.rotate(-angleRad);\r
+                g.translate(-s, -c);\r
+                g.rotate(angleRad);\r
+                g.translate(-point.getX(), -point.getY());\r
+\r
+    }\r
+\r
+    boolean pressHit = false;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
+\r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
+       \r
+    protected boolean hitTest(org.simantics.scenegraph.g2d.events.MouseEvent event, double tolerance) {\r
+        if(beginBounds == null || endBounds == null) return false;\r
+        Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());\r
+        return Arcs.hitTest(beginBounds, endBounds, angle, localPos.getX(), localPos.getY(), tolerance);\r
+    }\r
+    \r
+    protected double getRadialDistanse(Point2D coord) {\r
+       if(beginBounds == null || endBounds == null) return Double.NaN;\r
+        Point2D localPos = NodeUtil.worldToLocal(this, coord, new Point2D.Double());\r
+        return Arcs.getRadialDistance(beginBounds, endBounds, angle, localPos.getX(), localPos.getY());\r
+    }\r
+\r
+    @Override\r
+    public Rectangle2D getBoundsInLocal() {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public int getEventMask() {\r
+        return super.getEventMask() | EventTypes.MouseDragBeginMask\r
+                | EventTypes.MouseButtonPressedMask\r
+                | EventTypes.MouseButtonReleasedMask\r
+                ;\r
+    }\r
+    \r
+    @Override\r
+    protected boolean mouseMoved(MouseMovedEvent event) {\r
+        boolean hit = hitTest(event, HITMARGIN);\r
+        if(dragging) {\r
+            Point2D localPos = NodeUtil.worldToLocal(this, event.controlPosition, new Point2D.Double());\r
+            \r
+            setAngle(Arcs.angleOfArc(\r
+                    beginBounds.getBounds2D().getCenterX(), beginBounds.getBounds2D().getCenterY(),\r
+                    localPos.getX(), localPos.getY(),\r
+                    endBounds.getBounds2D().getCenterX(), endBounds.getBounds2D().getCenterY()));\r
+            repaint();\r
+        }\r
+        \r
+        if (hit != hover) {\r
+            hover = hit;\r
+            repaint();\r
+        }\r
+        return false;\r
+    }\r
+\r
+    private static boolean isEventDummy(MouseDragBegin e) {\r
+       if (e.controlPosition.distance(0, 0) == 0 \r
+                       && e.screenPosition.distance(0, 0) == 0\r
+                       && e.buttons == 0) {\r
+               return true;\r
+       } else {\r
+               return false;\r
+       }\r
+    }\r
+    \r
+    @Override\r
+    protected boolean mouseDragged(MouseDragBegin e) {\r
+       // Get rid of dummy events from dragGestureRecognized\r
+       if (isEventDummy(e)) {\r
+               return false;\r
+       }\r
+       \r
+       // Disable dragging if LockSketch is ON\r
+               if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode()))\r
+                       return false;\r
+               \r
+       //System.out.println(this.toString() + " event: " + e.toString());\r
+       boolean selected = NodeUtil.isSelected(this, 2);\r
+       double myRadialDistance = this.getRadialDistanse(e.controlPosition);\r
+       Collection<?> nodes = this.getParent().getParent().getParent().getNodes();\r
+       if (!selected) {\r
+               for (Object temp1 : nodes) {\r
+                       if (temp1 instanceof ConnectionNode) {\r
+                               for ( IG2DNode temp2 : ((ConnectionNode)temp1).getNodes()) {\r
+                                       if (temp2 instanceof SingleElementNode) {\r
+                                               for ( IG2DNode temp3 : ((SingleElementNode)temp2).getNodes()) {\r
+                                                       if (temp3 instanceof DependencyNode){\r
+                                                               DependencyNode otherDependencyNode = (DependencyNode)temp3;\r
+                                                               if (otherDependencyNode == this) {\r
+                                                                       continue;\r
+                                                               }\r
+                                                               double otherNodeDist = otherDependencyNode.getRadialDistanse(e.controlPosition);\r
+                                                               if (Double.isNaN(otherNodeDist)) {\r
+                                                                       continue;\r
+                                                               }\r
+                                                       if (otherDependencyNode.isDragging()) {\r
+                                                                       return true;\r
+                                                               } \r
+                                                               if (NodeUtil.isSelected(otherDependencyNode, 2) && (otherNodeDist < HITMARGIN)) {\r
+                                                                       return false;\r
+                                                               } \r
+                                                               if (otherNodeDist < myRadialDistance) {\r
+                                                                       return false;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+               if ( (myRadialDistance < HITMARGIN) && !dragging) {\r
+               dragging = true;\r
+                       return true;\r
+               }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    protected boolean mouseButtonPressed(MouseButtonPressedEvent e) {\r
+        return false;\r
+    }\r
+\r
+    protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {\r
+        if(dragging) {\r
+            commitProperty("angle", angle);\r
+            dragging = false;\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    protected boolean isDragging() {\r
+       return dragging;\r
+    }\r
+\r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       repaint();\r
+               }\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowArrowLineStyle.java
new file mode 100644 (file)
index 0000000..a48e700
--- /dev/null
@@ -0,0 +1,142 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Path2D;\r
+import java.io.Serializable;\r
+import java.util.StringTokenizer;\r
+\r
+import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
+\r
+\r
+/**\r
+ * Copied from ArrowLLineEndStyle\r
+ */\r
+public class FlowArrowLineStyle implements ILineEndStyle, Serializable {\r
+\r
+    private static final long serialVersionUID = 5348566089660986479L;\r
+\r
+    public static enum ArrowType { None, Stroke, Fill }\r
+\r
+    public static final double length = FlowConnectionStyle.DEFAULT_LINE_WIDTH * 4;\r
+    public static final double width = FlowConnectionStyle.DEFAULT_LINE_WIDTH * 2;\r
+    public static final double space = 0.0;\r
+\r
+    protected ArrowType type;\r
+    protected Path2D path;\r
+    protected double lineEndLength;\r
+    protected Color color;\r
+    \r
+    public FlowArrowLineStyle(String desc, Color color) {\r
+        this.type = ArrowType.None;\r
+        this.lineEndLength = 0.0;\r
+\r
+        double l = length;\r
+        double w = width;\r
+        double s = space;\r
+        \r
+        if(color != null)\r
+            this.color = color;\r
+        else\r
+            this.color = Color.BLACK;\r
+\r
+        StringTokenizer tokenizer = new StringTokenizer(desc);\r
+        if (tokenizer.hasMoreTokens()) {\r
+            String type = tokenizer.nextToken();\r
+            this.type = parseType(type);\r
+\r
+            if (tokenizer.hasMoreTokens()) {\r
+                String ls = tokenizer.nextToken();\r
+                l = parseSize(ls, length);\r
+\r
+                if (tokenizer.hasMoreTokens()) {\r
+                    String ws = tokenizer.nextToken();\r
+                    w = parseSize(ws, width);\r
+\r
+                    if (tokenizer.hasMoreTokens()) {\r
+                        String ss = tokenizer.nextToken();\r
+                        s = parseSize(ss, space);\r
+                    }\r
+                }\r
+            }\r
+            if (this.type != ArrowType.None) {\r
+                this.path = arrow(l, w, s);\r
+                lineEndLength = l+s;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void render(Graphics2D g, double x, double y, int dir) {\r
+        if (type == ArrowType.None || path == null)\r
+            return;\r
+        AffineTransform old = g.getTransform();\r
+        g.translate(x, y);\r
+        g.rotate(dir*Math.PI*0.5);\r
+        g.setColor(color);\r
+\r
+        switch (type) {\r
+            case Fill:\r
+                g.fill(path);\r
+                break;\r
+            case Stroke:\r
+                g.draw(path);\r
+                break;\r
+                       default:\r
+                               break;\r
+        }\r
+\r
+        g.setTransform(old);\r
+    }\r
+\r
+    @Override\r
+    public double getLineEndLength(int direction) {\r
+        return lineEndLength;\r
+    }\r
+\r
+    private static Path2D arrow(double length, double width, double space) {\r
+        Path2D.Double path = new Path2D.Double();\r
+        path.moveTo(-space, 0);\r
+        path.lineTo(-length-space, -width);\r
+        path.lineTo(-length-space, +width);\r
+        path.closePath();\r
+        return path;\r
+    }\r
+\r
+    private double parseSize(String size, double defaultValue) {\r
+        try {\r
+            return Double.parseDouble(size);\r
+        } catch (NumberFormatException e) {\r
+            return defaultValue;\r
+        }\r
+    }\r
+\r
+    private ArrowType parseType(String type) {\r
+        String lower = type.toLowerCase();\r
+        if ("none".equals(lower))\r
+            return ArrowType.None;\r
+        if ("stroke".equals(lower))\r
+            return ArrowType.Stroke;\r
+        if ("fill".equals(lower))\r
+            return ArrowType.Fill;\r
+        throw new IllegalArgumentException("unrecognized arrow type: " + type);\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return getClass().getSimpleName() + "[" + type + ", " + path + "]";\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/FlowConnectionStyle.java
new file mode 100644 (file)
index 0000000..a7476de
--- /dev/null
@@ -0,0 +1,97 @@
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Graphics2D;\r
+import java.awt.Stroke;\r
+import java.awt.geom.Path2D;\r
+\r
+import org.simantics.databoard.Bindings;\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.diagram.connection.rendering.BasicConnectionStyle;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class FlowConnectionStyle  extends BasicConnectionStyle {\r
+\r
+    private static final long serialVersionUID = 2777194644079591357L;\r
+\r
+    Color                     lineColor;\r
+    Stroke                    lineStroke;\r
+\r
+       private Resource resource;\r
+\r
+       // Is the default color overridden by the loop color\r
+       private boolean loopColorOverride = false;\r
+    \r
+    public static final float DEFAULT_LINE_WIDTH = 1.0f;\r
+\r
+    public FlowConnectionStyle(Color lineColor, Stroke lineStroke, Resource resource) {\r
+        super(lineColor, Color.BLACK, 0.5, lineStroke, lineStroke, 0.8);\r
+        this.lineColor = lineColor;\r
+        this.lineStroke = lineStroke;\r
+        this.resource = resource;\r
+    }\r
+    \r
+    @Override\r
+    public void drawBranchPoint(Graphics2D g, double x, double y) {\r
+    }\r
+\r
+    @Override\r
+    public void drawLine(Graphics2D g, double x1, double y1, double x2, double y2, boolean isTransient) {\r
+    }\r
+\r
+    @Override\r
+    public void drawPath(Graphics2D g, Path2D path, boolean isTransient) {\r
+        if (lineColor != null) // Highlight the flow if loop where the flow belongs to is selected.\r
+            g.setColor(loopColorOverride ? LoopNode.HIGHLIGHT_COLOR : lineColor);\r
+        if (lineStroke != null)\r
+            g.setStroke(lineStroke);\r
+\r
+        // Fetch the width of the flow\r
+        Float width = DEFAULT_LINE_WIDTH;\r
+        try {\r
+                       Float connectionWidth = SimanticsUI.getSession().syncRequest(new Read<Float>() {\r
+\r
+                               @Override\r
+                               public Float perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       if (resource == null)\r
+                                               return null;\r
+                                       return graph.getPossibleRelatedValue(resource, sr.FlowConnection_width, Bindings.FLOAT);\r
+                               }\r
+                       });\r
+                       if (connectionWidth != null)\r
+                               width = connectionWidth; \r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+        Path2D p1 = Flows.createOffsetPath(path, width/2);\r
+        Path2D p2 = Flows.createOffsetPath(path, -width/2);\r
+        p1.append(p2, false);\r
+        g.draw(p1);\r
+    }\r
+\r
+    @Override\r
+    public void drawDegeneratedLine(Graphics2D g, double x, double y, boolean isHorizontal, boolean isTransient) {\r
+    }\r
+\r
+    @Override\r
+    public double getDegeneratedLineLength() {\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     * Set if the flow color should be overwritten with loop color\r
+     * @param loopColorOverride \r
+     */\r
+       public void setLoopColorOverride(boolean loopColorOverride) {\r
+               this.loopColorOverride  = loopColorOverride;\r
+       }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/Flows.java
new file mode 100644 (file)
index 0000000..a7c6bd9
--- /dev/null
@@ -0,0 +1,257 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.geom.Path2D;\r
+import java.awt.geom.PathIterator;\r
+import java.awt.geom.Rectangle2D;\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(Path2D arrow, Rectangle2D tail, Rectangle2D head) {   \r
+\r
+       double x = tail.getCenterX();\r
+        double y = tail.getCenterY();\r
+\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
+        if(arrow == null)\r
+               arrow = new Path2D.Double();\r
+        else\r
+               arrow.reset();\r
+        \r
+        // approach from top\r
+        if (y < miny) {\r
+               arrow.moveTo(cx, miny);\r
+               arrow.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH);\r
+               arrow.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH);\r
+        } \r
+\r
+        // approach from beneath\r
+        else if (y > maxy) {\r
+               arrow.moveTo(cx, maxy);\r
+               arrow.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+               arrow.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH);\r
+        }\r
+\r
+        // approach from left\r
+        else if (x < minx) {\r
+               arrow.moveTo(minx, y);\r
+               arrow.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH);\r
+               arrow.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH);\r
+        }\r
+\r
+        // approach from right\r
+        else if (x > maxx) {\r
+               arrow.moveTo(maxx, y);\r
+               arrow.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH);\r
+               arrow.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
+        arrow.closePath();\r
+        \r
+        return arrow;\r
+        \r
+    }\r
+    \r
+    private static Path2D createLines(Path2D lines, boolean vertical, double ... coordinates) {\r
+       if(lines == null)\r
+               lines = new Path2D.Double();\r
+       else\r
+               lines.reset();\r
+       createOffsetLine(lines, vertical, OFFSET, coordinates);\r
+       createOffsetLine(lines, vertical, -OFFSET, coordinates);\r
+       return lines;\r
+    }\r
+\r
+    public static Path2D createLines(Path2D lines, boolean hasArrow, Rectangle2D valve, Rectangle2D node) {\r
+        double x0 = valve.getCenterX();\r
+        double y0 = valve.getCenterY();        \r
+        double x1 = node.getCenterX();\r
+        double y1 = node.getCenterY();\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 = 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(lines, true, y0, x0, minY);\r
+                else\r
+                       return createLines(lines, true, y0, x0, maxY);\r
+            }\r
+            else {\r
+                if(x1 > x0)\r
+                       return createLines(lines, true, y0, x0, y1, minX);\r
+                else\r
+                       return createLines(lines, 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(lines, false, x0, y0, minX);\r
+                else\r
+                       return createLines(lines, false, x0, y0, maxX);\r
+            }\r
+            else {\r
+                if(y1 > y0)\r
+                       return createLines(lines, false, x0, y0, x1, minY);\r
+                else\r
+                       return createLines(lines, false, x0, y0, x1, maxY);\r
+            }\r
+        }\r
+\r
+\r
+    }\r
+\r
+    public static Path2D createLine(Path2D path, boolean vertical, double ... coordinates) {\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(Path2D path, 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(path, vertical, newCoordinats);\r
+    }\r
+    \r
+    \r
+    private static int x = 0;\r
+    private static int y = 1;\r
+    public static Path2D createOffsetPath(Path2D originalPath, float offset) {\r
+        PathIterator pi = originalPath.getPathIterator(null);\r
+        Path2D newPath = new Path2D.Double();\r
+        double[] previous = new double[6];\r
+        double[] current = new double[6];\r
+        double[] next = new double[6];\r
+        boolean vertical = false;\r
+        pi.currentSegment(current);\r
+        pi.next();\r
+        pi.currentSegment(next);\r
+        \r
+        Direction direction = getDirection(current, next);\r
+\r
+        int i = 0;\r
+        if(direction == Direction.SOUTH || direction == Direction.NORTH) {\r
+            // First line vertical\r
+            vertical = true;\r
+            current[x] += offset;\r
+            newPath.moveTo(current[x], current[y]);\r
+            \r
+            if(direction == Direction.SOUTH)\r
+                offset = -offset;\r
+        } else {\r
+            // First line horizontal\r
+            current[y] += offset;\r
+            i = 1;\r
+            newPath.moveTo(current[x], current[y]);\r
+            if(direction == Direction.WEST)\r
+                offset = -offset;\r
+        }\r
+        \r
+\r
+        previous[x] = current[x];\r
+        previous[y] = current[y];\r
+        current[x] = next[x];\r
+        current[y] = next[y];\r
+\r
+        while(!pi.isDone()) {\r
+            pi.next();\r
+            pi.currentSegment(next);\r
+            if(previous[i] < next[i] ^ (i&1)==1) {\r
+                if(vertical) {\r
+                    if(!pi.isDone()) current[y] += offset;\r
+                    newPath.lineTo(previous[x], current[y]);\r
+                } else {\r
+                    if(!pi.isDone()) current[x] += offset;\r
+                    newPath.lineTo(current[x], previous[y]);\r
+                }\r
+            } else {\r
+                if(vertical) {\r
+                    if(!pi.isDone()) current[y] -= offset;\r
+                    newPath.lineTo(previous[x], current[y]);\r
+                } else {\r
+                    if(!pi.isDone()) current[x] -= offset;\r
+                    newPath.lineTo(current[x], previous[y]);\r
+                }\r
+            }\r
+            \r
+            previous[x] = current[x];\r
+            previous[y] = current[y];\r
+            current[x] = next[x];\r
+            current[y] = next[y];\r
+            vertical = !vertical;\r
+            i = (i + 1) % 2;\r
+        }\r
+        return newPath;\r
+    }\r
+    \r
+    private static enum Direction {NORTH, SOUTH, EAST, WEST};\r
+\r
+    private static Direction getDirection(double[] current, double[] next) {\r
+        if(current[x] == next[x]) {\r
+            // move vertically\r
+            if(current[y] < next[y])\r
+                return Direction.SOUTH;\r
+            else\r
+                return Direction.NORTH;\r
+        } else {\r
+            //move horizontally\r
+            if(current[x] < next[x])\r
+                return Direction.EAST;\r
+            else\r
+                return Direction.WEST;\r
+        }\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowConnectionFactory.java
new file mode 100644 (file)
index 0000000..517a696
--- /dev/null
@@ -0,0 +1,718 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.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.AffineTransform;\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.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.ConcurrentSkipListMap;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+\r
+import org.eclipse.jface.resource.StringConverter;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.db.procedure.SyncMultiProcedure;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.diagram.adapter.SyncElementFactory;\r
+import org.simantics.diagram.connection.ConnectionVisuals;\r
+import org.simantics.diagram.connection.RouteGraph;\r
+import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
+import org.simantics.diagram.connection.RouteLine;\r
+import org.simantics.diagram.connection.RouteNode;\r
+import org.simantics.diagram.connection.RouteTerminal;\r
+import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
+import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;\r
+import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
+import org.simantics.diagram.content.EdgeResource;\r
+import org.simantics.diagram.content.ResourceTerminal;\r
+import org.simantics.diagram.content.TerminalMap;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.diagram.synchronization.graph.RouteGraphConnection;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.connection.ConnectionEntity;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.handler.DataElementMap;\r
+import org.simantics.g2d.diagram.handler.Topology.Connection;\r
+import org.simantics.g2d.diagram.handler.Topology.Terminal;\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.EdgeVisuals.EdgeEnd;\r
+import org.simantics.g2d.element.handler.TerminalTopology;\r
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
+import org.simantics.g2d.routing.algorithm2.Router4;\r
+import org.simantics.g2d.utils.TopologicalSelectionExpander;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;\r
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphChangeEvent;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.CPTerminal;\r
+import org.simantics.structural2.modelingRules.IAttachmentRelationMap;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.ValveFactory.ValveSceneGraph;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPropertyExternalRead;\r
+import org.simantics.utils.datastructures.Pair;\r
+/**\r
+ * An element class for Sysdyn Flow elements.\r
+ * Copied from RouteGraphConnectionClassFactory and adapted to Flow needs\r
+ * \r
+ * @author Teemu Lempinen\r
+ * \r
+ */\r
+public class RouteFlowConnectionFactory extends SyncElementFactory {\r
+\r
+    public static final ElementClass CLASS = RouteFlowEdgeClass.FLOW_CLASS;\r
+\r
+    Layer0                             L0;\r
+    DiagramResource                    DIA;\r
+    StructuralResource2                STR;\r
+    ModelingResources                  MOD;\r
+\r
+    public RouteFlowConnectionFactory(ReadGraph graph) {\r
+        this.L0 = Layer0.getInstance(graph);\r
+        this.DIA = DiagramResource.getInstance(graph);\r
+        this.STR = StructuralResource2.getInstance(graph);\r
+        this.MOD = ModelingResources.getInstance(graph);\r
+    }\r
+\r
+    @Override\r
+    public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
+        procedure.execute(graph, CLASS.newClassWith(false, new StaticObjectAdapter(elementType)));\r
+    }\r
+\r
+    @Override\r
+    protected Resource getElementClassBaseType(AsyncReadGraph graph) {\r
+        return graph.getService(SysdynResource.class).FlowConnection;\r
+    }\r
+\r
+    @Override\r
+    public void load(ReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource connection,\r
+            final IElement element) throws DatabaseException {\r
+\r
+        // Do we need this?\r
+        element.setHint(DiagramHints.ROUTE_ALGORITHM, new Router4(false));\r
+        IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);\r
+\r
+        Color color = null;\r
+        DiagramResource DR = DiagramResource.getInstance(graph);\r
+        G2DResource G2D = G2DResource.getInstance(graph);\r
+        if (graph.isInstanceOf(connection, DR.ColorProvider)) {\r
+            Statement colorStatement = graph.getPossibleStatement(connection, G2D.HasColor);\r
+            if(colorStatement != null && !colorStatement.isAsserted(connection)) {\r
+                element.setHint(ElementHints.KEY_TEXT_COLOR, G2DUtils.getColor(graph, colorStatement.getObject()));\r
+            } else {\r
+                String colorString = graph.syncRequest(new SysdynDiagramPropertyExternalRead(new Pair<Resource, String>(connection, SysdynDiagramPreferences.getColorPreferenceName(graph, connection))));\r
+                if(colorString != null) {\r
+                    RGB rgb = StringConverter.asRGB(colorString, null);\r
+                    if(rgb != null) {\r
+                        color = new Color(rgb.red, rgb.green, rgb.blue);\r
+                        element.setHint(ElementHints.KEY_TEXT_COLOR, color);\r
+                    }\r
+                }\r
+\r
+            }\r
+        }\r
+\r
+        RouteGraph rg = new RouteGraph();\r
+\r
+        Set<Resource> nodes = new HashSet<Resource>();\r
+        Set<EdgeResource> links = new HashSet<EdgeResource>();\r
+        Map<Object, RouteNode> nodeByData = new HashMap<Object, RouteNode>();\r
+\r
+        // Needed to support ConnectionEntity#getTerminalConnections\r
+        Set<BackendConnection> backendonnections = new HashSet<BackendConnection>();\r
+\r
+        // Load all route graph interior RouteNodes: route lines and points\r
+        for (Resource interiorNode : graph.getObjects(connection, DIA.HasInteriorRouteNode)) {\r
+            if (graph.isInstanceOf(interiorNode, DIA.RouteLine)) {\r
+                Boolean isHorizontal = graph.getRelatedValue(interiorNode, DIA.IsHorizontal, Bindings.BOOLEAN);\r
+                Double position = graph.getRelatedValue(interiorNode, DIA.HasPosition, Bindings.DOUBLE);\r
+                RouteLine line = rg.addLine(isHorizontal, position);\r
+                line.setData( RouteGraphConnection.serialize(graph, interiorNode) );\r
+\r
+                nodes.add( interiorNode );\r
+                nodeByData.put( interiorNode, line );\r
+\r
+                for (Resource connectedTo : graph.getObjects(interiorNode, DIA.AreConnected)) {\r
+                    links.add( new EdgeResource(interiorNode, connectedTo) );\r
+                }\r
+            } else if (graph.isInstanceOf(interiorNode, DIA.RoutePoint)) {\r
+                // Not supported yet. Ignore.\r
+            }\r
+        }\r
+\r
+        Rectangle2D bounds = new Rectangle2D.Double();\r
+\r
+        // Load all node terminal connections as RouteTerminals\r
+        for (Statement toConnector : graph.getStatements(connection, DIA.HasConnector)) {\r
+            Resource connector = toConnector.getObject();\r
+            Resource attachmentRelation = toConnector.getPredicate();\r
+\r
+            Statement terminalStm = findTerminalStatement(graph, STR, connection, connector);\r
+            if (terminalStm == null)\r
+                // Ignore broken connector: attached to the connection but not to any terminal.\r
+                continue;\r
+\r
+            Resource terminalElement = terminalStm.getObject();\r
+            Resource terminalElementType = graph.getPossibleType(terminalElement, DIA.Element);\r
+            if (terminalElementType == null)\r
+                // Ignore non-element terminal elements\r
+                continue;\r
+\r
+            Resource connectionRelation = graph.getInverse(terminalStm.getPredicate());\r
+\r
+            // Discover node and terminal this connector is connected to.\r
+            TerminalMap terminals = graph.syncRequest(DiagramRequests.elementTypeTerminals(terminalElementType),\r
+                    TransientCacheListener.<TerminalMap> instance());\r
+            Resource terminal = terminals.getTerminal(connectionRelation);\r
+            if (terminal == null) {\r
+                System.err.println(getClass().getSimpleName()\r
+                        + ": Could not find terminal for connection point "\r
+                        + NameUtils.getSafeName(graph, connectionRelation, true)\r
+                        + " in element "\r
+                        + NameUtils.getSafeName(graph, terminalElement, true)); \r
+                continue;\r
+            }\r
+\r
+            double[] position = graph.getRelatedValue(connector, DIA.HasRelativeLocation, Bindings.DOUBLE_ARRAY);\r
+            if (position.length != 2)\r
+                position = new double[] { 0, 0 };\r
+\r
+            //System.out.println("terminalStm: " + NameUtils.toString(graph, terminalStm));\r
+            AffineTransform terminalElementTr = getWorldTransform(graph, terminalElement);\r
+\r
+            double x = terminalElementTr.getTranslateX();\r
+            double y = terminalElementTr.getTranslateY();\r
+            double minx = x-1, miny = y-1, maxx = x+1, maxy = y+1;\r
+            int direction = 0x0;\r
+\r
+            // Use modelingRules to ascertain the proper attachmentRelation\r
+            // for this terminal connection, if available.\r
+            if (modelingRules != null) {\r
+                // Get attachmentRelation from modelingRules if possible.\r
+                IAttachmentRelationMap map = modelingRules.getAttachmentRelations(graph, connection);\r
+                Resource att = map.get(graph, new CPTerminal(terminalElement, terminal));\r
+                if (att != null) {\r
+                    //System.out.println("modeling rules attachment: " + NameUtils.getSafeLabel(graph, att));\r
+                    attachmentRelation = att;\r
+                }\r
+            }\r
+            //System.out.println("attachment: " + NameUtils.getSafeLabel(graph, attachmentRelation));\r
+\r
+            // Get element bounds to decide allowed terminal direction(s)\r
+            IElement te = graph.syncRequest(DiagramRequests.getElement(canvas, diagram, terminalElement, null));\r
+  \r
+            // Fetch the flow width\r
+            float lw = FlowConnectionStyle.DEFAULT_LINE_WIDTH;\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Float width = graph.getPossibleRelatedValue(connection, sr.FlowConnection_width, Bindings.FLOAT);\r
+               if (width != null)\r
+                       lw = width;\r
+            \r
+               if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                // Valve behaves differently. The flow must start inside the valve bounds\r
+                ValveSceneGraph vs = te.getElementClass().getSingleItem(ValveSceneGraph.class);\r
+                Rectangle2D size = new Rectangle2D.Double();\r
+                vs.getValveBounds(te, size);\r
+                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(size, terminalElementTr);\r
+                size = (Rectangle2D) shp;\r
+                bounds.setFrame(new Rectangle2D.Double(size.getCenterX() - (lw/2), size.getCenterY() - (lw/2), lw, lw));\r
+            } else {\r
+                // Basic bounds\r
+                bounds = ElementUtils.getElementShape(te).getBounds2D();\r
+                Shape shp = org.simantics.g2d.utils.GeometryUtils.transformShape(bounds, terminalElementTr);\r
+                bounds.setFrame(shp.getBounds2D());\r
+            }\r
+            \r
+            x = bounds.getCenterX();\r
+            y = bounds.getCenterY();\r
+\r
+            // Expand bounds by 4mm to make the connections enter the terminals\r
+            // at a straight angle and from a distance instead of coming in\r
+            // "horizontally".\r
+            //GeometryUtils.expandRectangle(bounds, 4);\r
+\r
+            minx = bounds.getMinX();\r
+            miny = bounds.getMinY();\r
+            maxx = bounds.getMaxX();\r
+            maxy = bounds.getMaxY();\r
+\r
+            Integer allowedDirections = graph.getPossibleRelatedValue(terminal, DIA.Terminal_AllowedDirections, Bindings.INTEGER);\r
+\r
+            // Valve behaves differently. Allowed directions depend on the orientation of the valve\r
+            if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+                if(graph.hasStatement(terminalElement, sr.ValveSymbol_orientation, sr.Vertical)) {\r
+                    allowedDirections = 10; // Directions up and down (1010)\r
+                } else {\r
+                    allowedDirections = 5; // Directions left and right (0101)\r
+                }\r
+            }\r
+            if (allowedDirections != null) {\r
+                direction |= allowedDirections;\r
+            } else {\r
+                direction |= RouteGraphConnectionClass.shortestDirectionOutOfBounds(x, y, bounds);\r
+            }\r
+\r
+            backendonnections.add(\r
+                    new BackendConnection(\r
+                            toEdgeEnd(graph, attachmentRelation, EdgeEnd.Begin),\r
+                            terminalElement,\r
+                            terminal)\r
+                    );\r
+\r
+            if (direction == 0)\r
+                // Accept any horizontal/vertical direction if nothing is defined\r
+                direction = 0xf;\r
+\r
+            //System.out.println("load line style: " + NameUtils.getSafeLabel(graph, attachmentRelation));\r
+            ILineEndStyle endStyle = loadLineEndStyle(graph, te, attachmentRelation, color, lw);\r
+\r
+            RouteTerminal routeTerminal = rg.addBigTerminal(/*x, y,*/ minx, miny, maxx, maxy, /*direction,*/ endStyle);\r
+            routeTerminal.setData( RouteGraphConnection.serialize(graph, connector) );\r
+\r
+            nodes.add( connector );\r
+            nodeByData.put( connector, routeTerminal );\r
+\r
+            for (Resource connectedTo : graph.getObjects(connector, DIA.AreConnected)) {\r
+                links.add( new EdgeResource(connectedTo, connector) );\r
+            }\r
+        }\r
+\r
+        // Finish route graph loading by Linking route nodes together\r
+        for (EdgeResource link : links) {\r
+            RouteNode n1 = nodeByData.get(link.first());\r
+            RouteNode n2 = nodeByData.get(link.second());\r
+            if (n1 == null || n2 == null) {\r
+                System.err.println("Stray connection link found: " + link.toString(graph));\r
+                continue;\r
+            }\r
+            rg.link(n1, n2);\r
+        }\r
+\r
+        // Load connection line style\r
+        ConnectionStyle style = readConnectionStyle(graph, modelingRules, connection, element);\r
+        StyledRouteGraphRenderer renderer = new StyledRouteGraphRenderer(style);\r
+\r
+        // Finish element load\r
+        element.setHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH, rg);\r
+        element.setHint(RouteGraphConnectionClass.KEY_RENDERER, renderer);\r
+        element.setHint(RouteGraphConnectionClass.KEY_PICK_TOLERANCE, 0.5);\r
+\r
+        // Initialize ConnectionEntity in element\r
+        // NOTE: MUST use the mapped element with class CE, not the connection (element) were loading into.\r
+        // GDS will synchronize element into mappedElement in a controlled manner.\r
+        element.setHint(ElementHints.KEY_CONNECTION_ENTITY, new CE(diagram, connection, element, backendonnections));\r
+\r
+        // Setup graph writeback support for route graph modifications\r
+        final Session session = graph.getSession();\r
+        element.setHint(RouteGraphConnectionClass.KEY_RG_LISTENER, new IRouteGraphListener() {\r
+            @Override\r
+            public void routeGraphChanged(RouteGraphChangeEvent event) {\r
+                scheduleSynchronize(session, connection, event);\r
+            }\r
+        });\r
+        \r
+     // A complicated-looking procedure for obtaining all HasProperties to properties map\r
+        final AtomicInteger ready = new AtomicInteger(1);\r
+        final ConcurrentSkipListMap<String, Pair<Resource, Object>> properties = new ConcurrentSkipListMap<String, Pair<Resource, Object>>();\r
+        graph.forEachPredicate(connection, new SyncMultiProcedure<Resource>() {\r
+\r
+            @Override\r
+            public void exception(ReadGraph graph, Throwable throwable) {\r
+                throwable.printStackTrace();\r
+            }\r
+\r
+            @Override\r
+            public void execute(ReadGraph graph, final Resource property) {\r
+\r
+                ready.incrementAndGet();\r
+                Layer0 l0;\r
+                try {\r
+                    l0 = Layer0.getInstance(graph.getSession());\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                    return;\r
+                }\r
+\r
+                graph.forIsSubrelationOf(property, l0.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(connection, 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
+                                    Layer0 l0;\r
+                                    try {\r
+                                        l0 = Layer0.getInstance(graph.getSession());\r
+                                    } catch (DatabaseException e) {\r
+                                        e.printStackTrace();\r
+                                        return;\r
+                                    }\r
+\r
+                                    graph.forPossibleRelatedValue(property, l0.HasName, Bindings.STRING, 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
+                                            if(ready.decrementAndGet() == 0) {\r
+                                                element.setHint(DiagramHints.PROPERTIES, new HashMap<String, Pair<Resource, Object>>(properties));\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
+                            }\r
+\r
+                        }\r
+\r
+                    }\r
+\r
+                });\r
+            }\r
+\r
+            @Override\r
+            public void finished(ReadGraph graph) {\r
+\r
+                if(ready.decrementAndGet() == 0) {\r
+                    element.setHint(DiagramHints.PROPERTIES, new HashMap<String, Object>(properties));\r
+                }\r
+\r
+            }\r
+\r
+        });\r
+\r
+    }\r
+\r
+    private EdgeEnd toEdgeEnd(ReadGraph graph, Resource attachmentRelation, EdgeEnd defaultValue)\r
+            throws DatabaseException {\r
+        if (graph.isSubrelationOf(attachmentRelation, DIA.IsTailConnectorOf))\r
+            return EdgeEnd.Begin;\r
+        if (graph.isSubrelationOf(attachmentRelation, DIA.IsHeadConnectorOf))\r
+            return EdgeEnd.End;\r
+        return defaultValue;\r
+    }\r
+\r
+    private ConnectionStyle readConnectionStyle(ReadGraph graph, IModelingRules modelingRules, Resource connection,\r
+            IElement element) throws DatabaseException {\r
+        Resource connectionType = null;\r
+        if (modelingRules != null)\r
+            connectionType = modelingRules.getConnectionType(graph, connection);\r
+        if (connectionType == null)\r
+            connectionType = graph.getPossibleObject(connection, STR.HasConnectionType);\r
+\r
+        ConnectionVisuals cv = null;\r
+        if (connectionType != null)\r
+            cv = graph.syncRequest(DiagramRequests.getConnectionVisuals(connectionType),\r
+                    TransientCacheListener.<ConnectionVisuals> instance());\r
+\r
+\r
+        Color lineColor = element.getHint(ElementHints.KEY_TEXT_COLOR);\r
+        if (lineColor == null)\r
+            lineColor = (cv != null && cv.toColor() != null) ? cv.toColor() : Color.DARK_GRAY;\r
+\r
+            Stroke lineStroke = cv != null ? cv.stroke : null;\r
+            if (lineStroke == null)\r
+                lineStroke = new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, null, 0);\r
+\r
+            return new FlowConnectionStyle(\r
+                    lineColor,\r
+                    lineStroke,\r
+                    connection);\r
+    }\r
+\r
+    /**\r
+     * @param graph\r
+     * @param STR\r
+     * @param connection\r
+     * @param connector\r
+     * @return connection relation statement from diagram connection connector\r
+     *         to a node\r
+     * @throws DatabaseException\r
+     */\r
+    private static Statement findTerminalStatement(ReadGraph graph, StructuralResource2 STR, Resource connection,\r
+            Resource connector) throws DatabaseException {\r
+        for (Statement stm : graph.getStatements(connector, STR.Connects)) {\r
+            if (connection.equals(stm.getObject()))\r
+                continue;\r
+            return stm;\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public ILineEndStyle loadLineEndStyle(ReadGraph graph, IElement te, Resource attachmentRelation, Color color, float lineWidth)\r
+            throws DatabaseException {\r
+        ILineEndStyle style;\r
+        // TODO: change bounds according to terminal type: Very small rectangle for Valves, Text box size for Stocks and Clouds\r
+        if(te.getElementClass().containsClass(ValveSceneGraph.class)) {\r
+            style =  new FlowArrowLineStyle("none 0 0 0", color);\r
+        } else {\r
+            if (graph.isSubrelationOf(attachmentRelation, DIA.HasHeadConnector)) {\r
+                float arrowSize = lineWidth * 1.3f;\r
+                style = new FlowArrowLineStyle("fill " + arrowSize + " " + arrowSize + " 0", color);\r
+            } else {\r
+                style =  new FlowArrowLineStyle("none 0 0 0", color);\r
+            }\r
+        }\r
+        return style;\r
+    }\r
+\r
+    /**\r
+     * @param graph\r
+     * @param element\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    private static AffineTransform getWorldTransform(ReadGraph graph, Resource element) throws DatabaseException {\r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        AffineTransform result = DiagramGraphUtil.getAffineTransform(graph, element);\r
+        while (true) {\r
+            Resource parentComponent = graph.getPossibleObject(element, MOD.HasParentComponent);\r
+            if (parentComponent == null)\r
+                return result;\r
+            element = graph.getPossibleObject(parentComponent, MOD.ComponentToElement);\r
+            if (element == null)\r
+                return result;\r
+            AffineTransform tr = DiagramGraphUtil.getAffineTransform(graph, element);\r
+            tr.setToTranslation(tr.getTranslateX(), tr.getTranslateY());\r
+            result.preConcatenate(tr);\r
+        }\r
+    }\r
+\r
+\r
+    protected void scheduleSynchronize(Session session, Resource connection, RouteGraphChangeEvent event) {\r
+        session.asyncRequest(RouteGraphConnection.synchronizer(connection, event));\r
+    }\r
+\r
+    /**\r
+     * Must have this in order for {@link TopologicalSelectionExpander} to work.\r
+     * Otherwise this is pretty useless and should be deprecated altogether.\r
+     * \r
+     * @see ElementHints#KEY_CONNECTION_ENTITY\r
+     */\r
+    static class CE implements ConnectionEntity {\r
+\r
+        \r
+        private IDiagram diagram;\r
+\r
+        private transient DataElementMap dataMap;\r
+        \r
+        /**\r
+         * The connection instance resource in the graph backend.\r
+         */\r
+        final Resource               connection;\r
+\r
+        /**\r
+         * The connection entity element which is a part of the diagram.\r
+         */\r
+        IElement               connectionElement;\r
+\r
+        /**\r
+         * @see #getTerminalConnections(Collection)\r
+         */\r
+        final Set<BackendConnection> backendConnections;\r
+\r
+        /**\r
+         * Cache.\r
+         */\r
+        Set<Connection>              terminalConnections;\r
+\r
+        \r
+        public CE(IDiagram diagram, Resource connection, IElement connectionElement, Set<BackendConnection> backendConnections) {\r
+            if (connectionElement == null)\r
+                throw new NullPointerException("null connection element");\r
+            this.diagram = diagram;\r
+            this.dataMap = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
+            this.connection = connection;\r
+            this.connectionElement = connectionElement;\r
+            this.backendConnections = backendConnections;\r
+            IElement ce = getConnection0();\r
+            if (ce != null)\r
+                this.connectionElement = ce;\r
+        }\r
+\r
+        public IElement getConnection0() {\r
+            IElement connectionElement = dataMap.getElement(diagram, connection);\r
+            return connectionElement;\r
+        }\r
+\r
+        @Override\r
+        public IElement getConnection() {\r
+            IElement c = getConnection0();\r
+            if (c == null)\r
+                c = this.connectionElement;\r
+            return c;\r
+        }\r
+\r
+        public Object getConnectionObject() {\r
+            return connection;\r
+        }\r
+\r
+        public IElement getConnectionElement() {\r
+            return connectionElement;\r
+        }\r
+\r
+        @Override\r
+        public Collection<IElement> getBranchPoints(Collection<IElement> result) {\r
+            return result != null ? result : Collections.<IElement> emptyList();\r
+        }\r
+\r
+        @Override\r
+        public Collection<IElement> getSegments(Collection<IElement> result) {\r
+            return result != null ? result : Collections.<IElement> emptyList();\r
+        }\r
+\r
+        @Override\r
+        public Collection<Connection> getTerminalConnections(Collection<Connection> result) {\r
+            if (terminalConnections == null)\r
+                terminalConnections = calculateTerminalConnections();\r
+            if (result == null)\r
+                result = new ArrayList<Connection>(terminalConnections);\r
+            else\r
+                result.addAll(terminalConnections);\r
+            return terminalConnections;\r
+        }\r
+\r
+        private Set<Connection> calculateTerminalConnections() {\r
+            DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
+            Set<Connection> result = new HashSet<Connection>();\r
+            ArrayList<Terminal> ts = new ArrayList<Terminal>();\r
+            for (BackendConnection bc : backendConnections) {\r
+                IElement e = dem.getElement(diagram, bc.node);\r
+                if (e == null)\r
+                    continue;\r
+                TerminalTopology tt = e.getElementClass().getSingleItem(TerminalTopology.class);\r
+                tt.getTerminals(e, ts);\r
+                for (Terminal t : ts) {\r
+                    if (t instanceof ResourceTerminal) {\r
+                        ResourceTerminal rt = (ResourceTerminal) t;\r
+                        if (bc.terminal.equals(rt.getResource())) {\r
+                            result.add(new Connection(connectionElement, bc.end, e, t));\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public void setListener(ConnectionListener listener) {\r
+            throw new UnsupportedOperationException();\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return getClass().getSimpleName() + "[resource=" + connection + ", connectionElement=" + connectionElement\r
+                    + "]";\r
+        }\r
+\r
+    }\r
+\r
+    public static class BackendConnection {\r
+        public final Resource node;\r
+        public final Resource terminal;\r
+        public final EdgeEnd  end;\r
+        public BackendConnection(EdgeEnd end, Resource node, Resource terminal) {\r
+            assert end != null;\r
+            assert node != null;\r
+            assert terminal != null;\r
+            this.end = end;\r
+            this.node = node;\r
+            this.terminal = terminal;\r
+        }\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (!(obj instanceof Connection))\r
+                return false;\r
+            Connection other = (Connection) obj;\r
+            return other.terminal == terminal\r
+                    && other.node == node\r
+                    && other.end == end;\r
+        }\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + end.hashCode();\r
+            result = prime * result + ((node == null) ? 0 : node.hashCode());\r
+            result = prime * result + ((terminal == null) ? 0 : terminal.hashCode());\r
+            return result;\r
+        }\r
+        @Override\r
+        public String toString() {\r
+            return "BackendConnection[node=" + node + ", terminal=" + terminal + ", end=" + end + "]";\r
+        }\r
+    }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeClass.java
new file mode 100644 (file)
index 0000000..5061e73
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.simantics.diagram.connection.RouteGraph;\r
+import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
+import org.simantics.diagram.connection.rendering.IRouteGraphRenderer;\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.handler.ElementHandler;\r
+import org.simantics.g2d.element.handler.SceneGraph;\r
+import org.simantics.scenegraph.g2d.G2DParentNode;\r
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;\r
+\r
+\r
+public class RouteFlowEdgeClass extends RouteGraphConnectionClass {\r
+    \r
+    public static final ElementClass FLOW_CLASS = getElementClass();\r
+\r
+            \r
+    public static final ElementClass getElementClass() {\r
+        List<ElementHandler> oldList = CLASS.getAll();\r
+        ArrayList<ElementHandler> list = new ArrayList<ElementHandler>();\r
+        list.add(FlowConnectionSceneGraph.INSTANCE);\r
+        for(ElementHandler eh : oldList) {\r
+            if(!(eh instanceof SceneGraph)) {\r
+                list.add(eh);\r
+            }\r
+        }\r
+        return  ElementClass.compile(list);\r
+    }\r
+    \r
+    \r
+    static final class FlowConnectionSceneGraph implements SceneGraph {\r
+\r
+        public static final FlowConnectionSceneGraph INSTANCE = new FlowConnectionSceneGraph();\r
+\r
+        private static final long serialVersionUID = 1865920472882420644L;\r
+\r
+        @Override\r
+        public void init(IElement connection, G2DParentNode parent) {\r
+            RouteGraph rg = connection.getHint(KEY_ROUTEGRAPH);\r
+            IRouteGraphRenderer renderer = connection.getHint(KEY_RENDERER);\r
+            if (rg == null || renderer == null) {\r
+                cleanup(connection);\r
+            } else {\r
+               RouteFlowNode rgn = ElementUtils.getOrCreateNode(connection, parent, KEY_RG_NODE, "flow_" + connection.hashCode(), RouteFlowNode.class);\r
+                rgn.setRouteGraph(rg);\r
+                rgn.setRenderer(renderer);\r
+\r
+                IRouteGraphListener listener = connection.getHint(KEY_RG_LISTENER);\r
+                rgn.setRouteGraphListener(listener);\r
+\r
+                Double tolerance = connection.getHint(KEY_PICK_TOLERANCE);\r
+                if (tolerance != null)\r
+                    rgn.setPickTolerance(tolerance);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void cleanup(IElement connection) {\r
+            ElementUtils.removePossibleNode(connection, KEY_RG_NODE);\r
+            connection.removeHint(KEY_RG_NODE);\r
+        }\r
+    }\r
+\r
+}\r
+\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowEdgeFactory.java
new file mode 100644 (file)
index 0000000..97bb845
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.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
+public class RouteFlowEdgeFactory extends ElementFactoryAdapter {\r
+\r
+    private static final ElementClass CLASS = RouteFlowEdgeClass.FLOW_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
+        procedure.execute(graph, CLASS);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/RouteFlowNode.java
new file mode 100644 (file)
index 0000000..4a75f08
--- /dev/null
@@ -0,0 +1,72 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013-2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
+import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;\r
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode;\r
+import org.simantics.sysdyn.ui.elements.LoopNode.ILoopComponentNode;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+\r
+/**\r
+ * Node for flow arrows.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class RouteFlowNode extends RouteGraphNode implements ILoopComponentNode {\r
+\r
+       private static final long serialVersionUID = 2576929364910319487L;\r
+       boolean isLock = false;\r
+       private HashMap<LoopNode, Boolean> loopSelectionMap = new HashMap<LoopNode, Boolean>();\r
+\r
+       private boolean isLoopSelected() {\r
+               return loopSelectionMap.containsValue(true);\r
+       }\r
+       \r
+       @Override\r
+    protected boolean mouseDragged(MouseDragBegin e) {\r
+               // Disable dragging if LockSketch is ON\r
+               if (SysdynElementHints.LOCK_TOOL.equals(SysdynWorkbenchUtils.getSysdynToolMode()))\r
+                       return false;\r
+               else\r
+                       return super.mouseDragged(e);\r
+       }\r
+\r
+       @Override\r
+       public void setLoopSelected(LoopNode loop, boolean selected) {\r
+               Boolean loopSelected = loopSelectionMap.get(loop);\r
+               if (loopSelected == null || loopSelected != selected) {\r
+                       loopSelectionMap.put(loop, selected);\r
+                       \r
+                       // Here the FlowConnectionStyle takes care of drawing the flow, so\r
+                       // find it and tell it to change the color accordingly\r
+                       if (!(renderer instanceof StyledRouteGraphRenderer))\r
+                               return;\r
+               \r
+                       StyledRouteGraphRenderer renderer = (StyledRouteGraphRenderer)this.renderer;\r
+                       ConnectionStyle style = renderer.getStyle();\r
+                       if (!(style instanceof FlowConnectionStyle))\r
+                               return;\r
+                       \r
+                       FlowConnectionStyle fcs = (FlowConnectionStyle)style;\r
+                       \r
+                       fcs.setLoopColorOverride(isLoopSelected());\r
+                       repaint();\r
+               }\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/connections/SysdynConnectionClass.java
new file mode 100644 (file)
index 0000000..e9fc970
--- /dev/null
@@ -0,0 +1,572 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.connections;\r
+\r
+import java.awt.Color;\r
+import java.awt.Composite;\r
+import java.awt.Font;\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.TextColorImpl;\r
+import org.simantics.g2d.element.handler.impl.TextFontImpl;\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
+                TextFontImpl.DEFAULT,\r
+                TextColorImpl.BLACK,\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 class ThreadLocalList extends ThreadLocal<List<IElement>> {\r
+        @Override\r
+        protected java.util.List<IElement> initialValue() {\r
+            return new ArrayList<IElement>();\r
+        }\r
+    };\r
+\r
+    private static final ThreadLocal<List<IElement>> perThreadSceneGraphList = new ThreadLocalList();\r
+    private static final ThreadLocal<List<IElement>> perThreadBoundsList = new ThreadLocalList();\r
+    private static final ThreadLocal<List<IElement>> perThreadShapeList = new ThreadLocalList();\r
+    private static final ThreadLocal<List<IElement>> perThreadPickList = new ThreadLocalList();\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
+\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 = perThreadSceneGraphList.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
+               Font font = connection.getHint(ElementHints.KEY_FONT);\r
+               Color color = connection.getHint(ElementHints.KEY_TEXT_COLOR);\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
+                if(font != null)\r
+                    child.setHint(ElementHints.KEY_FONT, font);\r
+                \r
+                if(color != null)\r
+                    child.setHint(ElementHints.KEY_TEXT_COLOR, color);\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((AffineTransform) at2.clone());\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
+            ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY);\r
+            if (ce == null)\r
+                return size;\r
+\r
+            Collection<IElement> parts = perThreadBoundsList.get();\r
+            parts.clear();\r
+            parts = ce.getSegments(parts);\r
+            if (parts.isEmpty())\r
+                return size;\r
+\r
+            parts = ce.getBranchPoints(parts);\r
+\r
+            Rectangle2D temp = null;\r
+            for (IElement part : parts) {\r
+                if (ElementUtils.isHidden(part))\r
+                    continue;\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
+                // bounds also need to be calculated in absolute coordinates.\r
+                Rectangle2D bounds = ElementUtils.getElementBoundsOnDiagram(part, size);\r
+                if (bounds == null)\r
+                    continue;\r
+\r
+//                System.out.println("InternalSize BOUNDS: " + size + " for part " + part + " " + part.getElementClass());\r
+                if (temp == null) {\r
+                    temp = new Rectangle2D.Double();\r
+                    temp.setRect(bounds);\r
+                } else\r
+                    Rectangle2D.union(temp, bounds, temp);\r
+                //System.out.println("InternalSize Combined BOUNDS: " + temp);\r
+            }\r
+            if (temp != null) {\r
+                if (size == null)\r
+                    size = temp;\r
+                else\r
+                    size.setRect(temp);\r
+            }\r
+\r
+            // Don't leave dangling references behind.\r
+            parts.clear();\r
+\r
+            return size;\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 = perThreadShapeList.get();\r
+            parts.clear();\r
+            parts = ce.getSegments(parts);\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 = org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(bounds, 0, 0, exp, exp);\r
+                    else if (h <= 0.0)\r
+                        shape = org.simantics.scenegraph.utils.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
+            // Don't leave dangling references behind.\r
+            parts.clear();\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 = perThreadPickList.get();\r
+            parts.clear();\r
+            parts = ce.getBranchPoints(parts);\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
+            parts.clear();\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 = perThreadPickList.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
+            parts.clear();\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/elements/profiles/IssueDecorationStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/IssueDecorationStyle.java
new file mode 100644 (file)
index 0000000..e3db689
--- /dev/null
@@ -0,0 +1,190 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.profiles;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.PossibleTypedParent;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.diagram.profile.StyleBase;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.issues.common.ErrorIssues;\r
+import org.simantics.issues.common.FatalIssues;\r
+import org.simantics.issues.common.WarningIssues;\r
+import org.simantics.issues.ontology.IssueResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.g2d.nodes.SVGNode;\r
+import org.simantics.scenegraph.profile.EvaluationContext;\r
+import org.simantics.scenegraph.profile.common.ProfileVariables;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.utils.datastructures.map.Tuple;\r
+\r
+/**\r
+ * Issue Decorations. Display an issue icon on \r
+ * a diagram element depending on the type of the issue\r
+ * .\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class IssueDecorationStyle extends StyleBase<IssueResult> {\r
+\r
+    private static final String DECORATION_NODE_NAME = "issueDecorations";\r
+\r
+    @Override\r
+    public IssueResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        // Find a component for the element \r
+        Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);\r
+        \r
+        // If component is shadow, find the original component\r
+        if (component != null && graph.isInstanceOf(component, SR.Shadow)) {\r
+            component = graph.getPossibleObject(component, SR.Shadow_original);\r
+        }\r
+\r
+        if (component == null)\r
+            return null;\r
+        \r
+        // Get the current transform of the element to be able to move the decoration with the element\r
+        AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element);\r
+\r
+        // Find the model of the component\r
+        Resource model = graph.syncRequest(new PossibleTypedParent(component, SimulationResource.getInstance(graph).Model));\r
+        if (model == null)\r
+            return null;\r
+\r
+        // Project\r
+        Resource project = graph.getPossibleObject(model, L0.PartOf);\r
+        if (project == null)\r
+            return null;\r
+\r
+        IssueResult result = null;\r
+        \r
+        /*\r
+         * Search for issues. Start from fatal and move to\r
+         * less important issues. This way the most important \r
+         * issue will be displayed.\r
+         * \r
+         * The issue is returned immediately after it is found.\r
+         */\r
+        \r
+        Set<Variable> fatals = graph.syncRequest(new FatalIssues(project, true));\r
+        result = getIssue(graph, IssueResult.Severity.FATAL, fatals, component, transform);\r
+        if(result != null) return result;\r
+        \r
+        Set<Variable> errors = graph.syncRequest(new ErrorIssues(project, true));\r
+        result = getIssue(graph, IssueResult.Severity.ERROR, errors, component, transform);\r
+        if(result != null) return result;\r
+\r
+        Set<Variable> warnings = graph.syncRequest(new WarningIssues(project, true));\r
+        result = getIssue(graph, IssueResult.Severity.WARNING, warnings, component, transform);\r
+        if(result != null) return result;\r
+\r
+        // No issue was found\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * See if a set of issue variables concern this component\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param severity IssueResult.Severity of the issue\r
+     * @param issues Collection of issues of type severity\r
+     * @param component The component that is evaluated for issues\r
+     * @param transform AffineTransform of the diagram element\r
+     * @return IssueResult containing the severity and transform of the issue or null if no issue concerned component\r
+     * @throws DatabaseException\r
+     */\r
+    private IssueResult getIssue(ReadGraph graph, IssueResult.Severity severity, Set<Variable> issues, Resource component, AffineTransform transform) throws DatabaseException {\r
+        IssueResource ISSUE = IssueResource.getInstance(graph);\r
+        Resource list, issueResource;\r
+        for(Variable issue : issues) {\r
+            issueResource = issue.getRepresents(graph);\r
+            list = graph.getPossibleObject(issueResource, ISSUE.Issue_HasContexts);\r
+            List<Resource> contexts = ListUtils.toList(graph, list);\r
+            if(!contexts.isEmpty()) {\r
+                if(ListUtils.toList(graph, list).subList(0, 1).contains(component)) {\r
+                    return new IssueResult(severity, transform);\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void applyStyleForNode(EvaluationContext observer, INode node, IssueResult result) {\r
+        \r
+        // If result == null, remove possible issue decoration\r
+        if (result == null) {\r
+            ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME);\r
+            return;\r
+        }\r
+\r
+        // Create issue decoration node\r
+        SVGNode svgNode = ProfileVariables.claimChild(node, "", DECORATION_NODE_NAME, SVGNode.class, observer);\r
+\r
+        // Move the decoration to the upper right corner of the element\r
+        Rectangle2D bounds = NodeUtil.getLocalBounds(node, Collections.<INode>singleton(svgNode));\r
+        double tx = bounds.getMaxX();\r
+        double ty = bounds.getY();\r
+        svgNode.setZIndex( Integer.MAX_VALUE );\r
+        svgNode.setTransform( AffineTransform.getTranslateInstance(tx-1, ty-1)); \r
+        svgNode.getTransform().scale(0.5, 0.5);\r
+        \r
+\r
+        // Apply the corresponding svg graphics to the node\r
+        IssueResult.Severity sev = result.getSeverity();\r
+        if (IssueResult.Severity.FATAL.equals(sev))\r
+            svgNode.setData(Activator.FATAL_SVG_TEXT);\r
+        else if (IssueResult.Severity.ERROR.equals(sev))\r
+            svgNode.setData(Activator.ERROR_SVG_TEXT);\r
+        else if (IssueResult.Severity.WARNING.equals(sev))\r
+            svgNode.setData(Activator.WARNING_SVG_TEXT);\r
+    }\r
+\r
+    @Override\r
+    protected void cleanupStyleForNode(INode node) {\r
+        ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME);\r
+    }\r
+\r
+}\r
+\r
+/**\r
+ * This is needed to keep the issue decoration up-to-date when its parent\r
+ * element moves.\r
+ */\r
+class IssueResult extends Tuple {\r
+    \r
+    public enum Severity{FATAL, ERROR, WARNING};\r
+    \r
+    public IssueResult(Severity severity, AffineTransform transform) {\r
+        super(severity, transform);\r
+    }\r
+    public Severity getSeverity() {\r
+        return (Severity) getField(0);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/ShadowStyle.java
new file mode 100644 (file)
index 0000000..ee0f442
--- /dev/null
@@ -0,0 +1,164 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.profiles;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Stroke;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.Collection;\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.layer0.variable.Variable;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.profile.StyleBase;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
+import org.simantics.scenegraph.profile.EvaluationContext;\r
+import org.simantics.scenegraph.profile.common.ProfileVariables;\r
+import org.simantics.scenegraph.utils.GeometryUtils;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.profiles.ShadowResult.Style;\r
+import org.simantics.utils.datastructures.map.Tuple;\r
+\r
+public class ShadowStyle extends StyleBase<ShadowResult> {\r
+    \r
+    private static String SHADOW_DECORATION_NODE = "SHADOW_DECORATION_NODE";  \r
+    private static Stroke SHADOW_DECORATION_STROKE = new BasicStroke(0.2f);\r
+    \r
+    @Override\r
+    public ShadowResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element);\r
+        \r
+        Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);\r
+        \r
+        if (component == null)\r
+               return new ShadowResult(Style.NONE, transform);\r
+\r
+        Resource original = graph.getPossibleObject(component, SR.Shadow_original);\r
+        Collection<Resource> shadows = graph.getObjects(component, SR.Shadow_original_Inverse);\r
+        \r
+        for(Resource r : graph.getObjects(runtimeDiagram, SR.ConfigurationDiagram_selection)) {\r
+            Resource selection = graph.getPossibleObject(r, MOD.ElementToComponent);\r
+            if(original != null) {\r
+                Collection<Resource> otherShadows = graph.getObjects(original, SR.Shadow_original_Inverse);\r
+                otherShadows.remove(component);\r
+                if(selection.equals(original) || otherShadows.contains(selection)) {\r
+                    return new ShadowResult(Style.SHADOW, transform);\r
+                }\r
+            }\r
+\r
+            if(shadows.contains(selection)) {\r
+                return new ShadowResult(Style.ORIGINAL, transform);\r
+            }\r
+        }\r
+        \r
+        return new ShadowResult(Style.NONE, transform);\r
+    }\r
+    \r
+    public void applyStyleForNode(EvaluationContext observer, INode _node, ShadowResult result) {\r
+        \r
+        if(result == null || result.getStyle() == Style.NONE) {\r
+            cleanupStyleForNode(_node);\r
+            return;\r
+        }\r
+        // Create a node that will show the style effect\r
+        A node = ProfileVariables.claimChild(_node, "", SHADOW_DECORATION_NODE, A.class, observer);\r
+        if (node == null)\r
+            return;\r
+        \r
+        AffineTransform at = result.getTransform();\r
+\r
+        // Create a node for the style\r
+        INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class);\r
+        Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0);\r
+        node.setFill(false);\r
+        node.setColor(result.getStyle() == Style.SHADOW ? Color.BLUE : Color.MAGENTA);\r
+        node.setStroke(SHADOW_DECORATION_STROKE);\r
+        node.setValue("shape", expandedElementBounds);\r
+        node.setTransform(at);\r
+\r
+        // Find z-index for the TextNode associated with the element and place the style node just below that text node \r
+        int zIndex = -1;\r
+        if(n != null) {\r
+            at = ((TextNode)n).getTransform();\r
+            zIndex = ((TextNode)n).getZIndex() - 1;\r
+        } else {\r
+            n = _node;\r
+        }\r
+        node.setZIndex(zIndex);\r
+\r
+    }\r
+\r
+    @Override\r
+    protected void cleanupStyleForNode(INode node) {\r
+        ProfileVariables.denyChild(node, "", SHADOW_DECORATION_NODE);\r
+    }\r
+    \r
+    /**\r
+     * Dummy class for displaying the style\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    public static class A extends ShapeNode {\r
+\r
+        private static final long serialVersionUID = -5273246617906214956L;\r
+\r
+        @Override\r
+        public Rectangle2D getBoundsInLocal() {\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public Rectangle2D getBoundsInLocal(boolean b) {\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public Rectangle2D getBounds() {\r
+            return null;\r
+        }\r
+\r
+    }\r
+    \r
+}\r
+\r
+/**\r
+ * This is needed to keep the issue decoration up-to-date when its parent\r
+ * element moves.\r
+ */\r
+class ShadowResult extends Tuple {\r
+    \r
+    public enum Style{NONE, ORIGINAL, SHADOW};\r
+    \r
+    public ShadowResult(Style style, AffineTransform transform) {\r
+        super(style, transform);\r
+    }\r
+    public Style getStyle() {\r
+        return (Style) getField(0);\r
+    }\r
+    \r
+    public AffineTransform getTransform() {\r
+        return (AffineTransform) getField(1);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements/profiles/SimulationPlaybackStyle.java
new file mode 100644 (file)
index 0000000..35516ae
--- /dev/null
@@ -0,0 +1,316 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.elements.profiles;\r
+\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.databoard.Bindings;\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.layer0.variable.Variable;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.profile.StyleBase;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.project.IProject;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
+import org.simantics.scenegraph.profile.EvaluationContext;\r
+import org.simantics.scenegraph.profile.Observer;\r
+import org.simantics.scenegraph.profile.common.ProfileVariables;\r
+import org.simantics.scenegraph.utils.GeometryUtils;\r
+import org.simantics.scenegraph.utils.NodeUtil;\r
+import org.simantics.scl.runtime.tuple.Tuple2;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.adapter.VariableRVIUtils;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Triple;\r
+import org.simantics.utils.ui.color.Color;\r
+import org.simantics.utils.ui.color.ColorGradient;\r
+import org.simantics.utils.ui.color.ColorValue;\r
+\r
+/**\r
+ * Profile style definition for simulation playback mode. Works only with SimulationPlaybackExperiment\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SimulationPlaybackStyle extends StyleBase<Triple<AffineTransform, Double, ColorGradient>> {\r
+\r
+    Resource gradientResource;\r
+    ColorGradient cg;\r
+    byte[] gradient;\r
+\r
+    /**\r
+     * Determine if style needs to be redrawn and return objects that are needed to redraw the style.\r
+     * \r
+     * @return All necessary components that are needed to draw this style\r
+     */\r
+    @Override\r
+    public Triple<AffineTransform, Double, ColorGradient> calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
+\r
+        // Find SimulationPlaybackExperiment\r
+        IProject project = SimanticsUI.getProject();\r
+        IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = em.getActiveExperiment();\r
+        if(!(experiment instanceof SysdynPlaybackExperiment))\r
+            return null;\r
+\r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+        DiagramResource dr = DiagramResource.getInstance(graph);\r
+\r
+        ColorGradient cg = null;\r
+\r
+        Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
+        if (component == null)\r
+            return null;\r
+\r
+        try {\r
+\r
+            // Find Variable for this component\r
+            String dv = graph.getPossibleRelatedValue(runtimeDiagram, dr.RuntimeDiagram_HasVariable);\r
+            Variable rootVariable = graph.getPossibleAdapter(graph.getRootLibrary(), Variable.class);\r
+            if (rootVariable == null) \r
+                return null;\r
+            Variable diagramVariable = rootVariable.browsePossible(graph, dv.substring(6));\r
+            if(diagramVariable == null) \r
+                return null;\r
+\r
+            Variable var = diagramVariable.browsePossible(graph, component);\r
+            if(var == null)\r
+                return null;\r
+\r
+            // Get simulation result values for this component\r
+            // Get values\r
+            Variable dsVariable = var.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#");\r
+            Object object = null;\r
+            if(dsVariable != null)\r
+                object = dsVariable.getValue(graph);\r
+            if(object == null || !(object instanceof ArrayList<?>))\r
+                return null;\r
+\r
+            ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+\r
+            for(Object o : (ArrayList<?>)object) {\r
+                if(o instanceof SysdynDataSet)\r
+                    datasets.add((SysdynDataSet)o);\r
+            }\r
+\r
+            if(datasets.size() == 0)\r
+                return null;\r
+\r
+            if(datasets.size() > 1) {\r
+                String range = datasets.get(0).name.substring(\r
+                        datasets.get(0).name.indexOf('[') + 1,\r
+                        datasets.get(0).name.indexOf(']'));\r
+                int size = range.split(",").length;\r
+                String[] filter = new String[size];\r
+                for(int i = 0; i < size; i++)\r
+                    filter[i] = "Sum";\r
+\r
+                ArrayList<SysdynDataSet> result2 = VariableRVIUtils.getDataset(datasets, filter);\r
+                if(result2 != null) {\r
+                    datasets = result2;\r
+                }\r
+\r
+            }\r
+\r
+            // The datasets list should always be size == 1\r
+            SysdynDataSet dataset = datasets.get(0);\r
+            \r
+            // Get values (or sum of values)\r
+            double[] va = dataset.values;\r
+            if(va.length < 2)\r
+                return null;\r
+\r
+            // Get simulation timesteps for this component\r
+            double[] ta = dataset.times;\r
+            if(ta == null || ta.length < 2)\r
+                return null;\r
+\r
+            if(va.length == 0 || va.length == 2)\r
+                return null;\r
+\r
+            // Get playback time from the experiment run\r
+            Double time = null;\r
+            if(diagramVariable != null) {\r
+                Variable timeVar = diagramVariable.browsePossible(graph, "#" + Functions.TIME + "#");\r
+                if(timeVar != null)\r
+                    time = timeVar.getValue(graph, Bindings.DOUBLE);\r
+            }\r
+\r
+            if(time == null)\r
+                return null;\r
+\r
+            // Find minimum and maximum values for this variable\r
+            double min = va[0], max = va[0];\r
+            for(double d : va) {\r
+                if(d < min) \r
+                    min = d;\r
+                if(d > max)\r
+                    max = d;\r
+            }\r
+\r
+            // Find the index in time and value arrays for this time \r
+            // (time steps may vary, we need to loop to find the correct time) \r
+            int index = 0;\r
+            if(ta[ta.length - 1] - time > ta[ta.length / 2] ) {\r
+                index = ta.length - 1;\r
+                while(ta[index] > time && index > 0)\r
+                    index--;\r
+            } else {\r
+                while(ta[index] < time && index < ta.length - 1)\r
+                    index++;\r
+            }\r
+\r
+            double value = va[index];\r
+\r
+            // Calculate where the value is located between min and max values [0..1].   \r
+            double multiplier = (value - min) / (max - min);\r
+\r
+\r
+            // Get the transform of this element\r
+            AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element,  G2DResource.getInstance(graph).HasTransform, true).clone();\r
+\r
+            // Find the gradient used to draw this style\r
+            G2DResource g2d = G2DResource.getInstance(graph);\r
+            Resource gradient = graph.getPossibleObject(experiment.getResource(), g2d.HasColorGradient);\r
+            if(this.gradientResource == null || !this.gradientResource.equals(gradient)) {\r
+                ArrayList<ColorValue> colorValues = new ArrayList<ColorValue>();\r
+                for(Resource placement : graph.syncRequest(new ObjectsWithType(gradient, g2d.HasColorPlacement, g2d.ColorPlacement))) {\r
+                    Double position = graph.getPossibleRelatedValue(placement, g2d.HasGradientPosition, Bindings.DOUBLE);\r
+                    Resource rColor = graph.getPossibleObject(placement, g2d.HasColor);\r
+                    if (rColor != null) {\r
+                        colorValues.add(new ColorValue(new Color((java.awt.Color) G2DUtils.getObject(graph, rColor)), position));\r
+                    }\r
+                }\r
+                cg = new ColorGradient(colorValues, ColorGradient.HSV);\r
+            } else {\r
+                cg = this.cg;\r
+            }\r
+\r
+            return new Triple<AffineTransform, Double, ColorGradient>(at, multiplier, cg);\r
+\r
+        } catch(Exception ignore) {\r
+            ignore.printStackTrace();\r
+        }\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void styleResultChanged(Observer observer, Resource runtimeDiagram, Resource element, Triple<AffineTransform, Double, ColorGradient> result) {\r
+        if (result != null)\r
+            values.put(new Tuple2(runtimeDiagram, element), result);\r
+        else\r
+            values.remove(new Tuple2(runtimeDiagram, element));\r
+        observer.update();\r
+    }\r
+\r
+    /**\r
+     * Apply style\r
+     */\r
+    @Override\r
+    public void applyStyleForNode(EvaluationContext observer, INode _node, Triple<AffineTransform, Double, ColorGradient> result) {\r
+        Double multiplier;\r
+        if (result != null && (multiplier = result.second) != null && !multiplier.isNaN()) {\r
+\r
+            // Create a node that will show the style effect\r
+            A node = ProfileVariables.claimChild(_node, "", "playbackColour", A.class, observer);\r
+            if (node == null)\r
+                return;\r
+\r
+            AffineTransform at = result.first;\r
+\r
+            if(this.cg == null || !this.cg.equals(result.third)) {\r
+                this.cg = result.third;\r
+                this.gradient = cg.getGradientArray(101);\r
+            }\r
+\r
+            // Get integer values for red, green and blue\r
+            int i = (int)(multiplier * 100);\r
+            int r = (int)(gradient[i * 3 + 0]  & 0xff);\r
+            int g = (int)(gradient[i * 3 + 1]  & 0xff);\r
+            int b = (int)(gradient[i * 3 + 2]  & 0xff);\r
+            // Get color with r, g and b\r
+            java.awt.Color c = new java.awt.Color(r, g, b, 200);\r
+\r
+            // Create a node for the style\r
+            INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class);\r
+            Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0);\r
+            node.setFill(true);\r
+            node.setColor(c);\r
+            node.setStroke(null);\r
+            node.setValue("shape", expandedElementBounds);\r
+            node.setTransform(at);\r
+\r
+            // Find z-index for the TextNode associated with the element and place the style node just below that text node \r
+            int zIndex = -1;\r
+            if(n != null) {\r
+                at = ((TextNode)n).getTransform();\r
+                zIndex = ((TextNode)n).getZIndex() - 1;\r
+            } else {\r
+                n = _node;\r
+            }\r
+            node.setZIndex(zIndex);\r
+\r
+\r
+        } else {\r
+            cleanupStyleForNode(_node);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void cleanupStyleForNode(INode node) {\r
+        ProfileVariables.denyChild(node, "", "playbackColour");\r
+    }\r
+\r
+\r
+    /**\r
+     * Dummy class for displaying the style\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    public static class A extends ShapeNode {\r
+\r
+        private static final long serialVersionUID = -5273246617906214956L;\r
+\r
+        @Override\r
+        public Rectangle2D getBoundsInLocal() {\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public Rectangle2D getBoundsInLocal(boolean b) {\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public Rectangle2D getBounds() {\r
+            return null;\r
+        }\r
+\r
+    }\r
+}\r
+
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/function/ModulesSearchFunction.java
new file mode 100644 (file)
index 0000000..2ef01ae
--- /dev/null
@@ -0,0 +1,158 @@
+/*******************************************************************************\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.function;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.layer0.genericrelation.Dependencies;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.scl.runtime.function.FunctionImpl5;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.handlers.FindSearchTrim;\r
+import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.workbench.search.NameAndTypeRow;\r
+import org.simantics.workbench.search.NamedResource;\r
+import org.simantics.workbench.search.SearchQuery;\r
+import org.simantics.workbench.search.SearchResult;\r
+import org.simantics.workbench.search.Searching;\r
+\r
+/**\r
+ * modulesSearchFunction:\r
+ *      (IProgressMonitor, ReadGraph, model : Resource, query : String, maxResults : Integer) -> QueryResult\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ * @author Tuomas Miettinen\r
+ */\r
+public class ModulesSearchFunction extends FunctionImpl5<IProgressMonitor, ReadGraph, Resource, SearchQuery, Integer, SearchResult> {\r
+\r
+       private final int MAX_RESULTS = 50000;\r
+       \r
+    @Override\r
+    public SearchResult apply(IProgressMonitor monitor, ReadGraph graph, Resource model, SearchQuery query, Integer maxResults) {\r
+        try {\r
+               String origQuery = query.getOriginalQuery();\r
+               SearchQuery wildcardedQuery;\r
+               if (!origQuery.isEmpty()) // Add asterisks for performSearch \r
+                       wildcardedQuery = query.withOriginalQuery("*" + origQuery + "*");\r
+               else\r
+                       wildcardedQuery = query.withOriginalQuery("*");\r
+               \r
+               String filteredQuery = wildcardedQuery.escaped(false).getQuery("Name","Types");\r
+               Collection<Map<String, Object>> results = Searching.performSearch(graph, \r
+                               Layer0X.getInstance(graph).Dependencies, \r
+                               model, \r
+                               filteredQuery, \r
+                               MAX_RESULTS);\r
+\r
+               // Check whether only currently open diagram is searched\r
+               if (!query.getSearchParams().contains(FindSearchTrim.CURRENT_DIAGRAM_OPTION))\r
+               return generateSearchResults(graph, results, Scope.ALL_MODELS);\r
+               else\r
+                       return generateSearchResults(graph, results, Scope.CURRENT_DIAGRAM);\r
+        } catch (DatabaseException e) {\r
+            Logger.defaultLogError(e);\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    private static boolean resourceFoundInCurrentDiagram(ReadGraph graph, Resource diagram) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+\r
+       IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+       DiagramEditor editor = (DiagramEditor)page.getActiveEditor();\r
+       if (editor != null) {\r
+               Resource inputResource = editor.getInputResource();\r
+               ModelingResources MOD = ModelingResources.getInstance(graph);\r
+               Resource editorResource = graph.getPossibleObject(inputResource, MOD.DiagramToComposite);\r
+               if (diagram.equalsResource(editorResource)) \r
+                       return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    private static final SearchResult generateSearchResults(ReadGraph graph,\r
+            Collection<Map<String, Object>> results, Scope scope) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+        SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+\r
+        SearchResult result = new SearchResult(NameAndTypeRow.columns);\r
+        Set<Resource> processed = new HashSet<Resource>();\r
+\r
+        for (Map<String, Object> r : results) {\r
+            Resource resource = (Resource) r.get(Dependencies.FIELD_RESOURCE);\r
+\r
+            // Only Auxiliary, Stock, Valve, Input, and Module \r
+            if (!(graph.isInstanceOf(resource, SYSDYN.IndependentVariable)\r
+                       || graph.isInstanceOf(resource, SYSDYN.Input)\r
+                       || graph.isInstanceOf(resource, SYSDYN.Module)))\r
+                continue;\r
+\r
+            // Prevent index corruption from producing duplicate results.\r
+            if (!processed.add(resource))\r
+                continue;\r
+\r
+            // Prevent diagram elements from being collected into the results.\r
+            Collection<Resource> typeResources = graph.getTypes(resource);\r
+            if (typeResources.contains(DIA.Element))\r
+                continue;\r
+\r
+            // Check if the result is found in the open diagram.  \r
+            Resource parent = (Resource) r.get(Dependencies.FIELD_PARENT);\r
+            if (scope == Scope.CURRENT_DIAGRAM &&\r
+                       !resourceFoundInCurrentDiagram(graph, parent))\r
+               continue;\r
+            \r
+            String name = (String) r.get(Dependencies.FIELD_NAME);\r
+            NameAndTypeRow rst = new NameAndTypeRow();\r
+            rst.resource = NamedResource.of(graph, resource, name);\r
+            rst.parent = NamedResource.of(graph, parent);\r
+\r
+            Collection<Resource> principalTypeResources = graph.getPrincipalTypes(resource);\r
+            if (!typeResources.isEmpty()) {\r
+                rst.types = new ArrayList<NamedResource>(typeResources.size());\r
+                rst.principalTypes = new ArrayList<NamedResource>(principalTypeResources.size());\r
+                for (Resource t : typeResources) {\r
+                    String typeName = graph.getPossibleRelatedValue(t, L0.HasName, Bindings.STRING);\r
+                    if (typeName == null)\r
+                        typeName = NameUtils.getSafeLabel(graph, t);\r
+                    NamedResource nr = NamedResource.of(graph, t, typeName);\r
+                    rst.types.add(nr);\r
+                    if (principalTypeResources.contains(t))\r
+                        rst.principalTypes.add(nr);\r
+                }\r
+            }\r
+  \r
+            result.addRow(rst);\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/AssignIC.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/AssignIC.java
new file mode 100644 (file)
index 0000000..16bb242
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\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.IDialogSettings;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.window.Window;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.Simantics;\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.ResourceRead;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.PossibleModel;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ui.Activator;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class AssignIC extends AbstractHandler {\r
+\r
+       private Resource query(Resource experiment) throws DatabaseException {\r
+\r
+        Map<Resource, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new ResourceRead<Map<Resource, Pair<String, ImageDescriptor>>>(experiment) {\r
+\r
+                       @Override\r
+                       public Map<Resource, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {\r
+                               Map<Resource, Pair<String, ImageDescriptor>> result = new HashMap<Resource, Pair<String, ImageDescriptor>>();\r
+                               Layer0 L0 = Layer0.getInstance(graph);\r
+                       SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+                               Resource model = graph.syncRequest(new PossibleModel(resource));\r
+                               for(Resource r : graph.syncRequest(new ObjectsWithType(model, L0.ConsistsOf, SYSDYN.InitialCondition))) {\r
+                                       String name = NameUtils.getSafeName(graph, r);\r
+                                       result.put(r, new Pair<String, ImageDescriptor>(name, null));\r
+                               }\r
+                               return result;\r
+                       }\r
+               \r
+        });\r
+        \r
+        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+        ResourceSelectionDialog3<Resource> dialog = new ResourceSelectionDialog3<Resource>(shell, map, "Select connection point type") {\r
+               @Override\r
+               protected IDialogSettings getBaseDialogSettings() {\r
+                       return Activator.getDefault().getDialogSettings();\r
+               }\r
+        };\r
+        if (dialog.open() == Window.OK) {\r
+               Object[] result = dialog.getResult();\r
+               if (result != null && result.length == 1) {\r
+                       final Resource res = (Resource)result[0];\r
+                       return res;\r
+               }\r
+        }\r
+        \r
+        return null;\r
+\r
+       }\r
+       \r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+       \r
+               ISelection selection = HandlerUtil.getCurrentSelection(event);\r
+        final Resource experiment = ResourceAdaptionUtils.toSingleResource(selection);\r
+        if (experiment == null)\r
+            return null;\r
+\r
+        try {\r
+\r
+               final Resource ic = query(experiment);\r
+               if(ic == null)\r
+                       return null;\r
+\r
+               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                           graph.markUndoPoint();\r
+                               SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+\r
+                               graph.deny(experiment, SYSDYN.Experiment_ic);\r
+                               graph.claim(experiment, SYSDYN.Experiment_ic, ic);\r
+                               Layer0Utils.addCommentMetadata(graph, "Assigned new IC " + NameUtils.getSafeName(graph, ic) + " to experiment " + NameUtils.getSafeLabel(graph, experiment));\r
+                       }\r
+               });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return null;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ChartPanelOrientationHandler.java
new file mode 100644 (file)
index 0000000..2d32ce8
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.Map;\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.IDialogSettings;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.ui.IWorkbenchPart;\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.handlers.HandlerUtil;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.jfreechart.ChartPanel;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+/**\r
+ * This handler changes the orientation of a {@link ChartPanel}\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ChartPanelOrientationHandler extends AbstractHandler implements IElementUpdater {\r
+\r
+    private static String COMMAND = "org.simantics.sysdyn.ui.chartPanelOrientation";\r
+    \r
+    /**\r
+     * Read chart panel settings from IDialogSettings and change the orientation accordingly.\r
+     * Finally order the element to update its appearance.\r
+     */\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        IWorkbenchPart part = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().getActivePart();\r
+        if(part instanceof ChartPanel) {\r
+            IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(ChartPanel.CHART_PANEL_SETTINGS);\r
+            if (settings == null) {\r
+                settings = Activator.getDefault().getDialogSettings().addNewSection(ChartPanel.CHART_PANEL_SETTINGS);\r
+            }\r
+            \r
+            String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION);\r
+            if(orientation == null)\r
+                settings.put(ChartPanel.CHART_PANEL_ORIENTATION, ChartPanel.CHART_PANEL_HORIZONTAL);\r
+            \r
+            if(ChartPanel.CHART_PANEL_VERTICAL.equals(orientation))\r
+                orientation = ChartPanel.CHART_PANEL_HORIZONTAL;\r
+            else\r
+                orientation = ChartPanel.CHART_PANEL_VERTICAL;\r
+            \r
+            settings.put(ChartPanel.CHART_PANEL_ORIENTATION, orientation);\r
+            ((ChartPanel)part).setOrientation(orientation);\r
+            \r
+            ICommandService commandService =\r
+                    (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);\r
+            commandService.refreshElements(COMMAND, null);\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Update the icon of the element. The new icon and text are always opposite to the current situation.\r
+     */\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public void updateElement(UIElement element, Map parameters) {\r
+        if(parameters == null)\r
+            return;\r
+        \r
+        IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(ChartPanel.CHART_PANEL_SETTINGS);\r
+        if(settings == null)\r
+            return;\r
+        \r
+        String orientation = settings.get(ChartPanel.CHART_PANEL_ORIENTATION);\r
+        if(orientation == null)\r
+            return;\r
+        \r
+        // Show the opposite icon and text to indicate change when the button is pressed\r
+        if(ChartPanel.CHART_PANEL_HORIZONTAL.equals(orientation)) {\r
+            element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/page_white_text.png")));\r
+            element.setTooltip("Vertical Orientation");\r
+        } else if (ChartPanel.CHART_PANEL_VERTICAL.equals(orientation)) {\r
+            element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/page_white_text_width.png")));\r
+            element.setTooltip("Horizontal Orientation");\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/DiagramToolHandler.java
new file mode 100644 (file)
index 0000000..7f4a251
--- /dev/null
@@ -0,0 +1,67 @@
+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.ui.handlers.HandlerUtil;\r
+import org.eclipse.ui.handlers.RadioState;\r
+import org.simantics.g2d.canvas.Hints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.IToolMode;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+\r
+public class DiagramToolHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               final ICanvasContext context = (ICanvasContext)HandlerUtil.getActiveEditor(event).getAdapter(ICanvasContext.class);\r
+               if (context == null) {\r
+                       throw new ExecutionException("Could not get context from editor");\r
+               }\r
+\r
+               String value = (String)event.getCommand().getState(RadioState.STATE_ID).getValue();\r
+               \r
+               final IToolMode mode;\r
+               if ("pointer".equals(value)) {\r
+                       mode = Hints.POINTERTOOL;\r
+               }\r
+               else if ("dependency".equals(value)) {\r
+                       mode = SysdynElementHints.DEPENDENCY_TOOL;\r
+               }\r
+               else if ("flow".equals(value)) {\r
+                       mode = SysdynElementHints.FLOW_TOOL;\r
+               }\r
+               else if ("lock".equals(value)) {\r
+                       mode = SysdynElementHints.LOCK_TOOL;\r
+               }\r
+               else {\r
+                       return null;\r
+               }\r
+               \r
+               ThreadUtils.syncExec(context.getThreadAccess(), new Runnable() {\r
+                       @Override\r
+                       public void run() {\r
+                               if (mode.equals(SysdynElementHints.DEPENDENCY_TOOL) \r
+                                               || mode.equals(SysdynElementHints.FLOW_TOOL)) {\r
+                                       // if one of the connection modes is selected, use the\r
+                                       // default connection tool as the base and indicate the\r
+                                       // desired connection type in another hint (this is done\r
+                                       // to make sure all features of the connection tool work\r
+                                       // as expected)\r
+                                       context.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.CONNECTTOOL);\r
+                                       context.getDefaultHintContext().setHint(SysdynElementHints.SYSDYN_KEY_TOOL, mode);\r
+                               } else if (mode.equals(SysdynElementHints.LOCK_TOOL)) {\r
+                                       context.getDefaultHintContext().setHint(Hints.KEY_TOOL, Hints.POINTERTOOL);\r
+                                       context.getDefaultHintContext().setHint(SysdynElementHints.SYSDYN_KEY_TOOL, mode);\r
+                               } else {\r
+                                       context.getDefaultHintContext().setHint(Hints.KEY_TOOL, mode);\r
+                                       context.getDefaultHintContext().removeHint(SysdynElementHints.SYSDYN_KEY_TOOL);\r
+                               }\r
+                       }\r
+               });\r
+               \r
+               return null;\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..45c3ef9
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.IProject;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\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
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \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(null);\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationIndexRenameNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationIndexRenameNodeHandler.java
new file mode 100644 (file)
index 0000000..11b5cc3
--- /dev/null
@@ -0,0 +1,73 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.eclipse.ui.part.IPage;\r
+import org.eclipse.ui.part.IPageSite;\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.browsing.ui.platform.PropertyPageView;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.sysdyn.ui.properties.SysdynPropertyPage;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class EnumerationIndexRenameNodeHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        ISelection sel2 = HandlerUtil.getActiveMenuSelection(event);\r
+        NodeContext ctx = ISelectionUtils.filterSingleSelection(sel2, 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
+        PropertyPageView ppv = (PropertyPageView) part;\r
+        IPage p = ppv.getCurrentPage();\r
+        Control control = p.getControl();\r
+        \r
+        Control geComposite = findGEComposite(control);\r
+        GraphExplorerComposite ge = (GraphExplorerComposite) geComposite;\r
+        ge.getExplorer().startEditing(ctx, ColumnKeys.SINGLE);\r
+        \r
+        return null;\r
+    }\r
+    \r
+    private Control findGEComposite(Control control) {\r
+        Control[] comp = ((Composite) control).getChildren();\r
+        Control ge = null;\r
+        for (Control cont : comp) {\r
+            if (cont instanceof GraphExplorerComposite)\r
+                return cont;\r
+            else if (cont instanceof Composite) {\r
+                ge = findGEComposite(cont);\r
+                return ge;\r
+            }\r
+            else\r
+                continue;\r
+        }\r
+        return ge;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/EnumerationPasteHandler.java
new file mode 100644 (file)
index 0000000..a37cb37
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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
+\r
+public class EnumerationPasteHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+               System.out.println("PASTE " + sel);\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExportSharedOntologyHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExportSharedOntologyHandler.java
new file mode 100644 (file)
index 0000000..5e29611
--- /dev/null
@@ -0,0 +1,32 @@
+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.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedOntologyNode;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class ExportSharedOntologyHandler  extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes to be called from a node with SysdynModel, Library or SysdynModelicaFunction as its resource\r
+     */\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+               SharedOntologyNode node = AdaptionUtils.adaptToSingle(sel, SharedOntologyNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        ModelingUtils.exportSharedOntologyWithUI(node.data);\r
+\r
+        return null;\r
+        \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ExtendedCopyPasteHandler.java
new file mode 100644 (file)
index 0000000..1295e08
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************\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.util.Set;\r
+\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.simantics.diagram.elements.TextElementNoBounds;\r
+import org.simantics.diagram.elements.TextNode;\r
+import org.simantics.diagram.handler.CopyPasteHandler;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
+import org.simantics.g2d.diagram.participant.Selection;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
+import org.simantics.scenegraph.g2d.events.command.Commands;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynCopyPasteStrategy;\r
+\r
+/**\r
+ * ExtendedCopyPasteHandler is a canvas handler for Commands.CUT, Commands.COPY,\r
+ * Commands.PASTE, and Commands.RENAME commands for an IDiagram.\r
+ * \r
+ * <p>\r
+ * The handler attempts to copy/paste the current selection for pointer 0,\r
+ * meaning {@link Selection#SELECTION0}.\r
+ * </p>\r
+ * \r
+ * <p>\r
+ * The handler logic follows the specifications at <a\r
+ * href="http://www.simantics.org/wiki/index.php/UC:Copy_Item" >UC:Copy Item</a>\r
+ * and <a href="http://www.simantics.org/wiki/index.php/UC:Cut_Item" >UC:Cut\r
+ * Item</a>.\r
+ * </p>\r
+ * \r
+ * @see Selection current diagram selection source\r
+ * \r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class ExtendedCopyPasteHandler extends CopyPasteHandler {\r
+\r
+    @Dependency\r
+    private Selection sel;\r
+    \r
+    public ExtendedCopyPasteHandler(IStatusLineManager statusLine) {\r
+        super(new SysdynCopyPasteStrategy(), statusLine);\r
+    }\r
+       \r
+    @EventHandler(priority = 0)\r
+    public boolean handleCommand(CommandEvent e) {\r
+        if (e.command.equals( Commands.RENAME) ) {\r
+            initiateRename(e);\r
+            return true;\r
+        }\r
+        else return super.handleCommand(e);\r
+    }\r
+\r
+       private boolean initiateRename(CommandEvent e) {\r
+        int selectionId = 0;        \r
+        Set<IElement> ss = sel.getSelection(selectionId);\r
+\r
+        ICanvasContext ctx = getContext();\r
+        if (ctx == null)\r
+            return false;\r
+        IElement ie = null;\r
+        TextNode node = null;\r
+        \r
+        //If multiple selected, just pick one\r
+        for (IElement temp : ss){\r
+               if (temp != null) {\r
+                       node = (TextNode)temp.getHint(TextElementNoBounds.SG_NODE);\r
+                       if (node != null){\r
+                               ie = temp;\r
+                               break;\r
+                       }\r
+               }\r
+        }\r
+        if (ie != null) {\r
+                       if (node != null && Boolean.TRUE.equals(node.setEditMode(true))) {\r
+                node.activateEdit(0, ie, ctx);\r
+                node.repaint();\r
+                return true;\r
+                       }\r
+        }\r
+        return false;\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceDialog.java
new file mode 100644 (file)
index 0000000..f467523
--- /dev/null
@@ -0,0 +1,107 @@
+package org.simantics.sysdyn.ui.handlers;\r
+\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.swt.SWT;\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.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope;\r
+\r
+/**\r
+ * Find dialog for finding variables in diagrams.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class FindReplaceDialog extends Dialog {\r
+    \r
+    private FindSearchTrim search;\r
+    \r
+    private Button scopeButtonAllModels; \r
+    private Button scopeButtonCurrentDiagram; \r
+    private Scope scope;\r
+    private boolean diagramOpen;\r
+    \r
+    protected FindReplaceDialog(Shell parentShell, Scope scope, boolean diagramOpen) {\r
+        super(parentShell);\r
+               setBlockOnOpen(false);\r
+               this.scope = scope; \r
+               this.diagramOpen = diagramOpen;\r
+    }\r
+\r
+    @Override\r
+       protected boolean isResizable() {\r
+               return true;\r
+       }\r
+    \r
+    @Override\r
+    protected Control createDialogArea(Composite parent) {\r
+        Composite composite = ( Composite )super.createDialogArea(parent);\r
+        composite.getShell().setText("Find");\r
+        GridLayoutFactory.fillDefaults().margins(5, 5).numColumns(2).applyTo(composite);\r
+        \r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Find: ");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).hint(40, SWT.DEFAULT).applyTo(label);\r
+\r
+        search = new FindSearchTrim(composite);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(search);\r
+        \r
+        Group scopeGroup = new Group(composite, SWT.SHADOW_NONE);\r
+        scopeGroup.setText("Scope");\r
+        GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(scopeGroup);\r
+        GridLayoutFactory.fillDefaults().margins(5, 5).applyTo(scopeGroup);\r
+        \r
+        Composite scopeComposite = new Composite(scopeGroup, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(scopeComposite);\r
+        GridLayoutFactory.fillDefaults().applyTo(scopeComposite);\r
+        \r
+        scopeButtonCurrentDiagram = new Button(scopeComposite, SWT.RADIO);\r
+        scopeButtonCurrentDiagram.setText("Current Diagram");\r
+        scopeButtonCurrentDiagram.setSelection(scope == Scope.CURRENT_DIAGRAM);\r
+        scopeButtonCurrentDiagram.setEnabled(diagramOpen);\r
+        GridDataFactory.fillDefaults().applyTo(scopeButtonCurrentDiagram);\r
+        \r
+        scopeButtonAllModels = new Button(scopeComposite, SWT.RADIO);\r
+        scopeButtonAllModels.setText("All Models");\r
+        scopeButtonAllModels.setSelection(scope == Scope.ALL_MODELS);\r
+        GridDataFactory.fillDefaults().applyTo(scopeButtonAllModels);\r
+\r
+        return composite;\r
+    }\r
+    \r
+    @Override\r
+    protected void createButtonsForButtonBar(Composite parent) {\r
+        // Replace "OK" with "Find".\r
+               createButton(parent, IDialogConstants.OK_ID, "Find",\r
+                               true);\r
+               createButton(parent, IDialogConstants.CANCEL_ID,\r
+                               "Close", false);\r
+    }\r
+\r
+    @Override\r
+    protected void cancelPressed() {\r
+        setReturnCode(CANCEL);\r
+        close();\r
+    }\r
+\r
+    @Override\r
+    protected void okPressed() {\r
+        if (scopeButtonAllModels.getSelection())\r
+               scope = Scope.ALL_MODELS;\r
+        else if (scopeButtonCurrentDiagram.getSelection())\r
+               scope = Scope.CURRENT_DIAGRAM;\r
+        else\r
+               scope = Scope.ALL_MODELS;\r
+        search.findNameAndTypeQuery(scope);\r
+        setReturnCode(OK);\r
+        close();\r
+    }\r
+\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindReplaceHandler.java
new file mode 100644 (file)
index 0000000..5239aec
--- /dev/null
@@ -0,0 +1,61 @@
+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.Shell;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.sysdyn.ui.browser.SysdynBrowser;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.sysdyn.ui.handlers.FindSearchTrim.Scope;\r
+\r
+/**\r
+ * Handler for Ctrl+F\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class FindReplaceHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event);\r
+        IWorkbenchPart workbenchPart = (IWorkbenchPart)HandlerUtil.getActivePart(event); \r
+        \r
+        Shell shell = HandlerUtil.getActiveShell(event);\r
+        if(shell == null)\r
+            return null;\r
+        \r
+        // If there is something else in the diagram view, do not allow search in current diagram\r
+        if (!(editor instanceof DiagramEditor) || !(((DiagramEditor) editor).getViewer() instanceof DiagramViewer)) {\r
+            if (workbenchPart != null && workbenchPart instanceof SysdynBrowser) {\r
+               // If focus is on model browser, allow search in all models.\r
+                FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.ALL_MODELS, false);\r
+                dialog.open();\r
+            }\r
+            return null;\r
+        }\r
+        \r
+        final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer();\r
+        if (viewer == null)\r
+            return null;\r
+        \r
+        Object d = viewer.getAdapter(IDiagram.class);\r
+        if (workbenchPart != null && workbenchPart instanceof SysdynBrowser) {\r
+               // If focus is on model browser, default search in all models, allow also current diagram.\r
+            FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.ALL_MODELS, true);\r
+            dialog.open();\r
+        } else if (d != null && d instanceof IDiagram && workbenchPart instanceof DiagramEditor) {\r
+               // If focus is on diagram editor, default search in current diagram, allow also all models.\r
+            FindReplaceDialog dialog = new FindReplaceDialog(shell, Scope.CURRENT_DIAGRAM, true);\r
+            dialog.open();\r
+        }\r
+\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/FindSearchTrim.java
new file mode 100644 (file)
index 0000000..502410c
--- /dev/null
@@ -0,0 +1,49 @@
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.workbench.internal.contributions.search.SearchTrim;\r
+import org.simantics.workbench.search.ISearchService;\r
+import org.simantics.workbench.search.SearchQuery;\r
+\r
+public class FindSearchTrim extends SearchTrim {\r
+       \r
+       public static enum Scope {\r
+               CURRENT_DIAGRAM,\r
+               ALL_MODELS\r
+       }\r
+       \r
+       public static final String CURRENT_DIAGRAM_OPTION = "@Current_diagram";\r
+       \r
+       public FindSearchTrim(Composite parent) {\r
+               super(parent);\r
+        GridDataFactory.fillDefaults().hint(160, SWT.DEFAULT).grab(true, true).applyTo(searchText);\r
+       }\r
+\r
+       public void findNameAndTypeQuery(Scope scope) {\r
+        \r
+           String originalQuery = searchText.getText();\r
+           String query = originalQuery;\r
+\r
+        // Don't allow empty queries\r
+        if (query.trim().isEmpty())\r
+            return;\r
+\r
+//        query = filter(query);\r
+//        query = "Name:" + query + " OR Types:" + query;\r
+        \r
+        // Add option for showing only findings in currently open diagram\r
+//        if (scope == Scope.CURRENT_DIAGRAM)\r
+//             query += " " + CURRENT_DIAGRAM_OPTION;\r
+//        SearchQuery searchQuery = new SearchQuery(originalQuery,query);\r
+        SearchQuery searchQuery = new SearchQuery(originalQuery);\r
+        searchQuery.setSearchFlag("Name", "on");\r
+        searchQuery.setSearchFlag("Types", "on");\r
+        if (scope == Scope.CURRENT_DIAGRAM)\r
+               searchQuery.setSearchParam(CURRENT_DIAGRAM_OPTION);\r
+        performQuery(searchQuery, ISearchService.ResultBrowser.VIEW);\r
+        \r
+       }       \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewAnnotationTypeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewAnnotationTypeHandler.java
new file mode 100644 (file)
index 0000000..f77b693
--- /dev/null
@@ -0,0 +1,51 @@
+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.annotation.ui.AnnotationUtils;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class NewAnnotationTypeHandler  extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes to be called from a node with SysdynModel, Library or SysdynModelicaFunction as its resource\r
+     */\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+               Resource res = AdaptionUtils.adaptToSingle(sel, Resource.class);\r
+        if(res == null) {\r
+               @SuppressWarnings("unchecked")\r
+                       AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+               if (node == null)\r
+                       return null;\r
+               res = node.data;\r
+        }\r
+\r
+        final Resource parent = res;\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+               \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                AnnotationUtils.newAnnotationType(graph, parent);\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/NewAnnotationValueHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewAnnotationValueHandler.java
new file mode 100644 (file)
index 0000000..e8f757e
--- /dev/null
@@ -0,0 +1,45 @@
+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.Simantics;\r
+import org.simantics.annotation.ui.AnnotationUtils;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.PossibleIndexRoot;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class NewAnnotationValueHandler  extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+               Resource res = AdaptionUtils.adaptToSingle(sel, Resource.class);\r
+        if(res == null) {\r
+               @SuppressWarnings("unchecked")\r
+                       AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+               if (node == null)\r
+                       return null;\r
+               res = node.data;\r
+        }\r
+\r
+        final Resource parent = res;\r
+               try {\r
+                       Resource model = Simantics.getSession().syncRequest(new PossibleIndexRoot(parent));\r
+                       if(model == null) return null;\r
+               AnnotationUtils.newAnnotationInstance(parent, model);\r
+               } catch (DatabaseException e) {\r
+                       throw new ExecutionException(e.getMessage());\r
+               }\r
+        \r
+        return null;\r
+        \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewLibraryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewLibraryHandler.java
new file mode 100644 (file)
index 0000000..0f20af7
--- /dev/null
@@ -0,0 +1,48 @@
+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.browsing.ui.common.node.AbstractNode;\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.modeling.ui.actions.NewLibrary;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class NewLibraryHandler  extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+               Resource res = AdaptionUtils.adaptToSingle(sel, Resource.class);\r
+        if(res == null) {\r
+               @SuppressWarnings("unchecked")\r
+                       AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+               if (node == null)\r
+                       return null;\r
+               res = node.data;\r
+        }\r
+\r
+        final Resource parent = res;\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+               \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                       NewLibrary.createLibrary(graph, parent);\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/NewSCLModuleHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewSCLModuleHandler.java
new file mode 100644 (file)
index 0000000..a026c31
--- /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.browsing.ui.common.node.AbstractNode;\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.modeling.ModelingUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class NewSCLModuleHandler  extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes to be called from a node with SysdynModel, Library or SysdynModelicaFunction as its resource\r
+     */\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        @SuppressWarnings("unchecked")\r
+               AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource parent = node.data;\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+               \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+               ModelingUtils.createSCLModuleDefault(graph, parent);\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/PasteSpecialDialog.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialDialog.java
new file mode 100644 (file)
index 0000000..a593b18
--- /dev/null
@@ -0,0 +1,85 @@
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.eclipse.jface.dialogs.Dialog;\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.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * Paste special dialog for copying variables in diagram. Default method is to add a number to the end of the variable name.\r
+ * Special paste enables users to define their own prefix and/or suffix to the copied variable name(s). \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class PasteSpecialDialog extends Dialog {\r
+\r
+    private Text prefixText, suffixText;\r
+    private String prefix, suffix;\r
+    \r
+    protected PasteSpecialDialog(Shell parentShell) {\r
+        super(parentShell);\r
+    }\r
+\r
+    @Override\r
+    protected Control createDialogArea(Composite parent) {\r
+        Composite composite = ( Composite )super.createDialogArea(parent);\r
+        composite.getShell().setText("Paste Special");\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Prefix will be added to the beginning of\nthe copied variables, suffix to the end.");\r
+        GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(label);\r
+        \r
+\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Prefix: ");\r
+        label.setToolTipText("Text added to the beginning of a copied variable name");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        prefixText = new Text(composite, SWT.BORDER);\r
+        prefixText.setToolTipText("Text added to the beginning of a copied variable name");\r
+        GridDataFactory.fillDefaults().applyTo(prefixText);\r
+        \r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Suffix: ");\r
+        label.setToolTipText("Text added to the end of a copied variable name");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        suffixText = new Text(composite, SWT.BORDER);\r
+        suffixText.setToolTipText("Text added to the end of a copied variable name");\r
+        GridDataFactory.fillDefaults().applyTo(suffixText);\r
+        \r
+        return composite;\r
+    }\r
+    \r
+    public String getPrefix() {\r
+        return prefix;\r
+    }\r
+\r
+    public String getSuffix() {\r
+        return suffix;\r
+    }\r
+\r
+    @Override\r
+    protected void cancelPressed() {\r
+        prefix = "";\r
+        suffix = "";\r
+        setReturnCode(CANCEL);\r
+        close();\r
+    }\r
+\r
+    @Override\r
+    protected void okPressed() {\r
+        prefix = prefixText.getText();\r
+        suffix = suffixText.getText();\r
+        setReturnCode(OK);\r
+        close();\r
+    }\r
+\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/PasteSpecialHandler.java
new file mode 100644 (file)
index 0000000..9ed9bde
--- /dev/null
@@ -0,0 +1,86 @@
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.Set;\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.window.Window;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.layer0.util.ClipboardUtils;\r
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
+import org.simantics.diagram.handler.CopyPasteHandler;\r
+import org.simantics.diagram.handler.DiagramSelection;\r
+import org.simantics.diagram.handler.DiagramSelectionRepresentation;\r
+import org.simantics.diagram.synchronization.SynchronizationHints;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.modeling.mapping.ElementCopyAdvisor;\r
+import org.simantics.modeling.mapping.MappedElementCopyAdvisor;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.scenegraph.g2d.events.command.Commands;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.sysdyn.ui.editor.participant.SysdynSpecialComponentCopyAdvisor;\r
+\r
+/**\r
+ * Handler for copying variables with custom prefix and/or suffix\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class PasteSpecialHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event);\r
+        if (!(editor instanceof DiagramEditor))\r
+            return null;\r
+        final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer();\r
+        if (viewer == null)\r
+            return null;\r
+\r
+        Object d = viewer.getAdapter(IDiagram.class);\r
+        if(d != null && d instanceof IDiagram) {\r
+            IDiagram diagram = (IDiagram) d;\r
+            MappedElementCopyAdvisor standardCopyAdvisor = diagram.getHint(SynchronizationHints.COPY_ADVISOR);\r
+\r
+            Shell shell = viewer.getComposite().getShell();\r
+            if(shell == null)\r
+                return null;\r
+            \r
+            PasteSpecialDialog dialog = new PasteSpecialDialog(shell);\r
+            if(dialog.open() == Window.CANCEL)\r
+                return null;\r
+            \r
+            String prefix = dialog.getPrefix();\r
+            String suffix = dialog.getSuffix();\r
+            \r
+            diagram.setHint(SynchronizationHints.COPY_ADVISOR, new MappedElementCopyAdvisor(new ElementCopyAdvisor(), new SysdynSpecialComponentCopyAdvisor(prefix, suffix)));\r
+\r
+            Object v = viewer.getAdapter(ICanvasContext.class);\r
+            if(v != null && v instanceof ICanvasContext) {\r
+                ICanvasContext ctx = (ICanvasContext) v;\r
+                CopyPasteHandler handler = ctx.getAtMostOneItemOfClass(CopyPasteHandler.class);\r
+                if(handler != null) {\r
+                    handler.paste(Commands.PASTE, getClipboardDiagramSelection());\r
+                }\r
+            }\r
+\r
+            diagram.setHint(SynchronizationHints.COPY_ADVISOR, standardCopyAdvisor);\r
+\r
+        }\r
+        return null;\r
+    }\r
+    \r
+    public DiagramSelection getClipboardDiagramSelection() {\r
+        for (Set<Representation> content : Simantics.getClipboard().getContents()) {\r
+            DiagramSelection sel = ClipboardUtils.accept(content, DiagramSelectionRepresentation.KEY_DIAGRAM_SELECTION);\r
+            if (sel != null)\r
+                return sel;\r
+        }\r
+        return DiagramSelection.EMPTY;\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..e2ee366
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.util.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
+    public static 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/RenameNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/RenameNodeHandler.java
new file mode 100644 (file)
index 0000000..4cb78c8
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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..1eba038
--- /dev/null
@@ -0,0 +1,61 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+\r
+import java.util.Map;\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.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.ExperimentState;\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.utils.HandlerUtils;\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
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+\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("rawtypes")\r
+       @Override\r
+    public void updateElement(UIElement element, Map parameters) {\r
+        IExperimentManager manager = \r
+            SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment instanceof SysdynExperiment) {\r
+               ExperimentState state = experiment.getState();\r
+               if(state == ExperimentState.RUNNING) {\r
+                       this.setBaseEnabled(false);\r
+               } else {\r
+                        this.setBaseEnabled(true);\r
+               }\r
+        }        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveHistoryDialog.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveHistoryDialog.java
new file mode 100644 (file)
index 0000000..44547c0
--- /dev/null
@@ -0,0 +1,292 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.dialogs.IDialogSettings;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.viewers.StructuredSelection;\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.GridData;\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.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.annotation.ui.Activator;\r
+import org.simantics.modelica.data.DataSet;\r
+import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
+import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class SaveHistoryDialog extends ResourceSelectionDialog3<DataSet> {\r
+\r
+       private String sheetName;\r
+       private String sheetLocation;\r
+       \r
+       private GridData filterLayout;\r
+       \r
+       private boolean filterStart = false;\r
+       private boolean startValid = false;\r
+       private double start;\r
+       private boolean filterStep = false;\r
+       private boolean stepValid = false;\r
+       private int step;\r
+\r
+       public SaveHistoryDialog(Shell shell,\r
+                       Map<DataSet, Pair<String, ImageDescriptor>> parameter, String title) {\r
+               super(shell, parameter, title);\r
+               this.sheetName = "";\r
+               this.sheetLocation = "";\r
+       }\r
+\r
+       @Override\r
+       protected IDialogSettings getBaseDialogSettings() {\r
+               return Activator.getDefault().getDialogSettings();\r
+       }\r
+       \r
+       @Override\r
+       protected void setSelectionResult(Object[] newResult) {\r
+               super.setSelectionResult(newResult);\r
+               validatePage();\r
+       }\r
+\r
+       @Override\r
+       protected Control createExtendedContentArea(final Composite parent_) {\r
+\r
+               Composite parent = new Composite(parent_, SWT.NONE);\r
+               GridLayoutFactory.swtDefaults().numColumns(2).applyTo(parent);\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(parent);\r
+\r
+               Label l = new Label(parent, SWT.NONE); \r
+               l.setText("Select a sheet:");\r
+               GridDataFactory.fillDefaults().grab(false, false).applyTo(l);\r
+               final Text t = new Text(parent,SWT.BORDER);\r
+               t.addModifyListener(new ModifyListener() {\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               sheetName = t.getText();\r
+                               validatePage();\r
+                       }\r
+               });\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(t);\r
+               Label l2 = new Label(parent, SWT.NONE); \r
+               l2.setText("Select cell in sheet:");\r
+               GridDataFactory.fillDefaults().grab(false, false).applyTo(l2);\r
+               final Text t2 = new Text(parent,SWT.BORDER);\r
+               t2.addModifyListener(new ModifyListener() {\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               sheetLocation = t2.getText();\r
+                               validatePage();\r
+                       }\r
+               });\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(t2);\r
+               \r
+               // filter options\r
+               Composite filterControls = new Composite(parent, SWT.NONE);\r
+               GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(filterControls);\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(filterControls);\r
+               \r
+               Button filterButton = new Button(filterControls, SWT.ARROW | SWT.DOWN);\r
+               GridDataFactory.fillDefaults().applyTo(filterButton);\r
+               Label filterLabel = new Label(filterControls, SWT.NONE);\r
+               GridDataFactory.fillDefaults().applyTo(filterLabel);\r
+               \r
+               filterButton.addSelectionListener(new SelectionAdapter() {\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               filterLayout.exclude = !filterLayout.exclude;\r
+                               parent_.layout();\r
+                       }\r
+               });\r
+               \r
+               filterLabel.setText("show filter options");\r
+               GridDataFactory.fillDefaults().applyTo(filterLabel);\r
+               \r
+               Composite filterOptions = new Composite(parent, SWT.NONE);\r
+               filterLayout = GridDataFactory.fillDefaults().span(2, 1).grab(true, false).exclude(true).create();\r
+               filterOptions.setLayoutData(filterLayout);\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(filterOptions);\r
+               \r
+               final Button startButton = new Button(filterOptions, SWT.CHECK);\r
+               GridDataFactory.fillDefaults().applyTo(startButton);\r
+               startButton.setText("start time (in terms of simulation time)");\r
+               final Text startInput = new Text(filterOptions, SWT.BORDER);\r
+               GridDataFactory.fillDefaults().applyTo(startInput);\r
+               \r
+               startButton.addSelectionListener(new SelectionAdapter() {\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               filterStart = startButton.getSelection();\r
+                               startInput.setEnabled(filterStart);\r
+                               startInput.setBackground(Display.getCurrent().getSystemColor(\r
+                                               !filterStart || startValid ? SWT.COLOR_WIDGET_BACKGROUND : SWT.COLOR_YELLOW));\r
+                               validatePage();\r
+                       }\r
+               });\r
+               \r
+               startInput.setEnabled(false);\r
+               startInput.addModifyListener(new ModifyListener() {\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               try {\r
+                                       start = Double.parseDouble(startInput.getText());\r
+                                       startValid = true;\r
+                               }\r
+                               catch (Exception ex) {\r
+                                       startValid = false;\r
+                               }\r
+                               startInput.setBackground(Display.getCurrent().getSystemColor(\r
+                                               startValid ? SWT.COLOR_WIDGET_BACKGROUND : SWT.COLOR_YELLOW));\r
+                               validatePage();\r
+                       }\r
+               });\r
+               \r
+               final Button stepButton = new Button(filterOptions, SWT.CHECK);\r
+               GridDataFactory.fillDefaults().applyTo(stepButton);\r
+               stepButton.setText("sample rate (1 = every step, 2 = every other step...)");\r
+               final Text stepInput = new Text(filterOptions, SWT.BORDER);\r
+               GridDataFactory.fillDefaults().applyTo(stepInput);\r
+               \r
+               stepButton.addSelectionListener(new SelectionAdapter() {\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               filterStep = stepButton.getSelection();\r
+                               stepInput.setEnabled(filterStep);\r
+                               stepInput.setBackground(Display.getCurrent().getSystemColor(\r
+                                               !filterStep || stepValid ? SWT.COLOR_WIDGET_BACKGROUND : SWT.COLOR_YELLOW));\r
+                               validatePage();\r
+                       }\r
+               });\r
+               \r
+               stepInput.setEnabled(false);\r
+               stepInput.addModifyListener(new ModifyListener() {\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               try {\r
+                                       step = Integer.parseInt(stepInput.getText());\r
+                                       stepValid = true;\r
+                               }\r
+                               catch (Exception ex) {\r
+                                       stepValid = false;\r
+                               }\r
+                               stepInput.setBackground(Display.getCurrent().getSystemColor(\r
+                                               stepValid ? SWT.COLOR_WIDGET_BACKGROUND : SWT.COLOR_YELLOW));\r
+                               validatePage();\r
+                       }\r
+               });\r
+               \r
+               validatePage();\r
+               return super.createExtendedContentArea(parent);\r
+       }\r
+\r
+       @Override\r
+       protected void handleSelected(StructuredSelection selection) {\r
+               super.handleSelected(selection);\r
+               validatePage(); \r
+       }\r
+\r
+       protected void validatePage() {\r
+               \r
+               if(getSelectedItems().size() == 0) {\r
+                       updateStatus(new Status(Status.ERROR, PlatformUI.PLUGIN_ID, "Please select some variable(s)"));\r
+                       return;\r
+               }\r
+               \r
+               String error = validateSheet(sheetName);\r
+               if (error != null) {\r
+                       updateStatus(new Status(Status.ERROR, PlatformUI.PLUGIN_ID, error));\r
+                       return;\r
+               }\r
+\r
+               error = validateLocation(sheetLocation);\r
+               if (error != null) {\r
+                       updateStatus(new Status(Status.ERROR, PlatformUI.PLUGIN_ID, error));\r
+                       return;\r
+               }\r
+               \r
+               error = validateFilter();\r
+               if (error != null) {\r
+                       updateStatus(new Status(Status.ERROR, PlatformUI.PLUGIN_ID, error));\r
+                       return;\r
+               }\r
+               \r
+               updateStatus(new Status(Status.OK, Activator.PLUGIN_ID, ""));\r
+               \r
+       }\r
+\r
+       protected String validateSheet(String name) {\r
+               if (name.trim().isEmpty())\r
+                       return "Sheet name cannot be empty";\r
+               return null;\r
+       }\r
+\r
+       protected String validateLocation(String location) {\r
+               try {\r
+                       if(location.isEmpty())\r
+                               return "Empty location";\r
+                       SpreadsheetUtils.decodeCellAbsolute(location);\r
+                       return null;\r
+               } catch (Exception e) {\r
+                       return e.getMessage();\r
+               }\r
+       }\r
+       \r
+       protected String validateFilter() {\r
+               if (filterStart && !startValid) {\r
+                       return "Invalid start time in filter";\r
+               }\r
+               else if (filterStep && !stepValid) {\r
+                       return "Invalid sample rate in filter";\r
+               }\r
+               else {\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       public String getSheetName() {\r
+               return sheetName;\r
+       }\r
+\r
+       public String getSheetLocation() {\r
+               return sheetLocation;\r
+       }\r
+       \r
+       public boolean filterStart() {\r
+               return filterStart;\r
+       }\r
+       \r
+       public double getStart() {\r
+               return start;\r
+       }\r
+       \r
+       public boolean filterStep() {\r
+               return filterStep;\r
+       }\r
+       \r
+       public int getStep() {\r
+               return step;\r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveHistoryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveHistoryHandler.java
new file mode 100644 (file)
index 0000000..f4a103c
--- /dev/null
@@ -0,0 +1,157 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\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.resource.ImageDescriptor;\r
+import org.eclipse.jface.window.Window;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.mutable.Variant;\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.layer0.request.PossibleModel;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modelica.data.DataSet;\r
+import org.simantics.modelica.data.SimulationResult;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.spreadsheet.Range;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
+import org.simantics.sysdyn.manager.MemoryResult;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.manager.SysdynResult;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+       \r
+public class SaveHistoryHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \r
+        IExperimentManager manager = \r
+            SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment instanceof SysdynGameExperimentBase) {\r
+            final SysdynGameExperimentBase exp = (SysdynGameExperimentBase)experiment;\r
+               try {\r
+                       \r
+                       Map<DataSet, Pair<String,ImageDescriptor>> map = new HashMap<DataSet, Pair<String,ImageDescriptor>>();\r
+\r
+                       SysdynResult r = exp.getCurrentResult(); \r
+                       if(r instanceof MemoryResult) {\r
+                               MemoryResult gr = (MemoryResult)r;\r
+                               SimulationResult sr = gr.getSimulationResult();\r
+                               for(DataSet ds : sr.getVariableDataSets()) {\r
+                                       map.put(ds, new Pair<String,ImageDescriptor>(ds.name, null));\r
+                               }\r
+                       }\r
+                       \r
+                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
+                SaveHistoryDialog dialog = new SaveHistoryDialog(shell, map, "Select variables");\r
+                if (dialog.open() == Window.OK) {\r
+                    final Object[] result = dialog.getResult();\r
+                    final String sheetName = dialog.getSheetName();\r
+                    final String sheetLocation = dialog.getSheetLocation();\r
+                    \r
+                    final boolean filterStart = dialog.filterStart();\r
+                    final double start = dialog.getStart();\r
+                    final boolean filterStep = dialog.filterStep();\r
+                    final int step = dialog.getStep();\r
+                    \r
+                    Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                       public void writeCell(WriteGraph graph, Variable sheet, String cellName, String value) throws DatabaseException {\r
+                               SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+                               Variable child = sheet.getPossibleChild(graph, cellName);\r
+                               if(child != null) {\r
+                                       child.setPropertyValue(graph, SHEET.Cell_content, Variant.ofInstance(value), Bindings.VARIANT);\r
+                               } else {\r
+                                       Layer0 L0 = Layer0.getInstance(graph);\r
+                                       Resource container = sheet.getRepresents(graph);\r
+                                       Resource cell = graph.newResource();\r
+                                       graph.claim(cell, L0.InstanceOf, null, SHEET.TextCell);\r
+                                       graph.addLiteral(cell, L0.HasName, L0.NameOf, L0.String, cellName, Bindings.STRING);\r
+                                       graph.addLiteral(cell, SHEET.Cell_content, SHEET.Cell_content_Inverse, L0.Variant, Variant.ofInstance(value), Bindings.VARIANT);\r
+                                       graph.claim(cell, L0.PartOf, container);\r
+                               }\r
+                       }\r
+                       \r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               \r
+                               SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+                               Resource modelResource = graph.syncRequest(new PossibleModel(exp.getResource()));\r
+                               if(modelResource == null) return;\r
+                               List<Resource> sheets = ModelingUtils.searchByTypeAndName(graph, modelResource, SHEET.Spreadsheet, sheetName);\r
+                               if(sheets.size() != 1) return;\r
+                               Variable sheet = Variables.getVariable(graph, sheets.get(0));\r
+                               \r
+                               Range base = SpreadsheetUtils.decodeCellAbsolute(sheetLocation);\r
+                               \r
+                               int row = base.startRow;\r
+                               DataSet first = (DataSet)result[0];\r
+                               writeCell(graph, sheet, SpreadsheetUtils.cellName(row++, base.startColumn), "time");\r
+                               for(int i=0;i<first.times.length;i++) {\r
+                                       if (filterStep && i % step != 0)\r
+                                               continue;\r
+                                       if (filterStart && first.times[i] < start)\r
+                                               continue;\r
+                                       String loc = SpreadsheetUtils.cellName(row++, base.startColumn);\r
+                                       writeCell(graph, sheet, loc, Double.toString(first.times[i]));\r
+                               }\r
+                               \r
+                               for(int j=0;j<result.length;j++) {\r
+                                       row = base.startRow;\r
+                                       first = (DataSet)result[j];\r
+                                       writeCell(graph, sheet, SpreadsheetUtils.cellName(row++, base.startColumn+1+j), first.name);\r
+                                       for(int i=0;i<first.values.length;i++) {\r
+                                               if (filterStep && i % step != 0)\r
+                                                       continue;\r
+                                               if (filterStart && first.times[i] < start)\r
+                                                       continue;\r
+                                               String loc = SpreadsheetUtils.cellName(row++, base.startColumn+1+j);\r
+                                               writeCell(graph, sheet, loc, Double.toString(first.values[i])); \r
+                                       }\r
+\r
+                               }\r
+                               \r
+                       }\r
+\r
+                    });\r
+                }\r
+                       \r
+                \r
+                       } catch (Throwable e) {\r
+                               e.printStackTrace();\r
+                       }\r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveICHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SaveICHandler.java
new file mode 100644 (file)
index 0000000..b11fddf
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Simantics;\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.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\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.manager.SysdynExperiments;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+\r
+public class SaveICHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \r
+        IExperimentManager manager = \r
+            Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment instanceof SysdynExperiment) {\r
+            final SysdynExperiment exp = (SysdynExperiment)experiment;\r
+               try {\r
+                               Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               Variable v = Variables.getVariable(graph, exp.getResource());\r
+                                               SysdynExperiments.saveIC(graph, v);\r
+                                       }\r
+                                       \r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+        }\r
+        return null;\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..616f835
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.sysdyn.ui.utils.HandlerUtils;\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
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \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..0514909
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.IEditorPart;\r
+import org.eclipse.ui.PartInitException;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\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.db.layer0.exception.MissingVariableException;\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.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.sysdyn.ui.editor.SysdynEditorInput;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\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
+               IEditorPart editor = (IEditorPart)HandlerUtil.getActiveEditor(event);\r
+               if (!(editor instanceof DiagramEditor))\r
+                       return null;\r
+               final DiagramViewer viewer = (DiagramViewer) ((DiagramEditor) editor).getViewer();\r
+               if (viewer == null)\r
+                       return null;\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.RuntimeDiagram_HasVariable, Bindings.STRING);\r
+                               Variable parent = Variables.getVariable(graph, uri);\r
+                               final Resource model = Variables.getModel(graph, parent);\r
+                               \r
+                               for(Resource element : resources) {\r
+\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
+                                       Variable variable;\r
+                                       String rvi = "";\r
+                                       try {\r
+                                               variable = parent.browse(graph, component);\r
+                                               rvi = Variables.getRVI(graph, variable);\r
+                                       } catch (MissingVariableException e ) {\r
+                                               variable = Variables.getVariable(graph, graph.getURI(component));\r
+                                       }\r
+                                       final String finalRvi = rvi;\r
+                                       \r
+\r
+                                       \r
+                                       PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+                                               @Override\r
+                                               public void run() {\r
+                                                       try {\r
+                                                               String editorId = EDITOR_ID;\r
+                                                               WorkbenchUtils.openEditor(editorId, new SysdynEditorInput(editorId, diagram, model, finalRvi));\r
+                                                       } catch (PartInitException e) {\r
+                                                               e.printStackTrace();\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/SynthesisSimulation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SynthesisSimulation.java
new file mode 100644 (file)
index 0000000..00f12bb
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.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.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.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * @author Tuomas Miettinen\r
+ */\r
+public class SynthesisSimulation extends AbstractHandler implements IElementUpdater {\r
+\r
+       public static final String COMMAND = "org.simantics.sysdyn.ui.synthesisSimulation";\r
+    public static final String STATE = "org.simantics.sysdyn.ui.synthesisSimulation.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
+        Command toggleCommand = service.getCommand(ToggleSimulation.COMMAND);\r
+        State toggleState = toggleCommand.getState(ToggleSimulation.STATE);\r
+        toggleState.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
+        HandlerUtils.saveBeforeExperimentRun(event);\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("rawtypes")\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/handlers/SysdynExperimentActivator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/SysdynExperimentActivator.java
new file mode 100644 (file)
index 0000000..4b13c46
--- /dev/null
@@ -0,0 +1,194 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.concurrent.Semaphore;\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.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\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.message.MessageService;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\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.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\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 extends AbstractHandler {\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
+                try {\r
+                    return SysdynExperimentActivator.activate(monitor, project, experimentManager, experiment);\r
+                } finally {\r
+                    monitor.done();\r
+                }\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 NameUtils.getSafeName(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
+        final SubMonitor mon = SubMonitor.convert(monitor, "Activating experiment", 100000);\r
+\r
+        SysdynExperimentManagerListener.listenManager(manager);\r
+        IExperiment[] experiments = manager.getExperiments();\r
+        SubMonitor shutdownMon = mon.newChild(10000);\r
+        int workPerExperiment;\r
+        if (experiments.length > 0)\r
+               workPerExperiment = 10000 / experiments.length;\r
+        else\r
+               workPerExperiment = 10000;\r
+        for(IExperiment e : experiments)\r
+            if(e.getState() != ExperimentState.DISPOSED)\r
+                e.shutdown(shutdownMon.newChild(workPerExperiment));\r
+        mon.setWorkRemaining(90000);\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
+                MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
+                activated.release();\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
+            @Override\r
+            public IProgressMonitor getProgressMonitor() {\r
+                return mon;\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
+    }\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               ISelection selection = HandlerUtil.getCurrentSelection(event);\r
+        final Resource experiment = ResourceAdaptionUtils.toSingleResource(selection);\r
+        if (experiment == null)\r
+            return null;\r
+\r
+        final IProject project = SimanticsUI.getProject();\r
+        if (project == null)\r
+            return null;\r
+        \r
+        final IExperimentManager experimentManager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        if (experimentManager == null) {\r
+            ErrorLogger.defaultLogWarning("Experiment manager not available.", new Exception());\r
+            return null;\r
+        }\r
+        \r
+        SysdynExperimentActivator.scheduleActivation(SimanticsUI.getSession(), project, experimentManager, experiment);\r
+               return null;\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..024c6cb
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.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
+    public static 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
+                    for(Resource r : resources) {\r
+                        if(graph.isInstanceOf(r, sr.Result)) {\r
+                            if (graph.hasStatement(r, sr.Result_showResult)) {\r
+                                graph.denyStatement(r, sr.Result_showResult, r);\r
+                            } else {\r
+                                graph.claim(r, sr.Result_showResult, 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/ToggleResultSetActivation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleResultSetActivation.java
new file mode 100644 (file)
index 0000000..a667a8c
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\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.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.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 ToggleResultSetActivation 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
+    public static 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
+                    for(Resource r : resources) {\r
+                       // If there is at least one result which shown, clear them all.\r
+                       // If not one result is shown, show them all.\r
+                       boolean resultShown = false;\r
+                       Collection<Resource> results = graph.getObjects(r, sr.Experiment_result); \r
+                       for (Resource result : results) {\r
+                               if (graph.hasStatement(result, sr.Result_showResult)) {\r
+                                       resultShown = true;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       for (Resource result : results) {\r
+                               if (resultShown) { \r
+                                       graph.denyStatement(result, sr.Result_showResult, result);\r
+                            } else {\r
+                                graph.claim(result, sr.Result_showResult, result);\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/ToggleSimulation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/ToggleSimulation.java
new file mode 100644 (file)
index 0000000..351f9c4
--- /dev/null
@@ -0,0 +1,84 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.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.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\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
+        Command synthesisCommand = service.getCommand(SynthesisSimulation.COMMAND);\r
+        State synthesisState = synthesisCommand.getState(SynthesisSimulation.STATE);\r
+        synthesisState.setValue(false);\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
+        HandlerUtils.saveBeforeExperimentRun(event);\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("rawtypes")\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/handlers/UnlinkNodeHandler2.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/UnlinkNodeHandler2.java
new file mode 100644 (file)
index 0000000..4689072
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import java.util.Set;\r
+\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.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.modeling.ui.modelBrowser.handlers.DeleteNodeHandler;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class UnlinkNodeHandler2 extends DeleteNodeHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        Set<NodeContext> ctxs = ISelectionUtils.filterSetSelection(sel, NodeContext.class);\r
+\r
+        NodeType previousNodeType = null;\r
+        for (NodeContext ctx : ctxs) {\r
+            NodeType nodeType = ctx.getConstant(NodeType.TYPE);\r
+            if(previousNodeType == null) {\r
+                previousNodeType = nodeType;\r
+            } else if(!previousNodeType.equals(nodeType)) {\r
+                MessageDialog dialog = new MessageDialog(shell, "Unable to remove", null, "Only items of same type can be removed at the same time.", 0,\r
+                        new String[] { "OK" }, 0);\r
+                dialog.create();\r
+                dialog.open();\r
+                return null;\r
+            }\r
+        }\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
+            super.execute(event);\r
+        }\r
+        return null;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportExternalFunctionFilesHandler.java
new file mode 100644 (file)
index 0000000..fe9d193
--- /dev/null
@@ -0,0 +1,97 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\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.core.runtime.Platform;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.widgets.DirectoryDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\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.common.utils.NameUtils;\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
+/**\r
+ * Exports external function files from SysdynModelicaFunctions\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ExportExternalFunctionFilesHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+           // Find shell and resources to be exported\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(sel);\r
+               if (resources.length < 1)\r
+                       return null;\r
+\r
+               return exportFiles(shell, resources);\r
+       }\r
+       \r
+       /**\r
+        * Exports selected file resources to files on disk. Assumes all resources are external files.\r
+        * \r
+        * @param shell SWT Shell\r
+        * @param resources External file resources\r
+        * @return null\r
+        */\r
+       public static Object exportFiles(Shell shell, final Resource[] resources) {\r
+           \r
+           // Select a path where to export the files\r
+               DirectoryDialog dd = new DirectoryDialog(shell);\r
+               dd.setFilterPath(Platform.getLocation().toOSString());\r
+               dd.setText("Export files to...");\r
+               dd.setMessage("Select a directory");\r
+               final String dir = dd.open();\r
+               if (dir == null) {\r
+                       return null;\r
+               }\r
+\r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               // Get byte arrays from each resource and write them to disk\r
+                               for(Resource r : resources) {\r
+                                       try {\r
+                                               String name = NameUtils.getSafeName(graph, r);\r
+                                               FileOutputStream fos = new FileOutputStream(dir + "\\" + name);\r
+                                               byte[] fileBArray = graph.getPossibleRelatedValue(r, sr.ExternalFunctionFile_externalFile, Bindings.BYTE_ARRAY);\r
+                                               fos.write(fileBArray);\r
+                                               fos.close();\r
+                                       } catch (IOException e) {\r
+                                               e.printStackTrace();\r
+                                       }\r
+                               }\r
+                               \r
+                       }\r
+               });\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportFunctionLibrary.java
new file mode 100644 (file)
index 0000000..251ab7a
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\r
+\r
+import java.io.File;\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.core.runtime.Platform;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graph.db.TransferableGraphSource;\r
+import org.simantics.graph.db.TransferableGraphs;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+/**\r
+ * Exports a function library\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExportFunctionLibrary  extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        final Resource functionLibrary = ResourceAdaptionUtils.toSingleResource(sel);\r
+        if(functionLibrary == null) return null;\r
+               \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
+                                       if (!graph.hasStatement(functionLibrary, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       String name = graph.syncRequest(new PossibleRelatedValue<String>(functionLibrary, l0.HasName, Bindings.STRING ));\r
+                                       return name;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               // Do not export if the resource has no name\r
+               if(name == null) return null;\r
+               \r
+               // Find a location (and name) for the exported library using FileDialog\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
+               fd.setText("Export Function Library");\r
+               fd.setFileName(name);\r
+               String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+               fd.setFilterPath(path);\r
+               String[] filterExt = {"*.sysdynFunctions"};\r
+               fd.setFilterExtensions(filterExt);\r
+               fd.setOverwrite(true);\r
+               final String selected = fd.open();\r
+               if(selected == null) return null;\r
+               \r
+               // Save location to preference store\r
+               Activator.getDefault().getPreferenceStore().setValue(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH, (new File(selected)).getParent());\r
+\r
+               // Asynchronously create the file using transferable graph\r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                   @Override\r
+                   public void run(ReadGraph graph) throws DatabaseException {\r
+                       TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, functionLibrary);\r
+                       TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
+                       try {\r
+                           TransferableGraphs.writeTransferableGraph(graph, "sysdynFunctionLibrary", 1, s,new File(selected));\r
+                       } catch (Exception e) {\r
+                           e.printStackTrace();\r
+                       }\r
+                   }\r
+               });\r
+\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelAsButtonHandler.java
new file mode 100644 (file)
index 0000000..8e63184
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * Exports a selected model asking the location.\r
+ * Model determination is based on any resource of the model.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExportModelAsButtonHandler extends ExportModelButtonHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+               status = WorkbenchUtils.getStatusLine( HandlerUtil.getActiveSite(event) );\r
+        \r
+               final Resource model = determineModel(event);\r
+        if (model == null)\r
+               return null;\r
+        \r
+        String selected = getAbsolutePath(model, event, true);\r
+        \r
+        if (selected != null) {\r
+               createFile(model, selected);\r
+               setExportStatus(model, selected);\r
+        }\r
+        \r
+               return null;\r
+       }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelButtonHandler.java
new file mode 100644 (file)
index 0000000..9954ae6
--- /dev/null
@@ -0,0 +1,122 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\r
+\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.jface.viewers.IStructuredSelection;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.platform.PropertyPageView;\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.request.PossibleModel;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.sysdyn.ui.utils.SysdynWorkbenchUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * Exports a selected model without asking the location.\r
+ * Model determination is based on any resource of the model.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExportModelButtonHandler extends ExportModelHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+               status = WorkbenchUtils.getStatusLine( HandlerUtil.getActiveSite(event) );\r
+        \r
+               final Resource model = determineModel(event);\r
+        if (model == null)\r
+               return null;\r
+\r
+        String selected = getAbsolutePath(model, event, false);\r
+        \r
+        if (selected != null) {\r
+               createFile(model, selected);\r
+               setExportStatus(model, selected);\r
+        }\r
+        \r
+        return null;\r
+       }\r
+\r
+       @Override\r
+       protected Resource determineModel(ExecutionEvent event) {\r
+               ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        if (sel == null) {\r
+               // No selection, this is true e.g. in PropertyPageView\r
+               IWorkbenchPart activePart = HandlerUtil.getActivePart(event);\r
+               // In such a case get the selection the PropertyPageView point to.\r
+               if (activePart instanceof PropertyPageView)\r
+                       sel = ((PropertyPageView)activePart).getLastSelection();\r
+        }\r
+        \r
+        // Get the Resource of the selection\r
+        Resource inputResource = ResourceAdaptionUtils.toSingleResource(sel);\r
+        if (inputResource == null) {\r
+               // Coner case for when export is called when some folder in model browser is selected.\r
+            if (sel instanceof IStructuredSelection) {\r
+                IStructuredSelection iss = (IStructuredSelection) sel;\r
+                if (iss.size() == 1) {\r
+                       Object element = iss.getFirstElement();\r
+                       AbstractNode<?> a = AdaptionUtils.adaptToSingle(element, AbstractNode.class);\r
+                       if (a != null)\r
+                               inputResource = (Resource)a.data;\r
+                }\r
+            }\r
+        }\r
+        \r
+        // When the selection doesn't have a resource, use the currently active diagram.\r
+        if (inputResource == null) {\r
+               IWorkbenchPage page = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+               DiagramEditor editor = (DiagramEditor)page.getActiveEditor();\r
+               if (editor != null && editor instanceof DiagramEditor) {\r
+               inputResource = editor.getInputResource();\r
+            } else {\r
+                       return null; \r
+            }\r
+       }\r
+        \r
+        // Now that we finally have determined which Resource is selected, we just need\r
+        // to get the model of that Resource.\r
+        Resource model;\r
+        final Resource resource = inputResource;\r
+               try {\r
+                       model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                                       return graph.sync(new PossibleModel(resource));\r
+                               }\r
+                               \r
+                       });\r
+               if(model == null) return null;\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+                       return null;\r
+               }\r
+               return model;\r
+       }\r
+       \r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModelHandler.java
new file mode 100644 (file)
index 0000000..78e893d
--- /dev/null
@@ -0,0 +1,291 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\r
+\r
+import java.io.File;\r
+import java.lang.reflect.InvocationTargetException;\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.core.runtime.NullProgressMonitor;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.action.IStatusLineManager;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelExport.SysdynModelExporter;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * Exports a selected model\r
+ * Model determination is based on the very Resource of the model.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExportModelHandler extends AbstractHandler {\r
+\r
+       protected static IStatusLineManager status;\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+               status = WorkbenchUtils.getStatusLine( HandlerUtil.getActiveSite(event) );\r
+        \r
+               final Resource model = determineModel(event);\r
+        if (model == null)\r
+               return null;\r
+        \r
+        String selected = getAbsolutePath(model, event, true);\r
+        \r
+        if (selected != null) {\r
+               createFile(model, selected);\r
+               setExportStatus(model, selected);\r
+        }\r
+\r
+        return null;\r
+       }\r
+       \r
+       /**\r
+        * Create the export file.\r
+        * @param model Model which is exported.\r
+        * @param fileName Full name of the file.\r
+        */\r
+       protected void setExportStatus(final Resource model, final String fileName) {\r
+               try {\r
+                       String modelName = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+       \r
+                               @Override\r
+                               public String perform(ReadGraph graph) throws DatabaseException {\r
+                                       if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       return graph.syncRequest(new PossibleRelatedValue<String>(model, l0.HasName, Bindings.STRING ));\r
+                               }\r
+                               \r
+                       });\r
+       \r
+                       if (modelName != null)\r
+                               setStatus("Saved model \"" + modelName + "\" to " + fileName);\r
+               \r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Create the export file.\r
+        * @param model Model which is exported.\r
+        * @param fileName Full name of the file.\r
+        */\r
+       protected void createFile(final Resource model, final String fileName) {\r
+               File exportLocation = new File(fileName);\r
+               try {\r
+            SysdynModelExporter.exportModel(new NullProgressMonitor(), model, exportLocation, "", false);\r
+        } catch (InvocationTargetException e1) {\r
+            ExceptionUtils.logAndShowError("Model Export Failed", "Sysdyn model export failed, see exception for details", e1);\r
+        }\r
+\r
+//             // Asynchronously create the file using transferable graph\r
+//             SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+//\r
+//                 @Override\r
+//                 public void run(ReadGraph graph) throws DatabaseException {\r
+//                     HashMap<Resource, ExtentStatus> map = new HashMap<Resource, ExtentStatus>();\r
+//                     \r
+//                     Resource relation = graph.getPossibleResource("http://www.simantics.org/Documentation-1.1/createdBy");\r
+//                     if(relation != null) {\r
+//                         Resource createdBy = graph.getPossibleObject(model, relation);\r
+//                         if(createdBy != null)\r
+//                             map.put(createdBy, ExtentStatus.EXCLUDED);\r
+//                     }\r
+//                     \r
+//                     TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model);\r
+//                     conf.preStatus.putAll(map);\r
+//                     \r
+//                     TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
+//                     try {\r
+//                         TransferableGraphs.writeTransferableGraph(graph, "sysdynModel", 1, s,new File(fileName));\r
+//                     } catch (Exception e) {\r
+//                         ExceptionUtils.logAndShowError("Model Export Failed", "Sysdyn model export failed, see exception for details", e);\r
+//                         \r
+//                         File modelFile = new File(fileName);\r
+//                         if (modelFile.exists())\r
+//                             modelFile.delete();\r
+//                     }\r
+//                     }\r
+//             });\r
+       }\r
+       \r
+       /**\r
+        * Get the model Resource based on the event.\r
+        * @param event\r
+        * @return model Resource which the event refers to.\r
+        */\r
+       protected Resource determineModel(ExecutionEvent event) {\r
+               // Just get the selected model.\r
+           ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+           final Resource model = ResourceAdaptionUtils.toSingleResource(sel);\r
+           return model;\r
+       }\r
+       \r
+       /**\r
+        * Get the absolute save path for the export file and save it to the database.\r
+        * @param model Model Resource which is exported.\r
+        * @param event\r
+        * @param saveAs true if save as... functionality is used; otherwise save \r
+        * functionality is used. \r
+        * @return The full path name of the exported model.\r
+        * @throws ExecutionException\r
+        */\r
+       protected String getAbsolutePath(final Resource model, ExecutionEvent event, boolean saveAs) throws ExecutionException {\r
+\r
+               // Determine the default path.\r
+               String path = null;\r
+               try {\r
+                       //If the model has been exported earlier, use that path.\r
+                       path = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                               @Override\r
+                               public String perform(ReadGraph graph) throws DatabaseException {\r
+                                       if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       SysdynResource SR = SysdynResource.getInstance(graph);\r
+                                       String path = graph.syncRequest(new PossibleRelatedValue<String>(model, SR.SysdynModel_lastExportFilePath, Bindings.STRING ));\r
+                                       return path;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               // If this is the initial save:\r
+               if (path == null) {\r
+                       if (saveAs == false) {\r
+                               // Save == Save as... when there has been no earlier save. \r
+                               return getAbsolutePath(model, event, true);\r
+                       }\r
+                       // Use import default path.\r
+                       path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH);\r
+               }\r
+               if (saveAs == false && !(new File(path).exists())) {\r
+                       // Save == Save as... when the path doesn't exist. \r
+                       return getAbsolutePath(model, event, true);\r
+               }\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+                               \r
+        // Determine the default name\r
+               // FIXME: Model browser doesn't change its selection even if the selected object is removed,\r
+        // so you can try to export a removed model \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
+                                       if (!graph.hasStatement(model, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       SysdynResource SR = SysdynResource.getInstance(graph);\r
+                                       // If the model has been exported earlier, use that name.\r
+                                       // When mere Save has progressed here, there is always be the name in the database.  \r
+                                       String name = graph.syncRequest(new PossibleRelatedValue<String>(model, SR.SysdynModel_lastExportFileName, Bindings.STRING ));\r
+                                       if (name == null) {\r
+                                               // If not, use the model name.\r
+                                               name = graph.syncRequest(new PossibleRelatedValue<String>(model, l0.HasName, Bindings.STRING ));\r
+                                       }\r
+                                       return name;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               // Do not export if the resource has no name\r
+               if(name == null) return null;\r
+               \r
+               final String selected;\r
+               String fullPath = null;\r
+               if (saveAs == true) {\r
+               // Find a location (and name) for the exported library using FileDialog\r
+                       Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+                       FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
+                       fd.setText("Export Model");\r
+                       fd.setFileName(name);\r
+                       \r
+                       fd.setFilterPath(path);\r
+                       String[] filterExt = {"*.sysdyn"};\r
+                       fd.setFilterExtensions(filterExt);\r
+                       fd.setOverwrite(true);\r
+                       fullPath = fd.open();\r
+               }\r
+               else {\r
+                       // Save to the earlier location. \r
+                       fullPath = path;\r
+                       if (path.charAt(path.length() - 1) != '\\')\r
+                               fullPath += "\\"; // Saving to C:\ would otherwise add excess backslashes.\r
+                       fullPath += name;\r
+               }\r
+               selected = fullPath;\r
+               \r
+               if(selected == null) return null;\r
+\r
+               // Save location to preference store\r
+               try {\r
+                       SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       SysdynResource SR = SysdynResource.getInstance(graph);\r
+                                       graph.deny(model, SR.SysdynModel_lastExportFilePath);\r
+                                       graph.deny(model, SR.SysdynModel_lastExportFileName);\r
+                                       graph.addLiteral(model, SR.SysdynModel_lastExportFilePath, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getParent(), Bindings.STRING);\r
+                                       graph.addLiteral(model, SR.SysdynModel_lastExportFileName, SR.SysdynModel_lastExportFilePath_Inverse, l0.String, new File(selected).getName(), Bindings.STRING); \r
+                               }\r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+               return selected;\r
+\r
+       }\r
+       \r
+    protected static void setStatus(final String message) {\r
+       if (status != null)\r
+            status.setMessage(message);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/exports/ExportModuleHandler.java
new file mode 100644 (file)
index 0000000..6a0cc12
--- /dev/null
@@ -0,0 +1,276 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.exports;\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.core.runtime.Platform;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.MessageBox;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graph.db.TransferableGraphSource;\r
+import org.simantics.graph.db.TransferableGraphs;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * Exports a selected module\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExportModuleHandler extends AbstractHandler {\r
+\r
+       /**\r
+        * Temporary exception. At this phase, the system will not support exporting modules\r
+        * that depend on other modules. \r
+        * \r
+        * @author Teemu Lempinen\r
+        *\r
+        */\r
+       class ContainsDependenciesException extends DatabaseException {\r
+               private static final long serialVersionUID = -1533706136673146020L;\r
+               \r
+               private final Collection<String> dependencies;\r
+               \r
+               ContainsDependenciesException(Collection<String> dependencies) {\r
+                       this.dependencies = dependencies;\r
+               }\r
+               \r
+               public Collection<String> getDependencies() {\r
+                       return this.dependencies;\r
+               }\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        final Resource modulesymbol = ResourceAdaptionUtils.toSingleResource(sel);\r
+        if(modulesymbol == null) return null;\r
+               \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
+                                       ModelingResources mr = ModelingResources.getInstance(graph);\r
+                                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       \r
+                                       // Start checking for module dependencies\r
+                                       Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType);\r
+                                       if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       \r
+                                       Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                                       if (configuration == null)\r
+                                               return null;\r
+                                       \r
+                                       ArrayList<String> dependencies = null;\r
+                                       for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) {\r
+                                               if(dependencies == null)\r
+                                                       dependencies = new ArrayList<String>();\r
+                                               String name = NameUtils.getSafeName(graph, r);\r
+                                               String instanceOf = NameUtils.getSafeName(graph, graph.getSingleObject(r, l0.InstanceOf));\r
+                                               dependencies.add(name + " : " + instanceOf);\r
+                                       }\r
+                                       if(dependencies != null && !dependencies.isEmpty())\r
+                                               throw new ContainsDependenciesException(dependencies);\r
+                                       // End checking for module dependencies. If dependencies were found, an exception was thrown\r
+                                       \r
+                                       String name = graph.getPossibleRelatedValue(component, l0.HasName, Bindings.STRING);\r
+                                       return name;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (ContainsDependenciesException e1) {\r
+                       Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+                       MessageBox mb = new MessageBox(shell, SWT.OK);\r
+                       StringBuilder sb = new StringBuilder();\r
+                       sb.append("This version does not support exporting modules with other module instances.\n\n");\r
+                       sb.append("Dependencies:\n");\r
+                       for(String s : e1.getDependencies())\r
+                               sb.append("    " + s + "\n");\r
+                       mb.setMessage(sb.toString());\r
+                       mb.setText("Module contains dependencies.");\r
+                       mb.open();\r
+                       return null;\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+        // Do not export if the resource has no name\r
+               if(name == null) return null;\r
+               \r
+        // Find a location (and name) for the exported library using FileDialog\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
+               fd.setText("Export Module");\r
+               fd.setFileName(name);\r
+               String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODULETPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+               fd.setFilterPath(path);\r
+               String[] filterExt = {"*.sysdynModule"};\r
+               fd.setFilterExtensions(filterExt);\r
+               fd.setOverwrite(true);\r
+               final String selected = fd.open();\r
+               if(selected == null) return null;\r
+               \r
+        // Save location to preference store\r
+               Activator.getDefault().getPreferenceStore().setValue(ImportUtilsUI.IMPORTMODULETPATH, (new File(selected)).getParent());\r
+               \r
+        // Asynchronously create the file using transferable graph\r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               ModelingResources mr = ModelingResources.getInstance(graph);\r
+\r
+                               final Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType);\r
+                               if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
+                                       return;\r
+                               String name = graph.syncRequest(new PossibleRelatedValue<String>(component, l0.HasName, Bindings.STRING ));\r
+                               final ArrayList<Pair<Resource, String>> roots = new ArrayList<Pair<Resource, String>>();\r
+                               roots.add(Pair.make(component, name));\r
+\r
+                               graph.asyncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+\r
+                                               Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                                               if (!graph.hasStatement(configuration, l0.PartOf, component)&& \r
+                                                               !graph.hasStatement(modulesymbol, l0.PartOf, component)) {\r
+                                                       // Make sure that configuration and symbol are included.\r
+                                                       // In old versions, they were attached to model, not to module.\r
+                                                       Resource previousPartof = graph.getSingleObject(configuration, l0.PartOf);\r
+\r
+                                                       graph.deny(configuration, l0.PartOf);\r
+                                                       graph.deny(modulesymbol, l0.PartOf);\r
+                                                       graph.claim(configuration, l0.PartOf, l0.ConsistsOf, component);\r
+                                                       graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, component);\r
+\r
+                                                       export(graph, selected, roots, component);\r
+\r
+                                                       graph.deny(configuration, l0.PartOf);\r
+                                                       graph.deny(modulesymbol, l0.PartOf);\r
+                                                       graph.claim(configuration, l0.PartOf, l0.ConsistsOf, previousPartof);\r
+                                                       graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, previousPartof);\r
+                                               } else {\r
+                                                       // Normal export\r
+                                                       export(graph, selected, roots, component);\r
+                                               }\r
+                                       }\r
+                               });\r
+\r
+                       }\r
+               });\r
+\r
+               return null;\r
+       }\r
+       \r
+       /**\r
+        * Export module (without dependencies to other modules) and write it to file. \r
+        * Disable existing enumeration replacement for during export.  \r
+        *  \r
+        * @param graph WriteGraph\r
+        * @param path Path for the exported file\r
+        * @param roots\r
+        * @param component Module\r
+        */\r
+       private void export(WriteGraph graph, final String path, ArrayList<Pair<Resource, String>> roots, final Resource component) {\r
+               \r
+               // FIXME: Enumeration replacement handling like this is not suitable.\r
+               try {\r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+\r
+                       Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                       ArrayList<Pair<Resource, Resource>> replacements = new ArrayList<Pair<Resource, Resource>>();\r
+\r
+                       for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
+                               if(graph.hasStatement(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
+                                       for(Resource replacement : graph.getObjects(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
+                                               replacements.add(new Pair<Resource, Resource>(enumeration, replacement));\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       for(Pair<Resource,Resource> replacement : replacements)\r
+                               graph.deny(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
+                       \r
+                       SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+\r
+                           @Override\r
+                           public void run(ReadGraph graph) throws DatabaseException {\r
+                               TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, component);\r
+                               TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
+                               try {\r
+                                   TransferableGraphs.writeTransferableGraph(graph, "sysdynModule", 1, s,new File(path));\r
+                               } catch (Exception e) {\r
+                                   e.printStackTrace();\r
+                               }\r
+                           }\r
+                       });\r
+\r
+                       \r
+                       for(Pair<Resource,Resource> replacement : replacements)\r
+                               graph.claim(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
+\r
+               } catch (RuntimeBindingConstructionException e) {\r
+                       e.printStackTrace();\r
+//             } catch (IOException e) {\r
+//                     e.printStackTrace();\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/handlers/game/ReloadGameExperimentHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/ReloadGameExperimentHandler.java
new file mode 100644 (file)
index 0000000..218512c
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.game;\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.ui.handlers.RunBasicExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Handler for initializing and reloading game experiments.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ReloadGameExperimentHandler extends RunBasicExperiment {\r
+       \r
+       private boolean started = false;\r
+       private boolean initialized = false;\r
+       \r
+       \r
+    public static final String COMMAND = "org.simantics.sysdyn.ui.reloadGame";\r
+    \r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+       SysdynGameExperimentBase game = getGameExperiment();\r
+        if(game != null)\r
+            game.simulate(true);\r
+        return null;\r
+    }\r
+       \r
+    /**\r
+     * Find currently active game experiment\r
+     * @return Currently active game experiment or null if game experiment not active\r
+     */\r
+    private SysdynGameExperimentBase getGameExperiment() {\r
+        // Find active experiment\r
+        IProject project = SimanticsUI.peekProject();\r
+        if (project == null)\r
+            return null;\r
+        \r
+        IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+\r
+        IExperiment active = manager.getActiveExperiment();\r
+        if (!(active instanceof SysdynGameExperimentBase))\r
+            return null;\r
+        \r
+        return (SysdynGameExperimentBase) active;\r
+    }\r
+       \r
+       @SuppressWarnings("rawtypes")\r
+       @Override\r
+       public void updateElement(UIElement element, Map parameters) {\r
+               // Disable button while initializign a model\r
+               super.updateElement(element, parameters);\r
+               \r
+               \r
+               // Change tooltip according to the current status\r
+               SysdynGameExperimentBase game = getGameExperiment();   \r
+\r
+        if(game == null) {\r
+                       started = false;\r
+                       initialized = false;\r
+                       return;\r
+        }\r
+        \r
+        ExperimentState state = game.getState();\r
+        \r
+               if(state==ExperimentState.INITIALIZING) {\r
+                       started = false;\r
+                       initialized = false;\r
+               } else if(state==ExperimentState.RUNNING) {\r
+                       started = true;\r
+                       initialized = false;\r
+               } else if(state==ExperimentState.STOPPED) {\r
+                       if(started && !initialized) {\r
+                               initialized = true;\r
+                       } \r
+               }\r
+               \r
+        \r
+        if(initialized) {\r
+            element.setTooltip("Reload Game");\r
+        } else {\r
+            element.setTooltip("Initialize Game");\r
+        }\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/game/StepHandler.java
new file mode 100644 (file)
index 0000000..ecb69ef
--- /dev/null
@@ -0,0 +1,108 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.game;\r
+\r
+import java.util.Map;\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.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Handler for stepping game simulations\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class StepHandler extends AbstractHandler implements IElementUpdater {\r
+       \r
+    public static String COMMAND = "org.simantics.sysdyn.ui.step";\r
+    \r
+       private boolean started = false;\r
+       private boolean initialized = false;\r
+       private boolean running = false;        \r
+    \r
+    private SysdynGameExperimentBase getGameExperiment() {\r
+        // Find active experiment\r
+        IProject project = SimanticsUI.peekProject();\r
+        if (project == null)\r
+            return null;\r
+        \r
+        IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+\r
+        IExperiment active = manager.getActiveExperiment();\r
+        if (!(active instanceof SysdynGameExperimentBase))\r
+            return null;\r
+        \r
+        return (SysdynGameExperimentBase) active;\r
+    }\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \r
+        SysdynGameExperimentBase game = getGameExperiment();\r
+        if(game != null)\r
+               game.simulateDuration(game.getStepDuration());\r
+       return null;\r
+    }\r
+\r
+       @SuppressWarnings("rawtypes")\r
+       @Override\r
+       public void updateElement(UIElement element, Map parameters) {\r
+               \r
+               // Disable button when model has not been initialized and change tooltip accordingly\r
+               SysdynGameExperimentBase game = getGameExperiment();   \r
+\r
+        if(game == null) {\r
+                       started = false;\r
+                       initialized = false;\r
+                       return;\r
+        }\r
+        \r
+        ExperimentState state = game.getState();\r
+        \r
+               if(state==ExperimentState.INITIALIZING) {\r
+                       started = false;\r
+                       initialized = false;\r
+                       running = false;\r
+               } else if(state==ExperimentState.RUNNING) {\r
+                       started = true;\r
+                       initialized = initialized == true ? true : false;\r
+                       running = true;\r
+               } else if(state==ExperimentState.STOPPED) {\r
+                       if(started && !initialized) {\r
+                               initialized = true;\r
+                       } \r
+                       running = false;\r
+               }\r
+        \r
+        if(initialized) {\r
+               if(!running)\r
+                       this.setBaseEnabled(true);\r
+               else\r
+                       this.setBaseEnabled(false);\r
+            element.setTooltip("Step");\r
+        } else {\r
+            this.setBaseEnabled(false);\r
+            element.setTooltip("Initialize Game First");\r
+        }\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportBPMNHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportBPMNHandler.java
new file mode 100644 (file)
index 0000000..1aba575
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.FileDialog;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.Simantics;\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.modelImport.BPMNParser;\r
+import org.simantics.sysdyn.modelImport.model.Model;\r
+\r
+public class ImportBPMNHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               FileDialog dialog = new FileDialog(HandlerUtil.getActiveShellChecked(event));\r
+               String path = dialog.open();\r
+               if (path == null) {\r
+                       return null;\r
+               }\r
+               final Model model; \r
+               try {\r
+                       model = new BPMNParser().parse(new File(path));\r
+               }\r
+               catch (Exception e) {\r
+                       e.printStackTrace();\r
+                       return null;\r
+               }\r
+               final Resource project = Simantics.getProject().get();\r
+               \r
+               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               model.write(graph, project);\r
+                       }\r
+               });\r
+               \r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportExternalFunctionFilesHandler.java
new file mode 100644 (file)
index 0000000..50277c1
--- /dev/null
@@ -0,0 +1,120 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.IOException;\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.core.runtime.Platform;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.databoard.Bindings;\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.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * Imports external functions to SysdynModelicaFunctions using FileDialog.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportExternalFunctionFilesHandler extends AbstractHandler {\r
+\r
+       public static final String[] C_EXTENSIONS = {"*.c","*.h","*.a","*.o"};\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               Pair<String, String[]> selected = importFiles(shell, "Import...", C_EXTENSIONS);\r
+               if(selected.second == null || selected.second.length < 1) return null;\r
+\r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                       \r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               // TODO: include files to database\r
+                       }\r
+               });\r
+               \r
+               return null;\r
+       }\r
+       \r
+       /**\r
+        * Opens a {@link FileDialog} to select the imported files.\r
+        *  \r
+        * @param shell SWT Shell\r
+        * @param text Header text for the FileDialog\r
+        * @param filter Filters for the FileDialog\r
+        * @return File names and paths for the files to be imported\r
+        */\r
+       public static Pair<String, String[]> importFiles(Shell shell, String text, String[] filter) {\r
+               FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+               fd.setText(text);\r
+               fd.setFilterPath(Platform.getLocation().toOSString());\r
+               fd.setFilterExtensions(filter);\r
+               fd.open();\r
+               return new Pair<String, String[]>(fd.getFilterPath(), fd.getFileNames());\r
+       }\r
+       \r
+       \r
+       /**\r
+        * Saves the given files as byte arrays to a function\r
+        * \r
+        * @param graph WriteGraph\r
+        * @param function Function where the files are to be added\r
+        * @param files Files to be added\r
+        * @throws DatabaseException\r
+        */\r
+       public static void addFilesToFunction(WriteGraph graph, Resource function, Pair<String, String[]> files) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               \r
+               if(!graph.isInstanceOf(function, sr.SysdynModelicaFunction))\r
+                       return;\r
+\r
+               for(String filename : files.second) {\r
+                       File file = new File(files.first, filename);\r
+                                       \r
+                       String name = file.getName();\r
+                       \r
+                       Resource externalFile = GraphUtils.create2(graph, \r
+                                       sr.ExternalFunctionFile,\r
+                                       l0.PartOf, function,\r
+                                       l0.HasName, name);\r
+                       \r
+                       try {\r
+                               byte[] fileBArray = new byte[(int)file.length()];\r
+                               FileInputStream fis = new FileInputStream(file);\r
+                               fis.read(fileBArray);\r
+                               graph.claimLiteral(externalFile, sr.ExternalFunctionFile_externalFile, fileBArray, Bindings.BYTE_ARRAY);\r
+                               fis.close();\r
+                       } catch (IOException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+\r
+               }\r
+               \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportFunctionLibrary.java
new file mode 100644 (file)
index 0000000..4e227e7
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionsFolder;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Imports an exported function library (or shared function library) transferable graph. \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportFunctionLibrary  extends AbstractHandler {\r
+       \r
+       /**\r
+        * Called from a functions folder node\r
+        */\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        Resource r = ResourceAdaptionUtils.toSingleResource(sel);\r
+        if(r == null) {\r
+               FunctionsFolder mn = AdaptionUtils.adaptToSingle(sel, FunctionsFolder.class);\r
+               r = mn.data;\r
+        }\r
+        if(r == null) return null;\r
+        \r
+        final Resource functionLibrary = r;\r
+        \r
+        \r
+        // Get a transferable graph file\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+               fd.setText("Import Function Library");\r
+               \r
+               String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTFUNCTIONLIBRARYPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                   path = Platform.getLocation().toOSString();\r
+               fd.setFilterPath(path);\r
+               String[] filterExt = {"*.sysdynFunctions; *.tg", "*.*"};\r
+               fd.setFilterExtensions(filterExt);\r
+               final String selected = fd.open();\r
+               if(selected == null) return null;\r
+\r
+               Job job = new DatabaseJob("Import function") {\r
+\r
+                   @Override\r
+                   protected IStatus run(IProgressMonitor monitor) {\r
+                       IStatus status = ImportUtilsUI.importFunctionLibrary(functionLibrary, selected, monitor);\r
+                       return status;\r
+                   }\r
+               };\r
+\r
+               job.setUser(true);\r
+               job.schedule();\r
+\r
+               return null;\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportMdlHandler.java
new file mode 100644 (file)
index 0000000..e1230b8
--- /dev/null
@@ -0,0 +1,88 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.core.runtime.Platform;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\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.DatabaseException;\r
+import org.simantics.sysdyn.modelImport.MdlParser;\r
+import org.simantics.sysdyn.modelImport.model.Model;\r
+import org.simantics.sysdyn.modelImport.model.WriteContext;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Class for importing Vensim models (.mdl) to Simantics SysDyn using MdlParser \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportMdlHandler extends AbstractHandler {\r
+\r
+       public static String IMPORTMDLTPATH = "IMPORT_MDL_PATH";\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               \r
+               final Resource project = SimanticsUI.getProject().get();\r
+               if(project == null) return null;\r
+\r
+               // Get the .mdl file\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+               fd.setText("Import .mdl");\r
+               String path = Activator.getDefault().getPreferenceStore().getString(IMPORTMDLTPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+               fd.setFilterPath(path);\r
+               String[] filterExt = {"*.mdl"};\r
+               fd.setFilterExtensions(filterExt);\r
+               String selected = fd.open();\r
+               if(selected == null) return null;\r
+\r
+               File file = new File(selected);\r
+               if(!file.isFile()) return null;\r
+               \r
+               Activator.getDefault().getPreferenceStore().setValue(IMPORTMDLTPATH, (new File(selected)).getParent());\r
+               \r
+               // Convert Vensim model to Simantics SysDyn format using MdlParser\r
+               final Model model;\r
+               try {\r
+                       model = new MdlParser().parse(file);\r
+               }\r
+               catch (Exception e) {\r
+                       e.printStackTrace();\r
+                       return null;\r
+               }\r
+               \r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               model.write(graph, project, new WriteContext());\r
+                       }\r
+               });\r
+               \r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java
new file mode 100644 (file)
index 0000000..2849101
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.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.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+/**\r
+ * Imports models from exported transferable graph files.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportModelHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        // Get imported transferable graph file using FileDialog\r
+        Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+        FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+        fd.setText("Import Model");\r
+\r
+        String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH);\r
+        if(path.isEmpty() || !(new File(path).exists())){\r
+               String execDir = System.getProperty("user.dir");\r
+               String slash = System.getProperty("file.separator");\r
+               path = execDir + slash + "sampleModels"; \r
+        }\r
+        \r
+        fd.setFilterPath(path);\r
+        String[] filterExt = {"*.sysdyn; *.tg", "*.*"};\r
+        fd.setFilterExtensions(filterExt);\r
+        final String selected = fd.open();\r
+        if(selected == null) return null;\r
+\r
+        Job job = new DatabaseJob("Import model") {\r
+\r
+            @Override\r
+            protected IStatus run(IProgressMonitor monitor) {\r
+               monitor.beginTask("Importing Model " + selected, 3);\r
+               IStatus status = null;\r
+               try {\r
+                       monitor.worked(1);\r
+                    status = ImportUtilsUI.importModelFile(selected, monitor);                         \r
+                    monitor.worked(2);\r
+               } catch (Exception e) {\r
+                       ExceptionUtils.logAndShowError("Model import failed, see exception for details",  e);\r
+                       ErrorLogger.defaultLogError("Model import failed, see exception for details", e);\r
+                       return Status.OK_STATUS;\r
+               } finally {\r
+                       monitor.done();\r
+               }\r
+\r
+                return status;\r
+            }\r
+        };\r
+        job.setUser(true);\r
+        job.schedule();\r
+\r
+        return null;\r
+\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModuleHandler.java
new file mode 100644 (file)
index 0000000..19c4031
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Imports modules from exported transferable graph files.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportModuleHandler extends AbstractHandler {\r
+\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+               ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+               @SuppressWarnings("unchecked")\r
+               AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+               if (node == null)\r
+                       return null;\r
+\r
+               final Resource model = node.data;\r
+\r
+               // Get imported transferable graph file using FileDialog\r
+               Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+               FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+               fd.setText("Import Module");\r
+\r
+               String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODULETPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+               fd.setFilterPath(path);\r
+               String[] filterExt = {"*.sysdynModule; *.tg", "*.*"};\r
+               fd.setFilterExtensions(filterExt);\r
+               final String selected = fd.open();\r
+               if(selected == null) return null;\r
+               \r
+               Job job = new DatabaseJob("Import module") {\r
+\r
+            @Override\r
+            protected IStatus run(IProgressMonitor monitor) {\r
+                IStatus status = ImportUtilsUI.importModuleFile(model, selected, monitor);\r
+                return status;\r
+            }\r
+        };\r
+        job.setUser(true);\r
+        job.schedule();\r
+\r
+               return null;\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportSharedLibraryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportSharedLibraryHandler.java
new file mode 100644 (file)
index 0000000..8165e54
--- /dev/null
@@ -0,0 +1,83 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.imports;\r
+\r
+import java.io.File;\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.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.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.graph.db.MissingDependencyException;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class ImportSharedLibraryHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        // Get imported transferable graph file using FileDialog\r
+        Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+        FileDialog fd = new FileDialog(shell, SWT.OPEN);\r
+        fd.setText("Import Shared Library");\r
+\r
+        String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH);\r
+        if(path.isEmpty() || !(new File(path).exists())){\r
+               String execDir = System.getProperty("user.dir");\r
+               String slash = System.getProperty("file.separator");\r
+               path = execDir + slash + "sampleModels"; \r
+        }\r
+        \r
+        fd.setFilterPath(path);\r
+        String[] filterExt = {"*.sharedLibrary; *.tg", "*.*"};\r
+        fd.setFilterExtensions(filterExt);\r
+        final String selected = fd.open();\r
+        if(selected == null) return null;\r
+\r
+        Job job = new DatabaseJob("Import Shared Library") {\r
+\r
+            @Override\r
+            protected IStatus run(IProgressMonitor monitor) {\r
+               monitor.beginTask("Importing Shared Library " + selected, 3);\r
+               try {\r
+                       monitor.worked(1);\r
+                                       ModelingUtils.importSharedOntology(selected);\r
+                                       monitor.worked(2);\r
+               } catch (Exception e) {\r
+                       ExceptionUtils.logAndShowError(e);\r
+                       ErrorLogger.defaultLogError("Shared Library import failed, see exception for details.", e);\r
+               } finally {\r
+                                       monitor.done();\r
+                               }\r
+                return Status.OK_STATUS;\r
+            }\r
+        };\r
+        job.setUser(true);\r
+        job.schedule();\r
+\r
+        return null;\r
+\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewBarChartHandler.java
new file mode 100644 (file)
index 0000000..1e34214
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.Collections;\r
+import java.util.UUID;\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Handler for creating a new Bar Chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewBarChartHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+        ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(g);\r
+                G2DResource g2d = G2DResource.getInstance(g);\r
+\r
+                String label = NameUtils.findFreshLabel(g, "Bar Chart", model);\r
+                \r
+                Resource jfreechart = GraphUtils.create2(g, jfree.Chart,\r
+                        l0.HasName, "BarChart" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, label,\r
+                        l0.PartOf, model,\r
+                        jfree.Chart_visibleBorder, true,\r
+                        jfree.Chart_borderWidth, 3,\r
+                        jfree.Chart_visibleLegend, false\r
+                        );\r
+                \r
+                g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                GraphUtils.create2(g, jfree.TextTitle,\r
+                        l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "Bar Chart Title",\r
+                        jfree.Title_position, jfree.Top,\r
+                        l0.PartOf, jfreechart);\r
+\r
+                Resource domainAxis = GraphUtils.create2(g, jfree.CategoryAxis,\r
+                        l0.HasName, "CategoryAxis" + UUID.randomUUID().toString());\r
+                \r
+                Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasName, "NumberAxis" + UUID.randomUUID().toString());\r
+\r
+                Resource renderer = GraphUtils.create2(g, jfree.BarRenderer);\r
+                \r
+                Resource dataset = GraphUtils.create2(g, jfree.CategoryDataset,\r
+                        l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(),\r
+                        jfree.Dataset_mapToDomainAxis, domainAxis,\r
+                        jfree.Dataset_mapToRangeAxis, rangeAxis,\r
+                        jfree.Dataset_seriesList, ListUtils.create(g, Collections.<Resource>emptyList()),\r
+                        jfree.Dataset_renderer, renderer);\r
+\r
+                GraphUtils.create2(g, jfree.CategoryPlot,\r
+                        l0.HasName, "Category plot" + UUID.randomUUID().toString(),\r
+                        l0.PartOf, jfreechart,\r
+                        jfree.Plot_domainAxis, domainAxis,\r
+                        jfree.Plot_rangeAxis, rangeAxis,\r
+                        jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)),\r
+                        l0.ConsistsOf, dataset,\r
+                        l0.ConsistsOf, domainAxis,\r
+                        l0.ConsistsOf, rangeAxis);\r
+                Layer0Utils.addCommentMetadata(g, "Created new Bar Chart " +  label + " " + jfreechart);\r
+            }\r
+\r
+        });\r
+        \r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewEnumerationNodeHandler.java
new file mode 100644 (file)
index 0000000..8112802
--- /dev/null
@@ -0,0 +1,91 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.ArrayList;\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.databoard.Bindings;\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new Enumeration node to a configuration or module\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewEnumerationNodeHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+               final Resource resource = AdaptionUtils.adaptToSingle(sel, Resource.class);\r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+               SysdynResource sr = SysdynResource.getInstance(g);\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+               \r
+               // Find the actual configuration. Possible cases for resource are sr.Configuration, sr.ModuleSymbol or sr.Module.\r
+               Resource configuration = null;\r
+               if(g.isInstanceOf(resource, sr.Configuration)) {\r
+                       configuration = resource;\r
+               } else if(g.isInheritedFrom(resource, sr.ModuleSymbol)) {\r
+                       Resource module = g.getPossibleObject(resource,ModelingResources.getInstance(g).SymbolToComponentType);\r
+                       configuration = g.getPossibleObject(module, StructuralResource2.getInstance(g).IsDefinedBy);\r
+               } else {\r
+                       Resource instanceOf = g.getSingleObject(resource, l0.InstanceOf);\r
+                       if(g.isInheritedFrom(instanceOf, sr.Module)) {\r
+                               configuration = g.getPossibleObject(instanceOf, StructuralResource2.getInstance(g).IsDefinedBy);\r
+                       } else {\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               // Create the enumeartion\r
+               \r
+               String name = NameUtils.findFreshName(g, "Enum", configuration, l0.ConsistsOf, "%s%d");\r
+               \r
+               GraphUtils.create2(g, \r
+                               sr.Enumeration,\r
+                               l0.HasName, name,\r
+                               sr.Enumeration_enumerationIndexList, ListUtils.create(g, new ArrayList<Resource>()),\r
+                               l0.PartOf, configuration);\r
+               Layer0Utils.addCommentMetadata(g, "Created new Enumeration " + name + " to " + g.getRelatedValue2(configuration, l0.HasLabel, Bindings.STRING));\r
+            }\r
+        });\r
+               return null;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..ddfc2b1
--- /dev/null
@@ -0,0 +1,101 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.UUID;\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.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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new normal SysDyn experiment\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewExperimentNodeHandler extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes that it is called from a node that has a SysDyn model as its resource.\r
+     */\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        ExperimentsFolder node = AdaptionUtils.adaptToSingle(sel, ExperimentsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                String label = NameUtils.findFreshName(g, getNameSuggestion(), model, l0.ConsistsOf, l0.HasLabel, "%s%d");\r
+                Resource experiment = GraphUtils.create2(g, getExperimentType(g),\r
+                        l0.HasName, UUID.randomUUID().toString(),\r
+                        l0.HasLabel, label,\r
+                        l0.PartOf, model);\r
+                configureExperiment(g, experiment);\r
+                Layer0Utils.addCommentMetadata(g, "Created new experiment " + label + " " + experiment.toString());\r
+            }\r
+        });\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * Override to do experiment-specific alterations\r
+     */\r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Get the type of this experiment.\r
+     * \r
+     * @param g ReadGraph\r
+     * @return The type resource of this experiment\r
+     */\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).BasicExperiment;\r
+    }\r
+    \r
+    /**\r
+     * Returns the suggested name for this experiment.\r
+     * If the name has already been taken, appropriate prefix needs to be added. \r
+     *  \r
+     * @return Suggested name for this experiment. \r
+     */\r
+    protected String getNameSuggestion() {\r
+        return "Experiment";\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionHandler.java
new file mode 100644 (file)
index 0000000..e048657
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\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.browsing.ui.common.node.AbstractNode;\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new function to a SysdynModel or Library.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewFunctionHandler extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes to be called from a node with SysdynModel, Library or SysdynModelicaFunction as its resource\r
+     */\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        @SuppressWarnings("unchecked")\r
+               AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource data = node.data;\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+                SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+                // Library can be either SysdynModel or L0.Library. \r
+                Resource library = null;\r
+                if(g.isInstanceOf(data, sr.SysdynModel) || g.isInstanceOf(data, l0.Library))\r
+                       library = data;\r
+                else if (g.isInstanceOf(data, sr.SysdynModelicaFunction))\r
+                       library = g.getPossibleObject(data, l0.PartOf);\r
+                \r
+                if(library == null)\r
+                       return;\r
+                       \r
+                \r
+                String name = NameUtils.findFreshName(g, "Function", library, l0.ConsistsOf, "%s%d");\r
+\r
+                Resource func = GraphUtils.create2(g, sr.SysdynModelicaFunction,\r
+                        l0.HasName, name,\r
+                        l0.HasDescription, "",\r
+                        sr.SysdynModelicaFunction_modelicaFunctionCode, "",\r
+                        l0.PartOf, library);\r
+                \r
+                Layer0Utils.addCommentMetadata(g, "Created new Function " + name + " " + func.toString());\r
+            }\r
+        });\r
+        \r
+        return null;\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewFunctionLibraryHandler.java
new file mode 100644 (file)
index 0000000..62d88a4
--- /dev/null
@@ -0,0 +1,110 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\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.browsing.ui.common.node.AbstractNode;\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ResourceNotFoundException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new function library to a model or other library.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewFunctionLibraryHandler extends AbstractHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        @SuppressWarnings("unchecked")\r
+               AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        createLibrary(node.data, false);\r
+        return null;\r
+       }\r
+       \r
+       /**\r
+        * Create function library. Shared libraries are created to root, local libraries to the model. \r
+        * Shared libraries can be used in other models in the project.\r
+        * \r
+        * @param model The initial location of the command\r
+        * @param shared Shared libraries are created to root, local libraries to the model.\r
+        */\r
+       protected void createLibrary(final Resource model, final boolean shared) {\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+               Layer0 l0 = Layer0.getInstance(g);\r
+                SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+                if(!(g.isInstanceOf(model, sr.SysdynModel) ||\r
+                               g.isInstanceOf(model, sr.SysdynModelicaFunctionLibrary) ||\r
+                                               g.isInstanceOf(model, sr.SharedFunctionOntology)))\r
+                       return;\r
+\r
+                Resource root = model;\r
+\r
+                String name = "FunctionLibrary";\r
+                Resource libraryType = sr.SysdynModelicaFunctionLibrary;\r
+                \r
+                if(shared) {\r
+                       \r
+                       try {\r
+                               root = g.getResource("http://SharedOntologies");\r
+                       } catch (ResourceNotFoundException e) {\r
+                               root = g.getResource("http:/");\r
+                               root = GraphUtils.create2(g, l0.Library, \r
+                                               l0.HasName, "SharedOntologies",\r
+                                               l0.PartOf, root);\r
+                       }\r
+                       \r
+                       name = "Shared" + name;\r
+                    libraryType = sr.SharedFunctionOntology;\r
+                }\r
+\r
+                name = NameUtils.findFreshName(g, name, root, l0.ConsistsOf, "%s%d");\r
+                \r
+                Resource functionLibrary = GraphUtils.create2(g, libraryType,\r
+                        l0.HasName, name,\r
+                        l0.HasDescription, "",\r
+                        l0.PartOf, root);\r
+                \r
+                if(shared)\r
+                       g.claim(model, l0.IsLinkedTo, functionLibrary);\r
+                \r
+                Layer0Utils.addCommentMetadata(g, "Created new Function Library " + name + " " + functionLibrary.toString());\r
+            }\r
+        });\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewGameExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..601de37
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\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.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+\r
+/**\r
+ * Handler for creating a new Game Experiment\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewGameExperimentNodeHandler extends NewExperimentNodeHandler  {\r
+\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).GameExperiment;\r
+    }\r
+    \r
+    /**\r
+     * Override to do experiment-specific alterations\r
+     */\r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+       SysdynResource sr = SysdynResource.getInstance(graph);\r
+        graph.claimLiteral(experiment, sr.GameExperiment_stepDuration, SysdynGameExperimentBase.DEFAULT_STEP_DURATION);\r
+        graph.claimLiteral(experiment, sr.GameExperiment_stepLength, SysdynGameExperimentBase.DEFAULT_STEP_LENGTH);\r
+    }\r
+\r
+    protected String getNameSuggestion() {\r
+        return "Game Experiment";\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewHistoryDataHandler.java
new file mode 100644 (file)
index 0000000..d97b684
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.UUID;\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Handler for creating new history dataset\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewHistoryDataHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+        final Resource experiment = AdaptionUtils.adaptToSingle(sel, Resource.class);\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(g);\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                if(!g.isInstanceOf(experiment, sr.Experiment))\r
+                    return; // Not called from an experiment\r
+\r
+                Resource model = g.getPossibleObject(experiment, l0.PartOf);\r
+                // Create the history dataset\r
+                GraphUtils.create2(g, \r
+                        sr.HistoryDataset,\r
+                        l0.HasName, "HistoryDataset" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, NameUtils.findFreshLabel(g, "History Dataset", experiment),\r
+                        sr.Experiment_result_Inverse, experiment, \r
+                        sr.HistoryDataset_columns, Boolean.TRUE,\r
+                        l0.PartOf, model);\r
+            }\r
+        });\r
+        return null;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModelHandler.java
new file mode 100644 (file)
index 0000000..6ed6858
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\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.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.DatabaseJob;\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.ui.Activator;\r
+import org.simantics.sysdyn.utils.ModelUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Creates a new SysDyn model.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewModelHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        \r
+        Job job = new DatabaseJob("Creating System Dynamics Model") {\r
+            @Override\r
+            protected IStatus run(IProgressMonitor monitor) {\r
+                try {\r
+                    SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph) throws DatabaseException {\r
+                            // Use ModelUtils to keep all model creations up-to-date\r
+                            ModelUtils.createModel(graph);\r
+                        }\r
+                    });\r
+                    return Status.OK_STATUS;\r
+                } catch (DatabaseException e) {\r
+                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, getName() + " failed.", e);\r
+                }\r
+            }\r
+        };\r
+//        job.setUser(true);\r
+        job.schedule();\r
+\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewModuleNodeHandler.java
new file mode 100644 (file)
index 0000000..b5939cb
--- /dev/null
@@ -0,0 +1,134 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\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.NameUtils;\r
+import org.simantics.db.common.utils.OrderedSetUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.adapter.Template;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.actions.newActions.NewModuleTypeAction;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModulesNode;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new module node for a model.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewModuleNodeHandler extends AbstractHandler {\r
+\r
+    /**\r
+     * Assumes to be called from a node that has a SysDyn model as its resource.\r
+     */\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        ModulesNode node = AdaptionUtils.adaptToSingle(sel, ModulesNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+        \r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                SysdynResource sr = SysdynResource.getInstance(g);\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                Layer0X L0X = Layer0X.getInstance(g);\r
+                ModelingResources mr = ModelingResources.getInstance(g);\r
+                StructuralResource2 sr2 = StructuralResource2.getInstance(g);\r
+                \r
+                String name = NameUtils.findFreshName(g, "ModuleType", model, l0.ConsistsOf, "%s%d");\r
+                \r
+                Resource moduleType = g.newResource();\r
+                g.claimLiteral(moduleType, l0.HasName, name);\r
+                g.claim(moduleType, l0.Inherits, sr.Module);\r
+                g.claim(moduleType, l0.PartOf, model);\r
+                \r
+                \r
+                \r
+                Resource configuration = GraphUtils.create2(g, \r
+                        sr.Configuration,\r
+                        l0.HasName, name + "Configuration",\r
+                        l0.PartOf, moduleType);\r
+                \r
+                g.claim(moduleType, sr2.IsDefinedBy , configuration);\r
+                \r
+                Resource diagram = g.newResource();\r
+                g.adapt(sr.ConfigurationDiagramTemplate, Template.class).apply(g,\r
+                        ArrayMap\r
+                        .keys("", "diagram", "name")\r
+                        .values(configuration, diagram, "Diagrammi")\r
+                );\r
+                \r
+                \r
+                // Remove default mapping and add sysdyn mapping\r
+                for(Resource trigger : g.getObjects(diagram, L0X.HasTrigger)) {\r
+                       if(g.isInstanceOf(trigger, mr.DiagramToCompositeMapping)) {\r
+                               g.deny(diagram, L0X.HasTrigger, trigger);\r
+                       }\r
+                }\r
+                \r
+                Resource mapping = g.newResource();\r
+                g.claim(mapping, l0.InstanceOf, null, sr.DiagramToCompositeMapping);\r
+                g.claim(diagram, L0X.HasTrigger, mapping);\r
+                \r
+                Resource moduleSymbol = g.newResource();\r
+                g.claimLiteral(moduleSymbol, l0.HasName, name + " Symbol");\r
+                g.claimLiteral(moduleSymbol, l0.HasLabel, name + " Symbol");\r
+                g.claim(moduleSymbol, l0.Inherits, sr.ModuleSymbol);\r
+                g.claim(moduleSymbol, mr.SymbolToComponentType, moduleType);\r
+                g.claim(moduleSymbol, l0.PartOf, moduleType);\r
+                \r
+                Resource terminal = g.newResource();\r
+                g.claim(terminal, l0.InstanceOf, sr.SysdynTerminal);\r
+                Resource relation = NewModuleTypeAction.createTerminalRelation(g, moduleSymbol, sr.IsHeadOfTerminal, sr.Variable_isHeadOf);\r
+                DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal, relation);               \r
+                \r
+                Resource terminal2 = g.newResource();\r
+                g.claim(terminal2, l0.InstanceOf, sr.SysdynTerminal);\r
+                relation = NewModuleTypeAction.createTerminalRelation(g, moduleSymbol, sr.IsTailOfTerminal, sr.Variable_isTailOf);\r
+                DiagramGraphUtil.addConnectionPoint(g, moduleSymbol, terminal2, relation);\r
+                                \r
+                g.claim(moduleSymbol, sr2.IsDefinedBy, OrderedSetUtils.create(g, sr2.Composite, terminal, terminal2));\r
+            \r
+                Layer0Utils.addCommentMetadata(g, "Created new Module Type " + name + " " + moduleType.toString());\r
+            }\r
+        });\r
+        return null;\r
+    }\r
+    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPieChartHandler.java
new file mode 100644 (file)
index 0000000..0d386c7
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.Collections;\r
+import java.util.UUID;\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Handler for craeting a new Pie Chart\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewPieChartHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        \r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+        ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(g);\r
+                G2DResource g2d = G2DResource.getInstance(g);\r
+\r
+                String label = NameUtils.findFreshLabel(g, "Pie Chart", model);\r
+                \r
+                Resource jfreechart = GraphUtils.create2(g, jfree.Chart,\r
+                        l0.HasName, "PieChart" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, label,\r
+                        l0.PartOf, model,\r
+                        jfree.Chart_visibleBorder, true,\r
+                        jfree.Chart_borderWidth, 3);\r
+                g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                GraphUtils.create2(g, jfree.TextTitle,\r
+                        l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "Pie Chart Title",\r
+                        jfree.Title_position, jfree.Top,\r
+                        l0.PartOf, jfreechart);\r
+                \r
+                Resource dataset = GraphUtils.create2(g, jfree.PieDataset,\r
+                        l0.HasName, "CategoryDataset" + UUID.randomUUID().toString(),\r
+                        jfree.Dataset_seriesList, ListUtils.create(g, Collections.<Resource>emptyList())\r
+                        );\r
+\r
+                GraphUtils.create2(g, jfree.PiePlot,\r
+                        l0.HasName, "PiePlot" + UUID.randomUUID().toString(),\r
+                        l0.PartOf, jfreechart,\r
+                        l0.ConsistsOf, dataset\r
+                        );\r
+                Layer0Utils.addCommentMetadata(g, "Created new Pie Chart " +  label + " " + jfreechart);\r
+                \r
+            }\r
+\r
+        });\r
+        \r
+        return null;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewPlaybackExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..a54ce36
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.awt.Color;\r
+\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.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Creates a new playback experiment.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewPlaybackExperimentNodeHandler  extends NewExperimentNodeHandler  {\r
+\r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+        G2DResource g2d = G2DResource.getInstance(graph);\r
+        Resource defaultGradient = GraphUtils.create2(graph, g2d.ColorGradient);\r
+        graph.claim(experiment, g2d.HasColorGradient, defaultGradient);\r
+\r
+        Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, \r
+                g2d.HasGradientPosition, 0.0);\r
+        graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(0, 62, 133).getColorComponents(new float[4]));\r
+        graph.claim(defaultGradient, g2d.HasColorPlacement, placement);\r
+        \r
+        placement = GraphUtils.create2(graph, g2d.ColorPlacement, \r
+                g2d.HasGradientPosition, 1.0);\r
+        graph.claimLiteral(placement, g2d.HasColor, g2d.Color, new Color(255, 230, 0).getColorComponents(new float[4]));\r
+        graph.claim(defaultGradient, g2d.HasColorPlacement, placement);\r
+    }\r
+\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).PlaybackExperiment;\r
+    }\r
+\r
+    protected String getNameSuggestion() {\r
+        return "Playback Experiment";\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityAnalysisExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..1a8ae7a
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Creates a new sensitivity analysis experiment.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class NewSensitivityAnalysisExperimentNodeHandler extends NewExperimentNodeHandler  {\r
+\r
+    @Override\r
+    protected void configureExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        \r
+        Resource method = GraphUtils.create2(graph, sr.RandomGenerator);\r
+        graph.claim(experiment, sr.SensitivityAnalysisExperiment_method, method);\r
+\r
+        Resource distribution = GraphUtils.create2(graph, sr.UniformDistribution,\r
+                sr.UniformDistribution_minValue, 0.0,\r
+                sr.UniformDistribution_maxValue, 10.0);\r
+        \r
+        Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter,\r
+                       sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution,\r
+                sr.SensitivityAnalysisExperiment_Parameter_variable, ChartUtils.emptyVariableName,\r
+                L0.PartOf, experiment);\r
+        \r
+        ArrayList<Resource> parameterList = new ArrayList<Resource>();\r
+        parameterList.add(parameter);\r
+        \r
+        graph.claim(experiment, sr.SensitivityAnalysisExperiment_parameterList, ListUtils.create(graph, parameterList));\r
+    }\r
+\r
+    @Override\r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).SensitivityAnalysisExperiment;\r
+    }\r
+\r
+    @Override\r
+    protected String getNameSuggestion() {\r
+        return "Sensitivity Experiment";\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSensitivityChartHandler.java
new file mode 100644 (file)
index 0000000..7bc7a37
--- /dev/null
@@ -0,0 +1,159 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.UUID;\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.jfreechart.chart.ChartUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class NewSensitivityChartHandler extends AbstractHandler {\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+        ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(g);\r
+                G2DResource g2d = G2DResource.getInstance(g);\r
+                SysdynResource SR = SysdynResource.getInstance(g);\r
+\r
+                String label = NameUtils.findFreshLabel(g, "SensitivityChart", model);\r
+                \r
+                Resource jfreechart = GraphUtils.create2(g, jfree.Chart,\r
+                        l0.HasName, "SensitivityChart" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, label,\r
+                        l0.PartOf, model,\r
+                        jfree.Chart_visibleBorder, true,\r
+                        jfree.Chart_borderWidth, 3);\r
+                g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                GraphUtils.create2(g, jfree.TextTitle,\r
+                        l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "Chart Title",\r
+                        jfree.Title_position, jfree.Top,\r
+                        l0.PartOf, jfreechart);\r
+\r
+                Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasName, "NumberAxis" + UUID.randomUUID().toString(),\r
+                        jfree.variableRVI, "/time",\r
+                        l0.HasLabel, "Time");\r
+                Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasName, "NumberAxis" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "");\r
+\r
+                Resource renderer = GraphUtils.create2(g, jfree.DeviationRenderer);\r
+                \r
+                Color[] colors = {\r
+                        new Color(255, 255, 64),\r
+                        new Color(0, 255, 0),\r
+                        new Color(0, 0, 255),\r
+                        new Color(128, 128, 128),\r
+                        new Color(192, 192, 192)\r
+                        };\r
+                \r
+                float[] colorContainer = new float[] {0, 0, 0, 1};\r
+\r
+                ArrayList<Resource> confidenceBounds = new ArrayList<Resource>();\r
+                confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound,\r
+                        SR.Charts_SensitivityDataset_ConfidenceBound_percent, 25.0\r
+                        ));      \r
+                g.claimLiteral(confidenceBounds.get(0), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[0].getColorComponents(colorContainer));\r
+                \r
+                \r
+                confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound,\r
+                        SR.Charts_SensitivityDataset_ConfidenceBound_percent, 50.0\r
+                        ));  \r
+                g.claimLiteral(confidenceBounds.get(1), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[1].getColorComponents(colorContainer));\r
+\r
+                confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound,\r
+                        SR.Charts_SensitivityDataset_ConfidenceBound_percent, 75.0\r
+                        ));  \r
+                g.claimLiteral(confidenceBounds.get(2), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[2].getColorComponents(colorContainer));\r
+\r
+                confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound,\r
+                        SR.Charts_SensitivityDataset_ConfidenceBound_percent, 100.0\r
+                        )); \r
+                g.claimLiteral(confidenceBounds.get(3), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[3].getColorComponents(colorContainer));\r
+\r
+                confidenceBounds.add(GraphUtils.create2(g, SR.Charts_SensitivityDataset_ConfidenceBound\r
+                        ));  \r
+                g.claimLiteral(confidenceBounds.get(4), SR.Charts_SensitivityDataset_ConfidenceBound_color, g2d.Color, colors[4].getColorComponents(colorContainer));\r
+\r
+                \r
+                Resource dataset = GraphUtils.create2(g, SR.Charts_SensitivityDataset,\r
+                        l0.HasName, "SensitivityDataset" + UUID.randomUUID().toString(),\r
+                        jfree.Dataset_mapToDomainAxis, domainAxis,\r
+                        jfree.Dataset_mapToRangeAxis, rangeAxis,\r
+                        jfree.Dataset_seriesList, ListUtils.create(g, new ArrayList<Resource>()),\r
+                        jfree.Dataset_renderer, renderer,\r
+                        SR.Charts_SensitivityDataset_confidenceBounds, ListUtils.create(g, confidenceBounds)\r
+                        );\r
+                \r
+                ChartUtils.createSeries(g, dataset, null);\r
+                \r
+\r
+\r
+\r
+                GraphUtils.create2(g, SR.Charts_SensitivityPlot,\r
+                        l0.HasName, "SensitivityPlot" + UUID.randomUUID().toString(),\r
+                        l0.PartOf, jfreechart,\r
+                        jfree.Plot_domainAxis, domainAxis,\r
+                        jfree.Plot_rangeAxis, rangeAxis,\r
+                        jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)),\r
+                        l0.ConsistsOf, dataset,\r
+                        l0.ConsistsOf, domainAxis,\r
+                        l0.ConsistsOf, rangeAxis);\r
+                Layer0Utils.addCommentMetadata(g, "Created new Sensitivity Chart " +  label + " " + jfreechart);\r
+            }\r
+\r
+        });\r
+\r
+\r
+\r
+        return null;\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSharedFunctionLibraryHandler.java
new file mode 100644 (file)
index 0000000..ab79d1f
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\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.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Creates a new shared function library.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewSharedFunctionLibraryHandler extends NewFunctionLibraryHandler {\r
+\r
+       @Override\r
+       public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        \r
+        @SuppressWarnings("unchecked")\r
+               AbstractNode<Resource> node = AdaptionUtils.adaptToSingle(sel, AbstractNode.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        createLibrary(node.data, true);\r
+        return null;\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewSpreadSheetHandler.java
new file mode 100644 (file)
index 0000000..5a612a4
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\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.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.sysdyn.utils.SheetUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+/**\r
+ * Creates a new spreadsheet sheet to a book.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NewSpreadSheetHandler extends AbstractHandler {\r
+\r
+    /**\r
+     * Called from a node that has a book as its resource.\r
+     */\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+        final Resource book = ResourceAdaptionUtils.toSingleResource(sel);\r
+        if(book == null) return null;\r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                graph.markUndoPoint();\r
+                Resource sheet = SheetUtils.createSheet(graph, book, null, new String[] {}, new int[] {50});\r
+                Layer0Utils.addCommentMetadata(graph, "Created new Spreadsheet " + NameUtils.getSafeName(graph, sheet) + " " + sheet.toString());\r
+            }\r
+        });      \r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/newComponents/NewXYLineChartHandler.java
new file mode 100644 (file)
index 0000000..9c2e675
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.newComponents;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.UUID;\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.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ChartsFolder;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Handler for creating a new XYLineChart in model browser\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class NewXYLineChartHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+\r
+\r
+        ISelection sel = HandlerUtil.getCurrentSelection(event);\r
+\r
+        ChartsFolder node = AdaptionUtils.adaptToSingle(sel, ChartsFolder.class);\r
+        if (node == null)\r
+            return null;\r
+\r
+        final Resource model = node.data;        \r
+\r
+        SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+            @Override\r
+            public void perform(WriteGraph g) throws DatabaseException {\r
+                g.markUndoPoint();\r
+                Layer0 l0 = Layer0.getInstance(g);\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(g);\r
+                G2DResource g2d = G2DResource.getInstance(g);\r
+                \r
+                String label = NameUtils.findFreshLabel(g, "Chart", model);\r
+                \r
+                Resource jfreechart = GraphUtils.create2(g, jfree.Chart,\r
+                        l0.HasName, "Chart" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, label,\r
+                        l0.PartOf, model,\r
+                        jfree.Chart_visibleBorder, true,\r
+                        jfree.Chart_borderWidth, 3);\r
+                g.claimLiteral(jfreechart, jfree.Chart_borderColor, g2d.Color, new float[] {0,0,0,1});\r
+\r
+                GraphUtils.create2(g, jfree.TextTitle,\r
+                        l0.HasName, "TextTitle" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "Chart Title",\r
+                        jfree.Title_position, jfree.Top,\r
+                        l0.PartOf, jfreechart);\r
+\r
+                Resource domainAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasName, "NumberAxis" + UUID.randomUUID().toString(),\r
+                        jfree.variableRVI, "/time",\r
+                        l0.HasLabel, "Time");\r
+                Resource rangeAxis = GraphUtils.create2(g, jfree.NumberAxis,\r
+                        l0.HasName, "NumberAxis" + UUID.randomUUID().toString(),\r
+                        l0.HasLabel, "Y-axis");\r
+                \r
+                Resource renderer = GraphUtils.create2(g, jfree.XYLineRenderer);\r
+\r
+                Resource dataset = GraphUtils.create2(g, jfree.XYDataset,\r
+                        l0.HasName, "XYDataset" + UUID.randomUUID().toString(),\r
+                        jfree.Dataset_mapToDomainAxis, domainAxis,\r
+                        jfree.Dataset_mapToRangeAxis, rangeAxis,\r
+                        jfree.Dataset_seriesList, ListUtils.create(g, new ArrayList<Resource>()),\r
+                        jfree.Dataset_renderer, renderer);\r
+\r
+                GraphUtils.create2(g, jfree.XYPlot,\r
+                        l0.HasName, "XYPlot" + UUID.randomUUID().toString(),\r
+                        l0.PartOf, jfreechart,\r
+                        jfree.Plot_domainAxis, domainAxis,\r
+                        jfree.Plot_rangeAxis, rangeAxis,\r
+                        jfree.Plot_rangeAxisList, ListUtils.create(g, Collections.singletonList(rangeAxis)),\r
+                        l0.ConsistsOf, dataset,\r
+                        l0.ConsistsOf, domainAxis,\r
+                        l0.ConsistsOf, rangeAxis);\r
+                Layer0Utils.addCommentMetadata(g, "Created new Line Chart " +  label + " " + jfreechart);\r
+            }\r
+\r
+        });\r
+\r
+\r
+\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/RunSensitivityAnalysisExperiment.java
new file mode 100644 (file)
index 0000000..a660276
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis;\r
+\r
+\r
+import java.util.Map;\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.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.ExperimentState;\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.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Handler for starting a sensitivity analysis simulation\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class RunSensitivityAnalysisExperiment extends AbstractHandler implements IElementUpdater {\r
+    \r
+    public static final String COMMAND = "org.simantics.sysdyn.ui.runSensitivityAnalysis";\r
+    \r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        // Current functionality is normal run experiment\r
+        \r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \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
+    // What does this method do, is this needed?\r
+    @SuppressWarnings("rawtypes")\r
+       @Override\r
+    public void updateElement(UIElement element, Map parameters) {\r
+        IExperimentManager manager = \r
+            SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment instanceof SysdynExperiment) {\r
+               ExperimentState state = experiment.getState();\r
+               if(state == ExperimentState.RUNNING) {\r
+                       this.setBaseEnabled(false);\r
+               } else {\r
+                        this.setBaseEnabled(true);\r
+               }\r
+        }        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/SaveResultsHandler.java
new file mode 100644 (file)
index 0000000..dab71d2
--- /dev/null
@@ -0,0 +1,45 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis;\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.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Save the results of a sensitivity analysis experiment\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SaveResultsHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        // Current functionality is normal run experiment\r
+        \r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \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/sensitivityAnalysis/ToggleSimulation.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/sensitivityAnalysis/ToggleSimulation.java
new file mode 100644 (file)
index 0000000..f90605c
--- /dev/null
@@ -0,0 +1,86 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.sensitivityAnalysis;\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.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Handle for the Toggle Simulation button. When the button is down, the\r
+ * simulation is run every time the model is changed.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ToggleSimulation extends AbstractHandler implements IElementUpdater {\r
+\r
+    public static final String COMMAND = "org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation";\r
+    public static final String STATE = "org.simantics.sysdyn.ui.toggleSensitivityAnalysisSimulation.state";\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        // Current functionality is normal run experiment\r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+\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(RunSensitivityAnalysisExperiment.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
+        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("rawtypes")\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/handlers/simulationPlayback/FastSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java
new file mode 100644 (file)
index 0000000..d98a44e
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+\r
+public class FastSpeedHandler extends SpeedHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_FAST);\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java
new file mode 100644 (file)
index 0000000..b2ece4d
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+\r
+public class NormalSpeedHandler extends SpeedHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_NORMAL);\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java
new file mode 100644 (file)
index 0000000..72ae6ec
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import java.util.Map;\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.resource.ImageDescriptor;\r
+import org.eclipse.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class PlaybackExperimentHandler extends AbstractHandler implements IElementUpdater {\r
+    \r
+    public static final String COMMAND = "org.simantics.sysdyn.ui.playback";\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return null;\r
+        SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;\r
+        if(!spe.isPlaybackRunning())\r
+            spe.startPlayback();\r
+        else\r
+            spe.stopPlayback();\r
+        return null;\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public void updateElement(UIElement element, Map parameters) {\r
+        IExperimentManager manager = \r
+            SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return;\r
+        SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;      \r
+        \r
+        ExperimentState state = experiment.getState();\r
+        if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) {\r
+            // RUNNING == simulation, not playback\r
+            this.setBaseEnabled(false);\r
+        } else {\r
+            this.setBaseEnabled(true);\r
+        }\r
+\r
+        if(spe.isPlaybackRunning()) {\r
+            element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause.png")));\r
+            element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause_blue.png")));\r
+        } else {\r
+            long duration = spe.getPlaybackDuration();\r
+            if(duration == SysdynPlaybackExperiment.DURATION_SLOW) {\r
+                element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step.png")));\r
+                element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step_blue.png")));\r
+            } else if(duration == SysdynPlaybackExperiment.DURATION_FAST) {\r
+                element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward.png")));\r
+                element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward_blue.png")));\r
+            } else {\r
+                element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play.png")));\r
+                element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play_blue.png")));\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackReloadHandler.java
new file mode 100644 (file)
index 0000000..75cc05a
--- /dev/null
@@ -0,0 +1,27 @@
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\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.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class PlaybackReloadHandler extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        HandlerUtils.saveBeforeExperimentRun(event);\r
+        \r
+        IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return null;\r
+        SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;\r
+        spe.simulate(true);\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java
new file mode 100644 (file)
index 0000000..e4155b6
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import java.util.Map;\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.ui.commands.IElementUpdater;\r
+import org.eclipse.ui.menus.UIElement;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class PlaybackResetHandler extends AbstractHandler implements IElementUpdater {\r
+\r
+    public static final String COMMAND = "org.simantics.sysdyn.ui.playbackReset";\r
+\r
+    \r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return null;\r
+        SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;\r
+        spe.resetPlayback();\r
+        return null;\r
+    }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public void updateElement(UIElement element, Map parameters) {\r
+        IExperimentManager manager = \r
+                SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return;\r
+        SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;      \r
+\r
+        ExperimentState state = experiment.getState();\r
+        if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) {\r
+            // RUNNING == simulation, not playback\r
+            this.setBaseEnabled(false);\r
+        } else {\r
+            this.setBaseEnabled(true);\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java
new file mode 100644 (file)
index 0000000..6ebeba3
--- /dev/null
@@ -0,0 +1,26 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.core.commands.ExecutionException;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+\r
+public class SlowSpeedHandler extends SpeedHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_SLOW);\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java
new file mode 100644 (file)
index 0000000..4fe9691
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.handlers.simulationPlayback;\r
+\r
+import org.eclipse.core.commands.AbstractHandler;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.commands.ICommandService;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+abstract class SpeedHandler extends AbstractHandler {\r
+    \r
+    protected void setPlaybackSpeed(long duration) {\r
+        \r
+        \r
+        IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+            return;\r
+        final SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;\r
+        \r
+        if(spe.getPlaybackDuration() == duration)\r
+            return;\r
+        \r
+        \r
+        spe.setPlaybackDuration(duration);\r
+        \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
+                commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null);\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
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..caea744
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.handlers.RunBasicExperiment;\r
+import org.simantics.sysdyn.ui.handlers.SynthesisSimulation;\r
+import org.simantics.sysdyn.ui.handlers.ToggleSimulation;\r
+import org.simantics.sysdyn.ui.handlers.game.ReloadGameExperimentHandler;\r
+import org.simantics.sysdyn.ui.handlers.game.StepHandler;\r
+import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackExperimentHandler;\r
+import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackResetHandler;\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 toggleCommand = commandService.getCommand(ToggleSimulation.COMMAND);\r
+                State toggleButtonState = toggleCommand.getState(ToggleSimulation.STATE);\r
+                Command synhesisCommand = commandService.getCommand(SynthesisSimulation.COMMAND);\r
+                State synthesisButtonState = synhesisCommand.getState(SynthesisSimulation.STATE);\r
+                                \r
+                switch(state) {\r
+                case DISPOSED:\r
+                       toggleButtonState.setValue(false); \r
+                       synthesisButtonState.setValue(false); \r
+                    break;\r
+                               default:\r
+                                       break;\r
+                }\r
+                commandService.refreshElements(toggleCommand.getId(), null); \r
+                commandService.refreshElements(synhesisCommand.getId(), null); \r
+                commandService.refreshElements(RunBasicExperiment.COMMAND, null);\r
+                commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null);\r
+                commandService.refreshElements(PlaybackResetHandler.COMMAND, null);\r
+                commandService.refreshElements(StepHandler.COMMAND, null);\r
+                commandService.refreshElements(ReloadGameExperimentHandler.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..09da1d4
--- /dev/null
@@ -0,0 +1,125 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.sysdyn.manager.SysdynSensitivityAnalysisExperiment;\r
+\r
+public class SysdynExperimentManagerListener implements IExperimentManagerListener{\r
+\r
+    public static final String BASIC_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.basicExperiment";\r
+    public static final String PLAYBACK_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.playbackExperiment";\r
+    public static final String GAME_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.gameExperiment";\r
+    public static final String SENSITIVITY_ANALYSIS_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.sensitivityAnalysisExperiment";\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
+                    if(experiment instanceof SysdynPlaybackExperiment) {\r
+                        contextActivations.add(contextService.activateContext(PLAYBACK_EXPERIMENT_CONTEXT));\r
+                        experiment.addListener(new SysdynPlaybackExperimentListener((SysdynPlaybackExperiment)experiment));\r
+                    } else if(experiment instanceof SysdynGameExperimentBase) {\r
+                        contextActivations.add(contextService.activateContext(GAME_EXPERIMENT_CONTEXT));\r
+                        // TODO: some listener?\r
+                    } else if(experiment instanceof SysdynSensitivityAnalysisExperiment) {\r
+                        contextActivations.add(contextService.activateContext(SENSITIVITY_ANALYSIS_EXPERIMENT_CONTEXT));\r
+                        // TODO: some listener?\r
+                    } else if(experiment instanceof SysdynExperiment) {\r
+                        contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT));\r
+                    }\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/listeners/SysdynPlaybackExperimentListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java
new file mode 100644 (file)
index 0000000..70dc93d
--- /dev/null
@@ -0,0 +1,267 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.listeners;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IEditorReference;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.diagram.profile.Profiles;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.experiment.IExperimentListener;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Listener for playback simulations. This listener activates and reverts the playback\r
+ * profile when a playback simlation is activated or disposed.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynPlaybackExperimentListener implements IExperimentListener {\r
+\r
+    private Resource model;\r
+    private Resource previousProfile;\r
+\r
+    public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) {\r
+        this.model = experiment.getModel();\r
+        activatePlaybackProfile();\r
+    }\r
+\r
+    @Override\r
+    public void stateChanged(final ExperimentState state) {\r
+        switch(state) {\r
+            case DISPOSED:\r
+                revertPlaybackProfiles();\r
+            default:\r
+                break;\r
+        }\r
+    }\r
+\r
+    class DiagramInfo {\r
+        public Resource model = null;\r
+        public Resource previousProfile = null;\r
+    }\r
+\r
+    HashMap<Resource, DiagramInfo> previousRuntimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+\r
+    private void activatePlaybackProfile() {\r
+        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+            @Override\r
+            public void run() {\r
+                previousRuntimeDiagramsAndModelUris.clear();\r
+                previousRuntimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
+                activatePlaybackProfileRequest(previousRuntimeDiagramsAndModelUris);\r
+            }\r
+        });\r
+    }\r
+    \r
+    private void revertPlaybackProfiles() {\r
+        \r
+        IProject project =  SimanticsUI.getProject();\r
+        if(project == null)\r
+            return;\r
+        IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = manager.getActiveExperiment();\r
+        \r
+        if(experiment != null && experiment instanceof SysdynPlaybackExperiment && this.model.equals(experiment.getModel()))\r
+                return;\r
+        \r
+        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+            @Override\r
+            public void run() {\r
+                final HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
+\r
+                VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
+                Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
+                    \r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        \r
+                        Resource model = SysdynPlaybackExperimentListener.this.model;\r
+                        if(model == null)\r
+                            return;\r
+                        \r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        SysdynResource sr = SysdynResource.getInstance(graph);\r
+                        \r
+                        Resource defaultProfile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.DefaultProfile));\r
+                        if(defaultProfile == null)\r
+                            return;\r
+                        \r
+                        setProfileForModel(graph, model, previousProfile == null ? defaultProfile : previousProfile);\r
+                        \r
+                        HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model);\r
+                        for(Resource runtimeDiagram : infos.keySet()) {\r
+                            Resource previous = null;\r
+                            if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) {\r
+                                previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile;\r
+                            }\r
+                            setProfileForDiagram(graph, runtimeDiagram, previous == null ? defaultProfile : previous);\r
+                        }\r
+                    }\r
+                });\r
+                \r
+            }\r
+        });\r
+    }\r
+    \r
+    /**\r
+     * Run in display thread.\r
+     * \r
+     * @return\r
+     */\r
+    private HashMap<Resource, DiagramInfo> getCurrentRuntimeDiagramInfos() {\r
+        HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+        IWorkbench workBench =  PlatformUI.getWorkbench();\r
+        IWorkbenchWindow window = workBench.getActiveWorkbenchWindow();\r
+        IWorkbenchPage[] pages = window.getPages();\r
+        for(IWorkbenchPage page : pages) {\r
+            for(IEditorReference reference : page.getEditorReferences()) {\r
+                IEditorPart iep = reference.getEditor(false);\r
+                if(iep instanceof DiagramEditor) {\r
+                    DiagramEditor editor = (DiagramEditor) iep;\r
+                    if (editor.getViewer() instanceof DiagramViewer) {\r
+                        DiagramViewer viewer = (DiagramViewer) editor.getViewer();\r
+                        Resource runtime = viewer.getRuntime();\r
+                        Resource model = viewer.getResourceInput2().getModel(null);\r
+                        DiagramInfo info = new DiagramInfo();\r
+                        info.model = model;\r
+                        runtimeDiagramsAndModelUris.put(runtime, info);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return runtimeDiagramsAndModelUris;\r
+    }\r
+    \r
+    \r
+    private HashMap<Resource, DiagramInfo> getRuntimesForModel(WriteGraph graph, HashMap<Resource, DiagramInfo> allInfos, Resource model) throws DatabaseException {\r
+        HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+        for(Resource runtimeDiagram : allInfos.keySet()) {\r
+            DiagramInfo di = allInfos.get(runtimeDiagram);\r
+            if(di == null)\r
+                continue;\r
+            Resource m = di.model;\r
+            if(m == null || !model.equals(m))                    \r
+                continue;\r
+            \r
+            runtimeDiagramsAndModelUris.put(runtimeDiagram, di);\r
+        }\r
+        return runtimeDiagramsAndModelUris;\r
+    }\r
+    \r
+    private void activatePlaybackProfileRequest(final HashMap<Resource, DiagramInfo> allDiagramInfos) {\r
+        VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
+        Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
+            \r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                \r
+                Resource model = SysdynPlaybackExperimentListener.this.model;\r
+                if(model == null)\r
+                    return;\r
+                \r
+                Resource profile = getSimulationPlaybackProfile(graph, model);\r
+                if(profile == null)\r
+                    return;\r
+                \r
+                DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+                Resource current = graph.getPossibleObject(model, DIA.HasActiveProfile);\r
+                previousProfile = current;\r
+\r
+                if(!profile.equals(current)) {\r
+                    setProfileForModel(graph, model, profile);\r
+                }\r
+                \r
+                HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, allDiagramInfos, model);\r
+                for(Resource runtimeDiagram : infos.keySet()) {\r
+                    DiagramInfo di = infos.get(runtimeDiagram);\r
+                    current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
+                    di.previousProfile = current;\r
+                    if(profile.equals(current)) \r
+                        continue;\r
+                    setProfileForDiagram(graph, runtimeDiagram, profile);\r
+                }\r
+            }\r
+        });\r
+    }\r
+    \r
+    \r
+    private void setProfileForDiagram(WriteGraph graph, Resource runtimeDiagram, Resource profile) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+        Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
+        if(profile.equals(current)) return;\r
+        \r
+        if(current != null)\r
+            graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current);\r
+        graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile);\r
+\r
+        // Set this profile as the default profile for this diagram\r
+        Resource configuration = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration);\r
+        graph.deny(configuration, DIA.HasActiveProfile);\r
+        graph.claim(configuration, DIA.HasActiveProfile, profile);\r
+    }\r
+    \r
+    private void setProfileForModel(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+        // Set this profile as the default profile for this model\r
+        graph.deny(model, DIA.HasActiveProfile);\r
+        graph.claim(model, DIA.HasActiveProfile, profile);\r
+    }\r
+    \r
+    private Resource getSimulationPlaybackProfile(WriteGraph graph, Resource model) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        \r
+        Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile));\r
+        if(profile == null) {\r
+            profile = Profiles.createProfile(graph, "Simulation Playback", sr.Profiles_SimulationPlaybackColours);\r
+            graph.deny(profile, l0.InstanceOf);\r
+            graph.claim(profile, l0.InstanceOf, null, sr.SimulationPlaybackProfile);\r
+            graph.claim(model, l0.ConsistsOf, profile);\r
+        }\r
+\r
+        if(!graph.hasStatement(profile, SIMU.IsActive)) {\r
+            graph.claim(profile, SIMU.IsActive, sr.Profiles_SimulationPlaybackColours);\r
+        }\r
+        \r
+        return profile;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/FontContextMenuContribution.java
new file mode 100644 (file)
index 0000000..9f69f7b
--- /dev/null
@@ -0,0 +1,196 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.menu;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+\r
+import org.eclipse.jface.action.ContributionItem;\r
+import org.eclipse.jface.action.IContributionItem;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Menu;\r
+import org.eclipse.swt.widgets.MenuItem;\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.diagram.G2DUtils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.contribution.DynamicMenuContribution;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+/**\r
+ * Context menu contribution for modifying fonts and font colors in diagram elements\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FontContextMenuContribution extends DynamicMenuContribution {\r
+\r
+       @Override\r
+       protected IContributionItem[] getContributionItems(final ReadGraph graph,\r
+                       Object[] selection) throws DatabaseException {\r
+               if (selection.length == 0)\r
+                       return new IContributionItem[0];\r
+\r
+               return new IContributionItem[] { new ContributionItem() {\r
+\r
+                       @Override\r
+                       public void fill(Menu menu, int index) {\r
+\r
+                               G2DResource G2D = G2DResource.getInstance(graph);\r
+\r
+                               Object[] selections = getSelectedObjects();\r
+\r
+                               Font font = null;\r
+                               Color color = null;\r
+\r
+                               /*\r
+                                *  Find a common font and color for the selected elements.\r
+                                *  \r
+                                *  If a common font or color is not found, the initial value in dialog is empty.\r
+                                */\r
+                               try {\r
+                                       for(Object o : selections) {\r
+                                               Resource element = ResourceAdaptionUtils\r
+                                                               .adaptToResource(o);\r
+                                               if(element != null) {\r
+                                                       Resource fontResource = graph.getPossibleObject(element, G2D.HasFont);\r
+                                                       if(fontResource != null) { \r
+                                                               Font newFont = G2DUtils.getFont(graph, fontResource);\r
+                                                               if(font == null) {\r
+                                                                       font = newFont;\r
+                                                               }\r
+\r
+                                                               if(font != null && !font.equals(newFont)) {\r
+                                                                       font = null;\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+\r
+                               try {\r
+                                       for(Object o : selections) {\r
+                                               Resource element = ResourceAdaptionUtils\r
+                                                               .adaptToResource(o);\r
+                                               if(element != null) {\r
+                                                   Resource colorResource = graph.getPossibleObject(element, G2D.HasColor);\r
+                                                   if(colorResource != null ) {\r
+                                                       Color newColor = G2DUtils.getColor(graph, colorResource);\r
+                                                       if(color == null)\r
+                                                           color = newColor;\r
+\r
+                                                       if(color != null && !color.equals(newColor))  {\r
+                                                           color = null;\r
+                                                           break;\r
+                                                       }\r
+                                                   }                    \r
+                                               }\r
+                                       }\r
+                               } catch (DatabaseException e) {\r
+                               }\r
+\r
+                               // Create the menu item with a selection listener\r
+                               MenuItem item;\r
+                               item = new MenuItem(menu, SWT.PUSH);\r
+\r
+                               item.setText("Font...");\r
+\r
+                               item.addSelectionListener(new FontSelectionListener(selections, font, color));\r
+                       }\r
+               } \r
+               };\r
+\r
+       }\r
+\r
+       /**\r
+        * Selection listener for font context menu action\r
+        * @author Teemu Lempinen\r
+        *\r
+        */\r
+       class FontSelectionListener implements SelectionListener {\r
+\r
+               private Font font;\r
+               private Color color;\r
+               private Object[] selections;\r
+\r
+               /**\r
+                * Font selection listener for context menu action in diagram\r
+                * \r
+                * @param selections Selected elements\r
+                * @param font Possible common font for the selected elements\r
+                * @param color Possible common color for the selected elements\r
+                */\r
+               public FontSelectionListener(Object[] selections, Font font, Color color) {\r
+                       this.selections = selections;\r
+                       this.font = font;\r
+                       this.color = color;\r
+               }\r
+\r
+               @Override\r
+               public void widgetSelected(SelectionEvent e) {\r
+                       // Create the dialog\r
+                       CustomFontDialog dialog = new CustomFontDialog(e.widget.getDisplay().getActiveShell(), "Sample");\r
+\r
+                       // Set possible font and color defaults\r
+                       if(font != null)\r
+                               dialog.setAWTFont(font);\r
+\r
+                       if(color != null)\r
+                               dialog.setColor(color);\r
+\r
+                       // Open dialog\r
+                       dialog.open();\r
+\r
+                       // Get results\r
+                       final Font resultFont = dialog.getAWTFont();\r
+                       final Color resultColor = dialog.getAWTColor();\r
+\r
+                       // Apply results to all selected elements\r
+                       SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       G2DResource G2D = G2DResource.getInstance(graph);\r
+\r
+                                       for(Object o : selections) {\r
+                                               Resource element = ResourceAdaptionUtils\r
+                                                               .adaptToResource(o);\r
+                                               if(resultFont != null) {\r
+                                                       graph.deny(element, G2D.HasFont);\r
+                                                       graph.claim(element, G2D.HasFont, G2DUtils.createFont(graph, resultFont));\r
+                                               }\r
+\r
+                                               if(resultColor != null) {\r
+                                                       graph.deny(element, G2D.HasColor);\r
+                                                       graph.claim(element, G2D.HasColor, G2DUtils.createColor(graph, resultColor));\r
+                                               }\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+\r
+               @Override\r
+               public void widgetDefaultSelected(SelectionEvent e) {\r
+               }\r
+\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/GameStepDurationContribution.java
new file mode 100644 (file)
index 0000000..fb1e41c
--- /dev/null
@@ -0,0 +1,106 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.menu;\r
+\r
+import org.eclipse.jface.action.IContributionItem;\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.SWT;\r
+import org.eclipse.swt.widgets.ToolBar;\r
+import org.eclipse.swt.widgets.ToolItem;\r
+import org.eclipse.ui.actions.CompoundContributionItem;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.validators.DoubleValidator;\r
+\r
+\r
+/**\r
+ * Contribution for adding a text field to menu bar. The text field is used \r
+ * to set the duration of one simulation step. This duration is different from\r
+ * the step length the simulator uses. Simulator steps as many steps that fit into\r
+ * the simulation duration determined in this field.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class GameStepDurationContribution extends CompoundContributionItem {\r
+\r
+       private TrackedText                             stepDuration;\r
+       private int                     width           = 40;\r
+    private ToolItem                           ti;\r
+    \r
+    public static String                       COMMAND         = "org.simantics.sysdyn.ui.gameStepDuration";\r
+\r
+    public GameStepDurationContribution() {\r
+        super(COMMAND);\r
+    }\r
+\r
+    @Override\r
+    protected IContributionItem[] getContributionItems() {\r
+        return new IContributionItem[0];\r
+    }\r
+\r
+    @Override\r
+    public void fill(final ToolBar parent, final int index) {\r
+        IProject project = SimanticsUI.peekProject();\r
+        if (project == null)\r
+            return;\r
+\r
+        // Find game experiment\r
+        IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+\r
+        IExperiment active = manager.getActiveExperiment();\r
+        if (!(active instanceof SysdynGameExperimentBase))\r
+            return;\r
+\r
+        final SysdynGameExperimentBase game = (SysdynGameExperimentBase) active;\r
+        \r
+        // Create the text\r
+        \r
+        ti = new ToolItem(parent, SWT.SEPARATOR, index);\r
+        ti.setText("Step Duration");\r
+        ti.setToolTipText("Step Duration");\r
+        \r
+        ISessionContext context = SimanticsUI.getSessionContext();\r
+        WidgetSupportImpl support = new WidgetSupportImpl(); // Dummy widget support for using tracked text\r
+\r
+        stepDuration = new TrackedText(parent, support, SWT.BORDER);\r
+        ResourceManager resourceManager = new LocalResourceManager(JFaceResources.getResources(), stepDuration.getWidget());\r
+        stepDuration.setColorProvider(new SysdynBasicColorProvider(resourceManager));\r
+        stepDuration.setInputValidator(new DoubleValidator());\r
+        stepDuration.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepDuration));\r
+        stepDuration.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepDuration));\r
+        \r
+        support.fireInput(context, game.getResource());\r
+        \r
+        ti.setWidth(width);\r
+        ti.setControl(stepDuration.getWidget());\r
+\r
+    }\r
+\r
+    @Override\r
+    public boolean isDynamic() {\r
+        return true;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java
new file mode 100644 (file)
index 0000000..27e3b55
--- /dev/null
@@ -0,0 +1,171 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.menu;\r
+\r
+import java.text.DecimalFormat;\r
+import java.text.DecimalFormatSymbols;\r
+\r
+import org.eclipse.jface.action.ToolBarContributionItem;\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.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Slider;\r
+import org.eclipse.swt.widgets.ToolBar;\r
+import org.eclipse.swt.widgets.ToolItem;\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.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Contribution to the main toolbar. PlaybackSliderContribution contains a slider\r
+ * that can be used to control the time in a playback experiment\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class PlaybackSliderContribution extends ToolBarContributionItem {\r
+\r
+    Runnable timeListener;\r
+    SysdynPlaybackExperiment spe;\r
+    Slider s;\r
+    Double startTime, endTime;\r
+    boolean ignoreChange = false;\r
+\r
+    @Override\r
+    public void fill(ToolBar parent, int index)\r
+    {\r
+        if (parent != null) {\r
+\r
+            IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+            IExperiment experiment = manager.getActiveExperiment();\r
+            if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+                return;\r
+            spe = (SysdynPlaybackExperiment)experiment;\r
+\r
+            Double[] numbers = new Double[2];\r
+            try {\r
+                numbers = SimanticsUI.getSession().syncRequest(new Read<Double[]>() {\r
+                    @Override\r
+                    public Double[] perform(ReadGraph graph) throws DatabaseException {\r
+                        Double[] numbers = new Double[2];\r
+                        Resource model = spe.getModel();\r
+                        SysdynResource sr = SysdynResource.getInstance(graph);\r
+                        numbers[0] = graph.getRelatedValue(model, sr.SysdynModel_startTime);\r
+                        numbers[1] = graph.getRelatedValue(model, sr.SysdynModel_stopTime);\r
+                        return numbers;\r
+                    }\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+\r
+            // Separator ToolItem can contain a composite. Add a composite with a slider to this item\r
+            ToolItem ti = new ToolItem(parent, SWT.SEPARATOR);\r
+\r
+            Composite composite = new Composite(parent, SWT.NONE);\r
+            GridLayoutFactory.fillDefaults().margins(3, SWT.DEFAULT).numColumns(2).applyTo(composite);\r
+            GridDataFactory.fillDefaults().applyTo(composite);\r
+\r
+            s = new Slider(composite, SWT.NONE);\r
+            s.setMinimum(0);\r
+            s.setMaximum(100);\r
+            s.setIncrement(1);\r
+            s.setPageIncrement(1);\r
+            s.setThumb(1);\r
+\r
+            final Label label = new Label(composite, SWT.NONE);\r
+            GridDataFactory.fillDefaults().hint(70, SWT.DEFAULT).applyTo(label);\r
+            label.setText("0.0");\r
+\r
+            ti.setWidth(270);\r
+            ti.setControl(composite);\r
+\r
+            startTime = numbers[0];\r
+            endTime = numbers[1];\r
+            \r
+            // Create a DesimalFormat for rounding the time\r
+            final DecimalFormat format = new DecimalFormat();\r
+            format.setMinimumFractionDigits(0);\r
+            format.setMaximumFractionDigits(2);\r
+            DecimalFormatSymbols symbols = new DecimalFormatSymbols();\r
+            symbols.setDecimalSeparator('.');\r
+            symbols.setGroupingSeparator(' ');\r
+            format.setDecimalFormatSymbols(symbols);\r
+            \r
+            // Selection listener for the slider\r
+            s.addSelectionListener(new SelectionListener() {\r
+\r
+                @Override\r
+                public void widgetSelected(SelectionEvent e) {\r
+                    Slider s = (Slider)e.widget;\r
+                    Double time = s.getSelection() / 99.0 * (endTime - startTime) + startTime;\r
+                    spe.setTimeAndContinue(time);\r
+                    if(!label.isDisposed()) {\r
+                        label.setText(format.format(time));\r
+                    }\r
+                }\r
+\r
+                @Override\r
+                public void widgetDefaultSelected(SelectionEvent e) {\r
+                }\r
+            });\r
+\r
+            if(timeListener != null) {\r
+                spe.removeTimeListener(timeListener);\r
+            }\r
+\r
+            // Time listener for setting the time in the slider if the time is changed somewhere else\r
+            timeListener = new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    s.getDisplay().asyncExec(new Runnable() {\r
+\r
+                        @Override\r
+                        public void run() {\r
+                            if(!startTime.equals(spe.getStartTime()) || !endTime.equals(spe.getEndTime())) {\r
+                                startTime = spe.getStartTime();\r
+                                endTime = spe.getEndTime();\r
+                            }\r
+                            int value = (int) Math.round(((spe.getTime() - startTime) / (endTime - startTime) * 99));\r
+                            s.setSelection(value);\r
+                            label.setText(format.format(spe.getTime()));\r
+                        }\r
+                    });\r
+\r
+                }\r
+\r
+            };\r
+            spe.addTimeListener(timeListener);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        if(this.timeListener != null && spe != null) {\r
+            spe.removeTimeListener(timeListener);\r
+            this.timeListener = null;\r
+        }\r
+        super.dispose();\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..84c0055
--- /dev/null
@@ -0,0 +1,170 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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
+       @Override\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
+       // Includes also tokens that are strictly speaking not keywords\r
+       // but should be handled in (almost) a similar fashion.\r
+       public static final Set<String> keywords = new HashSet<String>();\r
+\r
+    static {\r
+        keywords.add("algorithm");\r
+        keywords.add("discrete");\r
+        keywords.add("false");\r
+        keywords.add("model");\r
+        keywords.add("redeclare");\r
+        keywords.add("and");\r
+        keywords.add("each");\r
+        keywords.add("final");\r
+        keywords.add("not");\r
+        keywords.add("replaceable");\r
+        keywords.add("annotation");\r
+        keywords.add("else");\r
+        keywords.add("flow");\r
+        keywords.add("operator");\r
+        keywords.add("return");\r
+        keywords.add("assert");\r
+        keywords.add("elseif");\r
+        keywords.add("for");\r
+        keywords.add("or");\r
+        keywords.add("stream");\r
+        keywords.add("block");\r
+        keywords.add("elsewhen");\r
+        keywords.add("function");\r
+        keywords.add("outer");\r
+        keywords.add("then");\r
+        keywords.add("break");\r
+        keywords.add("encapsulated");\r
+        keywords.add("if");\r
+        keywords.add("output");\r
+        keywords.add("true");\r
+        keywords.add("class");\r
+        keywords.add("end");\r
+        keywords.add("import");\r
+        keywords.add("package");\r
+        keywords.add("type");\r
+        keywords.add("connect");\r
+        keywords.add("enumeration");\r
+        keywords.add("in");\r
+        keywords.add("parameter");\r
+        keywords.add("when");\r
+        keywords.add("connector");\r
+        keywords.add("equation");\r
+        keywords.add("initial");\r
+        keywords.add("partial");\r
+        keywords.add("while");\r
+        keywords.add("constant");\r
+        keywords.add("expandable");\r
+        keywords.add("inner");\r
+        keywords.add("protected");\r
+        keywords.add("within");\r
+        keywords.add("constrainedby");\r
+        keywords.add("extends");\r
+        keywords.add("input");\r
+        keywords.add("public");\r
+        keywords.add("der");\r
+        keywords.add("external");\r
+        keywords.add("loop");\r
+        keywords.add("record");\r
+        keywords.add("time");\r
+        keywords.add("pure");\r
+        keywords.add("impure");\r
+        keywords.add("Real");\r
+        keywords.add("Boolean");\r
+        keywords.add("Integer");\r
+        keywords.add("String");\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..6d4757d
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.modelica;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\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.IEditorInput;\r
+import org.eclipse.ui.IEditorSite;\r
+import org.eclipse.ui.PartInitException;\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.modelica.ModelicaManager;\r
+import org.simantics.sysdyn.modelica.ModelicaWriter;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.LoadRepresentation;\r
+import org.simantics.sysdyn.representation.Module;\r
+import org.simantics.sysdyn.representation.ModuleType;\r
+import org.simantics.sysdyn.representation.utils.RepresentationUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.workbench.ResourceEditorInput;\r
+\r
+/**\r
+ * Text editor for displaying Modelica code\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynModelicaEditor extends TextEditor {\r
+\r
+    AnnotationModel annotationModel = new AnnotationModel();\r
+    AnnotationPainter apainter;\r
+    \r
+    \r
+       public void init(final IEditorSite site, final IEditorInput input) throws PartInitException {\r
+               super.init(site, input);\r
+        try {\r
+                       Configuration configuration =\r
+                           LoadRepresentation.loadConfiguration(SimanticsUI.getSession(), ((ResourceEditorInput)input).getResource());\r
+                       setPartName(configuration.getLabel());\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\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
+                    \r
+                    HashSet<Configuration> configurations = new HashSet<Configuration>();\r
+                    configurations.add(configuration);\r
+                    getConfigurations(configuration, configurations);\r
+                    \r
+                    String version = ModelicaManager.getDefaultOMVersion();\r
+                    return new Document(ModelicaWriter.write(configurations, configuration.getModel().getStartTime(), RepresentationUtils.isGameExperimentActive(), version));\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
+    private void getConfigurations(Configuration configuration, Set<Configuration> configurations) {\r
+       for(IElement e : configuration.getElements()) {\r
+               if(e instanceof Module) {\r
+                       ModuleType mt = ((Module) e).getType();\r
+                       configurations.add(mt.getConfiguration());\r
+                       getConfigurations(mt.getConfiguration(), configurations);\r
+               }\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..555b13a
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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/preferences/ModelicaPreferencePage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/ModelicaPreferencePage.java
new file mode 100644 (file)
index 0000000..af438d9
--- /dev/null
@@ -0,0 +1,156 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.core.runtime.preferences.ConfigurationScope;\r
+import org.eclipse.core.runtime.preferences.IScopeContext;\r
+import org.eclipse.jface.preference.DirectoryFieldEditor;\r
+import org.eclipse.jface.preference.FieldEditorPreferencePage;\r
+import org.eclipse.jface.preference.RadioGroupFieldEditor;\r
+import org.eclipse.jface.preference.StringFieldEditor;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPreferencePage;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.osgi.service.prefs.Preferences;\r
+import org.simantics.modelica.Activator;\r
+import org.simantics.modelica.ModelicaManager;\r
+import org.simantics.modelica.preferences.OpenModelicaPreferences;\r
+\r
+public class ModelicaPreferencePage extends FieldEditorPreferencePage implements \r
+               IWorkbenchPreferencePage {\r
+\r
+       private static String CUSTOM_PATH = "Custom path";\r
+\r
+       private DirectoryFieldEditor path;\r
+       private RadioGroupFieldEditor rg;\r
+\r
+       public ModelicaPreferencePage() {\r
+               super(GRID);\r
+               setDescription("Modelica preferences");\r
+       }\r
+       \r
+       @Override\r
+       public void init(IWorkbench workbench) {\r
+               setPreferenceStore(new ScopedPreferenceStore(ConfigurationScope.INSTANCE, Activator.PLUGIN_ID));\r
+       }\r
+\r
+       @Override\r
+       public void createFieldEditors() {\r
+               final File installed = ModelicaManager.getInstalledOMHome();\r
+               final File builtIn = ModelicaManager.getBuiltinOMHome();\r
+\r
+               List<String[]> optionList = new ArrayList<String[]>();\r
+               optionList.add(new String[]{CUSTOM_PATH, CUSTOM_PATH});\r
+               if (installed != null) {\r
+                       optionList.add(new String[]{ "Local installation (" + ModelicaManager.getOMVersion(installed) + ")", installed.getAbsolutePath() });\r
+               }\r
+               if (builtIn != null) {\r
+                       optionList.add(new String[]{ "Built-in (" + ModelicaManager.getOMVersion(builtIn) + ")", builtIn.getAbsolutePath() });\r
+               }\r
+\r
+               String[][] options = optionList.toArray(new String[optionList.size()][]);\r
+\r
+               rg = new RadioGroupFieldEditor(OpenModelicaPreferences.OM_HOME,\r
+                               "&Choose the used OpenModelica version", 1,\r
+                               options, getFieldEditorParent()) {\r
+\r
+                       @Override\r
+                       protected void doStore() {\r
+                               // Do nothing. Path handles saving the value\r
+                       }\r
+\r
+                       @Override\r
+                       protected void fireValueChanged(String property, Object oldValue, Object newValue) {\r
+                               if((installed != null && newValue.equals(installed.getAbsolutePath())) || (builtIn != null && newValue.equals(builtIn.getAbsolutePath()))) {\r
+                                       path.setStringValue((String)newValue);\r
+                                       path.setEnabled(false, getFieldEditorParent());\r
+                               } else {\r
+                                       path.setEnabled(true, getFieldEditorParent());\r
+                               }   \r
+                       }\r
+\r
+                       @Override\r
+                       public void doLoadDefault() {\r
+                               IScopeContext context = ConfigurationScope.INSTANCE;\r
+                               Preferences node = context.getNode(Activator.PLUGIN_ID);\r
+                               node.put(OpenModelicaPreferences.OM_HOME, ModelicaManager.getDefaultOMHome().getAbsolutePath());\r
+                               load();\r
+                       }\r
+               };\r
+\r
+               addField(rg);\r
+\r
+               path = new DirectoryFieldEditor(OpenModelicaPreferences.OM_HOME, \r
+                               "&Modelica Home:", getFieldEditorParent()) {\r
+\r
+                       @Override\r
+                       public void setValidateStrategy(int value) {\r
+                               super.setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE);\r
+                       }\r
+\r
+                       @Override\r
+                       public void doStore() {\r
+                               super.doStore();\r
+                               IScopeContext context = ConfigurationScope.INSTANCE;\r
+                               Preferences node = context.getNode(Activator.PLUGIN_ID);\r
+                               node.put(OpenModelicaPreferences.OM_HOME, getStringValue());\r
+                       }\r
+\r
+                       @Override\r
+                       protected boolean doCheckState() {\r
+                               boolean valid = super.doCheckState();\r
+                               if(valid) {\r
+                                       // path is a valid directory\r
+                                       String path = getStringValue();\r
+                                       File dir = new File(path);\r
+                                       String version = ModelicaManager.getOMVersion(dir);\r
+                                       if(version == null || version.isEmpty()) {\r
+                                               return false;\r
+                                       }\r
+                               }\r
+\r
+                               return valid;\r
+                       }\r
+\r
+                       @Override\r
+                       public void doLoad() {\r
+                               super.doLoad();\r
+                               String value = getStringValue();\r
+                               updatePath(value);\r
+                       }\r
+\r
+                       @Override\r
+                       public void doLoadDefault() {\r
+                               updatePath(ModelicaManager.getDefaultOMHome().getAbsolutePath());\r
+                       }\r
+\r
+                       private void updatePath(String newValue) {\r
+                               if((installed != null && newValue.equals(installed.getAbsolutePath()) ||  newValue.equals(builtIn.getAbsolutePath()))) {\r
+                                       path.setStringValue(newValue);\r
+                                       path.setEnabled(false, getFieldEditorParent());\r
+                               } else {\r
+                                       path.setEnabled(true, getFieldEditorParent());\r
+                               }   \r
+                       }\r
+\r
+\r
+               };\r
+\r
+               path.setErrorMessage("Path must be a valid OpenModelica directory");\r
+               addField(path);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SolverPreferencePage.java
new file mode 100644 (file)
index 0000000..3cd3f05
--- /dev/null
@@ -0,0 +1,37 @@
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import org.eclipse.core.runtime.preferences.ConfigurationScope;\r
+import org.eclipse.jface.preference.FieldEditor;\r
+import org.eclipse.jface.preference.FieldEditorPreferencePage;\r
+import org.eclipse.jface.preference.RadioGroupFieldEditor;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPreferencePage;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.sysdyn.solver.SolverSettings;\r
+\r
+public class SolverPreferencePage extends FieldEditorPreferencePage implements\r
+               IWorkbenchPreferencePage {\r
+       \r
+       private FieldEditor solverEditor;\r
+       \r
+       public SolverPreferencePage() {\r
+               super(GRID);\r
+               setDescription("Solver preferences");\r
+       }\r
+\r
+       @Override\r
+       public void init(IWorkbench workbench) {\r
+               setPreferenceStore(new ScopedPreferenceStore(ConfigurationScope.INSTANCE, SolverSettings.QUALIFIER));\r
+       }\r
+\r
+       @Override\r
+       protected void createFieldEditors() {\r
+               solverEditor = new RadioGroupFieldEditor(SolverSettings.SOLVER_TYPE, "Solver type", 1,\r
+                               new String[][] { \r
+                                       { "Internal", SolverSettings.SOLVER_TYPE_INTERNAL },\r
+                                       { "OpenModelica", SolverSettings.SOLVER_TYPE_OPENMODELICA }\r
+                               }, getFieldEditorParent());\r
+               addField(solverEditor);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencePage.java
new file mode 100644 (file)
index 0000000..a61ae6b
--- /dev/null
@@ -0,0 +1,176 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *     VTT Technical Research Centre of Finland\r
+ *******************************************************************************/\r
+\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.preference.BooleanFieldEditor;\r
+import org.eclipse.jface.preference.ColorFieldEditor;\r
+import org.eclipse.jface.preference.FieldEditor;\r
+import org.eclipse.jface.preference.FieldEditorPreferencePage;\r
+import org.eclipse.jface.preference.FontFieldEditor;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridLayout;\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.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPreferencePage;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SysdynDiagramPreferencePage extends FieldEditorPreferencePage implements\r
+IWorkbenchPreferencePage {\r
+    \r
+    private HashMap<FieldEditor, Composite> fieldParents;\r
+    private Group colorEditors, fontEditors;\r
+\r
+    public SysdynDiagramPreferencePage() {\r
+        super(GRID);\r
+        setDescription("System dynamics diagram preferences");\r
+        fieldParents = new HashMap<FieldEditor, Composite>();\r
+    }\r
+\r
+    @Override\r
+    public void init(IWorkbench workbench) {\r
+        setPreferenceStore(Activator.getDefault().getPreferenceStore());\r
+    }\r
+\r
+    @Override\r
+    protected void createFieldEditors() {\r
+        Composite parent = new Composite(getFieldEditorParent(), SWT.NONE);\r
+        GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parent);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);\r
+        \r
+        // DEFAULTS\r
+        Group defaults = new Group(parent, SWT.NONE);\r
+        defaults.setText("Default settings");\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(defaults);\r
+        addField(new ColorFieldEditor(SysdynDiagramPreferences.DEFAULT_COLOR, "Color", defaults));\r
+        addField(new CustomFontFieldEditor(SysdynDiagramPreferences.DEFAULT_FONT, "Font", defaults));\r
+        GridLayout layout = (GridLayout) defaults.getLayout();\r
+        layout.marginHeight = 3;\r
+        layout.marginWidth = 3;\r
+        defaults.setLayout(layout);\r
+        \r
+        // COLORS\r
+        colorEditors = new Group(parent, SWT.NONE);\r
+        colorEditors.setText("Colors");\r
+        GridDataFactory.fillDefaults().applyTo(colorEditors);\r
+        GridDataFactory.fillDefaults().applyTo(colorEditors);\r
+        Label label = new Label(colorEditors, SWT.NONE);\r
+        GridDataFactory.fillDefaults().span(3, 1).applyTo(label);\r
+        \r
+        label = new Label(colorEditors, SWT.NONE);\r
+        label.setText("Use default");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        addColorFieldEditor(SysdynDiagramPreferences.ARROW_COLOR, "&Dependency", SysdynDiagramPreferences.ARROW_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.ARROW_STOCK_INITIAL_COLOR, "&Dependency to Stock Initial", SysdynDiagramPreferences.ARROW_STOCK_INITIAL_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.FLOW_COLOR, "&Flow", SysdynDiagramPreferences.FLOW_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.AUXILIARY_COLOR, "&Auxiliary", SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.STOCK_COLOR, "&Stock", SysdynDiagramPreferences.STOCK_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.VALVE_COLOR, "&Valve", SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.INPUT_COLOR, "&Input", SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.CLOUD_COLOR, "&Cloud", SysdynDiagramPreferences.CLOUD_USE_DEFAULT_COLOR);\r
+        addColorFieldEditor(SysdynDiagramPreferences.MODULE_COLOR, "&Module", SysdynDiagramPreferences.MODULE_USE_DEFAULT_COLOR);\r
+        \r
+        // FONTS\r
+        fontEditors = new Group(parent, SWT.NONE);\r
+        fontEditors.setText("Fonts");\r
+        GridDataFactory.fillDefaults().applyTo(fontEditors);\r
+        GridLayoutFactory.fillDefaults().applyTo(fontEditors);\r
+\r
+        label = new Label(fontEditors, SWT.NONE);\r
+        GridDataFactory.fillDefaults().span(3, 1).applyTo(label);\r
+        \r
+        label = new Label(fontEditors, SWT.NONE);\r
+        label.setText("Use default");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+\r
+        addFontFieldEditor(SysdynDiagramPreferences.ARROW_FONT, "Dependency", SysdynDiagramPreferences.ARROW_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.AUXILIARY_FONT, "Auxiliary", SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.STOCK_FONT, "Stock", SysdynDiagramPreferences.STOCK_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.VALVE_FONT, "Valve", SysdynDiagramPreferences.VALVE_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.INPUT_FONT, "Input", SysdynDiagramPreferences.INPUT_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.CLOUD_FONT, "Cloud", SysdynDiagramPreferences.CLOUD_USE_DEFAULT_FONT);\r
+        addFontFieldEditor(SysdynDiagramPreferences.MODULE_FONT, "Module", SysdynDiagramPreferences.MODULE_USE_DEFAULT_FONT);\r
+\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(colorEditors);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(fontEditors);\r
+    }\r
+    \r
+    \r
+    private void addColorFieldEditor(String property, String label, String defaultBoolean) {\r
+        ColorFieldEditor colorField = new ColorFieldEditor(property, label, colorEditors);\r
+        colorField.setEnabled(!getPreferenceStore().getBoolean(defaultBoolean), colorEditors);\r
+        Composite c = new Composite(colorEditors, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(c);\r
+        GridLayoutFactory.fillDefaults().applyTo(c);\r
+        BooleanFieldEditor useDefault = new DefaultBooleanFiedEditor(colorField, defaultBoolean, c);\r
+        fieldParents.put(colorField, colorEditors);\r
+        addField(useDefault);\r
+        addField(colorField);\r
+    }\r
+    \r
+    private void addFontFieldEditor(String property, String label, String defaultBoolean) {\r
+        CustomFontFieldEditor fontField = new CustomFontFieldEditor(property, label, fontEditors);\r
+        fontField.setEnabled(!getPreferenceStore().getBoolean(defaultBoolean), fontEditors);\r
+        Composite c = new Composite(fontEditors, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(c);\r
+        GridLayoutFactory.fillDefaults().applyTo(c);\r
+        BooleanFieldEditor useDefault = new DefaultBooleanFiedEditor(fontField, defaultBoolean, c);\r
+        \r
+        \r
+        \r
+        fieldParents.put(fontField, fontEditors);\r
+        addField(useDefault);\r
+        addField(fontField);\r
+    }\r
+    \r
+    private class DefaultBooleanFiedEditor extends BooleanFieldEditor {\r
+        private FieldEditor fieldEditor;\r
+        \r
+        public DefaultBooleanFiedEditor(FieldEditor fieldEditor, String name, Composite parent) {\r
+            super(name, "", parent);\r
+            this.fieldEditor = fieldEditor;\r
+        }\r
+        \r
+        @Override\r
+        protected void valueChanged(boolean oldValue, boolean newValue) {\r
+            super.valueChanged(oldValue, newValue);\r
+            fieldEditor.setEnabled(!newValue, fieldParents.get(fieldEditor));\r
+        }\r
+    }\r
+    \r
+    private class CustomFontFieldEditor extends FontFieldEditor {\r
+        \r
+        public CustomFontFieldEditor(String name, String labelText, Composite parent) {\r
+            super(name, labelText, parent);\r
+            \r
+            GridDataFactory.fillDefaults().applyTo(getChangeControl(parent));\r
+            setChangeButtonText("...");\r
+            getChangeControl(parent).setToolTipText("Change");\r
+            \r
+            \r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferences.java
new file mode 100644 (file)
index 0000000..1a8255f
--- /dev/null
@@ -0,0 +1,189 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *     VTT Technical Research Centre of Finland\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SysdynDiagramPreferences {\r
+\r
+    public static String DEFAULT_COLOR = "Default color";\r
+    public static String DEFAULT_FONT = "Default font";\r
+    \r
+    public static String ARROW_COLOR = "Arrow color";\r
+    public static String ARROW_STOCK_INITIAL_COLOR = "Arrow stock initial color";\r
+    public static String FLOW_COLOR = "Flow color";\r
+    public static String AUXILIARY_COLOR = "Auxiliary color";\r
+    public static String CLOUD_COLOR = "Cloud color";\r
+    public static String STOCK_COLOR = "Stock color";\r
+    public static String VALVE_COLOR = "Valve color";\r
+    public static String INPUT_COLOR = "Input color";\r
+    public static String MODULE_COLOR = "Module color";\r
+    \r
+    public static HashMap<String, String> colorPreferenceNames;\r
+    \r
+    static {\r
+        colorPreferenceNames = new HashMap<String, String>();\r
+        colorPreferenceNames.put(SysdynResource.URIs.DependencyConnection, ARROW_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.DependencyConnection + "_stockInitial", ARROW_STOCK_INITIAL_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.FlowConnection, FLOW_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.AuxiliarySymbol, AUXILIARY_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.CloudSymbol, CLOUD_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.StockSymbol, STOCK_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.ValveSymbol, VALVE_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.InputSymbol, INPUT_COLOR);\r
+        colorPreferenceNames.put(SysdynResource.URIs.ModuleSymbol, MODULE_COLOR);\r
+    }\r
+    \r
+    public static String getColorPreferenceName(ReadGraph graph, Resource resource) \r
+            throws DatabaseException {\r
+        String preference =  colorPreferenceNames.get(getSymbolUri(graph, resource));\r
+        return preference;\r
+    }\r
+    \r
+    public static String ARROW_USE_DEFAULT_COLOR = "Arrow use default color";\r
+    public static String ARROW_STOCK_INITIAL_USE_DEFAULT_COLOR = "Arrow stock initial use default color";\r
+    public static String FLOW_USE_DEFAULT_COLOR = "Flow use default color";\r
+    public static String AUXILIARY_USE_DEFAULT_COLOR = "Auxiliary use default color";\r
+    public static String CLOUD_USE_DEFAULT_COLOR = "Cloud use default color";\r
+    public static String STOCK_USE_DEFAULT_COLOR = "Stock use default color";\r
+    public static String VALVE_USE_DEFAULT_COLOR = "Valve use default color";\r
+    public static String INPUT_USE_DEFAULT_COLOR = "Input use default color";\r
+    public static String MODULE_USE_DEFAULT_COLOR = "Module use default color";\r
+    \r
+    public static HashMap<String, String> colorDefaults;\r
+    \r
+    static {\r
+        colorDefaults = new HashMap<String, String>();\r
+        colorDefaults.put(ARROW_COLOR, ARROW_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(ARROW_STOCK_INITIAL_COLOR, ARROW_STOCK_INITIAL_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(FLOW_COLOR, FLOW_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(AUXILIARY_COLOR, AUXILIARY_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(CLOUD_COLOR, CLOUD_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(STOCK_COLOR, STOCK_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(VALVE_COLOR, VALVE_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(INPUT_COLOR, INPUT_USE_DEFAULT_COLOR);\r
+        colorDefaults.put(MODULE_COLOR, MODULE_USE_DEFAULT_COLOR);\r
+\r
+    }\r
+    \r
+    public static String ARROW_FONT = "Arrow font";\r
+    public static String AUXILIARY_FONT = "Auxiliary font";\r
+    public static String CLOUD_FONT = "Cloud font";\r
+    public static String STOCK_FONT = "Stock font";\r
+    public static String VALVE_FONT = "Valve font";\r
+    public static String INPUT_FONT = "Input font";\r
+    public static String MODULE_FONT = "Module font";\r
+    \r
+    public static HashMap<String, String> fontPreferenceNames;\r
+    \r
+    static {\r
+        fontPreferenceNames = new HashMap<String, String>();\r
+        fontPreferenceNames.put(SysdynResource.URIs.DependencyConnection, ARROW_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.AuxiliarySymbol, AUXILIARY_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.CloudSymbol, CLOUD_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.StockSymbol, STOCK_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.ValveSymbol, VALVE_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.InputSymbol, INPUT_FONT);\r
+        fontPreferenceNames.put(SysdynResource.URIs.ModuleSymbol, MODULE_FONT);\r
+    }\r
+    \r
+    public static String getFontPreferenceName(ReadGraph graph, Resource resource) \r
+            throws DatabaseException {\r
+        \r
+        String preference =  fontPreferenceNames.get(getSymbolUri(graph, resource));\r
+        return preference;\r
+    }\r
+    \r
+    public static String ARROW_USE_DEFAULT_FONT = "Arrow use default font";\r
+    public static String AUXILIARY_USE_DEFAULT_FONT = "Auxiliary use default font";\r
+    public static String CLOUD_USE_DEFAULT_FONT = "Cloud use default font";\r
+    public static String STOCK_USE_DEFAULT_FONT = "Stock use default font";\r
+    public static String VALVE_USE_DEFAULT_FONT = "Valve use default font";\r
+    public static String INPUT_USE_DEFAULT_FONT = "Input use default font";\r
+    public static String MODULE_USE_DEFAULT_FONT = "Module use default font";\r
+    \r
+    \r
+    public static HashMap<String, String> fontDefaults;\r
+    \r
+    static {\r
+        fontDefaults = new HashMap<String, String>();\r
+        fontDefaults.put(ARROW_FONT, ARROW_USE_DEFAULT_FONT);\r
+        fontDefaults.put(AUXILIARY_FONT, AUXILIARY_USE_DEFAULT_FONT);\r
+        fontDefaults.put(CLOUD_FONT, CLOUD_USE_DEFAULT_FONT);\r
+        fontDefaults.put(STOCK_FONT, STOCK_USE_DEFAULT_FONT);\r
+        fontDefaults.put(VALVE_FONT, VALVE_USE_DEFAULT_FONT);\r
+        fontDefaults.put(INPUT_FONT, INPUT_USE_DEFAULT_FONT);\r
+        fontDefaults.put(MODULE_FONT, MODULE_USE_DEFAULT_FONT);\r
+    }\r
+    \r
+\r
+    \r
+    private static String getSymbolUri(ReadGraph graph, Resource resource)\r
+            throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Resource symbol = graph.getSingleObject(resource, L0.InstanceOf);\r
+        \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        if(graph.isInheritedFrom(symbol, SR.ModuleSymbol))\r
+            symbol = SR.ModuleSymbol;\r
+        \r
+        return graph.getURI(symbol);\r
+    }\r
+\r
+    /**\r
+     * Get the name of the property that decides whether to use default value or not\r
+     * @param property\r
+     * @return\r
+     */\r
+    public static String getUseDefaultProperty(String property) {\r
+        String result = colorDefaults.get(property);\r
+        if(result == null)\r
+            result = fontDefaults.get(property);\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Returns default property if USE DEFAULT is set, otherwise returns the \r
+     * same property as given as argument.\r
+     * @param property\r
+     * @return\r
+     */\r
+    public static String getPreferenceName(String property) {\r
+        String useDefault = fontDefaults.get(property);\r
+        IPreferenceStore store = Activator.getDefault().getPreferenceStore();\r
+        if(useDefault != null && store.getBoolean(useDefault)) {\r
+            return DEFAULT_FONT;\r
+        }\r
+        \r
+        useDefault = colorDefaults.get(property);\r
+        if(useDefault != null && store.getBoolean(useDefault)) {\r
+            return DEFAULT_COLOR;\r
+        }\r
+        \r
+        return property;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPreferencesInitializer.java
new file mode 100644 (file)
index 0000000..1b1c455
--- /dev/null
@@ -0,0 +1,85 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *     VTT Technical Research Centre of Finland\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.preference.PreferenceConverter;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+import com.lowagie.text.Font;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SysdynDiagramPreferencesInitializer extends AbstractPreferenceInitializer {  \r
+\r
+    @Override  \r
+    public void initializeDefaultPreferences() {\r
+        RGB black = new RGB(0, 0, 0);\r
+        RGB arrow = new RGB(0,128,192);\r
+        RGB arrowToStockInitial = new RGB(128,128,128);\r
+        \r
+        IPreferenceStore store = Activator.getDefault().getPreferenceStore();\r
+        \r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.DEFAULT_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.ARROW_STOCK_INITIAL_COLOR, arrowToStockInitial);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.ARROW_COLOR, arrow);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.FLOW_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.AUXILIARY_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.STOCK_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.VALVE_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.INPUT_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.CLOUD_COLOR, black);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.MODULE_COLOR, black);\r
+        \r
+\r
+        store.setDefault(SysdynDiagramPreferences.ARROW_USE_DEFAULT_COLOR, false);\r
+        store.setDefault(SysdynDiagramPreferences.ARROW_STOCK_INITIAL_USE_DEFAULT_COLOR, false);\r
+        store.setDefault(SysdynDiagramPreferences.FLOW_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.STOCK_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.VALVE_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.INPUT_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.CLOUD_USE_DEFAULT_COLOR, true);\r
+        store.setDefault(SysdynDiagramPreferences.MODULE_USE_DEFAULT_COLOR, true);\r
+        \r
+        FontData[] basicFont = new FontData[] {new FontData("Tahoma", 12, Font.NORMAL)};\r
+        FontData[] italicFont = new FontData[] {new FontData("Tahoma", 12, Font.ITALIC)};\r
+        FontData[] moduleFont = new FontData[] {new FontData("Tahoma", 16, Font.NORMAL)};\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.DEFAULT_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.ARROW_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.AUXILIARY_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.STOCK_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.VALVE_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.INPUT_FONT, italicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.CLOUD_FONT, basicFont);\r
+        PreferenceConverter.setDefault(store, SysdynDiagramPreferences.MODULE_FONT, moduleFont);\r
+\r
+        store.setDefault(SysdynDiagramPreferences.ARROW_USE_DEFAULT_FONT, true);\r
+        store.setDefault(SysdynDiagramPreferences.AUXILIARY_USE_DEFAULT_FONT, true);\r
+        store.setDefault(SysdynDiagramPreferences.STOCK_USE_DEFAULT_FONT, true);\r
+        store.setDefault(SysdynDiagramPreferences.VALVE_USE_DEFAULT_FONT, true);\r
+        store.setDefault(SysdynDiagramPreferences.INPUT_USE_DEFAULT_FONT, false);\r
+        store.setDefault(SysdynDiagramPreferences.CLOUD_USE_DEFAULT_FONT, true);\r
+        store.setDefault(SysdynDiagramPreferences.MODULE_USE_DEFAULT_FONT, false);\r
+\r
+    }  \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertyExternalRead.java
new file mode 100644 (file)
index 0000000..6a95001
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynDiagramPropertyExternalRead extends ParametrizedPrimitiveRead<Pair<Resource, String>, String> {\r
+\r
+    private SysdynDiagramPropertySubscription subscription;\r
+\r
+    public SysdynDiagramPropertyExternalRead(Pair<Resource, String> input) {\r
+        super(input);\r
+    }\r
+\r
+    @Override\r
+    public void register(ReadGraph graph, Listener<String> procedure) {\r
+        subscription = new SysdynDiagramPropertySubscription(procedure, parameter.second);\r
+        SysdynDiagramPropertySupport.INSTANCE.register(subscription);\r
+        IPreferenceStore store = Activator.getDefault().getPreferenceStore();\r
+        if(store.contains(parameter.second)) {\r
+            String preference = SysdynDiagramPreferences.getPreferenceName(parameter.second);\r
+            procedure.execute(store.getString(preference));\r
+        } else\r
+            procedure.execute(null);\r
+    }\r
+    \r
+    @Override\r
+    public void unregistered() {\r
+        if(subscription != null) {\r
+            SysdynDiagramPropertySupport.INSTANCE.unregister(subscription);\r
+            subscription = null;\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySubscription.java
new file mode 100644 (file)
index 0000000..286572c
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import org.simantics.db.procedure.Listener;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynDiagramPropertySubscription {\r
+    \r
+    private Listener<String> listener;\r
+    private String propertyName;\r
+    \r
+    public SysdynDiagramPropertySubscription(Listener<String> listener, String propertyName) {\r
+        this.listener = listener;\r
+        this.propertyName = propertyName;\r
+    }\r
+\r
+    public Listener<String> getListener() {\r
+        return listener;\r
+    }\r
+    \r
+    public String getPropertyName() {\r
+        return propertyName;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/preferences/SysdynDiagramPropertySupport.java
new file mode 100644 (file)
index 0000000..441b7fe
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.preferences;\r
+\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.util.IPropertyChangeListener;\r
+import org.eclipse.jface.util.PropertyChangeEvent;\r
+import org.simantics.sysdyn.ui.Activator;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynDiagramPropertySupport {\r
+    \r
+    public static SysdynDiagramPropertySupport INSTANCE = new SysdynDiagramPropertySupport();\r
+    \r
+    private Set<String> diagramProperties;\r
+    private THashSet<SysdynDiagramPropertySubscription> subscriptions = new THashSet<SysdynDiagramPropertySubscription>();\r
+    private SysdynDiagramPropertySubscription[] subscriptionSnapshot = null;\r
+    \r
+    private void add(String property) {\r
+        diagramProperties.add(property);\r
+        String useDefault = SysdynDiagramPreferences.getUseDefaultProperty(property);\r
+        if(useDefault != null)\r
+            diagramProperties.add(useDefault);\r
+    }\r
+    \r
+    public SysdynDiagramPropertySupport() {\r
+        diagramProperties = new HashSet<String>();\r
+        for(String property : SysdynDiagramPreferences.colorPreferenceNames.values())\r
+            add(property);\r
+        \r
+        add(SysdynDiagramPreferences.DEFAULT_COLOR);\r
+        add(SysdynDiagramPreferences.DEFAULT_FONT);\r
+        \r
+        \r
+        for(String property : SysdynDiagramPreferences.fontPreferenceNames.values())\r
+            add(property);\r
+        \r
+        Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {\r
+            @Override\r
+            public void propertyChange(PropertyChangeEvent event) {\r
+                String propertyName = event.getProperty();\r
+                if(diagramProperties.contains(propertyName)){\r
+                    for(SysdynDiagramPropertySubscription subscription : getSubscriptionSnapshot()) {\r
+                        String p = subscription.getPropertyName();\r
+                        String p2 = SysdynDiagramPreferences.getPreferenceName(p);\r
+                        String dp = SysdynDiagramPreferences.getUseDefaultProperty(subscription.getPropertyName());\r
+                        if(propertyName.equals(p) ||\r
+                                propertyName.equals(p2) ||\r
+                                propertyName.equals(dp)) {\r
+                            IPreferenceStore store = Activator.getDefault().getPreferenceStore();\r
+                            String result = store.getString(p2);\r
+                            subscription.getListener().execute(result);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+    public void register(SysdynDiagramPropertySubscription subscription) {\r
+        assert subscription != null;\r
+        synchronized (subscriptions) {\r
+            subscriptions.add(subscription);\r
+            subscriptionSnapshot = null;\r
+        }\r
+    }\r
+\r
+    public void unregister(SysdynDiagramPropertySubscription subscription) {\r
+        assert subscription != null;\r
+        synchronized (subscriptions) {\r
+            subscriptions.remove(subscription);\r
+            subscriptionSnapshot = null;\r
+        }\r
+\r
+    }\r
+    \r
+    public SysdynDiagramPropertySubscription[] getSubscriptionSnapshot() {\r
+        SysdynDiagramPropertySubscription[] snapshot = subscriptionSnapshot;\r
+        if (snapshot == null) {\r
+            synchronized (subscriptions) {\r
+                snapshot = subscriptionSnapshot;\r
+                if (snapshot == null) {\r
+                    snapshot = subscriptionSnapshot = \r
+                            subscriptions.toArray(new SysdynDiagramPropertySubscription[subscriptions.size()]);\r
+                }\r
+            }\r
+        }\r
+        return snapshot;\r
+    }    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynEquationPerspectiveFactory.java
new file mode 100644 (file)
index 0000000..d1c2a24
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.eclipse.ui.IPageLayout;\r
+import org.eclipse.ui.IPerspectiveFactory;\r
+\r
+public class SysdynEquationPerspectiveFactory implements IPerspectiveFactory {\r
+\r
+    @Override\r
+    public void createInitialLayout(IPageLayout layout) {\r
+        layout.setEditorAreaVisible(true);\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..096dfc5
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.eclipse.ui.IPageLayout;\r
+import org.eclipse.ui.IPerspectiveFactory;\r
+\r
+public class SysdynPerspectiveFactory implements IPerspectiveFactory {\r
+\r
+    @Override\r
+    public void createInitialLayout(IPageLayout layout) {\r
+        layout.setEditorAreaVisible(true);\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..96f4a89
--- /dev/null
@@ -0,0 +1,292 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.project;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\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.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.layer0.adapter.RuntimeValuations;\r
+import org.simantics.db.layer0.adapter.TrendVariable;\r
+import org.simantics.db.layer0.service.ActivationManager;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.GraphChangeListenerSupport;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.fmu.FMUControlJNI;\r
+import org.simantics.issues.common.IssueUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.modeling.services.CaseInsensitiveComponentNamingStrategy2;\r
+import org.simantics.modeling.services.ComponentNamingStrategy;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.project.exception.ProjectException;\r
+import org.simantics.project.features.AbstractProjectFeature;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.simulation.project.ExperimentManagerKeys;\r
+import org.simantics.simulation.project.ExperimentManagerMode;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.editor.SysdynEditorNamingService;\r
+import org.simantics.ui.workbench.IEditorNamingService;\r
+import org.simantics.utils.FileUtils;\r
+import org.simantics.utils.ui.BundleUtils;\r
+\r
+public class SysdynProject extends AbstractProjectFeature {\r
+       private static final String DEFAULT_PERSPECTIVE = "org.simantics.sysdyn.ui.perspective";\r
+\r
+       @Override\r
+       public void configure() throws ProjectException {\r
+               final IProject project = getProject();\r
+               final Session session = getSession();\r
+\r
+               try {\r
+                       File base = BundleUtils.findFile("org.simantics.sysdyn.ui", "");\r
+                       File f = new File(base, "../org.simantics.sysdyn.tests/src/org/simantics/sysdyn/tests/scripts");\r
+                       if(f.exists()) {\r
+                               System.setProperty("scl.test.path", f.getAbsolutePath());\r
+                       }\r
+               } catch (Exception e) {\r
+                       \r
+               }\r
+               \r
+\r
+               getProjectElement().setHint(ProjectKeys.DEFAULT_PERSPECTIVE, DEFAULT_PERSPECTIVE);\r
+               \r
+               // Multi for simupedia use\r
+               getProjectElement().setHint(ExperimentManagerKeys.EXPERIMENT_MANAGER_MODE, ExperimentManagerMode.MULTI_EXPERIMENT);\r
+               // Single for normal workbench use\r
+//             getProjectElement().setHint(ExperimentManagerKeys.EXPERIMENT_MANAGER_MODE, ExperimentManagerMode.SINGLE_EXPERIMENT);\r
+               \r
+               getProjectElement().setHint(IEditorNamingService.KEY_EDITOR_NAMING_SERVICE, new SysdynEditorNamingService());\r
+\r
+               // Install naming strategy for model components.\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
+               try {\r
+\r
+                       Resource projectResource = project.get();\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
+\r
+                       ActivationManager activationManager = session.getService(ActivationManager.class);\r
+                       if (activationManager != null) {\r
+                               activationManager.activate(session, projectResource);\r
+                       }\r
+\r
+\r
+                       final VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);\r
+\r
+                       support.getWorkspacePersistent("experiments");\r
+                       support.getWorkspacePersistent("profiles");\r
+            support.getWorkspacePersistent("preferences");\r
+                       support.getWorkspacePersistent("issues");\r
+\r
+               } catch (DatabaseException e) {\r
+\r
+                       throw new ProjectException(e);\r
+\r
+               }\r
+\r
+\r
+               cleanProjectFolder(session, project.get());\r
+\r
+               // Clean all temporary files possibly left by previous sysdyn instances\r
+               clearFMUTempDirectory();\r
+\r
+\r
+               // Issues\r
+               try {\r
+                       session.syncRequest(new ReadRequest() {\r
+                               @Override\r
+                               public void run(ReadGraph graph) throws DatabaseException {\r
+                                       onActivated(graph, getProject());\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       throw new ProjectException(e);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Clears fmu temp directory. This directory hosts\r
+        * fmu files for game experiments. In normal situations\r
+        * experiments clean up their temp files, but for example\r
+        * a system crash may leave files to temp directory. \r
+        */\r
+       private void clearFMUTempDirectory() {\r
+               // Find commone "TEMP/fmu" directory\r
+               File commonDir = new File(FMUControlJNI.TEMP_FMU_COMMON_DIRECTORY);\r
+               if(commonDir != null && commonDir.isDirectory()) {\r
+\r
+                       // List all files and directories in "TEMP/fmu" \r
+                       for(File child : commonDir.listFiles()) {\r
+                               if(child.isDirectory()) {\r
+                                       // If directory is found, try to get the lock file in it\r
+                                       File lock = new File(child, FMUControlJNI.LOCK_FILE_NAME);\r
+                                       if(!lock.isFile() || lock.delete()) {\r
+                                               // If lock is not found, or the lock can be delted, the directory is not locked. -> Delete the rest of the directory\r
+                                               try {\r
+                                                       FileUtils.deleteAll(child);\r
+                                                       child.delete();\r
+                                               } catch (IOException e) {\r
+\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void deconfigure() throws ProjectException {\r
+           \r
+        ModelingUtils.untrackDependencies(getSession());\r
+\r
+               getProjectElement().removeHint(ComponentNamingStrategy.PROJECT_KEY);\r
+       }\r
+\r
+       public void cleanProjectFolder(Session session, final Resource projectResource) throws ProjectException {\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
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       for(Resource model : graph.getObjects(projectResource, l0.ConsistsOf)) {\r
+                                               if(graph.isInstanceOf(model, sr.SysdynModel)){\r
+                                                       for(Resource experiment : graph.getObjects(model, l0.ConsistsOf)) {\r
+                                                               if(graph.isInstanceOf(experiment, SIMU.Experiment)) {\r
+                                                                       for(Resource result : graph.getObjects(experiment, sr.Experiment_result)) {\r
+                                                                               if(!graph.isInstanceOf(result, sr.HistoryDataset)) {\r
+                                                                                       String resultFile = (String)graph.getPossibleRelatedValue(result, sr.Result_resultFile);\r
+                                                                                       if(result != null) resultPaths.put(resultFile, result);\r
+                                                                               }\r
+                                                                       }\r
+                                                                       for(Resource resultSet : graph.getObjects(experiment, sr.Experiment_resultSet)) {\r
+                                                                               for(Resource result : graph.getObjects(resultSet, sr.Experiment_result)) {\r
+                                                                                       if(!graph.isInstanceOf(result, sr.HistoryDataset)) {\r
+                                                                                               String resultFile = (String)graph.getPossibleRelatedValue(result, sr.Result_resultFile);\r
+                                                                                               if(result != null) resultPaths.put(resultFile, result);\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       return graph.getPossibleRelatedValue(projectResource, l0.HasName);\r
+\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       throw new ProjectException(e);\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
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               for(String key : resultPaths.keySet()) {\r
+                                                       Resource result = resultPaths.get(key);\r
+                                                       graph.deny(result, l0.PartOf);\r
+                                                       graph.deny(result, graph.getInverse(SysdynResource.getInstance(graph).Experiment_result));\r
+                                               }\r
+                                       }\r
+                               }) ;\r
+                       }\r
+               }\r
+       }\r
+\r
+       public void onActivated(final ReadGraph graph, final IProject project) throws DatabaseException {\r
+\r
+//             GraphChangeListenerSupport changeSupport = graph.getService(GraphChangeListenerSupport.class);\r
+//             changeSupport.addMetadataListener(new GenericChangeListener<DependencyChangesRequest, DependencyChanges>() {\r
+//\r
+//                     @Override\r
+//                     public void onEvent(ReadGraph graph, DependencyChanges event) throws DatabaseException {\r
+//\r
+//                             WriteGraph w = (WriteGraph)graph;\r
+//                             w.addMetadata(event);\r
+//\r
+//                     }\r
+//\r
+//             });\r
+\r
+               IssueUtils.listenActiveProjectIssueSources(graph, project.get());\r
+               \r
+        ModelingUtils.trackDependencies(graph);\r
+\r
+\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynTrendPerspectiveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/project/SysdynTrendPerspectiveFactory.java
new file mode 100644 (file)
index 0000000..cf2eb01
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.project;\r
+\r
+import org.eclipse.ui.IPageLayout;\r
+import org.eclipse.ui.IPerspectiveFactory;\r
+\r
+public class SysdynTrendPerspectiveFactory implements IPerspectiveFactory {\r
+\r
+    @Override\r
+    public void createInitialLayout(IPageLayout layout) {\r
+        layout.setEditorAreaVisible(true);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayDependencyTab.java
new file mode 100644 (file)
index 0000000..1e78088
--- /dev/null
@@ -0,0 +1,394 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.Scale;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.util.ObjectUtils;\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.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass;\r
+import org.simantics.sysdyn.ui.elements.connections.DependencyNode;\r
+import org.simantics.sysdyn.ui.properties.widgets.ArrowHeadWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.DelayMarkWidget;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+/**\r
+ * Tab for multiple dependencies.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ArrayDependencyTab  extends AdjustableTab {\r
+\r
+    Button none, plus, minus, other, inside, outside;\r
+    TrackedText polarityText, polarityLocationText;\r
+    private DelayMarkWidget delayMark;\r
+    private ArrowHeadWidget arrowhead;\r
+       private Scale lineThicknessScale;\r
+       private Group hiddenDefaultbuttonGroup;\r
+       private Group polarityGroup;\r
+       private Group locationGroup;\r
+       private Composite misc;\r
+       private Group lineThicknessGroup;\r
+    \r
+    class LineThicknessSelectionListener extends SelectionListenerImpl<ArrayList<Resource>> {\r
+       Scale scale;\r
+               private int selection;\r
+\r
+        public LineThicknessSelectionListener(ISessionContext context, Scale scale) {\r
+               super(context);\r
+               this.scale = scale;\r
+        }\r
+        \r
+        @Override\r
+        public void beforeApply() {\r
+            this.selection = scale.getWidget().getSelection();\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, ArrayList<Resource> connectionElements) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            float width = ((float)selection) / 10.0f;\r
+            for (Resource r : connectionElements)\r
+               graph.claimLiteral(r, sr.DependencyConnection_strokeWidth, width);\r
+        }\r
+        \r
+    }\r
+    \r
+    class LineThicknessRadioSelectionFactory extends ReadFactoryImpl<ArrayList<Resource>, Integer> {\r
+\r
+        public LineThicknessRadioSelectionFactory() {\r
+        }\r
+\r
+        @Override\r
+        public Integer perform(ReadGraph graph, ArrayList<Resource> dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            if (dependencyConnection.size() > 0) {\r
+               Float width = graph.getPossibleRelatedValue(dependencyConnection.get(0), sr.DependencyConnection_strokeWidth, Bindings.FLOAT);  \r
+               if(width != null) {\r
+                       return (int)Math.round(width * 10);\r
+               }\r
+            }\r
+            return (int)Math.round(DependencyEdgeClass.DEFAULT_STROKE_WIDTH * 10);\r
+        }\r
+    }\r
+    \r
+    class OtherPolarityStringPropertyFactory extends ReadFactoryImpl<ArrayList<Resource>, String> {\r
+\r
+           private final String propertyURI;\r
+\r
+           public OtherPolarityStringPropertyFactory() {\r
+               this.propertyURI = SysdynResource.URIs.DependencyConnection_polarity;\r
+           }\r
+\r
+           @SuppressWarnings("unchecked")\r
+               @Override\r
+           public Object getIdentity(Object inputContents) {\r
+               return new Triple<ArrayList<Resource>, String, Object>((ArrayList<Resource>) inputContents, propertyURI, getClass());\r
+           }\r
+\r
+           @Override\r
+           public String perform(ReadGraph graph, ArrayList<Resource> resources) throws DatabaseException {\r
+               String value = graph.getPossibleRelatedValue(resources.get(0), graph.getResource(propertyURI));;\r
+               if (value == null)\r
+                       return "";\r
+               for (Resource r : resources) {\r
+                       String s = graph.getPossibleRelatedValue(r, graph.getResource(propertyURI));\r
+                       if (!value.equals(s))\r
+                               return "";\r
+               }\r
+               return value;\r
+           }           \r
+    }\r
+    \r
+    class OtherPolarityStringPropertyModifier extends TextModifyListenerImpl<ArrayList<Resource>> {\r
+\r
+       final private String propertyURI;\r
+       \r
+       public OtherPolarityStringPropertyModifier() {\r
+               this.propertyURI = SysdynResource.URIs.DependencyConnection_polarity;\r
+       }\r
+\r
+       @Override\r
+       public void applyText(WriteGraph graph, ArrayList<Resource> resources, String text) throws DatabaseException {\r
+               for (Resource r : resources)\r
+                       graph.claimLiteral(r, graph.getResource(propertyURI), text, Bindings.STRING);\r
+       }\r
+       \r
+    }\r
+\r
+    class PolarityLocationSelectionListener extends SelectionListenerImpl<ArrayList<Resource>> {\r
+        private String location;\r
+\r
+        public PolarityLocationSelectionListener(ISessionContext context, String location) {\r
+            super(context);\r
+            this.location = location;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, ArrayList<Resource> connectionElements) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            for (Resource r : connectionElements)\r
+               graph.claimLiteral(r, sr.DependencyConnection_polarityLocation, location);\r
+        }\r
+        \r
+    }\r
+    \r
+    class PolarityLocationRadioSelectionFactory extends ReadFactoryImpl<ArrayList<Resource>, Boolean> {\r
+        private String location;\r
+\r
+        public PolarityLocationRadioSelectionFactory(String location) {\r
+            this.location = location;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, location, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, ArrayList<Resource> dependencyConnections) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            for (Resource r : dependencyConnections) {\r
+               String location = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarityLocation, Bindings.STRING);  \r
+               if (DependencyNode.OUTSIDE.equals(this.location)) {\r
+                       if (ObjectUtils.objectEquals(this.location, location))\r
+                               continue;\r
+               } else {\r
+                       if (location == null) {\r
+                           continue;\r
+                       } else {\r
+                           if (ObjectUtils.objectEquals(this.location, location))\r
+                               continue;\r
+                       }\r
+               }\r
+               return false;\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+    \r
+    class PolaritySelectionListener extends SelectionListenerImpl<ArrayList<Resource>> {\r
+        private String polarity;\r
+\r
+        public PolaritySelectionListener(ISessionContext context, String polarity) {\r
+            super(context);\r
+            this.polarity = polarity;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, ArrayList<Resource> connectionElements) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            for (Resource r : connectionElements)\r
+               graph.claimLiteral(r, sr.DependencyConnection_polarity, polarity.trim());\r
+        }\r
+        \r
+    }\r
+    \r
+    class PolarityRadioSelectionFactory extends ReadFactoryImpl<ArrayList<Resource>, Boolean> {\r
+        private String polarity;\r
+\r
+        public PolarityRadioSelectionFactory(String polarity) {\r
+            this.polarity = polarity;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, polarity, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, ArrayList<Resource> dependencyConnections) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            for (Resource r : dependencyConnections) {\r
+               String polarity = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarity, Bindings.STRING);     \r
+               if (polarity == null && this.polarity.equals(""))\r
+                       continue;\r
+               if (ObjectUtils.objectEquals(polarity, this.polarity))\r
+                       continue;\r
+               return false;\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+    \r
+    class OtherPolaritySelectionFactory extends ReadFactoryImpl<ArrayList<Resource>, Boolean> {\r
+\r
+        String[] limits;\r
+        \r
+        public OtherPolaritySelectionFactory(String[] limits) {\r
+            this.limits = limits;\r
+        }\r
+        \r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Pair<Object, Class<?>>(inputContents, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, ArrayList<Resource> dependencyConnections) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            for (Resource r : dependencyConnections) {\r
+               String polarity = graph.getPossibleRelatedValue(r, sr.DependencyConnection_polarity, Bindings.STRING);\r
+                for(String s : limits) {\r
+                    if(ObjectUtils.objectEquals(polarity, s))\r
+                        return false;\r
+                }\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+\r
+       public ArrayDependencyTab(Object dependencies) {\r
+           super(dependencies);\r
+       }\r
+\r
+    @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               composite = new Composite(body, SWT.NONE);\r
+        \r
+        /* Add a dummy button at the begin to suck in the nonsense selection events that\r
+         * the first radio button in the group of ALL the radio buttons receives when no\r
+         * radio is selected and then one is selected in other group than where the first \r
+         * radio button lies.  \r
+         */\r
+        hiddenDefaultbuttonGroup = new Group(composite, SWT.NONE);\r
+        new Button(hiddenDefaultbuttonGroup, support, SWT.RADIO);\r
+        \r
+        polarityGroup = new Group(composite, SWT.NONE);\r
+        polarityGroup.setText("Polarity");\r
+        \r
+        none = new Button(polarityGroup, support, SWT.RADIO);\r
+        none.setText("None");\r
+        none.setSelectionFactory(new PolarityRadioSelectionFactory(""));\r
+        none.addSelectionListener(new PolaritySelectionListener(context, ""));\r
+        \r
+        plus = new Button(polarityGroup, support, SWT.RADIO);\r
+        plus.setText("+");\r
+        plus.setSelectionFactory(new PolarityRadioSelectionFactory("+"));\r
+        plus.addSelectionListener(new PolaritySelectionListener(context, "+"));\r
+        \r
+        minus = new Button(polarityGroup, support, SWT.RADIO);\r
+        minus.setText("-");\r
+        minus.setSelectionFactory(new PolarityRadioSelectionFactory("-"));\r
+        minus.addSelectionListener(new PolaritySelectionListener(context, "-"));\r
+        \r
+        other = new Button(polarityGroup, support, SWT.RADIO);\r
+        other.setText("other");\r
+        other.setSelectionFactory(new OtherPolaritySelectionFactory(new String[] {null, "+", "-", ""}));\r
+        \r
+        polarityText = new TrackedText(polarityGroup, support, SWT.BORDER);\r
+        polarityText.setTextFactory(new OtherPolarityStringPropertyFactory());\r
+        polarityText.addModifyListener(new OtherPolarityStringPropertyModifier());\r
+        \r
+        locationGroup = new Group(composite, SWT.NONE);\r
+        locationGroup.setText("Location");\r
+        \r
+        inside = new Button(locationGroup, support, SWT.RADIO);\r
+        inside.setText("Inside");\r
+        inside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.INSIDE));\r
+        inside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.INSIDE));\r
+        \r
+        outside = new Button(locationGroup, support, SWT.RADIO);\r
+        outside.setText("Outside");\r
+        outside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.OUTSIDE));\r
+        outside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.OUTSIDE));\r
+\r
+        misc = new Composite(composite, SWT.NONE);\r
+        \r
+        arrowhead = new ArrowHeadWidget(misc, support, SWT.NULL);\r
+        delayMark = new DelayMarkWidget(misc, support, SWT.NULL);\r
+        \r
+        lineThicknessGroup = new Group(misc, SWT.NONE);\r
+        lineThicknessGroup.setText("Line thickness:");\r
+        lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL);\r
+        lineThicknessScale.getWidget().setMinimum(1);\r
+        lineThicknessScale.getWidget().setMaximum(15);\r
+        lineThicknessScale.getWidget().setPageIncrement(1);\r
+        lineThicknessScale.getWidget().setIncrement(1);\r
+        lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory());\r
+        lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale));\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().exclude(true).applyTo(hiddenDefaultbuttonGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(hiddenDefaultbuttonGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(locationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(locationGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(misc);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(misc);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(arrowhead.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(delayMark.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().exclude(true).applyTo(hiddenDefaultbuttonGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(hiddenDefaultbuttonGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(locationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(locationGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(misc);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(misc);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(arrowhead.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(delayMark.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().span(1, 1).applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayFlowTab.java
new file mode 100644 (file)
index 0000000..47238fb
--- /dev/null
@@ -0,0 +1,109 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Scale;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.connections.FlowConnectionStyle;\r
+\r
+/**\r
+ * Tab for multiple dependencies.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ArrayFlowTab  extends LabelPropertyTabContributor {\r
+\r
+       private Scale lineThicknessScale;\r
+    \r
+    public ArrayFlowTab(Object input) {\r
+        super(input);\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(1).applyTo(composite);\r
+        \r
+        Group lineThicknessGroup = new Group(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+        lineThicknessGroup.setText("Flow thickness:");\r
+        lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL);\r
+        lineThicknessScale.getWidget().setMinimum(1);\r
+        lineThicknessScale.getWidget().setMaximum(9);\r
+        lineThicknessScale.getWidget().setPageIncrement(1);\r
+        lineThicknessScale.getWidget().setIncrement(1);\r
+        lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory());\r
+        lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale));\r
+    }\r
+    \r
+    class LineThicknessSelectionListener extends SelectionListenerImpl<ArrayList<Resource>> {\r
+       Scale scale;\r
+               private int selection;\r
+\r
+        public LineThicknessSelectionListener(ISessionContext context, Scale scale) {\r
+               super(context);\r
+               this.scale = scale;\r
+        }\r
+        \r
+        @Override\r
+        public void beforeApply() {\r
+            this.selection = scale.getWidget().getSelection();\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, ArrayList<Resource> connectionElements) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            float width = ((float)selection) / 3.0f;\r
+            for (Resource r : connectionElements)\r
+               graph.claimLiteral(r, sr.FlowConnection_width, width);\r
+        }\r
+        \r
+    }\r
+    \r
+    class LineThicknessRadioSelectionFactory extends ReadFactoryImpl<ArrayList<Resource>, Integer> {\r
+\r
+        public LineThicknessRadioSelectionFactory() {\r
+        }\r
+\r
+        @Override\r
+        public Integer perform(ReadGraph graph, ArrayList<Resource> flowConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            if (flowConnection.size() > 0) {\r
+               Float width = graph.getPossibleRelatedValue(flowConnection.get(0), sr.FlowConnection_width, Bindings.FLOAT);  \r
+               if(width != null) {\r
+                       return (int)Math.round(width * 3);\r
+               }\r
+            }\r
+            return (int)Math.round(FlowConnectionStyle.DEFAULT_LINE_WIDTH * 3);\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ArrayIndexesTab.java
new file mode 100644 (file)
index 0000000..0a2e68e
--- /dev/null
@@ -0,0 +1,495 @@
+package org.simantics.sysdyn.ui.properties;\r
+\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.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.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\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.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.ResourceArray;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.utils.RunnableWithObject;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.threads.SWTThread;\r
+\r
+public class ArrayIndexesTab extends LabelPropertyTabContributor implements Widget{\r
+\r
+       GraphExplorerComposite availableEnumerationsExplorer;\r
+       GraphExplorerComposite usedEnumerationsExplorer;\r
+       private WidgetSupportImpl buttonSupport;\r
+       private org.simantics.browsing.ui.swt.widgets.Label usedEnumerationsLabel;\r
+    private Button down;\r
+    private Button up;\r
+    private Button remove;\r
+       \r
+       public ArrayIndexesTab(Object variables) {\r
+        super(variables);\r
+    }\r
+\r
+\r
+    @Override\r
+       public void createControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               support.register(this);\r
+               \r
+               buttonSupport = new WidgetSupportImpl();\r
+               \r
+               GridLayoutFactory.fillDefaults().numColumns(4).applyTo(body);\r
+               \r
+               \r
+               Composite available = new Composite(body, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().applyTo(available);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(available);\r
+               Label label = new Label(available, SWT.None);\r
+               label.setText("Available Enumerations");\r
+               availableEnumerationsExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, available, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);\r
+               \r
+               availableEnumerationsExplorer\r
+               .setBrowseContexts(SysdynResource.URIs.AvailableVariableIndexes);\r
+               availableEnumerationsExplorer.setColumns(ColumnKeys.ENUMERATION_TABLE_COLUMNS);\r
+               availableEnumerationsExplorer.setInputSource(new SingleSelectionInputSource(\r
+                               ResourceArray.class));\r
+\r
+               availableEnumerationsExplorer.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               availableEnumerationsExplorer);\r
+               \r
+               Control c = availableEnumerationsExplorer.getExplorerControl();\r
+               if (c instanceof Tree)\r
+                       ((Tree) c).setLinesVisible(true);\r
+               \r
+               \r
+               Button add = new Button(body, buttonSupport, SWT.NONE);\r
+               add.setText(" -> ");\r
+               \r
+               add.addSelectionListener(new SelectionListenerImpl<ResourceArray>(context) {\r
+\r
+            List<Resource> enumerationResources;\r
+\r
+            @Override\r
+            public void beforeApply() { \r
+                enumerationResources = getSelectedResources(availableEnumerationsExplorer);\r
+            }\r
+\r
+                       @Override\r
+                       public void apply(WriteGraph graph, ResourceArray input)\r
+                                       throws DatabaseException {\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               for(Resource r : input.resources) {\r
+                                   Resource arrayIndexes = graph.getPossibleObject(r, sr.Variable_arrayIndexesList);\r
+                                   StringBuilder sb = new StringBuilder();\r
+                                   sb.append("Added new enumeration(s) ");\r
+                                   if(arrayIndexes == null) {\r
+                                       arrayIndexes = ListUtils.create(graph, enumerationResources);\r
+                                       graph.claim(r, sr.Variable_arrayIndexesList, arrayIndexes);\r
+                                       sb.append(enumerationResources.toString() + " ");\r
+                                   } else {\r
+                                       ArrayList<Resource> filtered = new ArrayList<Resource>();\r
+                                       for(Resource enumeration : enumerationResources) {\r
+                                           if(ListUtils.getNode(graph, arrayIndexes, enumeration) == null) {\r
+                                               filtered.add(enumeration);\r
+                                               sb.append(graph.getPossibleRelatedValue2(enumeration, Layer0.getInstance(graph).HasName, Bindings.STRING) + " ");\r
+                                           }\r
+                                       }\r
+                                       if (filtered.isEmpty())\r
+                                           return;\r
+                                       ListUtils.insertBack(graph, arrayIndexes, filtered);\r
+                                   }\r
+                    sb.append("to " + graph.getPossibleRelatedValue2(r, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+                    Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                    updateUsedButtons(graph, arrayIndexes);\r
+                               }\r
+                       }\r
+               });\r
+               \r
+               Composite used = new Composite(body, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().applyTo(used);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(used);\r
+               usedEnumerationsLabel = new org.simantics.browsing.ui.swt.widgets.Label(used, buttonSupport, SWT.None);\r
+               usedEnumerationsLabel.setTextFactory(new ReadFactoryImpl<ResourceArray, String>() {\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, ResourceArray input) throws DatabaseException {\r
+                if(input.size() < 2)\r
+                    return "Used Enumerations";\r
+                else {\r
+                    StringBuilder sb = new StringBuilder();\r
+                    sb.append("Enumerations in: ");\r
+                    boolean first = true;\r
+                    for(Resource r : input) {\r
+                        if(!first)\r
+                            sb.append(", ");\r
+                        first = false;\r
+                        \r
+                        String name = NameUtils.getSafeName(graph, r);\r
+                        sb.append(name);\r
+                    }\r
+                    return sb.toString();\r
+                }\r
+            }\r
+\r
+        });\r
+               \r
+               usedEnumerationsExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, used, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);\r
+               \r
+               usedEnumerationsExplorer\r
+               .setBrowseContexts(SysdynResource.URIs.UsedVariableIndexes);\r
+               usedEnumerationsExplorer.setColumns(ColumnKeys.ENUMERATION_TABLE_COLUMNS);\r
+               usedEnumerationsExplorer.setInputSource(new SingleSelectionInputSource(\r
+                               ResourceArray.class));\r
+\r
+               usedEnumerationsExplorer.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               usedEnumerationsExplorer);\r
+               \r
+               Control c2 = usedEnumerationsExplorer.getExplorerControl();\r
+               if (c2 instanceof Tree)\r
+                       ((Tree) c2).setLinesVisible(true);\r
+               \r
+               Composite buttons = new Composite(body, SWT.None);\r
+               GridLayoutFactory.fillDefaults().applyTo(buttons);\r
+               \r
+               up = new Button(buttons, buttonSupport, SWT.NONE);\r
+               up.setText("Up");\r
+               up.addSelectionListener(new SelectionListenerImpl<ResourceArray>(context) {\r
+\r
+            List<Integer> selectedIndexes;\r
+\r
+                   @Override\r
+                   public void beforeApply() {\r
+                selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer);\r
+                   }\r
+\r
+                   @Override\r
+                   public void apply(WriteGraph graph, ResourceArray input)\r
+                           throws DatabaseException {\r
+                       \r
+                       Layer0 L0 = Layer0.getInstance(graph);\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                for(Resource variable : input) {\r
+                    Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+                    if(arrayIndexes != null) {\r
+                        List<Resource> enumerations = ListUtils.toList(graph, arrayIndexes);\r
+                        List<Resource> toBeMoved = new ArrayList<Resource>();\r
+                        StringBuilder sb = new StringBuilder();\r
+                        sb.append("Moved enumeration(s) ");\r
+                        for(Integer index : selectedIndexes) {\r
+                            if(index < enumerations.size()) {\r
+                                Resource enumeration = enumerations.get(index);\r
+                                toBeMoved.add(enumeration);\r
+                            }\r
+\r
+                        }\r
+                        boolean moved = false;\r
+                        for(Resource enumeration : toBeMoved) {\r
+                            Resource node = ListUtils.getNode(graph, arrayIndexes, enumeration);\r
+                            Resource prev = graph.getSingleObject(node, L0.List_Previous);\r
+                            if(!arrayIndexes.equals(prev) && !toBeMoved.contains(graph.getPossibleObject(prev, L0.List_Element))) {\r
+                                sb.append(graph.getPossibleRelatedValue2(enumeration, Layer0.getInstance(graph).HasName, Bindings.STRING) + " ");\r
+                                moved = ListUtils.swapWithPrevious(graph, arrayIndexes, enumeration);\r
+                            }\r
+                        }\r
+                        if (moved) {\r
+                            sb.append("up");\r
+                            Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                        }\r
+\r
+                    }\r
+                }\r
+                \r
+                // Move selection\r
+                usedEnumerationsExplorer.getDisplay().asyncExec(new RunnableWithObject(usedEnumerationsExplorer, selectedIndexes) {\r
+                    @Override\r
+                    public void run() {\r
+                        Control c = ((GraphExplorerComposite)object).getExplorerControl();\r
+                        if(c != null && c instanceof Tree && object2 instanceof List<?>) {\r
+                            Tree tree = (Tree) c;\r
+                            tree.deselectAll();\r
+                            \r
+                            @SuppressWarnings("unchecked")\r
+                            List<Integer> list = (List<Integer>) object2;\r
+                            Set<TreeItem> selection = new HashSet<TreeItem>();\r
+                            for(Integer i : list) {\r
+                                TreeItem item = null;\r
+                                if(i - 1 >= 0)\r
+                                    item = tree.getItem(i - 1);\r
+                                if(item == null || selection.contains(item))\r
+                                    item = tree.getItem(i);\r
+                                if(item != null && !selection.contains(item))\r
+                                    selection.add(item);\r
+                            }\r
+                            tree.setSelection(selection.toArray(new TreeItem[selection.size()]));\r
+                        }\r
+                    }\r
+                });\r
+                   }\r
+               });\r
+\r
+               down = new Button(buttons, buttonSupport, SWT.NONE);\r
+               down.setText("Down");\r
+               down.addSelectionListener(new SelectionListenerImpl<ResourceArray>(context) {\r
+\r
+                   List<Integer> selectedIndexes;\r
+\r
+                   @Override\r
+                   public void beforeApply() {\r
+                       selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer);\r
+                   }\r
+\r
+\r
+                   @Override\r
+                   public void apply(WriteGraph graph, ResourceArray input)\r
+                           throws DatabaseException {\r
+\r
+                       Layer0 L0 = Layer0.getInstance(graph);\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                       for(Resource variable : input) {\r
+                           Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+                           if(arrayIndexes != null) {\r
+                               List<Resource> enumerations = ListUtils.toList(graph, arrayIndexes);\r
+                               List<Resource> toBeMoved = new ArrayList<Resource>();\r
+                               StringBuilder sb = new StringBuilder();\r
+                               sb.append("Moved enumeration(s) ");\r
+                               for(Integer index : selectedIndexes) {\r
+                                   if(index < enumerations.size()) {\r
+                                       Resource enumeration = enumerations.get(index);\r
+                                       toBeMoved.add(0, enumeration); // Make an inverted list. \r
+                                   }\r
+                               }\r
+                               boolean moved = false;\r
+                               for(Resource enumeration : toBeMoved) {\r
+                            Resource node = ListUtils.getNode(graph, arrayIndexes, enumeration);\r
+                            Resource next = graph.getSingleObject(node, L0.List_Next);\r
+                            \r
+                            if(!arrayIndexes.equals(next) && !toBeMoved.contains(graph.getPossibleObject(next, L0.List_Element))) {\r
+                                sb.append(graph.getPossibleRelatedValue2(enumeration, Layer0.getInstance(graph).HasName, Bindings.STRING) + " ");\r
+                                moved = ListUtils.swapWithNext(graph, arrayIndexes, enumeration);\r
+                                   }\r
+                               }\r
+                        if (moved) {\r
+                            sb.append("down");\r
+                            Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                        }\r
+                           }\r
+                       }\r
+                       \r
+                       // Move selection\r
+                       usedEnumerationsExplorer.getDisplay().asyncExec(new RunnableWithObject(usedEnumerationsExplorer, selectedIndexes) {\r
+                    @Override\r
+                           public void run() {\r
+                               Control c = ((GraphExplorerComposite)object).getExplorerControl();\r
+                               if(c != null && c instanceof Tree && object2 instanceof List<?>) {\r
+                                   Tree tree = (Tree) c;\r
+                                   tree.deselectAll();\r
+                                   \r
+                                   @SuppressWarnings("unchecked")\r
+                            List<Integer> list = (List<Integer>) object2;\r
+                                   Set<TreeItem> selection = new HashSet<TreeItem>();\r
+                                   Collections.reverse(list);\r
+                            for(Integer i : list) {\r
+                                TreeItem item = null;\r
+                                if(i + 1 < tree.getItemCount())\r
+                                    item = tree.getItem(i + 1);\r
+                                if(item == null || selection.contains(item))\r
+                                    item = tree.getItem(i);\r
+                                if(item != null && !selection.contains(item))\r
+                                    selection.add(item);\r
+                            }\r
+                                   tree.setSelection(selection.toArray(new TreeItem[selection.size()]));\r
+                               }\r
+                           }\r
+                       });\r
+                   }\r
+               });\r
+\r
+               \r
+               remove = new Button(buttons, buttonSupport, SWT.NONE);\r
+               remove.setText("Remove");\r
+               remove.addSelectionListener(new SelectionListenerImpl<ResourceArray>(context) {\r
+                   \r
+                   List<Integer> selectedIndexes;\r
+\r
+                   @Override\r
+                   public void beforeApply() {\r
+                       selectedIndexes = getSelectedIndexes(usedEnumerationsExplorer);\r
+                   }\r
+\r
+                   @Override\r
+                   public void apply(WriteGraph graph, ResourceArray input)\r
+                           throws DatabaseException {\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                       for(Resource variable : input) {\r
+                           Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+                           if(arrayIndexes != null) {\r
+                               List<Resource> enumerations = ListUtils.toList(graph, arrayIndexes);\r
+                               List<Resource> toBeRemoved = new ArrayList<Resource>();\r
+                               for(Integer index : selectedIndexes) {\r
+                               if(index < enumerations.size()) {\r
+                                   Resource enumeration = enumerations.get(index);\r
+                                   toBeRemoved.add(enumeration);\r
+                               }\r
+\r
+                               }\r
+                               StringBuilder sb = new StringBuilder();\r
+                               sb.append("Removed enumeration(s) ");\r
+                               for(Resource enumeration : toBeRemoved) {\r
+                                   ListUtils.removeElement(graph, arrayIndexes, enumeration);\r
+                                   sb.append(graph.getPossibleRelatedValue2(enumeration, Layer0.getInstance(graph).HasName, Bindings.STRING) + " ");\r
+                               }\r
+                               sb.append("from " + graph.getPossibleRelatedValue2(variable, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+                               Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                               updateUsedButtons(graph, arrayIndexes);\r
+                           }\r
+                       }\r
+                   }\r
+               });\r
+       }\r
+\r
+       \r
+    protected void updateUsedButtons(ReadGraph graph, Resource arrayIndexes) {\r
+        boolean enabled = false;\r
+        if (arrayIndexes == null)\r
+            enabled = false;\r
+        else {\r
+            try {\r
+                List<Resource> currEnumerations = ListUtils.toList(graph, arrayIndexes);\r
+                if (!currEnumerations.isEmpty()) {\r
+                    enabled = true;\r
+                }\r
+            } catch (DatabaseException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+        final boolean finalEnabled = enabled;\r
+        SWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+            \r
+            @Override\r
+            public void run() {\r
+                if (!up.getControl().isDisposed())\r
+                    up.getControl().setEnabled(finalEnabled);\r
+                if (!down.getControl().isDisposed())\r
+                    down.getControl().setEnabled(finalEnabled);\r
+                if (!remove.getControl().isDisposed())\r
+                    remove.getControl().setEnabled(finalEnabled);     \r
+            }\r
+        });\r
+    }\r
+\r
+\r
+       private List<Resource> getSelectedResources(GraphExplorerComposite explorer) {\r
+               List<Resource> result = new ArrayList<Resource>();\r
+               \r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return result;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               @SuppressWarnings("unchecked")\r
+               List<AdaptableHintContext> selections = iss.toList();\r
+               for(AdaptableHintContext ahc : selections) {\r
+                       Resource resource = (Resource) ahc.getAdapter(Resource.class);\r
+                       result.add(resource);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+          private List<Integer> getSelectedIndexes(final GraphExplorerComposite explorer) {\r
+               final List<Integer> result = new ArrayList<Integer>();\r
+\r
+               explorer.getDisplay().syncExec(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    Control c = explorer.getExplorerControl();\r
+                    if (c instanceof Tree) {\r
+                        Tree tree = (Tree) c;\r
+                        TreeItem[] selection = tree.getSelection();\r
+                        \r
+                        for(TreeItem item : selection) {\r
+                            result.add(tree.indexOf(item));\r
+                        }\r
+                    }\r
+                }\r
+               });\r
+\r
+               return result;\r
+           }\r
+\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+           \r
+        if(input != null && input instanceof IStructuredSelection) {\r
+            Object first = ((IStructuredSelection)input).getFirstElement();\r
+            ResourceArray resourceArray = null;\r
+            if(first instanceof Resource)\r
+                resourceArray = new ResourceArray((Resource)first);\r
+            else if( first instanceof Collection<?>)\r
+                resourceArray = new ResourceArray(((Collection<?>)first).toArray(new Resource[((Collection<?>)first).size()]));\r
+            final ResourceArray finalResourceArray = resourceArray;\r
+            if(resourceArray != null) {\r
+                StructuredSelection selection = new StructuredSelection(finalResourceArray);\r
+                availableEnumerationsExplorer.setInput(context, selection);\r
+                usedEnumerationsExplorer.setInput(context, selection);    \r
+                buttonSupport.fireInput(context, selection);\r
+                \r
+                try {\r
+                    context.getSession().syncRequest(new ReadRequest() {\r
+                        \r
+                        @Override\r
+                        public void run(ReadGraph graph) throws DatabaseException {\r
+                            Resource r = finalResourceArray.resources[0];\r
+                            Resource arrayIndexes = graph.getPossibleObject(r, SysdynResource.getInstance(graph).Variable_arrayIndexesList);\r
+                            updateUsedButtons(graph, arrayIndexes);\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/CommentTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/CommentTab.java
new file mode 100644 (file)
index 0000000..cc4838c
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\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.custom.ScrolledComposite;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\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.management.ISessionContext;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+\r
+/**\r
+ * Tab for editing diagram comments\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class CommentTab extends LabelPropertyTabContributor {\r
+\r
+       public CommentTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    @Override\r
+       public String getPartName(ISelection forSelection) {\r
+               return "Comment";\r
+       }\r
+        \r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+        ScrolledComposite sc = new ScrolledComposite(body,  SWT.H_SCROLL | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().applyTo(sc);\r
+        \r
+        Composite composite = new Composite(sc, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+        \r
+        // FIXME: Currently needs Ctrl+Enter to accept changes. Change so that the syntax is common in all sysdyn\r
+        TrackedText text = new TrackedText(composite, support, SWT.BORDER | SWT.WRAP | SWT.MULTI);\r
+        text.setTextFactory(new StringPropertyFactory(DiagramResource.URIs.HasText));\r
+        text.addModifyListener(new StringPropertyModifier(context, DiagramResource.URIs.HasText));\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).hint(200, SWT.DEFAULT).applyTo(text.getWidget());\r
+\r
+        // Scrolled composite settings\r
+        sc.setContent(composite);\r
+        sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+        sc.setExpandHorizontal(true);\r
+        sc.setExpandVertical(true);        \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..36e3fa1
--- /dev/null
@@ -0,0 +1,387 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\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.custom.ScrolledComposite;\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.widgets.Button;\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.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.PossibleObjectWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.issues.ontology.IssueResource;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.EquivalentUnitsWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.ComboStringPropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.ModelNameInputValidator;\r
+\r
+/**\r
+ * Tab displaying configuration properties. Displayed for model and configuration.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ConfigurationTab extends AdjustableTab {\r
+\r
+       public ConfigurationTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    private ScrolledComposite sc;\r
+       private Label nameLabel, startTimeLabel, stopTimeLabel, stepLengthLabel, \r
+               outputIntervalLabel, methodLabel, toleranceLabel, variableFilterLabel;\r
+       private TrackedText name, startTime, stopTime, stepLength, outputInterval, tolerance, variableFilter;\r
+       private TrackedCombo method, timeUnit;\r
+       private Button validateUnits;\r
+       private EquivalentUnitsWidget equivalentUnitsWidget;\r
+    /**\r
+     * Modifier for modifying model labels\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+       private class ModelLabelModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+               public ModelLabelModifier(ISessionContext context, String propertyURI) {\r
+               }\r
+               \r
+       @Override\r
+       public void applyText(WriteGraph graph, Resource issue, String text) throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+            graph.claimLiteral(issue, l0.HasLabel, text);\r
+            String safeName = NameUtils.findFreshName(graph, text, graph.getSingleObject(issue, l0.PartOf), l0.ConsistsOf, "%s%d");\r
+            graph.claimLiteral(issue, l0.HasName, safeName);\r
+       }\r
+               \r
+       }\r
+    \r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               sc = new ScrolledComposite(body,  SWT.H_SCROLL | SWT.V_SCROLL);\r
+               composite = new Composite(sc, SWT.NONE);\r
+        sc.setContent(composite);\r
+        \r
+        nameLabel = new Label(composite, SWT.NONE);\r
+        nameLabel.setText("Name");\r
+        \r
+        name = new TrackedText(composite, support, SWT.BORDER);\r
+        name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel));\r
+        name.addModifyListener(new ModelLabelModifier(context, Layer0.URIs.HasLabel));\r
+        name.setInputValidator(new ModelNameInputValidator(support));\r
+\r
+        startTimeLabel = new Label(composite, SWT.NONE);\r
+        startTimeLabel.setText("Start time");\r
+\r
+        startTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+        startTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_startTime));\r
+        startTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_startTime));\r
+        startTime.setInputValidator(new DoubleValidator());\r
+\r
+        stopTimeLabel = new Label(composite, SWT.NONE);\r
+        stopTimeLabel.setText("Stop time");\r
+\r
+        stopTime = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+        stopTime.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_stopTime));\r
+        stopTime.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_stopTime));\r
+        stopTime.setInputValidator(new DoubleValidator());\r
+\r
+        stepLengthLabel = new Label(composite, SWT.NONE);\r
+        stepLengthLabel.setText("Step length\n(empty = default)");\r
+\r
+        stepLength = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+        stepLength.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_simulationStepLength));\r
+        stepLength.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_simulationStepLength));\r
+        stepLength.setInputValidator(new DoubleValidator());\r
+\r
+        outputIntervalLabel = new Label(composite, SWT.NONE);\r
+        outputIntervalLabel.setText("Output interval\n(empty = all steps)");\r
+        outputIntervalLabel.setAlignment(SWT.RIGHT);\r
+\r
+        outputInterval = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+        outputInterval.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_outputInterval));\r
+        outputInterval.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_outputInterval));\r
+        outputInterval.setInputValidator(new DoubleValidator());\r
+\r
+        methodLabel = new Label(composite, SWT.NONE);\r
+        methodLabel.setText("Method");\r
+        \r
+        method = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+        method.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
+                map.put("euler", "euler");\r
+                map.put("rungekutta", "rungekutta");\r
+                map.put("dassl", "dassl");\r
+                map.put("inline-euler", "inline-euler");\r
+                map.put("inline-rungekutta", "inline-rungekutta");\r
+                map.put("dasslwort", "dasslwort");\r
+                map.put("dasslSymJac", "dasslSymJac");\r
+                map.put("dasslNumJac", "dasslNumJac");\r
+                map.put("dasslColorSymJac", "dasslColorSymJac");\r
+                map.put("dasslInternalNumJac", "dasslInternalNumJac");\r
+                map.put("qss", "qss");\r
+                return map;\r
+            }\r
+        });\r
+        \r
+        method.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                String s = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).SysdynModel_solver);\r
+                return s != null ? s : "";\r
+            }\r
+        });\r
+        \r
+        method.addModifyListener(new ComboStringPropertyModifier<Resource>() {\r
+\r
+                       @Override\r
+                       public void applyText(WriteGraph graph, Resource input, String text)\r
+                                       throws DatabaseException {\r
+                               graph.claimLiteral(input, SysdynResource.getInstance(graph).SysdynModel_solver, text);\r
+                       }\r
+               });\r
+        \r
+        validateUnits = new Button(composite, support, SWT.CHECK);\r
+        validateUnits.setText("Validate units");\r
+        validateUnits.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource model) throws DatabaseException {\r
+                Resource unitIssueSource = graph.syncRequest(\r
+                        new PossibleObjectWithType(model, \r
+                                Layer0X.getInstance(graph).Activates, \r
+                                SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource));\r
+                if(unitIssueSource == null)\r
+                    return false;\r
+                \r
+                Boolean result = graph.getPossibleRelatedValue(unitIssueSource, IssueResource.getInstance(graph).IssueSource_active, Bindings.BOOLEAN);\r
+                return Boolean.TRUE.equals(result);\r
+            }\r
+        });\r
+        \r
+        validateUnits.addSelectionListener(new SelectionListenerImpl<Resource>(context){\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource model) throws DatabaseException {\r
+                Resource unitIssueSource = graph.syncRequest(\r
+                        new PossibleObjectWithType(model, \r
+                                Layer0X.getInstance(graph).Activates, \r
+                                SysdynResource.getInstance(graph).Validations_Units_UnitIssueSource));\r
+                IssueResource ISSUE = IssueResource.getInstance(graph);\r
+                Boolean result = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN);\r
+                if(result == null)\r
+                    result = false;\r
+                graph.claimLiteral(unitIssueSource, ISSUE.IssueSource_active, Boolean.FALSE.equals(result));\r
+                \r
+                // Enable or disable the Unit Equivalents button based if\r
+                // unit validation is enabled or not.\r
+                final boolean enabled = !result;\r
+                if (!equivalentUnitsWidget.getWidget().isDisposed())\r
+                       equivalentUnitsWidget.getWidget().getDisplay().asyncExec(new Runnable() {\r
+                                               \r
+                                               @Override\r
+                                               public void run() {\r
+                                                       if(!equivalentUnitsWidget.getWidget().isDisposed())\r
+                                                               equivalentUnitsWidget.getWidget().setEnabled(enabled);\r
+                                               }\r
+                                       });\r
+\r
+            }\r
+            \r
+        });\r
+        \r
+        timeUnit = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+        timeUnit.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
+                map.put("year", "year");\r
+                map.put("month", "month");\r
+                map.put("week", "week");\r
+                map.put("day", "day");\r
+                map.put("hour", "hour");\r
+                map.put("min", "min");\r
+                map.put("s", "s");\r
+                return map;\r
+            }\r
+        });\r
+        \r
+        timeUnit.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                String s = graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).SysdynModel_timeUnit);\r
+                return s != null ? s : "month";\r
+            }\r
+        });\r
+        \r
+        timeUnit.addModifyListener(new ComboStringPropertyModifier<Resource>() {\r
+\r
+            @Override\r
+            public void applyText(WriteGraph graph, Resource input, String text)\r
+                    throws DatabaseException {\r
+                graph.claimLiteral(input, SysdynResource.getInstance(graph).SysdynModel_timeUnit, text);\r
+                Layer0Utils.addCommentMetadata(graph, "Modified " + graph.getRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING) + " time unit to " + text);\r
+            }\r
+        });\r
+        \r
+        equivalentUnitsWidget = new EquivalentUnitsWidget(composite, support, SWT.NONE);\r
+        \r
+        toleranceLabel = new Label(composite, SWT.NONE);\r
+        toleranceLabel.setText("Tolerance");\r
+\r
+        tolerance = new TrackedText(composite, support, SWT.BORDER | SWT.RIGHT);\r
+        tolerance.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.SysdynModel_tolerance));\r
+        tolerance.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.SysdynModel_tolerance));\r
+        tolerance.setInputValidator(new DoubleValidator());\r
+        \r
+        variableFilterLabel = new Label(composite, SWT.NONE);\r
+        variableFilterLabel.setText("Variable filter");\r
+        variableFilterLabel.setToolTipText("Variable filter as regular expression.\n" +\r
+                       "To include variables Auxiliary1, Auxiliary2 and Auxiliary3: \n" +\r
+                       "Auxiliary[1-3]\n" +\r
+                       "or\n" +\r
+                       "Auxiliary1|Auxiliary2|Auxiliary3\n" +\r
+                       "NOTE: whitespace must be replaced with an underscore ('_') character" +\r
+                       "e.g. 'Growth Rate' -> 'Growth_Rate'");\r
+\r
+        variableFilter = new TrackedText(composite, support, SWT.BORDER);\r
+        variableFilter.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SysdynModel_variableFilter, ""));\r
+        variableFilter.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.SysdynModel_variableFilter));\r
+        variableFilter.getWidget().setToolTipText("Variable filter as regular expression.\n" +\r
+                "To include variables Auxiliary1, Auxiliary2 and Auxiliary3: \n" +\r
+                "Auxiliary[1-3]\n" +\r
+                "or\n" +\r
+                "Auxiliary1|Auxiliary2|Auxiliary3\n" +\r
+                       "NOTE: whitespace must be replaced with an underscore ('_') character" +\r
+                       "e.g. 'Growth Rate' -> 'Growth_Rate'");\r
+        \r
+        sc.setExpandHorizontal(true);\r
+        sc.setExpandVertical(true);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().applyTo(sc);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(nameLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(name.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(startTimeLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(startTime.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(stopTimeLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stopTime.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(stepLengthLabel);\r
+        stepLengthLabel.setAlignment(SWT.LEFT);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stepLength.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(outputIntervalLabel);\r
+        outputIntervalLabel.setAlignment(SWT.LEFT);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(outputInterval.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(methodLabel);\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(validateUnits.getWidget());\r
+        GridDataFactory.fillDefaults().span(2, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(equivalentUnitsWidget.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(toleranceLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(tolerance.getWidget());\r
+        GridDataFactory.fillDefaults().span(2, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(variableFilterLabel);\r
+        GridDataFactory.fillDefaults().span(2, 1).grab(true, false).hint(100, SWT.DEFAULT).applyTo(variableFilter.getWidget());\r
+        \r
+        sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().applyTo(sc);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(wideScreen ? 13 : 6).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(nameLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 12 : 5, 1).hint(200, SWT.DEFAULT).applyTo(name.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(startTimeLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(startTime.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(stopTimeLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stopTime.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(stepLengthLabel);\r
+        stepLengthLabel.setAlignment(SWT.RIGHT);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(stepLength.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(outputIntervalLabel);\r
+        outputIntervalLabel.setAlignment(SWT.RIGHT);\r
+        GridDataFactory.fillDefaults().grab(true, false).hint(50, SWT.DEFAULT).applyTo(outputInterval.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(methodLabel);\r
+        GridDataFactory.fillDefaults().span(wideScreen ? 1 : 3, 1).align(SWT.BEGINNING, SWT.CENTER).applyTo(method.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(validateUnits.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(timeUnit.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.CENTER).applyTo(equivalentUnitsWidget.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(toleranceLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 1 : 2, 1).hint(60, SWT.DEFAULT).applyTo(tolerance.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(variableFilterLabel);\r
+        GridDataFactory.fillDefaults().grab(true, false).span(wideScreen ? 10 : 5, 1).hint(200, SWT.DEFAULT).applyTo(variableFilter.getWidget());\r
+        \r
+        sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\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/DependencyTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/DependencyTab.java
new file mode 100644 (file)
index 0000000..666d100
--- /dev/null
@@ -0,0 +1,328 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.Scale;\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.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.util.ObjectUtils;\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.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.connections.DependencyEdgeClass;\r
+import org.simantics.sysdyn.ui.elements.connections.DependencyNode;\r
+import org.simantics.sysdyn.ui.properties.widgets.ArrowHeadWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.DelayMarkWidget;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+/**\r
+ * Tab displaying dependency properties.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class DependencyTab  extends AdjustableTab {\r
+\r
+    public DependencyTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    Button none, plus, minus, other, inside, outside;\r
+    TrackedText polarityText, polarityLocationText;\r
+    Scale lineThicknessScale;\r
+    private DelayMarkWidget delayMark;\r
+    private ArrowHeadWidget arrowhead;\r
+       private Group polarityGroup;\r
+       private Group locationGroup;\r
+       private Composite misc;\r
+       private Group lineThicknessGroup;\r
+    \r
+    class LineThicknessSelectionListener extends SelectionListenerImpl<Resource> {\r
+       Scale scale;\r
+               private int selection;\r
+\r
+        public LineThicknessSelectionListener(ISessionContext context, Scale scale) {\r
+               super(context);\r
+               this.scale = scale;\r
+        }\r
+        \r
+        @Override\r
+        public void beforeApply() {\r
+            this.selection = scale.getWidget().getSelection();\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            float width = ((float)selection) / 10.0f;\r
+            graph.claimLiteral(connectionElement, sr.DependencyConnection_strokeWidth, width);\r
+            Layer0Utils.addCommentMetadata(graph, "Modified Line thickness for connection " + graph.getPossibleRelatedValue2(connectionElement, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to " + width);\r
+        }\r
+        \r
+    }\r
+    \r
+    class LineThicknessRadioSelectionFactory extends ReadFactoryImpl<Resource, Integer> {\r
+\r
+        public LineThicknessRadioSelectionFactory() {\r
+        }\r
+\r
+        @Override\r
+        public Integer perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            Float width = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_strokeWidth, Bindings.FLOAT);  \r
+            if(width == null)\r
+                return (int)Math.round(DependencyEdgeClass.DEFAULT_STROKE_WIDTH * 10);\r
+            else\r
+                return (int)Math.round(width * 10);\r
+        }\r
+    }\r
+    \r
+    class PolarityLocationSelectionListener extends SelectionListenerImpl<Resource> {\r
+        private String location;\r
+\r
+        public PolarityLocationSelectionListener(ISessionContext context, String location) {\r
+            super(context);\r
+            this.location = location;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String currentLocation = graph.getPossibleRelatedValue2(connectionElement, sr.DependencyConnection_polarityLocation, Bindings.STRING);\r
+            if (currentLocation != null && currentLocation.equals(location))\r
+                return;\r
+            graph.claimLiteral(connectionElement, sr.DependencyConnection_polarityLocation, location);\r
+            Layer0Utils.addCommentMetadata(graph, "Modified Location for connection " + graph.getPossibleRelatedValue2(connectionElement, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to " + location);\r
+        }\r
+    }\r
+    \r
+    class PolarityLocationRadioSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        private String location;\r
+\r
+        public PolarityLocationRadioSelectionFactory(String location) {\r
+            this.location = location;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, location, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String location = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarityLocation, Bindings.STRING);  \r
+            if(DependencyNode.OUTSIDE.equals(this.location)) {\r
+                return ObjectUtils.objectEquals(this.location, location);\r
+            } else {\r
+                if(location == null)\r
+                    return true;\r
+                else\r
+                    return ObjectUtils.objectEquals(this.location, location);\r
+            }\r
+        }\r
+    }\r
+    \r
+    class PolaritySelectionListener extends SelectionListenerImpl<Resource> {\r
+        private String polarity;\r
+\r
+        public PolaritySelectionListener(ISessionContext context, String polarity) {\r
+            super(context);\r
+            this.polarity = polarity;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String currentPolarity = graph.getPossibleRelatedValue2(connectionElement, sr.DependencyConnection_polarity, Bindings.STRING);\r
+            if (currentPolarity != null && currentPolarity.equals(polarity))\r
+                return;\r
+            graph.claimLiteral(connectionElement, sr.DependencyConnection_polarity, polarity.trim());\r
+            Layer0Utils.addCommentMetadata(graph, "Modified Polarity for connection " + graph.getPossibleRelatedValue2(connectionElement, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to " + polarity.trim());\r
+        }\r
+        \r
+    }\r
+    \r
+    class PolarityRadioSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        private String polarity;\r
+\r
+        public PolarityRadioSelectionFactory(String polarity) {\r
+            this.polarity = polarity;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, polarity, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String polarity = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarity, Bindings.STRING);     \r
+            if(polarity == null && this.polarity.equals(""))\r
+                return true;\r
+            return ObjectUtils.objectEquals(polarity, this.polarity);\r
+        }\r
+    }\r
+    \r
+    class OtherPolaritySelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+\r
+        String[] limits;\r
+        \r
+        public OtherPolaritySelectionFactory(String[] limits) {\r
+            this.limits = limits;\r
+        }\r
+        \r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Pair<Object, Class<?>>(inputContents, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String polarity = graph.getPossibleRelatedValue(dependencyConnection, sr.DependencyConnection_polarity, Bindings.STRING);\r
+            for(String s : limits) {\r
+                if(ObjectUtils.objectEquals(polarity, s))\r
+                    return false;\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+\r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               composite = new Composite(body, SWT.NONE);\r
+        \r
+        polarityGroup = new Group(composite, SWT.NONE);\r
+        polarityGroup.setText("Polarity");\r
+        \r
+        none = new Button(polarityGroup, support, SWT.RADIO);\r
+        none.setText("None");\r
+        none.setSelectionFactory(new PolarityRadioSelectionFactory(""));\r
+        none.addSelectionListener(new PolaritySelectionListener(context, ""));\r
+        \r
+        plus = new Button(polarityGroup, support, SWT.RADIO);\r
+        plus.setText("+");\r
+        plus.setSelectionFactory(new PolarityRadioSelectionFactory("+"));\r
+        plus.addSelectionListener(new PolaritySelectionListener(context, "+"));\r
+        \r
+        minus = new Button(polarityGroup, support, SWT.RADIO);\r
+        minus.setText("-");\r
+        minus.setSelectionFactory(new PolarityRadioSelectionFactory("-"));\r
+        minus.addSelectionListener(new PolaritySelectionListener(context, "-"));\r
+        \r
+        other = new Button(polarityGroup, support, SWT.RADIO);\r
+        other.setText("other");\r
+        other.setSelectionFactory(new OtherPolaritySelectionFactory(new String[] {null, "+", "-", ""}));\r
+        \r
+        polarityText = new TrackedText(polarityGroup, support, SWT.BORDER);\r
+        polarityText.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.DependencyConnection_polarity));\r
+        polarityText.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.DependencyConnection_polarity));\r
+        \r
+        locationGroup = new Group(composite, SWT.NONE);\r
+        locationGroup.setText("Location");\r
+        \r
+        inside = new Button(locationGroup, support, SWT.RADIO);\r
+        inside.setText("Inside");\r
+        inside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.INSIDE));\r
+        inside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.INSIDE));\r
+        \r
+        outside = new Button(locationGroup, support, SWT.RADIO);\r
+        outside.setText("Outside");\r
+        outside.setSelectionFactory(new PolarityLocationRadioSelectionFactory(DependencyNode.OUTSIDE));\r
+        outside.addSelectionListener(new PolarityLocationSelectionListener(context, DependencyNode.OUTSIDE));\r
+        \r
+        misc = new Composite(composite, SWT.NONE);\r
+        \r
+        arrowhead = new ArrowHeadWidget(misc, support, SWT.NULL);\r
+        delayMark = new DelayMarkWidget(misc, support, SWT.NULL);\r
+        \r
+        lineThicknessGroup = new Group(misc, SWT.NONE);\r
+        lineThicknessGroup.setText("Line thickness:");\r
+        lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL);\r
+        lineThicknessScale.getWidget().setMinimum(1);\r
+        lineThicknessScale.getWidget().setMaximum(15);\r
+        lineThicknessScale.getWidget().setPageIncrement(1);\r
+        lineThicknessScale.getWidget().setIncrement(1);\r
+        lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory());\r
+        lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale));\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(locationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(locationGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(misc);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(misc);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(arrowhead.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(delayMark.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(polarityGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(polarityText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(locationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(locationGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(misc);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(misc);\r
+\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(arrowhead.getWidget());\r
+        GridDataFactory.fillDefaults().align(SWT.BEGINNING, SWT.BEGINNING).applyTo(delayMark.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().span(1, 1).applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/EnumerationTab.java
new file mode 100644 (file)
index 0000000..4252b6c
--- /dev/null
@@ -0,0 +1,507 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashSet;\r
+import java.util.List;\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.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
+import org.simantics.browsing.ui.swt.widgets.Table;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.ui.properties.widgets.arrays.EnumerationIndexNode;\r
+import org.simantics.sysdyn.ui.properties.widgets.arrays.ReplaceableIndexesWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.threads.SWTThread;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class EnumerationTab extends LabelPropertyTabContributor implements Widget {\r
+\r
+       public EnumerationTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    GraphExplorerComposite indexExplorer;\r
+       \r
+       Button showAll;\r
+       Variable variable;\r
+       \r
+       Table table;\r
+\r
+    private Button add;\r
+    private Button remove;\r
+    \r
+       @Override\r
+       public void createControls(Composite body, IWorkbenchSite site,\r
+                       final ISessionContext context, WidgetSupport support) {\r
+\r
+               support.register(this);\r
+               \r
+               Composite container = new Composite(body, SWT.None);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(container);\r
+               GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(4).applyTo(container);\r
+\r
+        TrackedText nameText = new TrackedText(container, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        nameText.addModifyListener(new VariableNamePropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new VariableNameInputValidator(support));\r
+        GridDataFactory.fillDefaults().grab(true, false).span(4,1).applyTo(nameText.getWidget());\r
+        \r
+        indexExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, container, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.CHECK);\r
+               \r
+        indexExplorer.setContextMenuId("#EnumerationTabPopup");\r
+        \r
+        indexExplorer\r
+               .setBrowseContexts(SysdynResource.URIs.EnumerationIndexes);\r
+        indexExplorer.setInputSource(new SingleSelectionInputSource(\r
+                               Resource.class));\r
+        ((Tree)indexExplorer.getExplorerControl()).addListener(SWT.Selection, new Listener () {\r
+        \r
+            @Override\r
+            public void handleEvent (Event event) {\r
+                if(event.detail == SWT.CHECK) {\r
+                    final TreeItem item = (TreeItem)event.item;\r
+                    final boolean checked = item.getChecked();\r
+                    NodeContext context = (NodeContext)item.getData();\r
+                    final EnumerationIndexNode node = (EnumerationIndexNode) context.getAdapter(EnumerationIndexNode.class);\r
+                    node.setShowInChartsSelected(checked);\r
+                    \r
+                    Simantics.getSession().asyncRequest(new ReadRequest() {\r
+                                               @Override\r
+                                               public void run(ReadGraph graph) throws DatabaseException {\r
+                                                       updateModelResults(graph);\r
+                                               }\r
+                                       });\r
+                }\r
+            }\r
+        });\r
+        \r
+        \r
+        indexExplorer.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).span(4, 1).applyTo(\r
+                               indexExplorer);\r
+               \r
+               Control c = indexExplorer.getExplorerControl();\r
+               if (c instanceof Tree)\r
+                       ((Tree) c).setLinesVisible(true);\r
+\r
+\r
+               add = new Button(container, support, SWT.None);\r
+               add.setText("Add");\r
+               add.addSelectionListener(new AddEnumerationIndexListener(support));\r
+\r
+               remove = new Button(container, support, SWT.None);\r
+               remove.setText("Remove");\r
+               remove.addSelectionListener(new RemoveEnumerationIndexListener(support));\r
+               \r
+               ReplaceableIndexesWidget externalIndexes = new ReplaceableIndexesWidget(container, support, SWT.NULL);\r
+               GridDataFactory.fillDefaults().applyTo(externalIndexes.getWidget());\r
+               \r
+               showAll = new Button(container, support, SWT.CHECK);\r
+               showAll.setText("Show all in charts");\r
+               showAll.addSelectionListener(new ShowAllIndexesListener(support));\r
+               \r
+       }\r
+\r
+       private class AddEnumerationIndexListener implements SelectionListener, Widget {\r
+\r
+               Resource enumerationIndexes;\r
+\r
+               public AddEnumerationIndexListener(WidgetSupport support) {\r
+                       support.register(this);\r
+               }\r
+\r
+               @Override\r
+               public void setInput(ISessionContext context, Object input) {\r
+                       final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+                       try {\r
+                               context.getSession().syncRequest(new ReadRequest() {\r
+\r
+                                       @Override\r
+                                       public void run(ReadGraph graph) throws DatabaseException {\r
+                                               enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).Enumeration_enumerationIndexList);\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public void widgetSelected(SelectionEvent e) {\r
+                       try {\r
+                           \r
+                           currentItemCount = getCurrentItemCount();\r
+                           lastItemCount = currentItemCount;\r
+                           \r
+                               Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                           graph.markUndoPoint();\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               \r
+                                               HashSet<String> names = new HashSet<String>();\r
+                        for(Resource r : ListUtils.toList(graph, enumerationIndexes)) {\r
+                                                       names.add(NameUtils.getSafeName(graph, r));\r
+                                               }\r
+                                               \r
+                                               Resource ei = GraphUtils.create2(graph, \r
+                                                               sr.EnumerationIndex,\r
+                                                               l0.HasName, NameUtils.findFreshName(graph, "index", names, ""));\r
+                                               ArrayList<Resource> index = new ArrayList<Resource>();\r
+                                               index.add(ei);\r
+                                               ListUtils.insertBack(graph, enumerationIndexes, index);\r
+                                               \r
+                        List<Resource> list = ListUtils.toList(graph, enumerationIndexes);\r
+                        if (!list.isEmpty())\r
+                            updateRemoveButton(true);\r
+                                               \r
+                                               Layer0Utils.addCommentMetadata(graph, "Added new Enumeration Index " + NameUtils.getSafeName(graph, ei) + " to " + enumerationIndexes);\r
+                                       }\r
+                               });\r
+                               \r
+                               enableItemForRename();\r
+                               \r
+                       } catch (DatabaseException e1) {\r
+                               e1.printStackTrace();\r
+                       }\r
+\r
+               }\r
+\r
+               @Override\r
+               public void widgetDefaultSelected(SelectionEvent e) {\r
+                   System.out.println("asd");\r
+               }\r
+\r
+       }\r
+\r
+       private class RemoveEnumerationIndexListener implements SelectionListener, Widget {\r
+\r
+               Resource enumerationIndexes;\r
+\r
+               public RemoveEnumerationIndexListener(WidgetSupport support) {\r
+                       support.register(this);\r
+               }\r
+\r
+               @Override\r
+               public void setInput(ISessionContext context, Object input) {\r
+                       final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+                       try {\r
+                               context.getSession().syncRequest(new ReadRequest() {\r
+\r
+                                       @Override\r
+                                       public void run(ReadGraph graph) throws DatabaseException {\r
+                                               enumerationIndexes = graph.getSingleObject(enumeration, SysdynResource.getInstance(graph).Enumeration_enumerationIndexList);\r
+                                               List<Resource> list = ListUtils.toList(graph, enumerationIndexes);\r
+                                               if (list.isEmpty())\r
+                                                   updateRemoveButton(false);\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public void widgetSelected(SelectionEvent e) {\r
+                       ISelectionProvider selectionProvider = (ISelectionProvider)indexExplorer.getAdapter(ISelectionProvider.class);\r
+                       final IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection();\r
+\r
+                       try {\r
+                               Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                           graph.markUndoPoint();\r
+                                               for(Object o : selection.toList()) {\r
+                                                       Resource r = AdaptionUtils.adaptToSingle(o, Resource.class);\r
+                                                       if(r == null)\r
+                                                               continue;\r
+                                                       ListUtils.removeElement(graph, enumerationIndexes, r);\r
+                                               }\r
+                                               List<Resource> list = ListUtils.toList(graph, enumerationIndexes);\r
+                                               if (list.isEmpty())\r
+                                                   updateRemoveButton(false);\r
+                                               Layer0Utils.addCommentMetadata(graph, "Removed Enumeration Index " );\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e1) {\r
+                               e1.printStackTrace();\r
+                       }\r
+                       \r
+\r
+               }\r
+\r
+               @Override\r
+               public void widgetDefaultSelected(SelectionEvent e) {\r
+\r
+               }\r
+\r
+       }\r
+       \r
+       private class ShowAllIndexesListener implements SelectionListener, Widget {\r
+\r
+                       Resource enumerationIndexes;\r
+\r
+                       public ShowAllIndexesListener(WidgetSupport support) {\r
+                               support.register(this);\r
+                       }\r
+\r
+                       @Override\r
+                       public void setInput(ISessionContext context, Object input) {\r
+                               final Resource enumeration = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+                               \r
+                               context.getSession().asyncRequest(new Read<Boolean>() {\r
+\r
+                                       @Override\r
+                                       public Boolean perform(ReadGraph graph)\r
+                                                       throws DatabaseException {\r
+                                           if(!graph.hasStatement(enumeration))\r
+                                               return null;\r
+                                           \r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               enumerationIndexes = graph.getSingleObject(enumeration, sr.Enumeration_enumerationIndexList);\r
+                                               List<Resource> indexes = ListUtils.toList(graph, enumerationIndexes);\r
+                                               for(Resource index : indexes) {\r
+                                                       Boolean show = graph.getPossibleRelatedValue(index, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN);\r
+                                                       if(!Boolean.TRUE.equals(show))\r
+                                                               return false;\r
+                                               }\r
+                                               return true;\r
+                                       }\r
+                                       \r
+                               }, new org.simantics.db.procedure.Listener<Boolean>() {\r
+\r
+                                       @Override\r
+                                       public void execute(final Boolean result) {\r
+                                               showAll.getWidget().getDisplay().asyncExec(new Runnable() {\r
+\r
+                                                       @Override\r
+                                                       public void run() {\r
+                                                           if(result != null && !showAll.getWidget().isDisposed())\r
+                                                               showAll.getWidget().setSelection(result.booleanValue());\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
+                                               if(showAll == null)\r
+                                                       return true;\r
+                                               return showAll.getWidget().isDisposed();\r
+                                       }\r
+                               });\r
+                               \r
+                       }\r
+\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               final boolean selected = showAll.getWidget().getSelection();\r
+                               try {\r
+                                       Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                   graph.markUndoPoint();\r
+                                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                       List<Resource> indexes = ListUtils.toList(graph, enumerationIndexes);\r
+                                                       for(Resource index : indexes) {\r
+                                                               Boolean show = graph.getPossibleRelatedValue(index, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN);\r
+                                                               if(selected && !Boolean.TRUE.equals(show)) {\r
+                                                                       graph.claimLiteral(index, sr.EnumerationIndex_showEnumerationIndexInCharts, true, Bindings.BOOLEAN);\r
+                                                               } else if(!selected && !Boolean.FALSE.equals(show)) {\r
+                                                                       graph.claimLiteral(index, sr.EnumerationIndex_showEnumerationIndexInCharts, false, Bindings.BOOLEAN);\r
+                                                               }\r
+                                                       }\r
+                                                       Layer0Utils.addCommentMetadata(graph, "Modified Show all in charts");\r
+                                                       updateModelResults(graph);\r
+                                               }\r
+                                       });\r
+                               } catch (DatabaseException e1) {\r
+                                       e1.printStackTrace();\r
+                               }\r
+                               \r
+\r
+                       }\r
+\r
+                       @Override\r
+                       public void widgetDefaultSelected(SelectionEvent e) {\r
+\r
+                       }\r
+\r
+               }\r
+       \r
+       private void updateModelResults(ReadGraph graph) {\r
+               try {\r
+                       if(variable != null ) {\r
+                               Resource modelResource = Variables.getModel(graph, variable);\r
+                               if(modelResource != null) {\r
+                                       Resource configuration = graph.getSingleObject(\r
+                                                       modelResource, \r
+                                                       SimulationResource.getInstance(graph).HasConfiguration);\r
+                                       SysdynModel model = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration);\r
+                                       // update results in graphs\r
+                                       model.resultChanged();\r
+                               }\r
+                       }\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               variable = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+       }\r
+       \r
+       private void updateRemoveButton(final boolean enable) {\r
+           SWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+            \r
+            @Override\r
+            public void run() {\r
+                remove.getWidget().setEnabled(enable);\r
+                if (!enable)\r
+                    add.getWidget().setFocus();\r
+            }\r
+        });\r
+       }\r
+       \r
+       private int currentItemCount = 0;\r
+       private int lastItemCount = 0;\r
+       \r
+       private void enableItemForRename() {\r
+           \r
+           \r
+           \r
+           Job j = new Job("") {\r
+\r
+            @Override\r
+            protected IStatus run(IProgressMonitor monitor) {\r
+                \r
+                while (lastItemCount == currentItemCount) {\r
+                    SWTThread.getThreadAccess().syncExec(new Runnable() {\r
+\r
+                        @Override\r
+                        public void run() {\r
+                            lastItemCount = getCurrentItemCount();\r
+                        }\r
+                    });\r
+                    try {\r
+                        Thread.sleep(50);\r
+                    } catch (InterruptedException e) {\r
+                        e.printStackTrace();\r
+                    }\r
+                }\r
+                \r
+                SWTThread.getThreadAccess().syncExec(new Runnable() {\r
+                    \r
+                    @Override\r
+                    public void run() {\r
+                        Control c = indexExplorer.getExplorer().getControl();\r
+                        if (c instanceof Tree) {\r
+                            Tree tree = (Tree) c;    \r
+                            TreeItem[] items = tree.getItems();\r
+                            TreeItem lastItem = items[items.length - 1];\r
+                            tree.setSelection(lastItem);\r
+                        }\r
+                    }\r
+                });\r
+                \r
+                SWTThread.getThreadAccess().syncExec(new Runnable() {\r
+                    \r
+                    @Override\r
+                    public void run() {\r
+                        Control c = indexExplorer.getExplorer().getControl();\r
+                        if (c instanceof Tree) {\r
+                            Tree tree = (Tree) c;    \r
+                            TreeItem[] items = tree.getItems();\r
+                            TreeItem lastItem = items[items.length - 1];\r
+                            NodeContext context = (NodeContext)lastItem.getData();\r
+                            tree.setSelection(lastItem);\r
+                            indexExplorer.getExplorer().startEditing(context, ColumnKeys.SINGLE); \r
+                            tree.setSelection(lastItem);\r
+                        }\r
+                    }\r
+                });\r
+                \r
+                return Status.OK_STATUS;\r
+            }\r
+           };\r
+           j.schedule();\r
+       }\r
+       \r
+       public int getCurrentItemCount() {\r
+        Control c = indexExplorer.getExplorer().getControl();\r
+        Tree tree = (Tree) c;    \r
+        return tree.getItemCount();\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..4072c80
--- /dev/null
@@ -0,0 +1,774 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\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.viewers.StructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.VerifyEvent;\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.IWorkbenchPartReference;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.platform.PropertyPageView;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\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.SelectionListenerImpl;\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.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.AsyncReadGraph;\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.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.request.WriteResultRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.AsyncListener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionTypes.ExpressionType;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.arrays.NameAndArrayRangeModifyListener;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.DelayExpression;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionWidgetInput;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Tab for displaying equation information of a variable\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class EquationTab extends AdjustableTab implements Widget {\r
+\r
+       private TrackedCombo expressionTypeCombo, unitCombo, arrayEquationCombo;\r
+       private ShortcutTabWidget shortcutTabWidget;\r
+       private ExpressionWidget expressionWidget;\r
+       private org.eclipse.ui.IPartListener2 focusLostListener;  \r
+       private IWorkbenchSite site;\r
+       private Button deleteExpression, newExpression;\r
+       private WidgetSupportImpl support;\r
+       private ExpressionComposite expressionComposite;\r
+       private final WidgetSupportImpl expressionSupport = new WidgetSupportImpl();\r
+       private Composite nameComposite;\r
+       private Composite TypeAndUnit;\r
+       private Label typeLabel;\r
+       private Label unitLabel;\r
+       private IsOutputWidget isOutput;\r
+\r
+       public EquationTab(Object input) {\r
+           super(input);\r
+    }\r
+\r
+    @Override\r
+       public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport _support) {\r
+               _support.register(this);\r
+               setSupport();\r
+               this.site = site;\r
+               super.createControls(body, site, context, _support);\r
+       }\r
+       \r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+               GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+\r
+               GridLayoutFactory.fillDefaults().numColumns(wideScreen ? 4 : 3).applyTo(nameComposite);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(nameComposite);\r
+\r
+               GridDataFactory.fillDefaults().grab(true, false).hint(280, SWT.DEFAULT).applyTo(arrayEquationCombo.getWidget());\r
+               GridDataFactory.fillDefaults().applyTo(deleteExpression.getWidget());\r
+               GridDataFactory.fillDefaults().applyTo(newExpression.getWidget());\r
+\r
+               GridDataFactory.fillDefaults().span(1, wideScreen ? 2 : 3).grab(false, true).hint(250, SWT.DEFAULT).applyTo(shortcutTabWidget.getWidget());\r
+\r
+               GridDataFactory.fillDefaults().span(wideScreen ? 1 : 3, 1).grab(true, false).applyTo(TypeAndUnit);\r
+               GridLayoutFactory.fillDefaults().numColumns(5).applyTo(TypeAndUnit);\r
+               GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(typeLabel);\r
+               GridDataFactory.fillDefaults().applyTo(expressionTypeCombo.getWidget());\r
+               GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(unitLabel);\r
+               GridDataFactory.fillDefaults().grab(true, false).hint(160, SWT.DEFAULT).applyTo(unitCombo.getWidget());\r
+               GridDataFactory.fillDefaults().applyTo(isOutput.getWidget());\r
+\r
+               GridDataFactory.fillDefaults().span(wideScreen ? 4 : 3, 1).grab(true, true).applyTo(expressionComposite);\r
+       }\r
+               \r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+               GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+               \r
+               GridLayoutFactory.fillDefaults().numColumns(3).applyTo(nameComposite);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(nameComposite);\r
+\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(arrayEquationCombo.getWidget());\r
+               GridDataFactory.fillDefaults().applyTo(deleteExpression.getWidget());\r
+               GridDataFactory.fillDefaults().applyTo(newExpression.getWidget());\r
+\r
+               GridDataFactory.fillDefaults().span(3, 1).applyTo(TypeAndUnit);\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(TypeAndUnit);\r
+               GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(typeLabel);\r
+               GridDataFactory.fillDefaults().applyTo(expressionTypeCombo.getWidget());\r
+               GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(unitLabel);\r
+               GridDataFactory.fillDefaults().grab(true, false).hint(160, SWT.DEFAULT).applyTo(unitCombo.getWidget());\r
+               GridDataFactory.fillDefaults().span(3, 1).align(SWT.END, SWT.CENTER).applyTo(isOutput.getWidget());\r
+\r
+               GridDataFactory.fillDefaults().span(3, 1).grab(true, true).hint(SWT.DEFAULT, 250).applyTo(expressionComposite);\r
+               \r
+               GridDataFactory.fillDefaults().span(3, 1).grab(true, true).hint(SWT.DEFAULT, 300).applyTo(shortcutTabWidget.getWidget());\r
+       }\r
+       \r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport _support) {\r
+               // Composite for the whole tab\r
+               Composite composite = new Composite(body, SWT.NONE);\r
+               this.composite = composite;\r
+               \r
+               // Composite holding name controls and controls for adding and removing expressions\r
+               nameComposite = new Composite(composite, SWT.NONE);\r
+               arrayEquationCombo =  new ArrayExpressionCombo(nameComposite, support, SWT.DROP_DOWN | SWT.BORDER);\r
+               arrayEquationCombo.setInputValidator(new VariableNameInputValidator(support));\r
+               arrayEquationCombo.addModifyListener(new NameAndArrayRangeModifyListener(support, expressionWidget, (ArrayExpressionCombo)arrayEquationCombo));\r
+               deleteExpression = new Button(nameComposite, support, SWT.NONE);\r
+               deleteExpression.setText("Delete");\r
+               newExpression = new Button(nameComposite, support, SWT.NONE);\r
+               newExpression.setText("New");\r
+                               \r
+               // Shortcut widget. Tabular widget containing tabs for functions and connected variables\r
+               shortcutTabWidget = new ShortcutTabWidget(composite, support, SWT.NONE);\r
+               \r
+               TypeAndUnit = new Composite(nameComposite, SWT.NONE);\r
+               typeLabel = new Label(TypeAndUnit, SWT.SINGLE );\r
+               typeLabel.setText("Type:");\r
+               expressionTypeCombo = new TrackedCombo(TypeAndUnit, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+               unitLabel = new Label(TypeAndUnit, SWT.SINGLE );\r
+               unitLabel.setText("Unit:");\r
+               unitCombo = new TrackedCombo(TypeAndUnit, support, SWT.DROP_DOWN | SWT.BORDER);\r
+               isOutput = new IsOutputWidget(TypeAndUnit, support, SWT.NULL);\r
+               \r
+               // The actual expression\r
+               expressionComposite = new ExpressionComposite(nameComposite, SWT.NONE);\r
+               expressionWidget = new ExpressionWidget(expressionComposite, expressionSupport, SWT.NONE);\r
+               expressionWidget.setVariableTable(shortcutTabWidget.getVariableTable());\r
+\r
+               addListeners(context);\r
+       }\r
+       \r
+       private void setSupport() {\r
+               support = new WidgetSupportImpl() {\r
+                       \r
+               @Override\r
+               public void fireInput(ISessionContext context, Object input) {\r
+                       final Variable var = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+                       if(var != null) {\r
+                               Resource r;\r
+                                       try {\r
+                                               r = context.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                                                       @Override\r
+                                                       public Resource perform(ReadGraph graph)\r
+                                                                       throws DatabaseException {\r
+                                                               return var.getRepresents(graph);\r
+                                                       }\r
+                                               });\r
+                                       input = new StructuredSelection(r);\r
+                                       } catch (DatabaseException e) {\r
+                                               e.printStackTrace();\r
+                                       }\r
+                               \r
+                       }\r
+                       \r
+                       super.fireInput(context, input);\r
+               }\r
+       };\r
+       }\r
+       \r
+       @Override\r
+       public void setInput(ISessionContext context, final Object input) {\r
+               support.fireInput(context, input);\r
+               \r
+               final Variable var = AdaptionUtils.adaptToSingle(input, Variable.class);\r
+               final Resource variable;\r
+               \r
+               // Find variable resource either from Variable var or from input\r
+               if(var != null)\r
+                       try {\r
+                               variable = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                                       @Override\r
+                                       public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                                               return var.getRepresents(graph);\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                               return;\r
+                       }\r
+               else\r
+                       variable = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+               \r
+               if(var == null && variable == null)\r
+                       return;\r
+               \r
+               \r
+               Resource expression = null;\r
+               try {\r
+                       expression = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                                       return getActiveExpression(graph, variable);\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+               // The variable has no expressions -> creating a new ordered set expressions and the active expression\r
+               if(expression == null && variable != null) {\r
+                       try {\r
+                               expression = SimanticsUI.getSession().syncRequest(new WriteResultRequest<Resource>() {\r
+\r
+                                       @Override\r
+                                       public Resource perform(WriteGraph graph)\r
+                                       throws DatabaseException {\r
+                                           if(!graph.hasStatement(variable)) {\r
+                                            /* Trying to create empty experiment for removed variable due to \r
+                                             * async setInput\r
+                                             */\r
+                                               return null; \r
+                                           }\r
+                                           \r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               Resource expressions = ListUtils.create(graph, Collections.<Resource>emptyList());\r
+                                               graph.claim(variable, sr.Variable_expressionList, expressions);\r
+                                               final Resource expression = graph.newResource();\r
+\r
+                                               if(graph.isInstanceOf(variable, sr.Auxiliary) ||\r
+                                                               graph.isInstanceOf(variable, sr.Valve)) {\r
+                                                       graph.claim(expression, l0.InstanceOf, null, sr.NormalExpression);\r
+                                                       graph.claimLiteral(expression, sr.Expression_equation, "");\r
+                                               }\r
+                                               else if(graph.isInstanceOf(variable, sr.Stock)) {\r
+                                                       graph.claim(expression, l0.InstanceOf, null, sr.StockExpression);\r
+                                                       graph.claimLiteral(expression, sr.StockExpression_initialEquation, "");\r
+                                               }\r
+                                               ArrayList<Resource> addition = new ArrayList<Resource>(1);\r
+                                               addition.add(expression);\r
+                                               ListUtils.insertBack(graph, expressions, addition);\r
+\r
+                                               graph.claim(variable, l0.ConsistsOf, expression);\r
+\r
+                                               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
+                                               final Session session = graph.getSession();\r
+                                               session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {\r
+                                                       @Override\r
+                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                               VirtualGraph runtime = graph.getService(VirtualGraph.class);\r
+                                                               session.asyncRequest(new WriteRequest(runtime) {\r
+                                                                       @Override\r
+                                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                                               if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
+                                                                                       graph.deny(variable, sr.IndependentVariable_activeExpression);\r
+                                                                               graph.claim(variable, sr.IndependentVariable_activeExpression, expression);\r
+                                                                       }\r
+                                                               }\r
+                                                               );\r
+                                                       }\r
+                                               });\r
+                                               return expression;\r
+                                       }\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+                       if(expression == null)\r
+                           return;\r
+               }\r
+\r
+               // Now the variable should have an expression\r
+               SimanticsUI.getSession().asyncRequest(new Read<Pair<Boolean, Boolean>>() {\r
+\r
+                   /**\r
+                    * Find out if user can add a new expression or delete the current expression\r
+                    */\r
+                       @Override\r
+                       public Pair<Boolean, Boolean> perform(ReadGraph graph) throws DatabaseException {\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList);\r
+                               if(expressions == null) {\r
+                                       return new Pair<Boolean, Boolean>(false, false);\r
+                               }\r
+                               List<Resource> expressionList = ListUtils.toList(graph, expressions);\r
+                               if(expressionList.isEmpty()) {\r
+                                       return new Pair<Boolean, Boolean>(false, false);\r
+                               }\r
+\r
+                               boolean canAdd = true;\r
+                               boolean canDelete = false;\r
+                               // If there are multiple expressions, one can be removed\r
+                               if(expressionList.size() > 1)\r
+                                       canDelete = true;\r
+                               String defaultRange = ArrayExpressionCombo.getDefaultRange(graph, variable);\r
+\r
+                               /* If the variable is an array variable, a range has been set to all expressions and none of\r
+                                * the ranges is the default range, an expression can be added\r
+                                */ \r
+                               for(Resource expression : expressionList) {\r
+                                       String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);\r
+                                       if(range == null || range.equals("") || range.equals(defaultRange)) {\r
+                                               canAdd = false;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               return new Pair<Boolean, Boolean>(canAdd, canDelete);\r
+                       }\r
+               }, new AsyncListener<Pair<Boolean, Boolean>>() {\r
+\r
+                       @Override\r
+                       public void execute(AsyncReadGraph graph,\r
+                                       final Pair<Boolean, Boolean> result) {\r
+                               newExpression.getWidget().getDisplay().asyncExec(new Runnable() {\r
+                                       \r
+                                       @Override\r
+                                       public void run() {\r
+                                               if(!newExpression.getWidget().isDisposed())\r
+                                                       newExpression.getWidget().setEnabled(result.first);\r
+                                               if(!deleteExpression.getWidget().isDisposed())\r
+                                                       deleteExpression.getWidget().setEnabled(result.second);                                         \r
+                                       }\r
+                               });\r
+\r
+                       }\r
+\r
+                       @Override\r
+                       public void exception(AsyncReadGraph graph, Throwable throwable) {\r
+                               throwable.printStackTrace();\r
+                       }\r
+\r
+                       @Override\r
+                       public boolean isDisposed() {\r
+                               return newExpression.getWidget().isDisposed() || deleteExpression.getWidget().isDisposed();\r
+                       }\r
+               });\r
+               \r
+        // Set input to widgets using expressionSupport\r
+               StructuredSelection ss = new StructuredSelection(new ExpressionWidgetInput(var, expression));\r
+               expressionSupport.fireInput(context, ss);\r
+       }\r
+\r
+       /**\r
+        * Adds listeners to widgets in this tab\r
+        * \r
+        * @param context ISessionContext\r
+        */\r
+       private void addListeners(ISessionContext context) {\r
+\r
+           // Validate expression fields when a dependency has been added or removed\r
+               shortcutTabWidget.addDependencyListener(new Runnable() {\r
+                       \r
+                       @Override\r
+                       public void run() {\r
+                               expressionWidget.validateFields();\r
+                       }\r
+               });\r
+               \r
+               // Deletes a selected expression\r
+               deleteExpression.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                       @Override\r
+                       public void apply(WriteGraph graph, final Resource input)\r
+                       throws DatabaseException {\r
+\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               \r
+                               // Currently active expression should be located in (Model sr.HasActiveExpression expression)\r
+                               Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression);\r
+                               if(activeExpression == null)\r
+                                       return;\r
+\r
+                Resource expressionList = graph.getPossibleObject(input, sr.Variable_expressionList);\r
+\r
+                List<Resource> list = ListUtils.toList(graph, expressionList);\r
+                if(list.size() <= 1)\r
+                                       return;\r
+\r
+                               // Get the previous expression in expression list to be activated\r
+                int index = list.indexOf(activeExpression);\r
+                \r
+                ListUtils.removeElement(graph, expressionList, activeExpression);\r
+                               graph.deny(input, l0.ConsistsOf, activeExpression);\r
+                               \r
+                               final Resource newActive = index == 0 ? list.get(1) : list.get(index - 1);\r
+\r
+                               // Set newActive as active in virtual graph\r
+                               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
+                               final Session session = graph.getSession();\r
+                               session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               VirtualGraph runtime = graph.getService(VirtualGraph.class);\r
+                                               session.asyncRequest(new WriteRequest(runtime) {\r
+                                                       @Override\r
+                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                               if(graph.hasStatement(input, sr.IndependentVariable_activeExpression))\r
+                                                                       graph.deny(input, sr.IndependentVariable_activeExpression);\r
+                                                               graph.claim(input, sr.IndependentVariable_activeExpression, newActive);\r
+                                                       }\r
+                                               }\r
+                                               );\r
+                                       }\r
+                               });\r
+                               Layer0Utils.addCommentMetadata(graph, "Deleted Expression " + activeExpression + " from " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+                       }\r
+               });\r
+\r
+               // Creates a new expression\r
+               newExpression.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                       @Override\r
+                       public void apply(WriteGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+                               Resource expressions = graph.getPossibleObject(input, sr.Variable_expressionList);\r
+                               if(expressions == null) {\r
+                                       return;\r
+                               }\r
+                               // Get the currently active expression\r
+                               Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression);\r
+                               Resource newExpression = graph.newResource();\r
+                               if(activeExpression != null) {\r
+                                   // Create a new expression based on the old expression\r
+                                       graph.claim(newExpression, l0.InstanceOf, graph.getSingleObject(activeExpression, l0.InstanceOf));\r
+                                       if(graph.isInstanceOf(newExpression, sr.StockExpression)) {\r
+                                               graph.claimLiteral(newExpression, sr.StockExpression_initialEquation, "");\r
+                                               Layer0Utils.addCommentMetadata(graph, "Created new Stock Expression " + newExpression + " for " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+                                       }\r
+                               } else {\r
+                                   // If there was no active expression, create a normal expression\r
+                                       graph.claim(newExpression, l0.InstanceOf, sr.NormalExpression);\r
+                                       graph.claimLiteral(newExpression, sr.Expression_equation, "");\r
+                                       Layer0Utils.addCommentMetadata(graph, "Created new Normal Expression " + newExpression + " for " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING));\r
+                               }\r
+                               ArrayList<Resource> addition = new ArrayList<Resource>(1);\r
+                               addition.add(newExpression);\r
+                               ListUtils.insertBack(graph, expressions, addition);\r
+                               graph.claim(input, l0.ConsistsOf, newExpression);\r
+                       }\r
+               });\r
+\r
+               // Item factory for expression type combo\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
+                               // Select expression types based on the type of the variable\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
+               // Initial selection to the combo from active expression\r
+               expressionTypeCombo.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                               Resource activeExpression = getActiveExpression(graph, input);\r
+                               if(activeExpression == null)\r
+                                       return null;\r
+                               return ExpressionTypes.getExpressionType(graph, activeExpression).toString();\r
+                       }\r
+               });\r
+\r
+               // Modify listener for selecting expression type\r
+               expressionTypeCombo.addModifyListener(new TextModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(TrackedModifyEvent e) {\r
+                               expressionWidget.displayExpression(e.getText(), false);\r
+                               expressionWidget.save();                \r
+                       }\r
+               });\r
+\r
+\r
+               // Add all units used in the model to the unit combo\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
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               Resource model = graph.getPossibleObject(input, l0.PartOf);\r
+                               if (model != null) {\r
+                                       Collection<Resource> variables = graph.getObjects(model, l0.ConsistsOf);\r
+                                       for(Resource v : variables) {\r
+                                               Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit);\r
+                                               if (unit != null && !map.keySet().contains(unit)) {\r
+                                                       map.put((String)unit, (String)unit);\r
+\r
+                                               }\r
+                                       }\r
+                               }\r
+                               return map;\r
+                       }\r
+               });\r
+               \r
+               // Set initial selection of unit combo\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).Variable_unit);\r
+                               if(unit == null)\r
+                                       return "";\r
+                               else \r
+                                       return unit;\r
+                       }\r
+               });\r
+\r
+               // Modify unit\r
+               unitCombo.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+                       @Override\r
+                       public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
+                           graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit);\r
+                               graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text);\r
+                               \r
+                               Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf);\r
+                               SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+                               SysdynModel sm = smm.getModel(graph, conf);\r
+                               sm.getMapping().domainModified(input);\r
+                               sm.update(graph);\r
+                       }\r
+               });\r
+\r
+\r
+               /*\r
+                * Double-clicking something in shortcut tab widget\r
+                * writes the clicked element into expression widget,\r
+                * sets focus on expression widget and validates its fields\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().focus();\r
+                                                               expressionWidget.getExpression().replaceSelection(var);\r
+                                                               expressionWidget.validateFieldsTimed();\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
+\r
+               /* Modifying an expression sets a timed validation. The timer is\r
+                * reset after each modification \r
+                */ \r
+               expressionWidget.addModifyListener(new ModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               expressionWidget.validateFieldsTimed();\r
+                       }\r
+               });\r
+               \r
+               // Pressing return without shift key triggers saving the expression\r
+               expressionWidget.addVerifyKeyListener(new VerifyKeyListener() {\r
+\r
+                       @Override\r
+                       public void verifyKey(VerifyEvent event) {\r
+                           // Check if some of the expression fields has active completion assistant\r
+                               boolean isAnyAssistSessionActive = false;\r
+                               for (int i = 0; i < expressionWidget.getExpression().getExpressionFields().size(); ++i) {\r
+                                       if (expressionWidget.getExpression().getExpressionFields().get(i).isAssistSessionActive()) {\r
+                                               isAnyAssistSessionActive = true;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) {\r
+                                   if (!isAnyAssistSessionActive) {\r
+                                       if((event.stateMask & SWT.SHIFT) == 0) {\r
+                                           event.doit = false;\r
+                                                       ((StyledText)event.widget).getParent().forceFocus();\r
+                                                       expressionWidget.save();\r
+                                               }\r
+                                   } else {\r
+                                       // When a proposed expression is selected with enter, fields are validated.\r
+                           expressionWidget.validateFieldsTimed();\r
+                                       }\r
+                               }\r
+                       }\r
+               });\r
+               \r
+           // Triggers save when equation tab loses focus\r
+        if(focusLostListener == null) {\r
+            focusLostListener = new org.eclipse.ui.IPartListener2()\r
+            {\r
+                @Override\r
+                public void partInputChanged(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partVisible(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partHidden(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partOpened(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partDeactivated(IWorkbenchPartReference partRef)\r
+                {\r
+                    if(partRef.getPart(false) instanceof PropertyPageView) {\r
+                        PropertyPageView ppv = (PropertyPageView)partRef.getPart(false);\r
+                        if(ppv.getCurrentPage() instanceof SysdynPropertyPage) {\r
+                            // Save expressions\r
+                            if(expressionWidget != null) {\r
+                                expressionWidget.save();\r
+                            }\r
+//                          site.getPage().removePartListener(this);\r
+                        }\r
+                    }\r
+                }\r
+                @Override\r
+                public void partClosed(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partBroughtToTop(IWorkbenchPartReference partRef) {}\r
+                @Override\r
+                public void partActivated(IWorkbenchPartReference partRef) {}\r
+            };\r
+            site.getPage().addPartListener(focusLostListener);\r
+        }\r
+       }\r
+\r
+       @Override\r
+       public void dispose() {\r
+        if(expressionWidget != null && !(expressionWidget.getExpression() instanceof DelayExpression)) {\r
+               // For delay expression this doesn't work, \r
+               // but it doesn't matter since the saving is succeeded elsewhere.\r
+            expressionWidget.save();\r
+        }\r
+               if(focusLostListener != null && site != null)\r
+                       site.getPage().removePartListener(focusLostListener);\r
+               super.dispose();\r
+               if(expressionComposite != null && !expressionComposite.isDisposed())\r
+                   expressionComposite.dispose();\r
+       }\r
+\r
+       /**\r
+        * Get the currently active expression of the first expression in expression list if\r
+        * no expression has been set to active\r
+        * \r
+        * @param graph ReadGraph\r
+        * @param variable Variable\r
+        * @return active expression or the first expression in variables expression list\r
+        * @throws DatabaseException\r
+        */\r
+       private Resource getActiveExpression(ReadGraph graph, Resource variable) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource expression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression);\r
+               if(expression == null) {\r
+                       Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList);\r
+                       if(expressions == null) {\r
+                               return null;\r
+                       }\r
+                       List<Resource> expressionList = ListUtils.toList(graph, expressions);\r
+                       if(expressionList.isEmpty()) {\r
+                               return null;\r
+                       }\r
+                       expression = expressionList.get(0);\r
+               }\r
+               return expression;\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..d1bb32f
--- /dev/null
@@ -0,0 +1,31 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+\r
+public class ExperimentTab extends LabelPropertyTabContributor {\r
+\r
+    public ExperimentTab(Object id) {\r
+        super(id);\r
+    }\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/ExternalFilesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ExternalFilesTab.java
new file mode 100644 (file)
index 0000000..fb32aa5
--- /dev/null
@@ -0,0 +1,249 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.dialogs.MessageDialog;\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.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.handlers.exports.ExportExternalFunctionFilesHandler;\r
+import org.simantics.sysdyn.ui.handlers.imports.ImportExternalFunctionFilesHandler;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.threads.SWTThread;\r
+\r
+/**\r
+ * Tab for properties of a SysdynModelicaFunction containing all external files added to that function \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ExternalFilesTab extends LabelPropertyTabContributor implements Widget {\r
+\r
+       public ExternalFilesTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    GraphExplorerComposite externalFilesExplorer;\r
+       Button importButton, exportButton, removeButton; \r
+       \r
+       @Override\r
+       public void createControls(Composite body, IWorkbenchSite site,\r
+                       final ISessionContext context, WidgetSupport support) {\r
+               support.register(this);\r
+               \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
+        // Create the graph explorer displaying external files                 \r
+               externalFilesExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, composite, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);\r
+               \r
+               externalFilesExplorer\r
+               .setBrowseContexts(SysdynResource.URIs.ExternalFiles);\r
+               externalFilesExplorer.setInputSource(new SingleSelectionInputSource(\r
+                               Resource.class));\r
+\r
+               externalFilesExplorer.setContextMenuId("#ExternalFunctionFileBrowser");\r
+               \r
+               externalFilesExplorer.addListenerToControl(SWT.Selection, new Listener() {\r
+            \r
+            @Override\r
+            public void handleEvent(Event event) {\r
+                updateButtons(externalFilesExplorer);\r
+            }\r
+        });\r
+               \r
+               externalFilesExplorer.finish();\r
+               \r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               externalFilesExplorer);\r
+               \r
+               Control c = externalFilesExplorer.getExplorerControl();\r
+               if (c instanceof Tree)\r
+                       ((Tree) c).setLinesVisible(true);\r
+               \r
+               \r
+               // Create controls for importing, exporting and removing external files\r
+               Composite buttonRow = new Composite(composite, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonRow);\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(buttonRow);\r
+               \r
+               importButton = new Button(buttonRow, support, SWT.NONE);\r
+               importButton.setText("Import");\r
+               importButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                   private Pair<String, String[]> importedFiles; \r
+                   \r
+                   @Override\r
+                   public void beforeApply() {\r
+                Shell shell = importButton.getWidget().getShell();\r
+                importedFiles = ImportExternalFunctionFilesHandler.importFiles(shell, "Import files", ImportExternalFunctionFilesHandler.C_EXTENSIONS);                        \r
+                   }\r
+                   \r
+                       @Override\r
+                       public void apply(WriteGraph graph, final Resource input) throws DatabaseException {\r
+                           graph.markUndoPoint();\r
+                ImportExternalFunctionFilesHandler.addFilesToFunction(graph, input, importedFiles);\r
+                Layer0Utils.addCommentMetadata(graph, "Imported External File(s) " + Arrays.toString(importedFiles.second) + " to " + NameUtils.getSafeName(graph, input));\r
+                updateButtons(externalFilesExplorer);\r
+                       }\r
+               });\r
+\r
+               exportButton = new Button(buttonRow, support, SWT.NONE);\r
+               exportButton.setText("Export");\r
+               exportButton.getControl().setEnabled(false);\r
+               exportButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                       @Override\r
+                       public void apply(WriteGraph graph, final Resource input)\r
+                       throws DatabaseException {\r
+\r
+                               exportButton.getWidget().getDisplay().asyncExec(new Runnable() {\r
+\r
+                                       @Override\r
+                                       public void run() {\r
+                                               Shell shell = exportButton.getWidget().getShell();\r
+                                               List<Resource> resourceList = getSelectedResources(externalFilesExplorer);\r
+                                               Resource[] resources = resourceList.toArray(new Resource[resourceList.size()]);\r
+                                               if (resources.length > 0)\r
+                                                       ExportExternalFunctionFilesHandler.exportFiles(shell, resources);\r
+                                       }\r
+                               });\r
+                       }\r
+               });\r
+\r
+               removeButton = new Button(buttonRow, support, SWT.NONE);\r
+               removeButton.setText("Remove");\r
+               removeButton.getControl().setEnabled(false);\r
+               removeButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                   private int delete;\r
+                   private List<Resource> resourceList;\r
+                   \r
+                   @Override\r
+                   public void beforeApply() {\r
+                Shell shell = removeButton.getWidget().getShell();\r
+\r
+                resourceList = getSelectedResources(externalFilesExplorer);\r
+                Resource[] resources = resourceList.toArray(new Resource[resourceList.size()]);\r
+                if(resources.length > 0) {\r
+                    MessageDialog dialog = new MessageDialog(shell, resources.length > 1 ? "Remove selected items" : "Remove selected item" , null, "Are you sure?", 0,\r
+                            new String[] { "OK", "Cancel" }, 0);\r
+                    dialog.create();\r
+                    delete = dialog.open();\r
+                }\r
+                   }\r
+                   \r
+                       @Override\r
+                       public void apply(WriteGraph graph, final Resource input) throws DatabaseException {\r
+                           if (delete == 0) {\r
+                    Resource[] resources = resourceList.toArray(new Resource[resourceList.size()]);\r
+                    StringBuilder sb = new StringBuilder();\r
+                    sb.append("Removed External File(s) ");\r
+                    for (Resource resource : resources) {\r
+                        RemoverUtil.remove(graph, resource);\r
+                        sb.append(NameUtils.getSafeName(graph, resource) + " ");\r
+                    }\r
+                    sb.append("from " + NameUtils.getSafeName(graph, input));\r
+                    Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                    \r
+                    updateButtons(externalFilesExplorer);\r
+                           }\r
+                       }\r
+               });\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               externalFilesExplorer.setInput(context, input);\r
+               updateButtons(externalFilesExplorer);\r
+       }\r
+\r
+       /**\r
+        * Method for retreiving selected resources from a GraphExplorerComposite\r
+        * @param explorer\r
+        * @return\r
+        */\r
+       private List<Resource> getSelectedResources(GraphExplorerComposite explorer) {\r
+               List<Resource> result = new ArrayList<Resource>();\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return result;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               @SuppressWarnings("unchecked")\r
+               List<AdaptableHintContext> selections = iss.toList();\r
+               for(AdaptableHintContext ahc : selections) {\r
+                       Resource resource = (Resource) ahc.getAdapter(Resource.class);\r
+                       result.add(resource);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+       protected void updateButtons(final GraphExplorerComposite explorer) {\r
+           if (SWTThread.getThreadAccess().currentThreadAccess()) {\r
+               runnable.run();\r
+           } else {\r
+               SWTThread.getThreadAccess().asyncExec(runnable);\r
+           }\r
+       }\r
+       \r
+       Runnable runnable = new Runnable() {\r
+        \r
+        @Override\r
+        public void run() {\r
+            ISelection selection = ((ISelectionProvider) externalFilesExplorer.getAdapter(ISelectionProvider.class)).getSelection();\r
+            \r
+            IStructuredSelection iss = (IStructuredSelection) selection;\r
+            @SuppressWarnings("unchecked")\r
+            List<AdaptableHintContext> selections = iss.toList();\r
+            \r
+            boolean enabled = false;\r
+            if (!selections.isEmpty()) \r
+                enabled = true;\r
+            removeButton.getControl().setEnabled(enabled);\r
+            exportButton.getControl().setEnabled(enabled);\r
+        }\r
+    };\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FlowTab.java
new file mode 100644 (file)
index 0000000..1eee34c
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Scale;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.elements.connections.FlowConnectionStyle;\r
+\r
+public class FlowTab  extends LabelPropertyTabContributor {\r
+\r
+    public FlowTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    Scale lineThicknessScale;\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(1).applyTo(composite);\r
+        \r
+        Group lineThicknessGroup = new Group(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(lineThicknessGroup);\r
+        lineThicknessGroup.setText("Flow thickness:");\r
+        lineThicknessScale = new Scale(lineThicknessGroup, support, SWT.HORIZONTAL);\r
+        lineThicknessScale.getWidget().setMinimum(1);\r
+        lineThicknessScale.getWidget().setMaximum(9);\r
+        lineThicknessScale.getWidget().setPageIncrement(1);\r
+        lineThicknessScale.getWidget().setIncrement(1);\r
+        lineThicknessScale.setSelectionFactory(new LineThicknessRadioSelectionFactory());\r
+        lineThicknessScale.addSelectionListener(new LineThicknessSelectionListener(context, lineThicknessScale));\r
+    }\r
+    \r
+    class LineThicknessSelectionListener extends SelectionListenerImpl<Resource> {\r
+       Scale scale;\r
+               private int selection;\r
+\r
+        public LineThicknessSelectionListener(ISessionContext context, Scale scale) {\r
+               super(context);\r
+               this.scale = scale;\r
+        }\r
+        \r
+        @Override\r
+        public void beforeApply() {\r
+            this.selection = scale.getWidget().getSelection();\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            float width = ((float)selection) / 3.0f;\r
+            graph.claimLiteral(connectionElement, sr.FlowConnection_width, width);\r
+        }\r
+        \r
+    }\r
+    \r
+    class LineThicknessRadioSelectionFactory extends ReadFactoryImpl<Resource, Integer> {\r
+\r
+        public LineThicknessRadioSelectionFactory() {\r
+        }\r
+\r
+        @Override\r
+        public Integer perform(ReadGraph graph, Resource flowConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            Float width = graph.getPossibleRelatedValue(flowConnection, sr.FlowConnection_width, Bindings.FLOAT);  \r
+            if(width == null)\r
+                return (int)Math.round(FlowConnectionStyle.DEFAULT_LINE_WIDTH * 3);\r
+            else\r
+                return (int)Math.round(width * 3);\r
+        }\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionLibraryTab.java
new file mode 100644 (file)
index 0000000..567d57b
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.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.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.FunctionLibraryNameInputValidator;\r
+\r
+public class FunctionLibraryTab extends LabelPropertyTabContributor {\r
+\r
+       public FunctionLibraryTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    @Override\r
+       public void createControls(Composite body, IWorkbenchSite site,\r
+                       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
+\r
+               TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+               nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+               nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new FunctionLibraryNameInputValidator(support));\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+\r
+\r
+               TrackedText information = new TrackedText(composite, support, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);\r
+               information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription));\r
+               information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription));\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/FunctionTab.java
new file mode 100644 (file)
index 0000000..c4564ea
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Label;\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.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.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.properties.widgets.FunctionLabelFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.FunctionNameInputValidator;\r
+import org.simantics.sysdyn.ui.properties.widgets.functions.FunctionCodeWidget;\r
+import org.simantics.sysdyn.utils.SelectionUtils;\r
+\r
+public class FunctionTab extends AdjustableTab {\r
+       \r
+       public FunctionTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    ExpressionField modelicaCode;\r
+       private TrackedText nameText;\r
+       private Group modelicaGroup;\r
+       private Label startLabel;\r
+       private Label endLabel;\r
+       private Group documentationGroup;\r
+       private TrackedText information;\r
+\r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               composite = new Composite(body, SWT.NONE);\r
+\r
+        nameText = new TrackedText(composite, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new FunctionNameInputValidator(support));\r
+        \r
+        \r
+        modelicaGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+        modelicaGroup.setText("Modelica code");\r
+        \r
+        startLabel = new Label(modelicaGroup, support, SWT.NONE);\r
+        startLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, false));\r
+        \r
+        new FunctionCodeWidget(modelicaGroup, support, SWT.BORDER);\r
+        /*\r
+        TrackedText modelicaCode = new TrackedText(modelicaGroup, support, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.WRAP);\r
+        modelicaCode.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HasModelicaFunctionCode));\r
+        modelicaCode.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HasModelicaFunctionCode));\r
+        modelicaCode.addModifyListener(new TextModifyListenerImpl<Resource>() {\r
+\r
+                       @Override\r
+                       public void applyText(WriteGraph graph, Resource input, String text)\r
+                                       throws DatabaseException {\r
+                               Resource library = graph.getSingleObject(input, Layer0.getInstance(graph).PartOf);\r
+                               FunctionUtils.updateFunctionFileForLibrary(graph, library);\r
+                       }\r
+               });*/\r
+        \r
+        endLabel = new Label(modelicaGroup, support, SWT.NONE);\r
+        endLabel.setTextFactory(new FunctionLabelFactory(Layer0.URIs.HasName, true));\r
+\r
+        documentationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+        documentationGroup.setText("Documentation");\r
+\r
+        information = new TrackedText(documentationGroup, support, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);\r
+        information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription));\r
+        information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription));\r
+        \r
+        if (id instanceof Resource) {\r
+            final Resource r = (Resource) id;\r
+            try {\r
+                boolean editable = context.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                    @Override\r
+                    public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                        return SelectionUtils.canEdit(graph, r);\r
+                    }\r
+                });\r
+                information.setEditable(editable);\r
+                nameText.setEditable(editable);\r
+            } catch (DatabaseException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(1).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().span(1, 1).grab(true, false).applyTo(nameText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).minSize(150, 0).applyTo(modelicaGroup);\r
+        GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(modelicaGroup);\r
+        \r
+        /*\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode.getWidget());\r
+        */\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(documentationGroup);\r
+        GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(documentationGroup);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(nameText.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).minSize(150, 0).applyTo(modelicaGroup);\r
+        GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(modelicaGroup);\r
+        \r
+        /*\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode.getWidget());\r
+        */\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(documentationGroup);\r
+        GridLayoutFactory.fillDefaults().spacing(0, 0).margins(3, 3).applyTo(documentationGroup);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/GameExperimentTab.java
new file mode 100644 (file)
index 0000000..ea4941f
--- /dev/null
@@ -0,0 +1,90 @@
+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.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\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.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.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\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
+import org.simantics.utils.ui.validators.DoubleValidator;\r
+\r
+/**\r
+ * Tab for displaying game experiment properties\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class GameExperimentTab extends LabelPropertyTabContributor {\r
+\r
+       public GameExperimentTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    @Override\r
+       public void createControls(Composite body, IWorkbenchSite site,\r
+               ISessionContext context, WidgetSupport support) {\r
+               \r
+        ScrolledComposite sc = new ScrolledComposite(body,  SWT.H_SCROLL | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().applyTo(sc);\r
+        \r
+        Composite composite = new RemoveFocusBeforeExperimentComposite(sc, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        // Label\r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Name");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+        TrackedText name = new TrackedText(composite, support, SWT.BORDER);\r
+        name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        name.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), name.getWidget())));\r
+        \r
+        // Step duration (i.e. how many time units is one step in user's perspective)\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Step duration");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+        TrackedText stepDuration = new TrackedText(composite, support, SWT.BORDER);\r
+        stepDuration.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepDuration));\r
+        stepDuration.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepDuration));\r
+        stepDuration.setInputValidator(new DoubleValidator());\r
+        stepDuration.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), stepDuration.getWidget())));\r
+        GridDataFactory.fillDefaults().hint(80, SWT.DEFAULT).grab(true, false).applyTo(name.getWidget());\r
+\r
+        // Integrator step length (i.e. how long is a integration step in the simulator. This time is stepped until stepDuration is full)\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Integrator step length");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+\r
+        TrackedText integratorStep = new TrackedText(composite, support, SWT.BORDER);\r
+        integratorStep.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.GameExperiment_stepLength));\r
+        integratorStep.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.GameExperiment_stepLength));\r
+        integratorStep.setInputValidator(new DoubleValidator());\r
+        integratorStep.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), integratorStep.getWidget())));\r
+        \r
+        // Scrolled composite settings\r
+        sc.setContent(composite);\r
+        sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+        sc.setExpandHorizontal(true);\r
+        sc.setExpandVertical(true);\r
+               \r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/HistoryDataTab.java
new file mode 100644 (file)
index 0000000..2b4883e
--- /dev/null
@@ -0,0 +1,291 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.Collection;\r
+import java.util.LinkedHashMap;\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.viewers.ISelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.widgets.Combo;\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.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\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.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.PossibleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Tab for displaying and modifying history data settings in SysDyn.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class HistoryDataTab  extends LabelPropertyTabContributor {\r
+\r
+    public HistoryDataTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+        \r
+        // Scrolled composite for scrollable tab\r
+        ScrolledComposite sc = new ScrolledComposite(body, SWT.H_SCROLL | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(sc);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sc);\r
+\r
+        // Container for all components\r
+        Composite composite = new Composite(sc, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).margins(3, 3).applyTo(composite);\r
+\r
+        // Name\r
+        Label label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Name: ");\r
+        \r
+        TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel));\r
+        nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel));\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(nameText.getWidget());\r
+\r
+        // Sheet selection \r
+        label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Sheet: ");\r
+        \r
+        TrackedCombo sheet = new TrackedCombo(composite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+        sheet.setItemFactory(new SheetItemFactory());\r
+        sheet.setSelectionFactory(new SheetSelectionFactory());\r
+        sheet.addModifyListener(new SheetModifyListener());\r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(sheet.getWidget());\r
+\r
+        // Orientation (columns or rows)\r
+        label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Orientation: ");\r
+        \r
+        Composite orientation = new Composite(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(orientation);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(orientation);\r
+        \r
+        // Radio buttons for orientation\r
+        Button columns = new Button(orientation, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().applyTo(columns.getWidget());\r
+        columns.setText("Columns");\r
+        columns.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                graph.claimLiteral(input, SysdynResource.getInstance(graph).HistoryDataset_columns, Boolean.TRUE, Bindings.BOOLEAN);\r
+            }\r
+        });\r
+        columns.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                return graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HistoryDataset_columns);\r
+            }\r
+        });\r
+        \r
+        Button rows = new Button(orientation, support, SWT.RADIO);\r
+        rows.setText("Rows");\r
+        rows.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                graph.claimLiteral(input, SysdynResource.getInstance(graph).HistoryDataset_columns, Boolean.FALSE, Bindings.BOOLEAN);\r
+            }\r
+        });\r
+        rows.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                return Boolean.FALSE.equals(graph.getPossibleRelatedValue(input, SysdynResource.getInstance(graph).HistoryDataset_columns));\r
+            }\r
+        });\r
+        \r
+        \r
+        // Group container displaying all variables found in the defined range\r
+        Group c = new Group(composite, SWT.NONE);\r
+        c.setText("Variables in range");\r
+        GridDataFactory.fillDefaults().span(1, 4).applyTo(c);\r
+        GridLayoutFactory.fillDefaults().margins(3, 1).spacing(0, 0).applyTo(c);\r
+        \r
+        GraphExplorerComposite explorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                "displaySelectors", "displayFilter").values(false, false), site, c, support, SWT.FULL_SELECTION | SWT.BORDER);\r
+        explorer.setBrowseContexts(SysdynResource.URIs.HistoryDataset_HistoryDatasetVariablesBrowseContext);\r
+        explorer.setInputSource(new SingleSelectionInputSource(Resource.class));\r
+        explorer.finish();\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT,100).grab(true, false).applyTo(explorer);\r
+        \r
+        // Range start \r
+        label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Range Start: ");\r
+        \r
+        TrackedText start = new TrackedText(composite, support, SWT.BORDER);\r
+        start.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_start));\r
+        start.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_start));\r
+        GridDataFactory.fillDefaults().applyTo(start.getWidget());\r
+        \r
+        // Range end\r
+        label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Range End: ");\r
+        \r
+        TrackedText end = new TrackedText(composite, support, SWT.BORDER);\r
+        end.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_end));\r
+        end.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_end));\r
+        GridDataFactory.fillDefaults().applyTo(end.getWidget());\r
+        \r
+        // Time variable. This variable is used as time values in the history dataset\r
+        label = new Label(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Time variable: ");\r
+        \r
+        TrackedText time = new TrackedText(composite, support, SWT.BORDER);\r
+        time.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.HistoryDataset_timeName));\r
+        time.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.HistoryDataset_timeName));\r
+        GridDataFactory.fillDefaults().applyTo(time.getWidget());\r
+        \r
+        \r
+        // Scrolled composite settings\r
+        sc.setContent(composite);\r
+        sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
+        sc.setExpandHorizontal(true);\r
+        sc.setExpandVertical(true);\r
+\r
+\r
+    }\r
+\r
+    /**\r
+     * Item factory for finding spreadsheets from a model\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class SheetItemFactory extends ReadFactoryImpl<Resource, Map<String,Object>> {\r
+\r
+        @Override\r
+        public Map<String, Object> perform(ReadGraph graph, Resource historyData) throws DatabaseException {\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            SimulationResource simu = SimulationResource.getInstance(graph);\r
+            SpreadsheetResource spreadSheet = SpreadsheetResource.getInstance(graph);\r
+\r
+            Resource model = graph.getPossibleObject(historyData, l0.PartOf);\r
+            Resource config = graph.getPossibleObject(model, simu.HasConfiguration);\r
+            Resource book = graph.syncRequest(new PossibleObjectWithType(config, l0.ConsistsOf, spreadSheet.Book));\r
+            Collection<Resource> sheets = graph.syncRequest(new ObjectsWithType(book, l0.ConsistsOf, spreadSheet.Spreadsheet));\r
+\r
+            Map<String, Object> map = new LinkedHashMap<String, Object>();\r
+\r
+            for(Resource sheet : sheets) {\r
+                map.put(NameUtils.getSafeName(graph, sheet), sheet);\r
+            }\r
+            return map;\r
+        }\r
+    };\r
+    \r
+    /**\r
+     * Selection factory for finding the defined sheet name for a history dataset\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class SheetSelectionFactory extends ReadFactoryImpl<Resource, String> {\r
+\r
+        @Override\r
+        public String perform(ReadGraph graph, Resource historyData) throws DatabaseException {\r
+            Resource selectedSheet = graph.getPossibleObject(historyData, SysdynResource.getInstance(graph).HistoryDataset_sheet);\r
+            if(selectedSheet != null) {\r
+                String name = NameUtils.getSafeName(graph, selectedSheet);\r
+                return name;// Return the selected sheet, if it exits\r
+            } else {\r
+                return null;\r
+            }\r
+        }\r
+    };\r
+\r
+    /**\r
+     * Listener for listening sheet selections in sheet combo\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class SheetModifyListener implements TextModifyListener, Widget {\r
+\r
+        private ISessionContext context;\r
+        private Object lastInput = null;\r
+\r
+        @Override\r
+        public void modifyText(TrackedModifyEvent e) {\r
+\r
+            Combo combo = (Combo)e.getWidget();\r
+            String textValue = combo.getText();\r
+            Map<?,?> data = (Map<?, ?>) combo.getData();\r
+            if(data == null) return;\r
+            final Resource value = (Resource) data.get(textValue);\r
+            if(value == null) return;\r
+            final Object input = lastInput;\r
+\r
+            try {\r
+                context.getSession().syncRequest(new WriteRequest() {\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+\r
+                        Resource resource = (Resource) ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
+                        SysdynResource sr = SysdynResource.getInstance(graph);\r
+                        graph.deny(resource, sr.HistoryDataset_sheet);\r
+                        graph.claim(resource, SysdynResource.getInstance(graph).HistoryDataset_sheet, value);\r
+                    }\r
+\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void setInput(ISessionContext context, Object parameter) {\r
+            this.context = context;\r
+            lastInput = parameter;\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..5da056d
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\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.WidgetSupport;\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.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.ui.properties.widgets.IsOutputWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.UnitComboWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNamePropertyModifier;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.ui.validators.DoubleValidator;\r
+\r
+/**\r
+ * Properties for input variables: Name, default value, isOutput\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class InputVariableTab  extends LabelPropertyTabContributor {\r
+\r
+    \r
+    public InputVariableTab(Object id) {\r
+        super(id);\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().hint(200, SWT.DEFAULT).grab(false, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+\r
+        TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        nameText.addModifyListener(new VariableNamePropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new VariableNameInputValidator(support));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+\r
+        Composite defaultValueComposite = new Composite(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(false, false).applyTo(defaultValueComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(defaultValueComposite);\r
+        \r
+        Label label = new Label(defaultValueComposite, SWT.NULL);\r
+        label.setText("Default Value:");\r
+        \r
+        TrackedText defaultValue = new TrackedText(defaultValueComposite, support, SWT.RIGHT | SWT.BORDER);\r
+        defaultValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Input_defaultInputValue));\r
+        defaultValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Input_defaultInputValue));\r
+        defaultValue.setInputValidator(new DoubleValidator());\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(defaultValue.getWidget());\r
+\r
+\r
+        Composite unitComposite = new Composite(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().applyTo(unitComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(unitComposite);\r
+        \r
+        label = new Label(unitComposite, SWT.NULL );\r
+        label.setText("Unit:");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+\r
+        TrackedCombo unitCombo = new UnitComboWidget(unitComposite, support, SWT.DROP_DOWN | SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(unitCombo.getWidget());\r
+        \r
+        \r
+        Composite variabilityComposite = new Composite(composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(false, true).applyTo(variabilityComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(variabilityComposite);\r
+        \r
+        label = new Label(variabilityComposite, SWT.NULL);\r
+        label.setText("Variability:");\r
+        \r
+        TrackedCombo variability = new TrackedCombo(variabilityComposite, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(variability.getWidget());\r
+        setVariabilityFactories(variability);\r
+        \r
+        new IsOutputWidget(composite, support, SWT.NULL);\r
+    }\r
+    \r
+    /**\r
+     * set item, selection and modify properties for variability combo\r
+     * @param variability\r
+     */\r
+    private void setVariabilityFactories(TrackedCombo variability) {\r
+        variability.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
+                map.put("continuous", "continuous");\r
+                map.put("parameter", "parameter");\r
+                map.put("constant", "constant");\r
+                return map;\r
+            }\r
+        });\r
+        \r
+        variability.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+            \r
+            public Object getIdentity(Object inputContents) {\r
+                return new Pair<Object, Class<?>>(inputContents, getClass());\r
+            }\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                String variability = graph.getPossibleRelatedValue(input, sr.Variable_variability);\r
+                if(variability == null || variability.isEmpty())\r
+                    return "continuous";\r
+                else \r
+                    return variability;\r
+            }\r
+        });\r
+        \r
+        variability.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+            @Override\r
+            public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                String variability = text;\r
+                if(text.equals("continuous"))\r
+                    variability = "";\r
+                \r
+                if(variability != null) {\r
+                    graph.denyValue(input, sr.Variable_variability);\r
+                    graph.claimLiteral(input, sr.Variable_variability, variability);\r
+                    \r
+                    Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf);\r
+                    SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+                    SysdynModel sm = smm.getModel(graph, conf);\r
+                    sm.getMapping().domainModified(input);\r
+                    sm.update(graph);\r
+                    \r
+                }\r
+            }\r
+            \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..ec059e6
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\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 LabelPropertyTabContributor {\r
+\r
+    public LookupTableTab(Object id) {\r
+        super(id);\r
+    }\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.WithLookupExpression_maxY));\r
+        maxYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_maxY));\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.WithLookupExpression_minY));\r
+        minYText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_minY));\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.WithLookupExpression_minX));\r
+        minXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_minX));\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.WithLookupExpression_maxX));\r
+        maxXText.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.WithLookupExpression_maxX));\r
+\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/LoopTab.java
new file mode 100644 (file)
index 0000000..ffec528
--- /dev/null
@@ -0,0 +1,409 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013-2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.HashMap;\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.swt.SWT;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\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.widgets.Button;\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.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.util.ObjectUtils;\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.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.utils.LoopUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+\r
+/**\r
+ * Tab for displaying information of a loop\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class LoopTab extends AdjustableTab {\r
+\r
+       public LoopTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    private Label loopItemsLabel;\r
+       private TrackedCombo loopItemsDropdown;\r
+       Button auto, balancing, reinforcing, other, inside, outside;\r
+    TrackedText loopComment, polarityLocationText;\r
+    Composite loopItems;\r
+    Group commentGroup, rotationGroup;\r
+       protected Resource resource;\r
+       public static final String AUTO = "$$AUTO$$";\r
+\r
+    @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport support) {\r
+               composite = new Composite(body, SWT.NONE);\r
+\r
+               loopItems = new Composite(composite, SWT.NONE);\r
+               loopItemsLabel = new Label(loopItems, SWT.SINGLE);\r
+               loopItemsLabel.setText("Loop Items:");\r
+               loopItemsDropdown = new TrackedCombo(loopItems, support, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+                               \r
+        commentGroup = new Group(composite, SWT.NONE);\r
+        commentGroup.setText("Comment");\r
+        \r
+        auto = new Button(commentGroup, support, SWT.RADIO);\r
+        auto.setText("Auto");\r
+        auto.setSelectionFactory(new CommentRadioSelectionFactory(AUTO));\r
+        auto.addSelectionListener(new CommentSelectionListener(context, AUTO));\r
+        \r
+        balancing = new Button(commentGroup, support, SWT.RADIO);\r
+        balancing.setText("B");\r
+        balancing.setSelectionFactory(new CommentRadioSelectionFactory("B"));\r
+        balancing.addSelectionListener(new CommentSelectionListener(context, "B"));\r
+        \r
+        reinforcing = new Button(commentGroup, support, SWT.RADIO);\r
+        reinforcing.setText("R");\r
+        reinforcing.setSelectionFactory(new CommentRadioSelectionFactory("R"));\r
+        reinforcing.addSelectionListener(new CommentSelectionListener(context, "R"));\r
+        \r
+        other = new Button(commentGroup, support, SWT.RADIO);\r
+        other.setText("other");\r
+        other.setSelectionFactory(new OtherCommentSelectionFactory(new String[] {null, "B", "R", AUTO}));\r
+        other.addSelectionListener(new CommentSelectionListener(context, ""));\r
+        \r
+        loopComment = new TrackedText(commentGroup, support, SWT.BORDER);\r
+        loopComment.setTextFactory(new OtherCommentStringPropertyFactory());\r
+        loopComment.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.Loop_Comment));\r
+        \r
+        rotationGroup = new Group(composite, SWT.NONE);\r
+        rotationGroup.setText("Direction of Rotation");\r
+        \r
+        inside = new Button(rotationGroup, support, SWT.RADIO);\r
+        inside.setText("Clockwise");\r
+        inside.setSelectionFactory(new ClockwiseRotationRadioSelectionFactory(true));\r
+        inside.addSelectionListener(new ClockwiseRotationSelectionListener(context, true));\r
+        \r
+        outside = new Button(rotationGroup, support, SWT.RADIO);\r
+        outside.setText("Counterclockwise");\r
+        outside.setSelectionFactory(new ClockwiseRotationRadioSelectionFactory(false));\r
+        outside.addSelectionListener(new ClockwiseRotationSelectionListener(context, false));\r
+        \r
+        addListeners(context);\r
+       }\r
+\r
+       private void addListeners(ISessionContext context) {\r
+               // Item factory for loopItemsDropdown combo\r
+               loopItemsDropdown.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
+                               LoopTab.this.resource = input;\r
+                               Map<String, Object> map = new HashMap<String, Object>();\r
+                               List<List<Resource>> loops = LoopUtils.getAllLoopsInDiagram(graph, input);\r
+                               map.put("", null);\r
+                               for (List<Resource> loop : loops) {\r
+                                       map.put(LoopUtils.cycleToString(graph, loop), loop);\r
+                               }\r
+                               return map;\r
+                       }\r
+               });\r
+\r
+               // Initial selection to the combo\r
+               loopItemsDropdown.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                Resource itemListResource = graph.getPossibleObject(input, sr.Loop_Items);\r
+                \r
+                // If the loop hasn't been defined, return empty.\r
+                               if (itemListResource == null) {\r
+                                       return "";\r
+                               }\r
+                               List<Resource> itemList = ListUtils.toPossibleList(graph, itemListResource);\r
+                               if (itemList == null) {\r
+                                       return "";\r
+                               }\r
+                               \r
+                               // See if the defined loop still exists.\r
+                               List<List<Resource>> loops = LoopUtils.getAllLoopsInDiagram(graph, input);\r
+                               Resource first = itemList.get(0);\r
+                               for (List<Resource> loop : loops) {\r
+                                       // If the loops are of different size, continue.\r
+                                       if (loop.size() != itemList.size())\r
+                                               continue;\r
+                                       \r
+                                       // If the first element of the sought loop is not found, continue. \r
+                                       int indexOfFirst = loop.indexOf(first);\r
+                                       if (indexOfFirst < 0) {\r
+                                               continue;\r
+                                       }\r
+                                       \r
+                                       // Check if the loops are the same,\r
+                                       // even if they start at different Resources\r
+                                       boolean match = true;\r
+                                       int i = 1;// = indexOfFirst + 1;\r
+                                       do {\r
+                                               // Get the next Resource in the loop\r
+                                               Resource next = loop.get((i + indexOfFirst) % loop.size());\r
+                                               // If it is other than what should be, continue to the next loop.\r
+                                               if (!next.equalsResource(itemList.get(i))) {\r
+                                                       match = false;\r
+                                                       break;\r
+                                               }\r
+                                       } while (++i != itemList.size());\r
+                                       if (!match)\r
+                                               continue;\r
+                                       \r
+                                       return LoopUtils.cycleToString(graph, loop);\r
+                               }\r
+                               \r
+                               // No match found, hence empty\r
+                               return "";\r
+                       }\r
+               });\r
+\r
+               // Modify listener for selecting loop items\r
+               loopItemsDropdown.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+                       @SuppressWarnings("unchecked")\r
+                       @Override\r
+                       public void applyText(WriteGraph graph, final Resource input, String text) throws DatabaseException  {\r
+                               final Combo c = loopItemsDropdown.getWidget();\r
+                               Display.getDefault().asyncExec(new Runnable() {\r
+                                   public void run() {\r
+                                       Object o = c.getData();\r
+                                               if (o != null && !(o instanceof HashMap<?, ?>))\r
+                                                       return;\r
+                                               \r
+                                               Object loopObject = ((HashMap<?, ?>)o).get(c.getText());\r
+                                               if (loopObject == null || !(loopObject instanceof List<?>))\r
+                                                       return;\r
+                                               \r
+                                               final List<Resource> loop = (List<Resource>)loopObject;\r
+                                               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                                                       @Override\r
+                                                       public void perform(WriteGraph graph)\r
+                                                                       throws DatabaseException {\r
+                                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               Resource loopResource = graph.getPossibleObject(input, sr.Loop_Items);\r
+                                               // Delete the current list if it exists.\r
+                                                               if (loopResource != null) {\r
+                                                       List<Resource> removedList = ListUtils.toPossibleList(graph, loopResource);\r
+                                                                       for (Resource r : removedList)\r
+                                                                               ListUtils.removeElement(graph, loopResource, r);\r
+                                                                       graph.deny(loopResource);\r
+                                               }\r
+                                               // Create new list.\r
+                                               Resource newList = ListUtils.create(graph, loop);\r
+                                               graph.claim(input, sr.Loop_Items, newList);\r
+                                                       }\r
+                                               });\r
+                                   }\r
+                               });\r
+                               \r
+                       }\r
+               });\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+               GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(loopItems);\r
+               GridLayoutFactory.fillDefaults().numColumns(1).applyTo(loopItems);\r
+               GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel);\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget());\r
+        \r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(1).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget());\r
+        GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(rotationGroup);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+               GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(loopItems);\r
+               GridLayoutFactory.fillDefaults().numColumns(2).applyTo(loopItems);\r
+               GridDataFactory.fillDefaults().grab(false, false).applyTo(loopItemsLabel);\r
+               GridDataFactory.fillDefaults().grab(true, false).applyTo(loopItemsDropdown.getWidget());\r
+        \r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(commentGroup);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(commentGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(loopComment.getWidget());\r
+        GridDataFactory.fillDefaults().grab(false, false).applyTo(rotationGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(rotationGroup);\r
+       }\r
+       \r
+       class OtherCommentStringPropertyFactory extends ReadFactoryImpl<Resource, String> {\r
+\r
+           private final String propertyURI;\r
+\r
+           public OtherCommentStringPropertyFactory() {\r
+               this.propertyURI = SysdynResource.URIs.Loop_Comment;\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 resource) throws DatabaseException {\r
+               String value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI));;\r
+               if (value == null || AUTO.equals(value))\r
+                       return "";\r
+               return value;\r
+           }           \r
+    }\r
+       \r
+    class ClockwiseRotationSelectionListener extends SelectionListenerImpl<Resource> {\r
+        private boolean clockwise;\r
+\r
+        public ClockwiseRotationSelectionListener(ISessionContext context, boolean clockwise) {\r
+            super(context);\r
+            this.clockwise = clockwise;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource component) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+               Resource symbol = graph.getPossibleObject(component, mr.ComponentToElement);\r
+            if(symbol != null) {\r
+               graph.deny(symbol, sr.LoopSymbol_Clockwise);\r
+               graph.claimLiteral(symbol, sr.LoopSymbol_Clockwise, clockwise);\r
+            }\r
+        }\r
+        \r
+    }\r
+    \r
+    class ClockwiseRotationRadioSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        private boolean clockwise;\r
+\r
+        public ClockwiseRotationRadioSelectionFactory(boolean clockwise) {\r
+            this.clockwise = clockwise;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, clockwise, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource component) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph); \r
+               ModelingResources mr = ModelingResources.getInstance(graph);\r
+               Resource symbol = graph.getPossibleObject(component, mr.ComponentToElement);\r
+            if(symbol != null) {\r
+               Boolean clockwise = graph.getPossibleRelatedValue(symbol, sr.LoopSymbol_Clockwise, Bindings.BOOLEAN);  \r
+               return ObjectUtils.objectEquals(this.clockwise, clockwise);\r
+            }\r
+            return Boolean.TRUE;\r
+        }\r
+    }\r
+    \r
+    class CommentSelectionListener extends SelectionListenerImpl<Resource> {\r
+        private String comment;\r
+\r
+        public CommentSelectionListener(ISessionContext context, String comment) {\r
+            super(context);\r
+            this.comment = comment;\r
+        }\r
+        \r
+        @Override\r
+        public void apply(WriteGraph graph, Resource connectionElement) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            graph.deny(connectionElement, sr.Loop_Comment);\r
+            graph.claimLiteral(connectionElement, sr.Loop_Comment, comment.trim());\r
+        }\r
+        \r
+    }\r
+    \r
+    class CommentRadioSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        private String comment;\r
+\r
+        public CommentRadioSelectionFactory(String comment) {\r
+            this.comment = comment;\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, comment, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String comment = graph.getPossibleRelatedValue(dependencyConnection, sr.Loop_Comment, Bindings.STRING);     \r
+            if(comment == null && this.comment.equals(""))\r
+                return true;\r
+            return ObjectUtils.objectEquals(comment, this.comment);\r
+        }\r
+    }\r
+    \r
+    class OtherCommentSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+\r
+        String[] limits;\r
+        \r
+        public OtherCommentSelectionFactory(String[] limits) {\r
+            this.limits = limits;\r
+        }\r
+        \r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Pair<Object, Class<?>>(inputContents, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource dependencyConnection) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            String comment = graph.getPossibleRelatedValue(dependencyConnection, sr.Loop_Comment, Bindings.STRING);\r
+            for(String s : limits) {\r
+                if(ObjectUtils.objectEquals(comment, s))\r
+                    return false;\r
+            }\r
+            return true;\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..0455d0e
--- /dev/null
@@ -0,0 +1,96 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.widgets.impl.WidgetSupport;\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.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ModuleInputEditingSupport;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRow;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRowLabelProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceTable;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.RowProvider;\r
+\r
+public class ModuleInputTab extends LabelPropertyTabContributor {\r
+\r
+    public ModuleInputTab(Object id) {\r
+        super(id);\r
+    }\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 = { 200, 200 };\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
+                Layer0 l0 = Layer0.getInstance(graph);\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, l0.InstanceOf);\r
+                if(instanceOf == null) return result;\r
+                Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+                for(Resource input : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Input))) {\r
+                    if(!graph.getObjects(input, sr.Variable_isHeadOf).isEmpty())\r
+                        continue; // Only inputs with tail dependencies allowed.\r
+                    \r
+                    Resource dependency = null;\r
+                    for(Resource dep : graph.getObjects(module, sr.Variable_isHeadOf)) {\r
+                        Resource refersTo = graph.getPossibleObject(dep, sr.Dependency_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..d35bc40
--- /dev/null
@@ -0,0 +1,94 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.widgets.impl.WidgetSupport;\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.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ModuleOutputEditingSupport;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRow;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceRowLabelProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.ReferenceTable;\r
+import org.simantics.sysdyn.ui.properties.widgets.modules.RowProvider;\r
+\r
+public class ModuleOutputTab extends LabelPropertyTabContributor {\r
+\r
+    public ModuleOutputTab(Object id) {\r
+        super(id);\r
+    }\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 = { 200, 200 };\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
+                Layer0 l0 = Layer0.getInstance(graph);\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, l0.InstanceOf);\r
+                if(instanceOf == null) return result;\r
+                Resource configuration = graph.getSingleObject(instanceOf, sr2.IsDefinedBy);\r
+                for(Resource variable : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Variable))) {\r
+                    if(!graph.hasStatement(variable, sr.IsOutput)) continue;\r
+                    \r
+                    Resource dependency = null;\r
+                    for(Resource dep : graph.getObjects(module, sr.Variable_isTailOf)) {\r
+                        Resource refersTo = graph.getPossibleObject(dep, sr.Dependency_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/ModuleParameterTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/ModuleParameterTab.java
new file mode 100644 (file)
index 0000000..e80cf20
--- /dev/null
@@ -0,0 +1,62 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Control;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+public class ModuleParameterTab extends LabelPropertyTabContributor {\r
+\r
+    public ModuleParameterTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    GraphExplorerComposite explorer;\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
+        explorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER);\r
+        \r
+        explorer.setBrowseContexts(SysdynResource.URIs.Module_ParameterOverrideBrowseContext);\r
+        explorer.setColumns(ColumnKeys.MODULE_PARAMETER_COLUMNS);\r
+        explorer.setInputSource(new SingleSelectionInputSource(\r
+                Resource.class));\r
+\r
+        explorer.finish();\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                explorer);\r
+        \r
+        Control c = explorer.getExplorerControl();\r
+        if (c instanceof Tree)\r
+            ((Tree) c).setLinesVisible(true);\r
+    }\r
+}\r
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..0a6ed53
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Control;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.VariableNameInputValidator;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+public class ModuleTab extends LabelPropertyTabContributor implements Widget {\r
+\r
+       public ModuleTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+\r
+    GraphExplorerComposite enumerationRedeclarationExplorer;\r
+       \r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+       support.register(this);\r
+       \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
+        TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new VariableNameInputValidator(support));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(nameText.getWidget());\r
+        \r
+        Label label = new Label(composite, SWT.NONE);\r
+               label.setText("Replaceable enumerations");\r
+               enumerationRedeclarationExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, composite, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI);\r
+               \r
+               enumerationRedeclarationExplorer\r
+               .setBrowseContexts(SysdynResource.URIs.EnumerationReplacement);\r
+               enumerationRedeclarationExplorer.setColumns(ColumnKeys.ENUMERATION_REDECLARATION_COLUMNS);\r
+               enumerationRedeclarationExplorer.setInputSource(new SingleSelectionInputSource(\r
+                               Resource.class));\r
+\r
+               enumerationRedeclarationExplorer.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               enumerationRedeclarationExplorer);\r
+               \r
+               Control c = enumerationRedeclarationExplorer.getExplorerControl();\r
+               if (c instanceof Tree)\r
+                       ((Tree) c).setLinesVisible(true);\r
+        \r
+    }\r
+    \r
+    \r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               enumerationRedeclarationExplorer.setInput(context, input);\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..69976cc
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.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.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.ModuleTypeNameInputValidator;\r
+\r
+public class ModuleTypeTab extends LabelPropertyTabContributor {\r
+\r
+    public ModuleTypeTab(Object id) {\r
+        super(id);\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(6).applyTo(composite);\r
+        TrackedText nameText = new TrackedText(composite, support, SWT.BORDER);\r
+        nameText.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
+        nameText.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        nameText.setInputValidator(new ModuleTypeNameInputValidator(support));\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/PlaybackExperimentTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/PlaybackExperimentTab.java
new file mode 100644 (file)
index 0000000..0c595db
--- /dev/null
@@ -0,0 +1,215 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\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.Image;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.utils.datastructures.Triple;\r
+import org.simantics.utils.ui.color.Color;\r
+import org.simantics.utils.ui.color.ColorGradient;\r
+import org.simantics.utils.ui.color.ColorValue;\r
+\r
+public class PlaybackExperimentTab extends LabelPropertyTabContributor {\r
+\r
+    public PlaybackExperimentTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    private static int gradientWidth = 250;\r
+    private static int gradientHeight = 20;\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 gradientGroup = new Group(composite, SWT.NONE);\r
+        gradientGroup.setText("Color scale");\r
+        GridDataFactory.fillDefaults().applyTo(gradientGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(gradientGroup);\r
+\r
+\r
+        ColorValue cv1 = new ColorValue(new Color(0, 62, 133), 0.0);\r
+        ColorValue cv2 = new ColorValue(new Color(255, 230, 0), 1.0);\r
+        ColorValue[] values = new ColorValue[] {cv1, cv2};\r
+        ColorGradient cg = new ColorGradient(values, ColorGradient.HSV);\r
+        Image image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL);\r
+        Button b = new Button(gradientGroup, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget());\r
+        b.setImage(image);\r
+        b.addSelectionListener(new GradientSelectionListener(context, values));\r
+        b.setSelectionFactory(new GradientSelectionFactory(values));\r
+\r
+        cv1 = new ColorValue(new Color(255, 230, 0), 0.0);\r
+        cv2 = new ColorValue(new Color(0, 62, 133), 1.0);\r
+        values = new ColorValue[] {cv1, cv2};\r
+        cg = new ColorGradient(values, ColorGradient.HSV);\r
+        image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL);\r
+        b = new Button(gradientGroup, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget());\r
+        b.setImage(image);\r
+        b.addSelectionListener(new GradientSelectionListener(context, values));\r
+        b.setSelectionFactory(new GradientSelectionFactory(values));\r
+        \r
+        cv1 = new ColorValue(new Color(0, 0, 0), 0.0);\r
+        cv2 = new ColorValue(new Color(255, 255, 255), 1.0);\r
+        values = new ColorValue[] {cv1, cv2};\r
+        cg = new ColorGradient(values, ColorGradient.HSV);\r
+        image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL);\r
+        b = new Button(gradientGroup, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget());\r
+        b.setImage(image);\r
+        b.addSelectionListener(new GradientSelectionListener(context, values));\r
+        b.setSelectionFactory(new GradientSelectionFactory(values));\r
+        \r
+        cv1 = new ColorValue(new Color(0, 0, 255), 0.0);\r
+        cv2 = new ColorValue(new Color(255, 0, 0), 1.0);\r
+        values = new ColorValue[] {cv1, cv2};\r
+        cg = new ColorGradient(values, ColorGradient.HSV);\r
+        image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL);\r
+        b = new Button(gradientGroup, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget());\r
+        b.setImage(image);\r
+        b.addSelectionListener(new GradientSelectionListener(context, values));\r
+        b.setSelectionFactory(new GradientSelectionFactory(values));\r
+        \r
+      \r
+        cv1 = new ColorValue(new Color(255, 0, 0), 0.0);\r
+        cv2 = new ColorValue(new Color(0, 0, 255), 1.0);\r
+        values = new ColorValue[] {cv1, cv2};\r
+        cg = new ColorGradient(values, ColorGradient.HSV);\r
+        image = cg.getGradientImage(gradientWidth, gradientHeight, SWT.HORIZONTAL);\r
+        b = new Button(gradientGroup, support, SWT.RADIO);\r
+        GridDataFactory.fillDefaults().hint(gradientWidth, gradientHeight).applyTo(b.getWidget());\r
+        b.setImage(image);\r
+        b.addSelectionListener(new GradientSelectionListener(context, values));\r
+        b.setSelectionFactory(new GradientSelectionFactory(values));\r
+    }\r
+\r
+\r
+    class GradientSelectionListener extends SelectionListenerImpl<Resource> {\r
+        private ArrayList<ColorValue> colorValues;\r
+\r
+        public GradientSelectionListener(ISessionContext context, ColorValue[] colorValues) {\r
+            super(context);\r
+            this.colorValues = new ArrayList<ColorValue>();\r
+            for(ColorValue cv : colorValues)\r
+                this.colorValues.add(cv);\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+            G2DResource g2d = G2DResource.getInstance(graph);\r
+\r
+            Resource gradient = graph.getPossibleObject(experiment, g2d.HasColorGradient);\r
+\r
+            if(gradient != null) {\r
+                graph.denyStatement(experiment, g2d.HasColorGradient, gradient);\r
+                RemoverUtil.remove(graph, gradient);\r
+            }\r
+\r
+            gradient = GraphUtils.create2(graph, g2d.ColorGradient);\r
+            graph.claim(experiment, g2d.HasColorGradient, gradient);\r
+\r
+            for(ColorValue cv : colorValues) {\r
+                Resource placement = GraphUtils.create2(graph, g2d.ColorPlacement, \r
+                        g2d.HasGradientPosition, cv.getValue());\r
+                graph.claimLiteral(placement, g2d.HasColor, g2d.Color, cv.getColor().getAWTColor().getColorComponents(new float[4]));\r
+                graph.claim(gradient, g2d.HasColorPlacement, placement);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    class GradientSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        private ArrayList<ColorValue> colorValues;\r
+\r
+        public GradientSelectionFactory(ColorValue[] colorValues) {\r
+            this.colorValues = new ArrayList<ColorValue>();\r
+            for(ColorValue cv : colorValues)\r
+                this.colorValues.add(cv);\r
+        }\r
+\r
+        @Override\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Triple<Object, Object, Class<?>>(inputContents, colorValues, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource experiment) throws DatabaseException {\r
+            G2DResource g2d = G2DResource.getInstance(graph);\r
+            Resource gradient = graph.getPossibleObject(experiment, g2d.HasColorGradient);\r
+            if(gradient == null) {\r
+                return Boolean.FALSE;\r
+            }\r
+            Collection<Resource> placements =  graph.syncRequest(new ObjectsWithType(gradient, g2d.HasColorPlacement, g2d.ColorPlacement));\r
+            if(placements.isEmpty())\r
+                return Boolean.FALSE;\r
+            \r
+            for(Resource placement : placements) {\r
+                Double position = graph.getPossibleRelatedValue(placement, g2d.HasGradientPosition);\r
+                if(position == null) \r
+                    return Boolean.FALSE;\r
+                int index = -1;\r
+                \r
+                // First look for a color with matching value\r
+                for(int i = 0; i < colorValues.size(); i++) {\r
+                    if(position.equals(colorValues.get(i).getValue())) {\r
+                        \r
+                        index = i;\r
+                        break;\r
+                    }\r
+                }\r
+                \r
+                // If matching value was found, see if the color is the same\r
+                if(index >= 0) {\r
+                    Color c = colorValues.get(index).getColor();\r
+                    float[] cArray = c.getAWTColor().getColorComponents(new float[4]);\r
+                    float[] color = graph.getPossibleRelatedValue(placement, g2d.HasColor, Bindings.FLOAT_ARRAY);\r
+                    for(int i = 0; i < color.length; i++) {\r
+                        if(cArray[i] != color[i])\r
+                            // Some inconsistency found in colors, return false\r
+                            return Boolean.FALSE;\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // Everything matched\r
+            return Boolean.TRUE;\r
+        }\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..369a8da
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+\r
+public class ReferenceDependencyTab extends LabelPropertyTabContributor {\r
+\r
+    public ReferenceDependencyTab(Object id) {\r
+        super(id);\r
+    }\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/RemoveFocusBeforeExperimentComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/RemoveFocusBeforeExperimentComposite.java
new file mode 100644 (file)
index 0000000..1966ecc
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.sysdyn.ui.utils.HandlerUtils;\r
+\r
+/**\r
+ * Composite for providing info for {@link HandlerUtils}.saveBeforeExperimentRun to force focus\r
+ * of text and other widgets before simulation. Forcing focus off makes the widget to save its value. \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class RemoveFocusBeforeExperimentComposite extends Composite {\r
+\r
+    public RemoveFocusBeforeExperimentComposite(Composite parent, int style) {\r
+        super(parent, style);\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..ab129cf
--- /dev/null
@@ -0,0 +1,545 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType;\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.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.jfreechart.ChartSelectionTabContributor;\r
+import org.simantics.jfreechart.chart.properties.ChartTab;\r
+import org.simantics.jfreechart.chart.properties.xyline.XYLineGeneralPropertiesTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.ui.property.svg.SVGElementComposite;\r
+import org.simantics.selectionview.ComparableTabContributor;\r
+import org.simantics.selectionview.SelectionProcessor;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
+import org.simantics.sysdyn.ui.trend.SensitivityChartAxisAndVariablesTab;\r
+import org.simantics.sysdyn.utils.SelectionUtils;\r
+import org.simantics.ui.selection.AnyVariable;\r
+import org.simantics.ui.selection.WorkbenchSelectionElement;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * SelectionProcessor for processing selections for property view in system dynamics\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ResourceSelectionProcessor implements SelectionProcessor<Object, ReadGraph>  {\r
+\r
+    private SpecialNodeType sharedFunctionsTestNode;\r
+\r
+    @Override\r
+    public Collection<?> process(Object selection, ReadGraph backend) {\r
+        List<ComparableTabContributor> tabs = new ArrayList<ComparableTabContributor>();\r
+        SysdynResource sr = SysdynResource.getInstance(backend);\r
+        DiagramResource dr = DiagramResource.getInstance(backend);\r
+        ModelingResources mr = ModelingResources.getInstance(backend);\r
+        SimulationResource simu = SimulationResource.getInstance(backend);\r
+//        JFreeChartResource jfree = JFreeChartResource.getInstance(backend);\r
+\r
+        // Test nodes\r
+        if(sharedFunctionsTestNode == null)\r
+            sharedFunctionsTestNode = new SpecialNodeType(sr.ModelingBrowseContext_SharedFunctionsFolder, Resource.class);\r
+\r
+        try {\r
+            // Many elements \r
+            if (selection instanceof ArrayList<?> && ((ArrayList<?>) selection).size() > 1) {\r
+               List<Resource> variables = new ArrayList<Resource>();\r
+               List<Resource> dependencies = new ArrayList<Resource>();\r
+               List<Resource> flows = new ArrayList<Resource>();\r
+                Resource model = null;\r
+                for(Object o : (ArrayList<?>)selection) {\r
+                    Resource r = AdaptionUtils.adaptToSingle(o, Resource.class);\r
+                    if (r == null)\r
+                       continue;\r
+                    Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
+                    if (component != null) {\r
+                        r = component;\r
+                    } else {\r
+                       // Try connection\r
+                        Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
+                        if(connection != null)\r
+                            r = connection;\r
+                    }\r
+                    \r
+                    if(r != null) {\r
+                        if(model == null)\r
+                            model = backend.getPossibleObject(r, Layer0.getInstance(backend).PartOf);\r
+                        if(model != null && model.equals( backend.getSingleObject(r, Layer0.getInstance(backend).PartOf))) {\r
+                               if (backend.isInstanceOf(r, sr.Variable)) {\r
+                                       variables.add(r);\r
+                               } else if (backend.isInstanceOf(r, sr.Dependency)) {\r
+                                       Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+                                       dependencies.add(diaConnection);\r
+                               } else if (backend.isInstanceOf(r, sr.Flow)) {\r
+                                       Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+                                       flows.add(diaConnection);\r
+                               }\r
+                        }\r
+                    }\r
+                }\r
+                \r
+                if (!variables.isEmpty())\r
+                       // Do we have at least one variable\r
+                       tabs.add(new ComparableTabContributor(\r
+                               new ArrayIndexesTab(variables),\r
+                               1,\r
+                               variables,\r
+                               "Indexes"));\r
+                else if (!dependencies.isEmpty()) {\r
+                    // Dependencies only\r
+                       tabs.add(new ComparableTabContributor(\r
+                            new ArrayDependencyTab(dependencies),\r
+                            1,\r
+                            dependencies,\r
+                            "Dependency Properties"));\r
+                }\r
+                else if (!flows.isEmpty()) {\r
+                    // Flows only\r
+                       tabs.add(new ComparableTabContributor(\r
+                            new ArrayFlowTab(flows),\r
+                            1,\r
+                            flows,\r
+                            "Flow Properties"));\r
+                }\r
+                return tabs;\r
+            }\r
+\r
+            // Single element\r
+            Variable var = null; \r
+            WorkbenchSelectionElement wse = ISelectionUtils.filterSingleSelection(selection, WorkbenchSelectionElement.class);\r
+            if(wse != null) {\r
+                var = wse.getContent(new AnyVariable(backend));\r
+                if(var == null) {\r
+                    var = AdaptionUtils.adaptToSingle(selection, Variable.class);\r
+                    if(var != null) {\r
+                        Variable possibleActiveVariable = backend.syncRequest(new PossibleActiveVariableFromVariable(var));\r
+                        if(possibleActiveVariable != null)\r
+                            var = possibleActiveVariable;\r
+                    }\r
+                }\r
+            }\r
+\r
+            Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
+            if(r == null) {\r
+                // Selection is not directly a resource, try if it is a variable \r
+                var = AdaptionUtils.adaptToSingle(selection, Variable.class);\r
+                if(var != null)\r
+                    r = var.getRepresents(backend);\r
+            }\r
+            \r
+            if(r == null) {\r
+                // SharedFunctionsFolder has properties but no adapted resource\r
+                SharedFunctionsFolder sff = AdaptionUtils.adaptToSingle(selection, SharedFunctionsFolder.class);\r
+                if (sff != null) {\r
+                    return Collections.singleton(new ComparableTabContributor(\r
+                            new SharedFunctionLibrariesTab(sff.data),\r
+                            2,\r
+                            sff.data,\r
+                            "Shared Functions"));\r
+                }\r
+\r
+                return Collections.emptyList();\r
+            }\r
+\r
+            NodeContext nc = AdaptionUtils.adaptToSingle(selection, NodeContext.class);\r
+            if(nc != null) {\r
+                NodeType type = nc.getConstant(NodeType.TYPE);\r
+                if(type != null && type.equals(sharedFunctionsTestNode)) {\r
+                    return Collections.singleton(new ComparableTabContributor(\r
+                            new SharedFunctionLibrariesTab(r),\r
+                            2,\r
+                            r,\r
+                            "Shared Functions"));\r
+                }\r
+            }\r
+\r
+            // SVG elements in symbol editor\r
+            if (backend.isInstanceOf(r, dr.SVGElement))\r
+                return Collections.singleton(SVGElementComposite.make(r, 1, "SVG"));\r
+\r
+            // if r == diagram element, change it to component\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
+            \r
+            \r
+            // Check that var has found the correct variable\r
+            if(r != null && var != null) {\r
+                if(!r.equals(var.getRepresents(backend)))\r
+                    // Var found the wrong variable. This may happen with ModuleType editors\r
+                    var = null;\r
+            }\r
+            \r
+            \r
+            // If shadow variable, display properties of the original variable\r
+            if(backend.isInstanceOf(r, sr.Shadow)) {\r
+                Resource original = backend.getPossibleObject(r, sr.Shadow_original);\r
+                if(original != null && var != null) {\r
+                    r = original;\r
+                    Variable parent = var.getParent(backend);\r
+                    var = parent.getPossibleChild(backend, NameUtils.getSafeName(backend, r));\r
+                }\r
+            }\r
+\r
+            // If loop\r
+            if(backend.isInstanceOf(r, sr.Loop)) {\r
+               return Collections.singleton(\r
+                               (new ComparableTabContributor(\r
+                               new LoopTab(r),\r
+                               1,\r
+                               r,\r
+                               "Loop")));\r
+            }\r
+\r
+            // Independent variable\r
+            if (backend.isInstanceOf(r, sr.IndependentVariable)) {\r
+                Resource activeExpression = backend.getPossibleObject(r, sr.IndependentVariable_activeExpression);\r
+                Resource expression = null;\r
+                if(activeExpression != null)\r
+                    // if variable has active expression, display it\r
+                    expression = activeExpression;\r
+                else if (backend.hasStatement(r, sr.Variable_expressionList)){\r
+                    // else display the first expression of the variable\r
+                    Resource expressions = backend.getPossibleObject(r, sr.Variable_expressionList);\r
+                    List<Resource> expressionList = ListUtils.toList(backend, expressions);\r
+                    if(expressionList.isEmpty()) {\r
+                        System.err.println("expressionList is empty for " + r);\r
+                        return Collections.emptyList();\r
+                    }\r
+                    expression = expressionList.get(0);\r
+                }\r
+                tabs.add(new ComparableTabContributor(\r
+                        new EquationTab(var != null ? var : r),\r
+                        3,\r
+                        var != null ? var : r,\r
+                        "Equation"));\r
+                if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+                    // WithLookupExpression has its own extra tab for visual configuration\r
+                    tabs.add(new ComparableTabContributor(\r
+                            new LookupTableTab(expression),\r
+                            2,\r
+                            expression,\r
+                            "Lookup Table"));\r
+                }\r
+\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ArrayIndexesTab(r),\r
+                        1,\r
+                        r,\r
+                        "Indexes"));\r
+\r
+                tabs.add(new ComparableTabContributor(\r
+                        new VariableInformationTab(r),\r
+                        0,\r
+                        r,\r
+                        "Additional Information"));\r
+                return tabs;\r
+            }\r
+\r
+            // Input variable\r
+            if (backend.isInstanceOf(r, sr.Input)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new InputVariableTab(r),\r
+                        2,\r
+                        r,\r
+                        "Input"));\r
+\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ArrayIndexesTab(r),\r
+                        1,\r
+                        r,\r
+                        "Indexes"));\r
+\r
+                tabs.add(new ComparableTabContributor(\r
+                        new VariableInformationTab(r),\r
+                        0,\r
+                        r,\r
+                        "Additional Information"));\r
+                return tabs;\r
+            }\r
+\r
+            // Enumeration\r
+            if (backend.isInstanceOf(r, sr.Enumeration)) {\r
+                Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
+                if(s == null)\r
+                    s = r;\r
+                // give either variable or the actual resource\r
+                return Collections.singleton(new ComparableTabContributor(\r
+                        new EnumerationTab(s),\r
+                        2,\r
+                        s,\r
+                        "Enumeration"));\r
+            }\r
+\r
+            // Configuration and model. They both show the properties of the configuration\r
+            if ( backend.isInstanceOf(r, sr.Configuration) || backend.isInstanceOf(r, sr.SysdynModel)) {\r
+                if(!backend.isInstanceOf(r, sr.SysdynModel))\r
+                    r = backend.getPossibleObject(r, SimulationResource.getInstance(backend).IsConfigurationOf);\r
+                if (r != null)\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new ConfigurationTab(r),\r
+                                    0,\r
+                                    r,\r
+                                    "Model Properties"));\r
+            }\r
+\r
+            // Module\r
+            if (backend.isInstanceOf(r, sr.Module)){\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleTab(r),\r
+                        10,\r
+                        r,\r
+                        "Module Properties"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleParameterTab(r),\r
+                        9,\r
+                        r,\r
+                        "Parameters"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleInputTab(r),\r
+                        2,\r
+                        r,\r
+                        "Inputs"));\r
+                tabs.add(new ComparableTabContributor(\r
+                        new ModuleOutputTab(r),\r
+                        1,\r
+                        r,\r
+                        "Outputs"));\r
+                return tabs;\r
+            }\r
+\r
+            // Playback experiment\r
+            if (backend.isInstanceOf(r, sr.PlaybackExperiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new PlaybackExperimentTab(r),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+\r
+         // Game experiment\r
+            if (backend.isInstanceOf(r, sr.GameExperiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new GameExperimentTab(r),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+\r
+         // Sensitivity analysis experiment\r
+            if (backend.isInstanceOf(r, sr.SensitivityAnalysisExperiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new SensitivityAnalysisExperimentTab(r),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+\r
+         // Default experiment\r
+            if (backend.isInstanceOf(r, simu.Experiment))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new ExperimentTab(r),\r
+                                0,\r
+                                r,\r
+                                "Experiment Properties"));\r
+\r
+            // History data\r
+            if (backend.isInstanceOf(r, sr.HistoryDataset))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new HistoryDataTab(r),\r
+                                0,\r
+                                r,\r
+                                "History Data Properties"));\r
+\r
+            // Saved simulation result\r
+            if (backend.isInstanceOf(r, sr.Result))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new ResultTab(r),\r
+                                0,\r
+                                r,\r
+                                "Result Properties"));\r
+\r
+            // Dependency\r
+            if (backend.isInstanceOf(r, sr.Dependency))\r
+                if (backend.hasStatement(r, sr.Dependency_refersTo)) {\r
+                    Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new DependencyTab(diaConnection),\r
+                                    0,\r
+                                    diaConnection,\r
+                                    "Reference Properties"));\r
+                } else {\r
+                    Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new DependencyTab(diaConnection),\r
+                                    0,\r
+                                    diaConnection,\r
+                                    "Dependency Properties"));\r
+                }\r
+\r
+            // Flow\r
+            if (backend.isInstanceOf(r, sr.Flow)) {\r
+               Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
+               return Collections.singleton(\r
+                       new ComparableTabContributor(\r
+                                       new FlowTab(diaConnection),\r
+                                       0,\r
+                                       diaConnection,\r
+                                       "Flow Properties"));\r
+            }\r
+\r
+            // Module symbol. Modules in modules-folder are actually symbol resources\r
+            if (backend.isInheritedFrom(r, sr.ModuleSymbol)) {\r
+                // Find the component resource\r
+                r =  backend.getPossibleObject(r, mr.SymbolToComponentType);\r
+                if(r != null)\r
+                    return Collections.singleton(\r
+                            new ComparableTabContributor(\r
+                                    new ModuleTypeTab(r),\r
+                                    0,\r
+                                    r,\r
+                                    "Module Type Properties"));\r
+            }\r
+\r
+            // Function\r
+            if (backend.isInstanceOf(r, sr.SysdynModelicaFunction)) {\r
+                tabs.add(new ComparableTabContributor(\r
+                        new FunctionTab(r),\r
+                        2,\r
+                        r,\r
+                        "Function"));\r
+                if (SelectionUtils.canEdit(backend, r)) {\r
+                    tabs.add(new ComparableTabContributor(\r
+                        new ExternalFilesTab(r),\r
+                        1,\r
+                        r,\r
+                        "External files"));\r
+                }\r
+                return tabs;\r
+            }\r
+\r
+            // Function library\r
+            if (backend.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)) {\r
+                Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
+                if(s == null)\r
+                    s = r;\r
+                // give either variable or the actual resource\r
+                return Collections.singleton(new ComparableTabContributor(\r
+                        new FunctionLibraryTab(s),\r
+                        2,\r
+                        s,\r
+                        "Function library"));\r
+            }\r
+            \r
+            // Try sensitivity chart before other charts\r
+            if (contributeSensitivityChart(backend, r, tabs)) {\r
+                return tabs;\r
+            }\r
+            \r
+            // Try normal charts\r
+            if (ChartSelectionTabContributor.contibuteTabs(backend, r, tabs)) {\r
+               return tabs;\r
+            }\r
+\r
+            // Default experiment\r
+            if (backend.isInstanceOf(r, sr.AdditionalSymbols_MultilineText))\r
+                return Collections.singleton(\r
+                        new ComparableTabContributor(\r
+                                new CommentTab(r),\r
+                                0,\r
+                                r,\r
+                                "Comment"));\r
+\r
+        } catch (ServiceException e) {\r
+            e.printStackTrace();\r
+        } catch (ManyObjectsForFunctionalRelationException e) {\r
+            e.printStackTrace();\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return Collections.emptyList();\r
+    }\r
+    \r
+    public static boolean contributeSensitivityChart(ReadGraph backend, Resource r, List<ComparableTabContributor> tabs) throws DatabaseException {\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(backend);\r
+        if(backend.isInstanceOf(r, jfree.ChartElement)) {\r
+            if(backend.hasStatement(r, jfree.ChartElement_component))\r
+                r = backend.getSingleObject(r, jfree.ChartElement_component);\r
+        }\r
+\r
+        if (backend.isInstanceOf(r, jfree.Chart)) {\r
+\r
+            Collection<Resource> plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot));\r
+            if(!plots.isEmpty()) {\r
+                Resource plot = plots.iterator().next();\r
+\r
+                if(backend.isInstanceOf(plot, SysdynResource.getInstance(backend).Charts_SensitivityPlot)) {\r
+                    tabs.add(new ComparableTabContributor(\r
+                            new XYLineGeneralPropertiesTab(r),\r
+                            10,\r
+                            r,\r
+                            "General"));\r
+                    tabs.add(new ComparableTabContributor(\r
+                            new SensitivityChartAxisAndVariablesTab(r),\r
+                            9,\r
+                            r,\r
+                            "Axis and Variables"));\r
+                    tabs.add(new ComparableTabContributor(\r
+                            new ChartTab(r),\r
+                            1,\r
+                            r,\r
+                            "Chart"));\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\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..0fff894
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+\r
+public class ResultTab extends LabelPropertyTabContributor {\r
+\r
+    public ResultTab(Object id) {\r
+        super(id);\r
+    }\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/SensitivityAnalysisExperimentTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SensitivityAnalysisExperimentTab.java
new file mode 100644 (file)
index 0000000..60b3fdc
--- /dev/null
@@ -0,0 +1,647 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\r
+import org.eclipse.swt.events.DisposeEvent;\r
+import org.eclipse.swt.events.DisposeListener;\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.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.Column;\r
+import org.simantics.browsing.ui.Column.Align;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.common.NodeContextBuilder.MapNodeContext;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.SelectionListenerImpl;\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.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.procedure.adapter.DisposableListener;\r
+import org.simantics.db.common.utils.ListUtils;\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.jfreechart.chart.ChartUtils;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.jfreechart.chart.properties.RangeComposite;\r
+import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.IntegerPropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.IntegerPropertyModifier;\r
+import org.simantics.sysdyn.ui.properties.widgets.sensitivity.DistributionPropertyWidget;\r
+import org.simantics.sysdyn.ui.properties.widgets.sensitivity.ParameterChildRule;\r
+import org.simantics.sysdyn.ui.properties.widgets.sensitivity.VariableNameModifier;\r
+import org.simantics.sysdyn.ui.validation.ParameterExistsValidator;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.RunnableWithObject;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.validators.IntegerValidator;\r
+\r
+/**\r
+ * Tab for displaying sensitivity analysis experiment properties\r
+ * \r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SensitivityAnalysisExperimentTab extends AdjustableTab implements Widget {\r
+\r
+    public SensitivityAnalysisExperimentTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    private GraphExplorerComposite explorer;\r
+    private WidgetSupportImpl parameterSupport = new WidgetSupportImpl();\r
+    private ScrolledComposite propertyContainer;\r
+    private Composite parameterProperties;\r
+    private Composite content;\r
+    private Button remove;\r
+    private Resource experiment;\r
+    \r
+    private boolean dirty = false;\r
+    private boolean dirtyMethod = false;\r
+    \r
+    private DisposableListener<Collection<Resource>> contentListener;\r
+       private Composite labelComposite;\r
+       private Label labelName;\r
+       private Label labelNumber;\r
+       private Label labelMethod;\r
+       private TrackedCombo methodSelector;\r
+       private Label labelSeed;\r
+       private TrackedText seed;\r
+       private Tree tree;\r
+       private Composite buttonComposite;\r
+       private Group parameterPropertyGroup;\r
+       private Label labelVariable;\r
+       private TrackedText variable;\r
+       private Label labelRange;\r
+       private RangeComposite rangeComposite;\r
+       private Label labelDistribution;\r
+       private TrackedCombo distributionSelector;\r
+       private DistributionPropertyWidget dpw;\r
+       private TrackedText name;\r
+       private TrackedText n;\r
+       private Button addVariable;\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site,\r
+            final ISessionContext context, final WidgetSupport support) {\r
+        support.register(this);\r
+        super.createControls(body, site, context, support);\r
+    }\r
+\r
+    /**\r
+     * Updates the content of propertyContainer  \r
+     * @param context\r
+     */\r
+    private void updateSelection(ISessionContext context) {\r
+        ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+        IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection();\r
+        parameterSupport.fireInput(context, selection);\r
+\r
+        propertyContainer.setContent(content);\r
+        Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        propertyContainer.setMinSize(size);\r
+    }\r
+\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        experiment = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        if(contentListener == null) {\r
+            contentListener = new DisposableListener<Collection<Resource>>() {\r
+\r
+                @Override\r
+                public void execute(Collection<Resource> result) {\r
+                    if(remove != null && !remove.getWidget().isDisposed() && result != null) {\r
+                        remove.getWidget().getDisplay().asyncExec(new RunnableWithObject(result) {\r
+                            @Override\r
+                            public void run() {\r
+                                if(!remove.getWidget().isDisposed()) {\r
+                                    @SuppressWarnings("unchecked")\r
+                                    Collection<Resource> result = (Collection<Resource>) getObject();\r
+                                    if(result.size() > 1)\r
+                                        remove.getWidget().setEnabled(true);\r
+                                    else\r
+                                        remove.getWidget().setEnabled(false);\r
+                                }\r
+                            }\r
+                        });\r
+\r
+                    }\r
+                }\r
+\r
+                @Override\r
+                public void exception(Throwable t) {\r
+                    t.printStackTrace();\r
+                }\r
+            };\r
+\r
+            SimanticsUI.getSession().asyncRequest(new Read<Collection<Resource>> () {\r
+\r
+                @SuppressWarnings("unchecked")\r
+                @Override\r
+                public Collection<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                    return (Collection<Resource>) new ParameterChildRule().getChildren(graph, experiment);\r
+                }\r
+\r
+            }, contentListener);\r
+        }\r
+\r
+    }\r
+\r
+\r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       final ISessionContext context, final WidgetSupport support) {\r
+\r
+        composite = new RemoveFocusBeforeExperimentComposite(body, SWT.NONE);\r
+        \r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL);\r
+        propertyContainer.setExpandHorizontal(true);\r
+        propertyContainer.setExpandVertical(true);\r
+        \r
+        content = new Composite(propertyContainer, SWT.NONE);\r
+\r
+        // Label\r
+        labelComposite = new Composite(content, SWT.NONE);\r
+        labelName = new Label(labelComposite, SWT.NONE);\r
+        labelName.setText("Name");\r
+\r
+        name = new TrackedText(labelComposite, support, SWT.BORDER);\r
+        name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasLabel));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasLabel));\r
+        name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
+        name.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), name.getWidget())));\r
+        \r
+        labelNumber = new Label(labelComposite, SWT.NONE);\r
+        labelNumber.setText("Number of runs");\r
+        \r
+        n = new TrackedText(labelComposite, support, SWT.BORDER);\r
+        n.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues));\r
+        n.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_numberOfValues));\r
+        n.setInputValidator(new IntegerValidator());\r
+        n.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), n.getWidget())));\r
+        \r
+        labelMethod = new Label(labelComposite, SWT.NONE);\r
+        labelMethod.setText("Method");\r
+        \r
+        methodSelector = new TrackedCombo(labelComposite, support, SWT.DROP_DOWN);\r
+        methodSelector.setItemFactory(new ReadFactoryImpl<Resource, Map<String,Object>>() {\r
+\r
+            @Override\r
+            public Map<String, Object> perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+                Map<String, Object> items = new HashMap<String, Object>();\r
+\r
+                items.put("Halton", SR.HaltonSequenceGenerator);\r
+                items.put("Random", SR.RandomGenerator);\r
+                \r
+                return items;\r
+            }\r
+\r
+        });\r
+        methodSelector.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, Resource parameter) throws DatabaseException {\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+                Resource method = graph.getPossibleObject(parameter, SR.SensitivityAnalysisExperiment_method);\r
+                if(method == null)\r
+                    return null;\r
+                \r
+                if(graph.isInstanceOf(method, SR.RandomGenerator))\r
+                    return "Random";\r
+                else if(graph.isInstanceOf(method, SR.HaltonSequenceGenerator))\r
+                    return "Halton";\r
+                else\r
+                    return "";\r
+\r
+            }\r
+        });\r
+        methodSelector.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+            @Override\r
+            public void applyText(WriteGraph graph, Resource input, String text)\r
+                    throws DatabaseException {\r
+                if(text == null || text.isEmpty())\r
+                    return;\r
+\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+                Resource type = SR.RandomGenerator;\r
+\r
+                if("Halton".equals(text))\r
+                    type = SR.HaltonSequenceGenerator;\r
+                \r
+                graph.deny(input, SR.SensitivityAnalysisExperiment_method);\r
+\r
+                GraphUtils.create2(graph, type,\r
+                        SR.SensitivityAnalysisExperiment_method_Inverse, input);\r
+\r
+                dirtyMethod = true;\r
+            }\r
+        });\r
+        methodSelector.addModifyListener(new TextModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(TrackedModifyEvent e) {\r
+                if(dirtyMethod) {\r
+                    support.update();\r
+                    dirtyMethod = false;\r
+                    propertyContainer.setContent(content);\r
+                    Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                    propertyContainer.setMinSize(size);\r
+                }\r
+            }\r
+        });\r
+        \r
+        labelSeed = new Label(labelComposite, SWT.NONE);\r
+        labelSeed.setText("Seed");\r
+        \r
+        seed = new TrackedText(labelComposite, support, SWT.BORDER);\r
+        seed.setTextFactory(new IntegerPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_randomSeed));\r
+        seed.addModifyListener(new IntegerPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_randomSeed));\r
+        seed.setInputValidator(new IntegerValidator());\r
+        seed.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), seed.getWidget())));\r
+\r
+        // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis\r
+        explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys(\r
+                "displaySelectors", "displayFilter", "treeView").values(false, false, true), site, content, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE);\r
+        \r
+        explorer.setBrowseContexts(SysdynResource.URIs.SensitivityAnalysisExperiment_ParameterBrowseContext);\r
+        explorer.setInputSource(new SingleSelectionInputSource(\r
+                Resource.class));\r
+        explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning\r
+        explorer.setColumns( new Column[] { new Column(ColumnKeys.SINGLE, Align.LEFT, 0, "", true) });\r
+        explorer.finish();\r
+        \r
+        \r
+        ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                updateSelection(context);\r
+            }\r
+        });\r
+\r
+        /* Listener for displaying information of the first parameter during view initialization\r
+         * The view does not have focus, so normal selection listener mechanisms do not work. \r
+         * Need to do it the hard way. \r
+         */ \r
+        Listener listener = new Listener() {\r
+\r
+            boolean flag = false;\r
+            @Override\r
+            public void handleEvent(Event event) {\r
+                switch (event.type) {\r
+                    case SWT.Activate:\r
+                    case SWT.Show:\r
+                    case SWT.Paint:\r
+                    {\r
+                        if(!flag && ((Tree) event.widget).getItems().length > 0) {\r
+                            flag = true;\r
+                            TreeItem item = ((Tree) event.widget).getItems()[0];\r
+                            IAdaptable adaptable = (IAdaptable) item.getData();\r
+                            MapNodeContext nc = (MapNodeContext) adaptable.getAdapter(NodeContext.class);\r
+                            parameterSupport.fireInput(context, new StructuredSelection(nc.getConstant(BuiltinKeys.INPUT)));\r
+                            propertyContainer.setContent(content);\r
+                            Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                            propertyContainer.setMinSize(size);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        };\r
+\r
+        tree = explorer.getExplorerControl();\r
+        tree.addListener(SWT.Activate, listener);\r
+        tree.addListener(SWT.Show, listener);\r
+        tree.addListener(SWT.Paint,listener);\r
+        /* End listener for displaying information for first parameter during view initialization*/\r
+        \r
+        explorer.addDisposeListener(new DisposeListener() {\r
+            \r
+            @Override\r
+            public void widgetDisposed(DisposeEvent e) {\r
+                if(contentListener != null)\r
+                    contentListener.dispose();              \r
+            }\r
+        });\r
+        \r
+        \r
+        buttonComposite = new Composite(explorer, SWT.NONE);\r
+        \r
+        addVariable = new Button(buttonComposite, support, SWT.NONE);\r
+        addVariable.setText("Add parameter");\r
+        addVariable.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
+                Layer0 L0 = Layer0.getInstance(graph);\r
+                \r
+                Resource distribution = GraphUtils.create2(graph, sr.UniformDistribution,\r
+                        sr.UniformDistribution_minValue, 0.0,\r
+                        sr.UniformDistribution_maxValue, 10.0);\r
+                \r
+                Resource parameter = GraphUtils.create2(graph, sr.SensitivityAnalysisExperiment_Parameter,\r
+                        sr.SensitivityAnalysisExperiment_Parameter_propabilityDistribution, distribution,\r
+                        sr.SensitivityAnalysisExperiment_Parameter_variable, ChartUtils.emptyVariableName,\r
+                        L0.PartOf, input);\r
+                \r
+                Resource parameterList = graph.getPossibleObject(input, sr.SensitivityAnalysisExperiment_parameterList);\r
+                ListUtils.insertBack(graph, parameterList, Collections.singleton(parameter));\r
+            }\r
+        });\r
+\r
+        remove = new Button(buttonComposite, parameterSupport, SWT.NONE);\r
+        remove.setText("Remove");\r
+        remove.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                if(input == null)\r
+                    return;\r
+                \r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                Layer0 L0 = Layer0.getInstance(graph);\r
+                \r
+                Resource experiment = graph.getPossibleObject(input, L0.PartOf);\r
+                Resource parameterList = graph.getPossibleObject(experiment, sr.SensitivityAnalysisExperiment_parameterList);\r
+                \r
+                if(ListUtils.toList(graph, parameterList).size() > 1)\r
+                    ListUtils.removeElement(graph, parameterList, input);\r
\r
+            }\r
+            \r
+        });\r
+        propertyContainer.setContent(content);\r
+        \r
+        \r
+        parameterPropertyGroup = new Group(content, SWT.NONE);\r
+        \r
+        parameterProperties = new Composite(parameterPropertyGroup, SWT.NONE);\r
+\r
+        // Label\r
+        labelVariable = new Label(parameterProperties, SWT.NONE);\r
+        labelVariable.setText("Variable:");\r
+\r
+        variable = new TrackedText(parameterProperties, parameterSupport, SWT.BORDER);\r
+        variable.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable));\r
+        variable.addModifyListener(new VariableNameModifier(variable.getWidget(), parameterSupport, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_indexes));\r
+        variable.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), variable.getWidget())));\r
+        variable.setInputValidator(new ParameterExistsValidator(parameterSupport, variable));\r
+        \r
+        labelRange = new Label(parameterProperties, SWT.NONE);\r
+        labelRange.setText("Range:");\r
+        \r
+        rangeComposite = new RangeComposite(parameterProperties, context, parameterSupport, SWT.NONE) {\r
+            @Override\r
+            protected Resource getIndexRelation(ReadGraph graph) {\r
+                return SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_indexes;\r
+            }\r
+        };\r
+        \r
+//        TrackedText variable = new TrackedText(parameterProperties, parameterSupport, SWT.BORDER);\r
+//        variable.setTextFactory(new StringPropertyFactory(SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable));\r
+//        variable.addModifyListener(new StringPropertyModifier(context, SysdynResource.URIs.SensitivityAnalysisExperiment_Parameter_variable));\r
+//        variable.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), variable.getWidget())));\r
+//        GridDataFactory.fillDefaults().grab(true, false).applyTo(variable.getWidget());\r
+\r
+        labelDistribution = new Label(parameterProperties, SWT.NONE);\r
+        labelDistribution.setText("Distribution:");\r
+\r
+        distributionSelector = new TrackedCombo(parameterProperties, parameterSupport, SWT.DROP_DOWN);\r
+        distributionSelector.setItemFactory(new ReadFactoryImpl<Resource, Map<String,Object>>() {\r
+\r
+            @Override\r
+            public Map<String, Object> perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+                Map<String, Object> items = new HashMap<String, Object>();\r
+\r
+                items.put("Normal", SR.NormalDistribution);\r
+                items.put("Uniform", SR.UniformDistribution);\r
+                items.put("Interval", SR.Interval);\r
+\r
+                return items;\r
+            }\r
+\r
+        });\r
+\r
+        distributionSelector.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+            @Override\r
+            public String perform(ReadGraph graph, Resource parameter) throws DatabaseException {\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+                Resource distribution = graph.getPossibleObject(parameter, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution);\r
+                if(distribution == null)\r
+                    return null;\r
+                \r
+                if(graph.isInstanceOf(distribution, SR.UniformDistribution))\r
+                    return "Uniform";\r
+                else if(graph.isInstanceOf(distribution, SR.NormalDistribution))\r
+                    return "Normal";\r
+                else if(graph.isInstanceOf(distribution, SR.Interval))\r
+                    return "Interval";\r
+                else\r
+                    return "";\r
+\r
+            }\r
+        });\r
+\r
+        distributionSelector.addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+            @Override\r
+            public void applyText(WriteGraph graph, Resource input, String text)\r
+                    throws DatabaseException {\r
+                if(text == null || text.isEmpty())\r
+                    return;\r
+\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+                Resource type = SR.UniformDistribution;\r
+\r
+                if("Normal".equals(text))\r
+                    type = SR.NormalDistribution;\r
+                else if("Interval".equals(text))\r
+                    type = SR.Interval; \r
+\r
+                graph.deny(input, SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution);\r
+\r
+                GraphUtils.create2(graph, type,\r
+                        SR.SensitivityAnalysisExperiment_Parameter_propabilityDistribution_Inverse, input);\r
+\r
+                dirty = true;\r
+            }\r
+        });\r
+\r
+        distributionSelector.addModifyListener(new TextModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(TrackedModifyEvent e) {\r
+                if(dirty) {\r
+                    parameterSupport.update();\r
+                    dirty = false;\r
+                    propertyContainer.setContent(content);\r
+                    Point size = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                    propertyContainer.setMinSize(size);\r
+                }\r
+            }\r
+        });\r
+\r
+        dpw = new DistributionPropertyWidget(parameterProperties, context, parameterSupport, SWT.NONE);\r
+    }\r
+\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+       \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+        \r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(propertyContainer);\r
+        GridLayoutFactory.fillDefaults().applyTo(propertyContainer);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(content);\r
+        GridLayoutFactory.fillDefaults().numColumns(1).applyTo(content);\r
+\r
+        // Label\r
+        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(labelComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(labelComposite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(n.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(seed.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().hint(150, SWT.DEFAULT).grab(false, true).applyTo(explorer);\r
+        \r
+        GridDataFactory.fillDefaults().applyTo(buttonComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);\r
+        \r
+        Point tsize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        propertyContainer.setMinSize(tsize);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterPropertyGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(parameterPropertyGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterProperties);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parameterProperties);\r
+\r
+        // Label\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelVariable);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(variable.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelRange);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(rangeComposite);\r
+        \r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelDistribution);\r
+        \r
+        GridDataFactory.fillDefaults().span(3, 1).grab(true, true).applyTo(dpw);\r
+        GridLayoutFactory.fillDefaults().margins(6, 0).applyTo(dpw);\r
+       }\r
+       \r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(composite);\r
+        \r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(propertyContainer);\r
+        GridLayoutFactory.fillDefaults().applyTo(propertyContainer);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(content);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(content);\r
+\r
+        // Label\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(labelComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(8).applyTo(labelComposite);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(name.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(n.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(seed.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer);\r
+\r
+        GridDataFactory.fillDefaults().applyTo(buttonComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(buttonComposite);\r
+        \r
+        Point tsize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        propertyContainer.setMinSize(tsize);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterPropertyGroup);\r
+        GridLayoutFactory.fillDefaults().applyTo(parameterPropertyGroup);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(parameterProperties);\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(parameterProperties);\r
+\r
+        // Label\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelVariable);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(variable.getWidget());\r
+        \r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelRange);\r
+        \r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(rangeComposite);\r
+        \r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(labelDistribution);\r
+\r
+        GridDataFactory.fillDefaults().span(1, 1).grab(true, true).applyTo(dpw);\r
+        GridLayoutFactory.fillDefaults().margins(6, 0).applyTo(dpw);\r
+\r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SharedFunctionLibrariesTab.java
new file mode 100644 (file)
index 0000000..a130a91
--- /dev/null
@@ -0,0 +1,254 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\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.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\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.NodeContext;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.LabelPropertyTabContributor;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class SharedFunctionLibrariesTab extends LabelPropertyTabContributor implements Widget {\r
+       \r
+       public SharedFunctionLibrariesTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    GraphExplorerComposite availableSharedFunctionLibraries;\r
+       GraphExplorerComposite usedSharedFunctionLibraries;\r
+       Resource model;\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+               support.register(this);\r
+               \r
+               GridLayoutFactory.fillDefaults().numColumns(4).applyTo(body);\r
+               \r
+               \r
+               Composite available = new Composite(body, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().applyTo(available);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(available);\r
+               Label label = new Label(available, SWT.None);\r
+               label.setText("Available Shared Function Libraries");\r
+               availableSharedFunctionLibraries = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, available, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI) {\r
+                   \r
+                       @Override\r
+                       protected void handleDrop(Object data, NodeContext target) {\r
+                       if (!(data instanceof IStructuredSelection))\r
+                               return;\r
+                       \r
+                       IStructuredSelection iss = (IStructuredSelection)data;\r
+                       if (iss == null || iss.isEmpty())\r
+                               return;\r
+                       \r
+                       for (Iterator<?> iterator = iss.iterator(); iterator.hasNext();) {\r
+                           Object o = iterator.next();\r
+                           if(o instanceof IAdaptable) {\r
+                               IAdaptable a = (IAdaptable)o;\r
+                               final SharedFunctionLibraryNode node = (SharedFunctionLibraryNode)a.getAdapter(SharedFunctionLibraryNode.class);\r
+                               if(node != null) {\r
+                                       SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                       if(getModel() != null && node.data != null)\r
+                                                               graph.deny(getModel(), Layer0.getInstance(graph).IsLinkedTo, node.data);                                                                \r
+                                               }\r
+                                       });\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+               };\r
+               \r
+               availableSharedFunctionLibraries\r
+               .setBrowseContexts(SysdynResource.URIs.AvailableSharedFunctionLibraries);\r
+               availableSharedFunctionLibraries.setInputSource(new SingleSelectionInputSource(\r
+                               Resource.class));\r
+\r
+               availableSharedFunctionLibraries.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               availableSharedFunctionLibraries);\r
+               \r
+               Composite middleButtons = new Composite(body, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().applyTo(middleButtons);\r
+               GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(false, true).applyTo(middleButtons);\r
+               \r
+               Button add = new Button(middleButtons, support, SWT.NONE);\r
+               add.setText(" -> ");\r
+               \r
+               add.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+                   List<Resource> selectedLibraries;\r
+\r
+                   public void beforeApply() {\r
+                       selectedLibraries = getSelectedResources(availableSharedFunctionLibraries);\r
+                   }\r
+\r
+                   @Override\r
+                   public void apply(WriteGraph graph, Resource input)\r
+                           throws DatabaseException {\r
+                       if(selectedLibraries != null) {\r
+                           Layer0 l0 = Layer0.getInstance(graph);\r
+                    StringBuilder sb = new StringBuilder();\r
+                    sb.append("Added Shared Function Library ");\r
+                    for(Resource library : selectedLibraries) {\r
+                        graph.claim(input, l0.IsLinkedTo, library);\r
+                        sb.append(NameUtils.getSafeName(graph, library) + " ");\r
+                    }\r
+                    sb.append("to " + NameUtils.getSafeName(graph, input));\r
+                    Layer0Utils.addCommentMetadata(graph,  sb.toString());\r
+                       }\r
+                   }\r
+               });\r
+\r
+               Button remove = new Button(middleButtons, support, SWT.NONE);\r
+               remove.setText(" <- ");\r
+               \r
+               remove.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+                   \r
+                   List<Resource> selectedLibraries;\r
+                   \r
+                   public void beforeApply() {\r
+                       selectedLibraries = getSelectedResources(usedSharedFunctionLibraries);\r
+                   }\r
+\r
+                       @Override\r
+                       public void apply(WriteGraph graph, Resource input)\r
+                               throws DatabaseException {\r
+                           if(selectedLibraries != null) {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               StringBuilder sb = new StringBuilder();\r
+                               sb.append("Removed Shared Function Library ");\r
+                               for(Resource library : selectedLibraries) {\r
+                                   graph.deny(input, l0.IsLinkedTo, library);\r
+                                   sb.append(NameUtils.getSafeName(graph, library) + " ");\r
+                               }\r
+                               sb.append("from " + NameUtils.getSafeName(graph, input));\r
+                               Layer0Utils.addCommentMetadata(graph,  sb.toString());\r
+                           }\r
+                       }\r
+               });\r
+               \r
+               \r
+               Composite used = new Composite(body, SWT.NONE);\r
+               GridLayoutFactory.fillDefaults().applyTo(used);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(used);\r
+               label = new Label(used, SWT.None);\r
+               label.setText("Selected Shared Function Libraries");\r
+               \r
+               usedSharedFunctionLibraries = new GraphExplorerComposite(ArrayMap.keys(\r
+                               "displaySelectors", "displayFilter").values(false, false), site, used, SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI)  {\r
+                   \r
+                       @Override\r
+                       protected void handleDrop(Object data, NodeContext target) {\r
+                       if (!(data instanceof IStructuredSelection))\r
+                               return;\r
+                       \r
+                       IStructuredSelection iss = (IStructuredSelection)data;\r
+                       if (iss == null || iss.isEmpty())\r
+                               return;\r
+                       \r
+                       for (Iterator<?> iterator = iss.iterator(); iterator.hasNext();) {\r
+                           Object o = iterator.next();\r
+                           if(o instanceof IAdaptable) {\r
+                               IAdaptable a = (IAdaptable)o;\r
+                               final SharedFunctionLibraryNode node = (SharedFunctionLibraryNode)a.getAdapter(SharedFunctionLibraryNode.class);\r
+                               if(node != null) {\r
+                                       SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                       if(getModel() != null && node.data != null)\r
+                                                               graph.claim(getModel(), Layer0.getInstance(graph).IsLinkedTo, node.data);                                                               \r
+                                               }\r
+                                       });\r
+                               }\r
+                           }\r
+                       }\r
+                   }\r
+               };\r
+               \r
+               usedSharedFunctionLibraries\r
+               .setBrowseContexts(SysdynResource.URIs.SelectedSharedFunctionLibraries);\r
+               usedSharedFunctionLibraries.setInputSource(new SingleSelectionInputSource(\r
+                               Resource.class));\r
+\r
+               usedSharedFunctionLibraries.finish();\r
+\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                               usedSharedFunctionLibraries);\r
+       }\r
+       \r
+       \r
+       private List<Resource> getSelectedResources(GraphExplorerComposite explorer) {\r
+               List<Resource> result = new ArrayList<Resource>();\r
+               \r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return result;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               @SuppressWarnings("unchecked")\r
+               List<AdaptableHintContext> selections = iss.toList();\r
+               for(AdaptableHintContext ahc : selections) {\r
+                       Resource resource = (Resource) ahc.getAdapter(Resource.class);\r
+                       result.add(resource);\r
+               }\r
+               return result;\r
+       }\r
+\r
+       private Resource getModel() {\r
+               return model;\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               availableSharedFunctionLibraries.setInput(context, input);\r
+               usedSharedFunctionLibraries.setInput(context, input);\r
+               this.model = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+       }\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/SysdynBasicColorProvider.java
new file mode 100644 (file)
index 0000000..e5444a8
--- /dev/null
@@ -0,0 +1,57 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import org.eclipse.jface.resource.ColorDescriptor;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ITrackedColorProvider;\r
+\r
+/**\r
+ * Color provider for sysdyn tool. Use this color provider to get a consistent look for the product.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class SysdynBasicColorProvider  implements ITrackedColorProvider {\r
+    \r
+    private final ResourceManager resourceManager;\r
+    \r
+    private final ColorDescriptor highlightColor = ColorDescriptor.createFrom(new RGB(254, 255, 197));\r
+    private final ColorDescriptor inactiveColor = ColorDescriptor.createFrom(new RGB(255, 255, 255));\r
+    private final ColorDescriptor invalidInputColor = ColorDescriptor.createFrom(new RGB(255, 128, 128));\r
+\r
+    public SysdynBasicColorProvider(ResourceManager resourceManager) {\r
+        this.resourceManager = resourceManager;\r
+    }\r
+    \r
+    @Override\r
+    public Color getEditingBackground() {\r
+        return resourceManager.createColor(inactiveColor);\r
+    }\r
+\r
+    @Override\r
+    public Color getHoverBackground() {\r
+        return resourceManager.createColor(highlightColor);\r
+    }\r
+\r
+    @Override\r
+    public Color getInactiveBackground() {\r
+        return resourceManager.createColor(inactiveColor);\r
+    }\r
+\r
+    @Override\r
+    public Color getInvalidBackground() {\r
+        return resourceManager.createColor(invalidInputColor);\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..59e61e5
--- /dev/null
@@ -0,0 +1,24 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.util.Set;\r
+\r
+import org.eclipse.ui.IWorkbenchPartSite;\r
+import org.simantics.selectionview.StandardPropertyPage;\r
+\r
+public class SysdynPropertyPage extends StandardPropertyPage {\r
+\r
+    public SysdynPropertyPage(IWorkbenchPartSite site, Set<String> set) {\r
+        super(site, set);\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..bb66b6e
--- /dev/null
@@ -0,0 +1,445 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2011, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.SWTException;\r
+import org.eclipse.swt.graphics.FontData;\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.swt.widgets.Group;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\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.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.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\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.diagram.G2DUtils;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.CustomFontDialog;\r
+import org.simantics.sysdyn.ui.properties.widgets.ValveOrientationGroup;\r
+import org.simantics.sysdyn.ui.properties.widgets.ValveTextLocationGroup;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+import org.simantics.utils.ui.validators.DoubleValidator;\r
+\r
+/**\r
+ * Information tab for additional information of variables. \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class VariableInformationTab extends AdjustableTab implements Widget {\r
+    \r
+    public VariableInformationTab(Object id) {\r
+        super(id);\r
+    }\r
+\r
+    private Composite orientationComposite;\r
+    private WidgetSupport support;\r
+    private Resource component;\r
+    private org.simantics.browsing.ui.swt.widgets.Label sample;\r
+    private LocalResourceManager resourceManager;\r
+\r
+    @Override\r
+    public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) {\r
+        this.support = support;\r
+        support.register(this);\r
+        \r
+        // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), body);\r
+        \r
+        super.createControls(body, site, context, support);\r
+    }\r
+\r
+    private Read<Pair<Font, Color>> fontAndColorRead;\r
+       private Group informationGroup;\r
+       private TrackedText information;\r
+       private Group rangeGroup;\r
+       private Label label;\r
+       private TrackedText rangeStart;\r
+       private TrackedText rangeEnd;\r
+       private TrackedText rangeStep;\r
+       private Composite fontComposite;\r
+       private Button b;\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        component = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        // is the displayed variable a valve?\r
+        Boolean isValve = false;\r
+        try {\r
+            isValve = context.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                @Override\r
+                public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                    SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    return graph.isInstanceOf(component, sr.Valve);\r
+                }\r
+\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        // if it is a valve, display the orientation information\r
+        if(isValve) {\r
+            ValveOrientationGroup vog = new ValveOrientationGroup(orientationComposite, context, support, SWT.NONE);\r
+            vog.setInput(context, input);\r
+            ValveTextLocationGroup vtlg = new ValveTextLocationGroup(orientationComposite, context, support, SWT.NONE);\r
+            vtlg.setInput(context, input);\r
+            orientationComposite.getParent().layout();\r
+        }\r
+\r
+        // Read font and color information for sample text\r
+        if(fontAndColorRead == null) {\r
+            fontAndColorRead = new Read<Pair<Font, Color>>() {\r
+\r
+                @Override\r
+                public Pair<Font, Color> perform(ReadGraph graph) throws DatabaseException {\r
+                    Font font = null;\r
+                    Color color = null;\r
+                    if(component != null) {\r
+                        Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);\r
+                        if(element != null) {\r
+                            G2DResource g2d = G2DResource.getInstance(graph);\r
+                            Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);\r
+                            if(fontResource != null)\r
+                                font = G2DUtils.getFont(graph, fontResource);\r
+                            Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);\r
+                            if(colorResource != null)\r
+                                color = G2DUtils.getColor(graph, colorResource);\r
+                        }\r
+                    }\r
+                    return new Pair<Font, Color>(font, color);\r
+                }\r
+            };\r
+\r
+            SimanticsUI.getSession().asyncRequest(fontAndColorRead, new Listener<Pair<Font, Color>>() {\r
+\r
+                @Override\r
+                public void execute(final Pair<Font, Color> result) {\r
+                    final Display device;\r
+                    try {\r
+                        device = sample.getWidget().getDisplay();\r
+                    } catch (SWTException e) {\r
+                        // Widget is disposed, the GUI probably did'n function as fast as the user commanded.\r
+                        // Thus do nothing.\r
+                        return;\r
+                    }\r
+                    \r
+                    device.asyncExec(new Runnable() {\r
+                        \r
+                        @Override\r
+                        public void run() {\r
+                            try {\r
+                                if(sample.getWidget().isDisposed())\r
+                                    return;\r
+                            } catch (SWTException e) {\r
+                                // Widget is disposed, the GUI probably did'n function as fast as the user commanded.\r
+                                // Thus do nothing.\r
+                                return;\r
+                            }\r
+                            if(result.first != null) {\r
+                                FontData fd = toSwtFontData(result.first);\r
+                                sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));\r
+                            }\r
+                            if(result.second != null) {\r
+                                RGB rgb = new RGB(result.second.getRed(), result.second.getGreen(), \r
+                                        result.second.getBlue());\r
+                                sample.setForeground(resourceManager.createColor(rgb));\r
+                            }\r
+                            try {\r
+                                sample.getWidget().getParent().getParent().layout();\r
+                            } catch (SWTException e) {\r
+\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 sample == null || sample.getWidget().isDisposed();\r
+                }\r
+\r
+            });\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Create SWT FontData based on AWT Font\r
+     * @param font AWT Font\r
+     * @return SWT FontData based on AWT Font\r
+     */\r
+    private static FontData toSwtFontData(Font font) {\r
+        FontData fontData = new FontData();\r
+        fontData.setName(font.getFamily());\r
+        fontData.setStyle(font.getStyle());\r
+        fontData.setHeight(font.getSize());\r
+        return fontData;\r
+    }\r
+\r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       ISessionContext context, WidgetSupport _support) {\r
+\r
+        composite = new Composite(body, SWT.NONE);\r
+\r
+        informationGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+        informationGroup.setText("Information");\r
+\r
+        // Textual format documentation\r
+        information = new TrackedText(informationGroup, support, SWT.MULTI | SWT.BORDER);\r
+        information.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasDescription));\r
+        information.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasDescription));\r
+\r
+        // Orientation information for valves\r
+        orientationComposite = new Composite(composite, SWT.NONE);\r
+\r
+        // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts\r
+        rangeGroup = new Group(composite, SWT.SHADOW_ETCHED_IN);\r
+        rangeGroup.setText("Range");\r
+\r
+        label = new Label(rangeGroup, SWT.NONE);\r
+        label.setText("Start");\r
+\r
+        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
+\r
+        label = new Label(rangeGroup, SWT.NONE);\r
+        label.setText("End");\r
+\r
+\r
+        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
+\r
+        label = new Label(rangeGroup, SWT.NONE);\r
+        label.setText("Step");\r
+\r
+        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
+\r
+        \r
+        // Font options. FIXME: very bad appearance right now\r
+        \r
+        fontComposite = new Composite(composite, SWT.NONE);\r
+        b = new Button(fontComposite, support, SWT.PUSH);\r
+        b.setText("Choose Font");\r
+\r
+        // Sample text with selected font\r
+        sample = new org.simantics.browsing.ui.swt.widgets.Label(fontComposite, support, SWT.NONE);\r
+        sample.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName, "Sample"));\r
+\r
+        b.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+            Font f;\r
+            Color color;\r
+            Object input;\r
+\r
+            @Override\r
+            public void beforeApply() {\r
+\r
+                Triple<Font, Color, String> result = null;\r
+\r
+                try {\r
+                    result = SimanticsUI.getSession().syncRequest(new Read<Triple<Font, Color, String>>(){\r
+\r
+                        @Override\r
+                        public Triple<Font, Color, String> perform(ReadGraph graph) throws DatabaseException {\r
+                            Resource component = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+                            String name = NameUtils.getSafeName(graph, component);\r
+\r
+                            Resource element = graph.getPossibleObject(component, ModelingResources.getInstance(graph).ComponentToElement);\r
+                            if(element != null) {\r
+                                G2DResource g2d = G2DResource.getInstance(graph);\r
+                                Resource fontResource = graph.getPossibleObject(element, g2d.HasFont);\r
+                                Resource colorResource = graph.getPossibleObject(element, g2d.HasColor);\r
+\r
+                                Font font = null;\r
+                                if(fontResource != null)\r
+                                    font = G2DUtils.getFont(graph, fontResource);\r
+                                Color color = null;\r
+                                if(colorResource != null)\r
+                                    color = G2DUtils.getColor(graph, colorResource);\r
+\r
+                                return new Triple<Font, Color, String>(font, color, name);\r
+                            }\r
+\r
+                            return null;\r
+                        }\r
+\r
+                    });\r
+                } catch (DatabaseException e) {\r
+                }\r
+\r
+\r
+                CustomFontDialog dialog = new CustomFontDialog(composite.getShell(), (result != null ? result.third : null));\r
+\r
+                if(result != null) {\r
+                    if(result.first != null) {\r
+                        dialog.setAWTFont(result.first);\r
+                        f = result.first;\r
+                    }\r
+                    if(result.second != null) {\r
+                        dialog.setColor(result.second);\r
+                        color = result.second;\r
+                    }\r
+                }\r
+\r
+                dialog.open();\r
+                if(dialog.getAWTFont() != null)\r
+                    f = dialog.getAWTFont();\r
+                if(dialog.getAWTColor() != null) {\r
+                    color = dialog.getAWTColor();\r
+                }\r
+\r
+                FontData fd = dialog.getSWTFontData();\r
+                if(fd != null)\r
+                    sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));\r
+                RGB rgb = dialog.getRGB(); \r
+                if(rgb != null)\r
+                    sample.setForeground(resourceManager.createColor(rgb));\r
+                fontComposite.layout();\r
+            }\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                graph.markUndoPoint();\r
+                Resource element = graph.getPossibleObject(input, ModelingResources.getInstance(graph).ComponentToElement);\r
+                if(element != null) {\r
+                    G2DResource g2d = G2DResource.getInstance(graph);\r
+                    graph.deny(element, g2d.HasFont);\r
+                    StringBuilder sb = new StringBuilder();\r
+                    if(f != null) {\r
+                        graph.claim(element, g2d.HasFont, G2DUtils.createFont(graph, f));\r
+                        sb.append(" font to " + f.getName());\r
+                    }\r
+                    graph.deny(element, g2d.HasColor);\r
+                    if(color != null) {\r
+                        graph.claim(element,  g2d.HasColor, G2DUtils.createColor(graph, color));\r
+                        sb.append(" color to " + color.getRGB());\r
+                    }\r
+                    sb.insert(0, "Modified");\r
+                    Layer0Utils.addCommentMetadata(graph, sb.toString());\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void setInput(ISessionContext context, Object parameter) {\r
+                super.setInput(context, parameter);\r
+                input = parameter;\r
+            }\r
+\r
+        });\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);\r
+\r
+        // Textual format documentation\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+\r
+        // Orientation information for valves\r
+        GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite);\r
+        GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite);\r
+\r
+        // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts\r
+        GridDataFactory.fillDefaults().applyTo(rangeGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(rangeGroup);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().applyTo(fontComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(1).applyTo(fontComposite);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(informationGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(informationGroup);\r
+\r
+        // Textual format documentation\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(information.getWidget());\r
+\r
+        // Orientation information for valves\r
+        GridDataFactory.fillDefaults().span(1, 2).applyTo(orientationComposite);\r
+        GridLayoutFactory.fillDefaults().margins(3,3).applyTo(orientationComposite);\r
+\r
+        // Range of a variable (e.g. from 0 to 10). Does not affect simulation, but the infor can be used for example in charts\r
+        GridDataFactory.fillDefaults().applyTo(rangeGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(6).applyTo(rangeGroup);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStart.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeEnd.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(rangeStep.getWidget());\r
+\r
+        GridDataFactory.fillDefaults().applyTo(fontComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(fontComposite);\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrayExpressionCombo.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrayExpressionCombo.java
new file mode 100644 (file)
index 0000000..42607db
--- /dev/null
@@ -0,0 +1,191 @@
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\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.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ArrayExpressionCombo extends TrackedCombo {\r
+\r
+       int lastSelectedIndex = -2;\r
+\r
+       public ArrayExpressionCombo(Composite parent, WidgetSupport support,\r
+                       int style) {\r
+               super(parent, support, style);\r
+\r
+               /*\r
+               this.setInputValidator(new VariableNameValidator(support));\r
+                */\r
+\r
+               this.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 LinkedHashMap<String, Object>();\r
+                               if(input == null) {\r
+                                       return map;\r
+                               }\r
+\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               String name = graph.getPossibleRelatedValue(input, l0.HasName);\r
+                               if(name == null)\r
+                                       return map;\r
+\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                               String defaultRange = getDefaultRange(graph, input);\r
+                               for(Resource expression : getExpressions(graph, input)) {\r
+                                       String arrayRange = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange); \r
+                                       if(arrayRange != null) {\r
+                                               map.put(name + arrayRange, expression);\r
+                                       } else if(defaultRange != null) {\r
+                                               map.put(name + defaultRange, expression);\r
+                                       } else {\r
+                                               map.put(name, expression);\r
+                                       }\r
+                               }\r
+                               if(map.isEmpty()) {\r
+                                       map.put(name, input);\r
+                               }\r
+                               return map;\r
+                       }\r
+\r
+               });\r
+\r
+\r
+               this.setSelectionFactory(new ReadFactoryImpl<Resource, String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph, final Resource input) throws DatabaseException {\r
+                               String name = graph.getPossibleRelatedValue(input,  Layer0.getInstance(graph).HasName);\r
+                               if(name == null)\r
+                                       return "";\r
+                               \r
+                               String defaultRange = getDefaultRange(graph, input);\r
+                               if(defaultRange == null)\r
+                                       return name;\r
+\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                               Resource activeExpression = graph.getPossibleObject(input, sr.IndependentVariable_activeExpression);\r
+                               Resource expression;\r
+                               if(activeExpression == null) {\r
+                                       ArrayList<Resource> expressions = getExpressions(graph, input);\r
+                                       if(expressions == null || expressions.isEmpty())\r
+                                               return name;\r
+                                       expression = expressions.get(0);\r
+                               } else {\r
+                                       expression = activeExpression;\r
+                               }\r
+                               String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);\r
+                               if(range != null)\r
+                                       return name + range;\r
+                               else\r
+                                       return name + defaultRange;\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               super.setInput(context, input);\r
+\r
+               if(selectionFactory != null) {\r
+                       selectionFactory.listen(context, input, new Listener<String>() {\r
+\r
+                               @Override\r
+                               public void execute(final String result) {\r
+                                       if(getWidget().isDisposed()) return;\r
+                                       getWidget().getDisplay().asyncExec(new Runnable() {\r
+                                               \r
+                                               @Override\r
+                                               public void run() {\r
+                                                       Combo combo = getWidget();\r
+                                                       if(combo != null && !combo.isDisposed() && result != null) {\r
+                                                               Object o = getWidget().getData(result);\r
+                                                               if(o != null)\r
+                                                                       lastSelectedIndex = (Integer)o;\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 getWidget().isDisposed();\r
+                               }\r
+\r
+                       });\r
+               }\r
+       }\r
+\r
+       private ArrayList<Resource> getExpressions(ReadGraph graph, Resource variable) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource hasExpressions = graph.getPossibleObject(variable, sr.Variable_expressionList);\r
+               if(hasExpressions == null)\r
+                       return new ArrayList<Resource>();\r
+               else\r
+                       return new ArrayList<Resource>(ListUtils.toList(graph, hasExpressions));\r
+       }\r
+\r
+       public static String getDefaultRange(ReadGraph graph, Resource variable) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource hasArrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+\r
+               if(hasArrayIndexes == null)\r
+                       return null;\r
+\r
+               Iterator<Resource> iterator = ListUtils.toList(graph, hasArrayIndexes).iterator();\r
+               if(!iterator.hasNext())\r
+                       return null;\r
+\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append("[");\r
+\r
+               while(iterator.hasNext()) {\r
+                       sb.append(NameUtils.getSafeName(graph, iterator.next()));\r
+                       if(iterator.hasNext()) {\r
+                               sb.append(", ");\r
+                       }\r
+               }\r
+               sb.append("]");\r
+               return sb.toString();\r
+       }\r
+       \r
+       /**\r
+        * Get the index that has previously been selected\r
+        * @return\r
+        */\r
+       public int getLastSelectedIndex() {\r
+               return lastSelectedIndex;\r
+       }\r
+       \r
+       public void setLastSelectedIndex(int lastSelectedIndex) {\r
+               this.lastSelectedIndex = lastSelectedIndex;\r
+       }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ArrowHeadWidget.java
new file mode 100644 (file)
index 0000000..7698135
--- /dev/null
@@ -0,0 +1,169 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\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
+/**\r
+ * Widget for showing arrow head in dependencies.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ArrowHeadWidget implements Widget{\r
+\r
+    List<Resource> variables = null; \r
+    org.simantics.browsing.ui.swt.widgets.Button arrowheadButton;\r
+    \r
+    public ArrowHeadWidget(Composite parent, WidgetSupport support, int style) {\r
+        support.register(this);\r
+        arrowheadButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK);\r
+        arrowheadButton.setText("Arrowhead");\r
+    }\r
+\r
+    @SuppressWarnings({ "rawtypes", "unchecked" })\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
+               List<Resource> resources = ISelectionUtils.filterSelection(selection, Resource.class);\r
+                if(resources != null && !resources.isEmpty()) {\r
+                    variables = resources;\r
+                } else {\r
+                       List<ArrayList> resourceLists = ISelectionUtils.filterSelection(selection, ArrayList.class);\r
+                       variables = resourceLists.get(0);\r
+                }\r
+            }\r
+        }\r
+\r
+        if(variables == 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
+                    \r
+                    // Determine if there are arrowheads in some of the variables.\r
+                    boolean hasArrowheads = false, hasNotArrowheads = false;\r
+                    for (Resource variable : variables) {\r
+                       if (!graph.hasStatement(variable, sr.DependencyConnection_hideArrow)) {\r
+                               hasArrowheads = true;\r
+                       } else {\r
+                               hasNotArrowheads = true;\r
+                       }\r
+                    }\r
+                    \r
+                    // If some have arrowheads but others don't, the check box is grayed.\r
+                    final Button button = getWidget();\r
+                    final boolean arrowhead = hasArrowheads;\r
+                    final boolean mixedArrowheads = hasArrowheads && hasNotArrowheads;\r
+                       button.getDisplay().asyncExec(new Runnable() {\r
+                               \r
+                        @Override\r
+                        public void run() {\r
+                            if(button.isDisposed()) return;\r
+                            button.setSelection(arrowhead);\r
+                            button.setGrayed(mixedArrowheads);\r
+                        }\r
+                    });\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        // Multiple selections\r
+        arrowheadButton.addSelectionListener(new SelectionListenerImpl<ArrayList<Resource>>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, ArrayList<Resource> inputs) throws DatabaseException {\r
+                if (inputs == null)\r
+                       return;\r
+                \r
+                final SysdynResource sr =  SysdynResource.getInstance(graph);\r
+                boolean nextState = true; // The next state of the checkbox\r
+                for (Resource variable : variables) {\r
+                       if (!graph.hasStatement(variable, sr.DependencyConnection_hideArrow)) {\r
+                               nextState = false; // The next state is true iff all have hideArrow.\r
+                               break;\r
+                       }\r
+                }\r
+\r
+               try {\r
+                       if (nextState) {\r
+                                               for (Resource input : inputs) {\r
+                                                       graph.deny(input, sr.DependencyConnection_hideArrow);\r
+                                               }\r
+                                       } else {\r
+                                               for (Resource input : inputs) {\r
+                                                       graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_hideArrow, null, input);\r
+                                               }\r
+                                       }\r
+               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                \r
+               // Get the button out of the grayed state.\r
+               final Button button = getWidget();\r
+                button.getDisplay().asyncExec(new Runnable() {\r
+                    \r
+                    @Override\r
+                    public void run() {\r
+                       button.setGrayed(false);\r
+                    }\r
+                });\r
+            }\r
+        });\r
+        \r
+        // One selection\r
+        arrowheadButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                if (input == null)\r
+                       return;\r
+                \r
+                final SysdynResource sr =  SysdynResource.getInstance(graph);\r
+                if(graph.hasStatement(input, sr.DependencyConnection_hideArrow)) {\r
+                           graph.deny(input, sr.DependencyConnection_hideArrow);\r
+                       } else {\r
+                           graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_hideArrow, null, input);\r
+                       }\r
+            }  \r
+        });\r
+    }\r
+    \r
+    public Button getWidget() {\r
+        return arrowheadButton.getWidget();\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..b600df8
--- /dev/null
@@ -0,0 +1,247 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.Collections;\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
+                    if(!graph.isInstanceOf(expression, sr.WithLookupExpression))\r
+                       return null;\r
+                    return graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_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
+                       if(lookup == null) return;\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
+        ArrayList<InputOutput> inputOutputList = (ArrayList<InputOutput>)table.getTableViewer().getInput();\r
+        Collections.sort(inputOutputList, table.new InputOutputComparator());\r
+        Iterator<InputOutput> iterator = inputOutputList.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.claimLiteral(expression, sr.WithLookupExpression_lookup, 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..2dd769d
--- /dev/null
@@ -0,0 +1,240 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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
+\r
+import javax.swing.JComponent;\r
+import javax.swing.JPanel;\r
+\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.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
+import org.simantics.utils.ui.SWTAWTComponent;\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
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                       if(!graph.isInstanceOf(expression, sr.WithLookupExpression))\r
+                               return null;\r
+                       Auxiliary auxiliary = new Auxiliary();\r
+                    auxiliary.minX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minX);\r
+                    auxiliary.maxX = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxX);\r
+                    auxiliary.minY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_minY);\r
+                    auxiliary.maxY = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_maxY);\r
+                    auxiliary.table = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup);\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
+                       if(result == null) return;\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
+                    if(result.minY == null) result.minY = rangeAxis.getLowerBound();\r
+                    if(result.maxY == null) result.maxY = rangeAxis.getUpperBound();\r
+                    rangeAxis.setRange(result.minY, result.maxY);\r
+                    ValueAxis domainAxis = plot.getDomainAxis();\r
+                    domainAxis.setAutoRange(false);\r
+                    if(result.minX == null) result.minX = domainAxis.getLowerBound();\r
+                    if(result.maxX == null) result.maxX = domainAxis.getUpperBound();\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.claimLiteral(expression, sr.WithLookupExpression_lookup, table);\r
+                }\r
+            });\r
+\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ColumnKeys.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ColumnKeys.java
new file mode 100644 (file)
index 0000000..1a9dda4
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import org.simantics.browsing.ui.Column;\r
+import org.simantics.browsing.ui.Column.Align;\r
+\r
+public class ColumnKeys {\r
+       \r
+       public static final String   ENUMERATION           = "Enumeration";\r
+       public static final String   INDEXES               = "Indexes";\r
+       public static final String   SHOW_IN_CHARTS    = "ShowInCharts";\r
+       public static final String   REPLACED_WITH     = "Replaced with";\r
+       public static final String   MODULE_PARAMETER  = "Parameter in Module";\r
+       public static final String   VALUE             = "Value";\r
+       \r
+       public static String[] ENUMERATION_COLUMNS_KEYS = { ENUMERATION, INDEXES };\r
+    public static Column[] ENUMERATION_TABLE_COLUMNS = new Column[] {\r
+        new Column(ENUMERATION, Align.LEFT, 100, "Enumeration", false),\r
+        new Column(INDEXES, Align.LEFT, 100, "Indexes", true),\r
+    };\r
+    \r
+\r
+       public static String[] ENUMERATION_INDEX_COLUMNS_KEYS = { ENUMERATION, SHOW_IN_CHARTS };\r
+    public static Column[] ENUMERATION_INDEX_TABLE_COLUMNS = new Column[] {\r
+        new Column(ENUMERATION, Align.LEFT, 100, "Enumeration", true),\r
+        new Column(SHOW_IN_CHARTS, Align.LEFT, 20, "Show in charts", false),\r
+    };\r
+    \r
+       public static String[] ENUMERATION_REDECLARATION_KEYS = { ENUMERATION, REPLACED_WITH };\r
+    public static Column[] ENUMERATION_REDECLARATION_COLUMNS = new Column[] {\r
+        new Column(ENUMERATION, Align.LEFT, 200, "Enumeration in module", false),\r
+        new Column(REPLACED_WITH, Align.LEFT, 200, "Replaced with", true),\r
+    };\r
+    \r
+    public static String[] MODULE_PARAMETER_KEYS = { MODULE_PARAMETER, VALUE };\r
+    public static Column[] MODULE_PARAMETER_COLUMNS = new Column[] {\r
+        new Column(MODULE_PARAMETER, Align.LEFT, 200, MODULE_PARAMETER, false),\r
+        new Column(VALUE, Align.LEFT, 200, VALUE, true),\r
+    };\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/CustomFontDialog.java
new file mode 100644 (file)
index 0000000..8bf97ce
--- /dev/null
@@ -0,0 +1,380 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.util.LinkedHashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.dialogs.Dialog;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.preference.PreferenceConverter;\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.nebula.widgets.tablecombo.TableCombo;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.graphics.Rectangle;\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.Group;\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.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.preferences.SysdynDiagramPreferences;\r
+import org.simantics.utils.ui.gfx.ColorImageDescriptor;\r
+\r
+/**\r
+ * Custom dialog for selecting font and font color. Similar to SWT FontDialog.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class CustomFontDialog extends Dialog {\r
+    \r
+    private Map<String, Integer> systemColors = createColorMap();\r
+    \r
+    private FontData resultSWTFontData;\r
+    private Font awtFont;\r
+    private Font resultAWTFont;\r
+    private Color color;\r
+    private Color resultAWTColor;\r
+    \r
+    private FontSelectionComposite vpc;\r
+    private TableCombo tc;\r
+    \r
+    private String example = "Example";\r
+    private Label sample;\r
+    private Group sampleGroup;\r
+    private RGB rgb;\r
+    \r
+    private LocalResourceManager resourceManager;\r
+\r
+\r
+    // Default color map\r
+    protected static Map<String, Integer> createColorMap() {\r
+        LinkedHashMap<String, Integer> colors  =     new LinkedHashMap<String, Integer>();\r
+        colors.put("Black", SWT.COLOR_BLACK);\r
+        colors.put("White", SWT.COLOR_WHITE);\r
+        colors.put("Blue", SWT.COLOR_BLUE);\r
+        colors.put("Dark Blue", SWT.COLOR_DARK_BLUE);\r
+        colors.put("Red", SWT.COLOR_RED);\r
+        colors.put("Dark Red", SWT.COLOR_DARK_RED);\r
+        colors.put("Yellow", SWT.COLOR_YELLOW);\r
+        colors.put("Dark Yellow", SWT.COLOR_DARK_YELLOW);\r
+        colors.put("Gray", SWT.COLOR_GRAY);\r
+        colors.put("Dark Gray", SWT.COLOR_DARK_GRAY);\r
+        colors.put("Green", SWT.COLOR_GREEN);\r
+        colors.put("Dark Green", SWT.COLOR_DARK_GREEN);\r
+        colors.put("Cyan", SWT.COLOR_CYAN);\r
+        colors.put("Dark Cyan", SWT.COLOR_DARK_CYAN);\r
+        colors.put("Magenta", SWT.COLOR_MAGENTA);\r
+        colors.put("Dark Magenta", SWT.COLOR_DARK_MAGENTA);\r
+        return colors;\r
+    }\r
+\r
+    /**\r
+     * Creates a font dialog with sample text\r
+     * @param parentShell\r
+     * @param example Sample text in the dialog. Null example => "Example"\r
+     */\r
+    public CustomFontDialog(Shell parentShell, String example) {\r
+        super(parentShell);\r
+        if(example != null)\r
+            this.example = example;\r
+    }\r
+\r
+    /**\r
+     * Sets the initial font for this dialog\r
+     * @param awtFont Current AWT font\r
+     */\r
+    public void setAWTFont(java.awt.Font awtFont) {\r
+        this.awtFont = awtFont; \r
+        this.resultAWTFont = awtFont;\r
+    }\r
+\r
+    /**\r
+     * Get selected font as AWT font\r
+     * @return AWT font\r
+     */\r
+    public java.awt.Font getAWTFont() {\r
+        return resultAWTFont;\r
+    }\r
+    \r
+    /**\r
+     * Get selected font as SWT font dta\r
+     * @return\r
+     */\r
+    public FontData getSWTFontData() {\r
+        return resultSWTFontData;\r
+    }\r
+    \r
+    /**\r
+     * Set initial color for this dialog\r
+     * @param color AWT color\r
+     */\r
+    public void setColor(Color color) {\r
+        this.color = color;\r
+        this.resultAWTColor = color;\r
+    }\r
+    \r
+    /**\r
+     * Get selected color as AWT color\r
+     * @return\r
+     */\r
+    public Color getAWTColor() {\r
+        return resultAWTColor;\r
+    }\r
+    \r
+    /**\r
+     * Get selected color as RGB\r
+     * @return\r
+     */\r
+    public RGB getRGB() {\r
+        return rgb;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Creates font choosing area\r
+     * @param parent Parent composite\r
+     */\r
+    protected void createFontChooser(Composite parent) {\r
+        vpc = new FontSelectionComposite(parent, SWT.NONE);\r
+        vpc.setFont(awtFont, false);\r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(vpc);\r
+        \r
+        vpc.addFontModifiedListener(new FontModifyListener() {\r
+            \r
+            @Override\r
+            public void swtFontDataChanged(FontData fd) {\r
+                sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(fd)));\r
+                sampleGroup.layout();\r
+            }\r
+            \r
+            @Override\r
+            public void awtFontChanged(Font font) {\r
+            }\r
+        });      \r
+        \r
+    }\r
+    \r
+    /**\r
+     * Creates a TableCombo for choosing a color for a font\r
+     * @param parent Parent composite\r
+     */\r
+    protected void createColorChooser(Composite parent) {\r
+        // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), parent);\r
+        \r
+        Composite colorComposite = new Composite(parent, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(colorComposite);\r
+        \r
+        Label label = new Label(colorComposite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.FILL).applyTo(label);\r
+        label.setText("Color: ");        \r
+\r
+        tc = new TableCombo(colorComposite, SWT.BORDER | SWT.READ_ONLY);\r
+        GridDataFactory.fillDefaults().hint(170, SWT.DEFAULT).applyTo(tc);\r
+        \r
+        tc.defineColumns(2);\r
+        tc.setDisplayColumnIndex(1);\r
+        tc.setToolTipText("this is tooltip");\r
+        \r
+        createColorItems(tc.getTable());\r
+\r
+        if(this.color != null) {\r
+            for(int i = 0; i < tc.getTable().getItemCount(); i++) {\r
+                TableItem ti = tc.getTable().getItem(i);\r
+                RGB rgb = (RGB) ti.getData();\r
+                if(rgb.red == this.color.getRed() &&\r
+                        rgb.green == this.color.getGreen() &&\r
+                        rgb.blue == this.color.getBlue()) {\r
+                    tc.setText(ti.getText(1));\r
+                    tc.setForeground(resourceManager.createColor(rgb));\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+        \r
+        // add listener\r
+        tc.addSelectionListener(new SelectionListener() {\r
+            \r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TableItem[] selection = tc.getTable().getSelection();\r
+                if(selection.length == 1) {\r
+                    rgb = (RGB) selection[0].getData();\r
+                    org.eclipse.swt.graphics.Color swtColor = resourceManager.createColor(rgb);\r
+                    sample.setForeground(swtColor);\r
+                    tc.setForeground(swtColor);\r
+                }\r
+                tc.getTextControl().setSelection(0);\r
+                tc.getParent().forceFocus();\r
+            }\r
+            \r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+    }\r
+\r
+    /**\r
+     * Creates a sample text area\r
+     * @param parent Parent composite\r
+     */\r
+    protected void createSampleArea(Composite parent) {\r
+        sampleGroup = new Group(parent, SWT.NONE);\r
+        sampleGroup.setText("Sample");\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 70).applyTo(sampleGroup);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(sampleGroup);\r
+\r
+        sample = new Label(sampleGroup, SWT.NONE);\r
+        sample.setText(example);\r
+        if(awtFont != null) {\r
+            sample.setFont(resourceManager.createFont(FontDescriptor.createFrom(toSwtFontData(awtFont))));\r
+        }\r
+        if(rgb != null) {\r
+            sample.setForeground(resourceManager.createColor(rgb));\r
+        }\r
+        GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, true).applyTo(sample);\r
+    }\r
+    \r
+    @Override\r
+    protected Control createDialogArea(Composite parent)\r
+    {\r
+        Composite composite = ( Composite )super.createDialogArea(parent);\r
+        composite.getShell().setText("Choose Font");\r
+\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(composite);\r
+        \r
+        // Init SWT RGB, if AWT color has been set\r
+        if(color != null)\r
+            this.rgb = new RGB(color.getRed(), color.getGreen(), color.getBlue());\r
+\r
+        // Font selection composite\r
+        createFontChooser(composite);\r
+        \r
+        // Color selection\r
+        createColorChooser(composite);\r
+        \r
+        // Sample text\r
+        createSampleArea(composite);\r
+\r
+        //Set the dialog position in the middle of the monitor\r
+        setDialogLocationToMonitorCenter();\r
+\r
+        return composite;\r
+    }\r
+\r
+    @Override\r
+    protected void cancelPressed() {\r
+        resultAWTFont = awtFont;\r
+        resultAWTColor = color;\r
+        if(resultAWTFont != null)\r
+               resultSWTFontData =  toSwtFontData(resultAWTFont);\r
+\r
+        setReturnCode(CANCEL);\r
+        close();\r
+    }\r
+\r
+    @Override\r
+    protected void okPressed() {\r
+        resultAWTFont = vpc.getAWTFont();\r
+        resultSWTFontData =  toSwtFontData(resultAWTFont);\r
+        \r
+        TableItem[] selection = tc.getTable().getSelection();\r
+        if(selection.length == 1) {\r
+            RGB rgb = (RGB) selection[0].getData();\r
+            resultAWTColor = new Color(rgb.red, rgb.green, rgb.blue);\r
+        }\r
+\r
+        setReturnCode(OK);\r
+        close();\r
+    }\r
+\r
+    /**\r
+     * Sets the dialog location to the middle of the screen\r
+     */\r
+    protected void setDialogLocationToMonitorCenter() {\r
+        Rectangle monitorArea = getShell().getDisplay().getPrimaryMonitor().getBounds();\r
+        Rectangle shellArea = getShell().getBounds();\r
+        int x = monitorArea.x + (monitorArea.width - shellArea.width)/2;\r
+        int y = monitorArea.y + (monitorArea.height - shellArea.height)/2;\r
+        getShell().setLocation(x,y);\r
+    }\r
+    \r
+    /**\r
+     * Builds SWT FontData from AWT font. Simple conversion.\r
+     * \r
+     * @param font AWT font\r
+     * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed)\r
+     * @return\r
+     */\r
+    protected static FontData toSwtFontData(Font font) {\r
+        FontData fontData = new FontData();\r
+        fontData.setName(font.getFontName());\r
+        fontData.setStyle(font.getStyle());\r
+        fontData.setHeight(font.getSize());\r
+        return fontData;\r
+    }\r
+    \r
+    /**\r
+     * Creates color items for color combo\r
+     * @param table\r
+     */\r
+    protected void createColorItems(Table table) {\r
+        Image image;\r
+        TableItem ti;\r
+        int code;\r
+        RGB color;\r
+        Display display = Display.getCurrent();\r
+        \r
+        //IWorkbenchPage iwp = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+               //final ICanvasContext context = (ICanvasContext)iwp.getActiveEditor().getAdapter(ICanvasContext.class);\r
+        \r
+        IPreferenceStore store = Activator.getDefault().getPreferenceStore();\r
+        color = PreferenceConverter.getColor(store, SysdynDiagramPreferences.ARROW_COLOR);\r
+        image = resourceManager.createImage(new ColorImageDescriptor(color.red, color.green, color.blue, 25, 15, false));\r
+        \r
+        ti = new TableItem(table, SWT.NONE);\r
+        ti.setImage(0, image);\r
+        ti.setText(1, "Default Arrow");\r
+        ti.setForeground(display.getSystemColor(SWT.COLOR_BLACK));\r
+        ti.setData(color);\r
+        \r
+        for(String text : systemColors.keySet()) {\r
+            code = systemColors.get(text);\r
+            color = display.getSystemColor(code).getRGB();\r
+            image = resourceManager.createImage(new ColorImageDescriptor(color.red, color.green, color.blue, 25, 15, false));\r
+            \r
+            ti = new TableItem(table, SWT.NONE);\r
+            ti.setImage(0, image);\r
+            ti.setText(1, text);\r
+            ti.setForeground(display.getSystemColor(SWT.COLOR_BLACK));\r
+            ti.setData(color);\r
+        }\r
+        \r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/DelayMarkWidget.java
new file mode 100644 (file)
index 0000000..d13f3e6
--- /dev/null
@@ -0,0 +1,174 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\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.databoard.Bindings;\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.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Widget for Delay marks in dependencies.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class DelayMarkWidget implements Widget{\r
+\r
+    List<Resource> variables = null; \r
+    org.simantics.browsing.ui.swt.widgets.Button delayMarkButton;\r
+    \r
+    public DelayMarkWidget(Composite parent, WidgetSupport support, int style) {\r
+        support.register(this);\r
+        delayMarkButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK);\r
+        delayMarkButton.setText("Delay mark");\r
+    }\r
+\r
+    @SuppressWarnings({ "rawtypes", "unchecked" })\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
+               List<Resource> resources = ISelectionUtils.filterSelection(selection, Resource.class);\r
+                if(resources != null && !resources.isEmpty()) {\r
+                    variables = resources;\r
+                } else {\r
+                       List<ArrayList> resourceLists = ISelectionUtils.filterSelection(selection, ArrayList.class);\r
+                       variables = resourceLists.get(0);\r
+                }\r
+            }\r
+        }\r
+\r
+        if(variables == 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
+                    \r
+                    // Determine if there are delay marks in some of the variables.\r
+                    boolean hasDelayMarks = false, hasNotDelayMarks = false;\r
+                    for (Resource variable : variables) {\r
+                       if (graph.hasStatement(variable, sr.DependencyConnection_delayMark)) {\r
+                               hasDelayMarks = true;\r
+                       } else {\r
+                               hasNotDelayMarks = true;\r
+                       }\r
+                    }\r
+                    \r
+                    // If some have delay marks but others don't, the check box is grayed.\r
+                    final Button button = getWidget();\r
+                    final boolean delayMark = hasDelayMarks;\r
+                    final boolean mixedDelayMarks = hasDelayMarks && hasNotDelayMarks;\r
+                       button.getDisplay().asyncExec(new Runnable() {\r
+                               \r
+                        @Override\r
+                        public void run() {\r
+                            if(button.isDisposed()) return;\r
+                            button.setSelection(delayMark);\r
+                            button.setGrayed(mixedDelayMarks);\r
+                        }\r
+                    });\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        // Multiple selections\r
+        delayMarkButton.addSelectionListener(new SelectionListenerImpl<ArrayList<Resource>>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, ArrayList<Resource> inputs) throws DatabaseException {\r
+                if (inputs == null)\r
+                       return;\r
+                \r
+                final SysdynResource sr =  SysdynResource.getInstance(graph);\r
+                boolean nextState = true; // The next state of the checkbox\r
+                for (Resource variable : variables) {\r
+                       if (graph.hasStatement(variable, sr.DependencyConnection_delayMark)) {\r
+                               nextState = false; // The next state is true iff at least one has the delay mark.\r
+                               break;\r
+                       }\r
+                }\r
+\r
+               try {\r
+                       if (nextState) {\r
+                                               for (Resource input : inputs) {\r
+                                                       graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_delayMark, null, input);\r
+                                               }\r
+                                       } else {\r
+                                               for (Resource input : inputs) {\r
+                                                       graph.deny(input, sr.DependencyConnection_delayMark);\r
+                                               }\r
+                                       }\r
+               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                \r
+               // Get the button out of the grayed state.\r
+               final Button button = getWidget();\r
+                button.getDisplay().asyncExec(new Runnable() {\r
+                    \r
+                    @Override\r
+                    public void run() {\r
+                       button.setGrayed(false);\r
+                    }\r
+                });\r
+            }\r
+        });\r
+        \r
+        // One selection\r
+        delayMarkButton.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource input) throws DatabaseException {\r
+                if (input == null)\r
+                       return;\r
+                \r
+                final SysdynResource sr =  SysdynResource.getInstance(graph);\r
+                if(graph.hasStatement(input, sr.DependencyConnection_delayMark)) {\r
+                           graph.deny(input, sr.DependencyConnection_delayMark);\r
+                           Layer0Utils.addCommentMetadata(graph, "Modified Delay mark for connection " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to False");\r
+                       } else {\r
+                           graph.claim(input, SysdynResource.getInstance(graph).DependencyConnection_delayMark, null, input);\r
+                           Layer0Utils.addCommentMetadata(graph, "Modified Delay mark for connection " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to True");\r
+                       }\r
+            }  \r
+        });\r
+    }\r
+    \r
+    public Button getWidget() {\r
+        return delayMarkButton.getWidget();\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/EquivalentUnitsWidget.java
new file mode 100644 (file)
index 0000000..1310655
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.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.databoard.Bindings;\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.PossibleObjectWithType;\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.issues.ontology.IssueResource;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Widget for equivalent units selection.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class EquivalentUnitsWidget implements Widget{\r
+\r
+    Resource model = null; \r
+    org.simantics.browsing.ui.swt.widgets.Button unitEquivalents;\r
+    \r
+    public EquivalentUnitsWidget(Composite parent, WidgetSupport support, int style) {\r
+        support.register(this);\r
+        unitEquivalents = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK);\r
+        unitEquivalents.setText("Unit equivalents");\r
+        unitEquivalents.getWidget().setToolTipText("Supported equivalent units:\n" +\r
+                       "$, $s, dollar, dollars, usd\n"+\r
+                       "\u20ac, \u20acs, eur, euro, euros, e, ecu\n"+\r
+                       "£, Â£s, pound, pounds, gbp\n"+\r
+                       "Unit, Units\n"+\r
+                       "Person, People, Persons\n"+\r
+                       "second, seconds, sec, s\n"+\r
+                       "minute, minutes, min\n"+\r
+                       "hour, hours, h, hr\n"+\r
+                       "day, days, d\n"+\r
+                       "month, months, mon, mth, mo, mos\n"+\r
+                       "year, years, a, y, yr");\r
+        \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
+                    model = resource;\r
+                }\r
+            }\r
+        }\r
+        \r
+        if(model == null) return;\r
+        \r
+        try {\r
+            context.getSession().syncRequest(new ReadRequest() {\r
+                \r
+                @Override\r
+                public void run(ReadGraph graph) throws DatabaseException {\r
+                       // Determine if unit validation is enabled.\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    final Resource unitIssueSource = graph.syncRequest(\r
+                            new PossibleObjectWithType(model, \r
+                                    Layer0X.getInstance(graph).Activates, \r
+                                    sr.Validations_Units_UnitIssueSource));\r
+                    IssueResource ISSUE = IssueResource.getInstance(graph);\r
+                    final Boolean issueSource_active = graph.getPossibleRelatedValue(unitIssueSource, ISSUE.IssueSource_active, Bindings.BOOLEAN);\r
+                    \r
+                    Boolean result = false;\r
+                    if(unitIssueSource != null) {\r
+                       result = graph.getPossibleRelatedValue(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Bindings.BOOLEAN);\r
+                    }\r
+\r
+                    final boolean enable = result;\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
+                            // Is unit validation is enabled, enable the button.\r
+                            getWidget().setEnabled(unitIssueSource!=null && issueSource_active);\r
+                            if(Boolean.TRUE.equals(enable))\r
+                               button.setSelection(true);\r
+                            else\r
+                                button.setSelection(false);\r
+                        }\r
+                    });                        \r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        unitEquivalents.addSelectionListener(new SelectionListenerImpl<Resource>(context) {\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource model) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                Resource unitIssueSource = graph.syncRequest(\r
+                        new PossibleObjectWithType(model, \r
+                                Layer0X.getInstance(graph).Activates, \r
+                                sr.Validations_Units_UnitIssueSource));\r
+                if(unitIssueSource == null)\r
+                    return;\r
+                \r
+                Boolean result = graph.getPossibleRelatedValue(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Bindings.BOOLEAN);\r
+                if(result == null)\r
+                    result = false;\r
+                graph.claimLiteral(unitIssueSource, sr.Validations_Units_UnitIssueSource_allowEquivalents, Boolean.FALSE.equals(result));\r
+            }\r
+        });\r
+    }\r
+    \r
+    public Button getWidget() {\r
+        return unitEquivalents.getWidget();\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..7b3b20b
--- /dev/null
@@ -0,0 +1,87 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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
+/**\r
+ * Expression type representations\r
+ * @author Teemu Lempinen\r
+ *\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.Auxiliary, \r
+               ExpressionType.Parameter, \r
+               ExpressionType.Constant, \r
+               ExpressionType.Delay,\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.Delay,\r
+               ExpressionType.WithLookup};\r
+\r
+       public static ExpressionType[] stockExpressions = new ExpressionType[] {\r
+               ExpressionType.Stock};\r
+\r
+       public static ExpressionType getExpressionType(final Resource expression) {\r
+               try {\r
+                       return SimanticsUI.getSession().syncRequest(new Read<ExpressionType>() {\r
+\r
+                               @Override\r
+                               public ExpressionType perform(ReadGraph graph) throws DatabaseException {\r
+                                       return getExpressionType(graph, expression);\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+                       return null;\r
+               }\r
+\r
+       }\r
+       \r
+       public static ExpressionType getExpressionType(ReadGraph graph, final Resource expression) throws DatabaseException {\r
+               ExpressionType et = null;\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\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
+               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..07b448b
--- /dev/null
@@ -0,0 +1,272 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import javax.swing.Timer;\r
+\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.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.layer0.variable.Variable;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\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.ExpressionComposite;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionWidgetInput;\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.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+/**\r
+ * Widget for displaying an expression. Widget creates the IExpression for displaying\r
+ * properties for each expression type and adds validation, saving and other services\r
+ * to the active IExpression.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExpressionWidget implements Widget {\r
+\r
+    private ExpressionWidgetInput input;\r
+       private Resource expr;\r
+       private Variable 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
+       private VerifyKeyListener verifyKeyListener;\r
+    private Timer validationTimer;\r
+    private static int VALIDATION_DELAY_TIME = 500;\r
+    private final LocalResourceManager resourceManager;\r
+    \r
+    /**\r
+     * Create a new expression widget\r
+     * @param parent\r
+     * @param support\r
+     * @param style\r
+     */\r
+    public ExpressionWidget(Composite parent, WidgetSupport support, int style) {\r
+               support.register(this);\r
+               this.parent = parent;\r
+               if (parent instanceof ExpressionComposite) {\r
+                   ExpressionComposite expressionComposite = (ExpressionComposite)parent;\r
+                   expressionComposite.setExpressionWidget(this);\r
+               }\r
+               this.data = new HashMap<String, Object>();\r
+               \r
+               // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this.parent);\r
+        \r
+               /*\r
+                *  Create a validation timer for expression fields. Validation timer\r
+                *  validates the field as the modeler is typing an expression \r
+                */\r
+               validationTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {\r
+\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+               if(variableTable == null || variableTable.isDisposed())\r
+                       return;\r
+                       variableTable.getDisplay().asyncExec(new Runnable() {\r
+                               \r
+                               @Override\r
+                               public void run() {\r
+                                       validateFields();\r
+                               }\r
+                       });\r
+            }\r
+        });\r
+               validationTimer.setRepeats(false);\r
+       }\r
+   \r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {  \r
+           // Update IExpression based on the newly selected expression\r
+               ExpressionWidgetInput i =  AdaptionUtils.adaptToSingle(input, ExpressionWidgetInput.class);\r
+               this.input = i;\r
+               expr = i.expression;\r
+               variable = i.variable;\r
+               ExpressionType et = ExpressionTypes.getExpressionType(expr);\r
+               displayExpression(et.toString(), true);\r
+       }\r
+\r
+       /**\r
+        * Displays IExpression corresponding to expressionType.\r
+        * @param expressionType Expression type\r
+        * @param original Is the displayed expression for a newly selected expression (true) or did the\r
+        * expression change its type (false) \r
+        */\r
+       public void displayExpression(String expressionType, boolean original) {\r
+               if(expressionType == null || parent.isDisposed()) {\r
+                       return;\r
+               }\r
+\r
+               // Get up-to-date data to data-map\r
+               if(this.expression != null) expression.updateData(data);\r
+               \r
+               // Create the new expression\r
+               ExpressionType et = ExpressionType.valueOf(expressionType);\r
+               IExpression exp = null;\r
+               switch (et) {\r
+               case Auxiliary: \r
+                       exp = new AuxiliaryExpression(input); break;\r
+               case Parameter: \r
+                       exp = new ParameterExpression(input); break;\r
+               case Constant: \r
+                       exp = new ConstantExpression(input); break;\r
+               case Lookup: \r
+                       exp = new LookupExpression(); break;\r
+               case WithLookup: \r
+                       exp = new WithLookupExpression(input); break;\r
+               case Stock: \r
+                       exp = new StockExpression(input); break;\r
+               case Delay: \r
+                       exp = new DelayExpression(input); break;\r
+               default: \r
+                       exp = new EmptyExpression();\r
+               }\r
+\r
+               if (exp != null) {\r
+                   // If expression was created, remove the old one\r
+                       for(Control c : parent.getChildren()) {\r
+                               c.dispose();\r
+                       } \r
+\r
+                       // If a completely new expression was selected, read data\r
+                       if(original) \r
+                               exp.readData(expr, data);\r
+\r
+                       // Create the visual representation of the expression type\r
+                       exp.createExpressionFields(parent, data, variableTable);\r
+                       \r
+                       // Add listeners\r
+                       if(modifyListener != null)\r
+                               exp.addModifyListener(modifyListener);\r
+                       if(focusListener != null)\r
+                               exp.addFocusListener(focusListener);\r
+                       if(verifyKeyListener != null)\r
+                               exp.addVerifyKeyListener(verifyKeyListener);\r
+                       this.expression = exp;\r
+                       this.parent.layout();\r
+                       validateFieldsTimed();\r
+\r
+                       save();\r
+               }  \r
+       }\r
+\r
+       /**\r
+        * Get current IExpression\r
+        * @return current IExpression\r
+        */\r
+       public IExpression getExpression() {\r
+               return expression;\r
+       }\r
+\r
+       /**\r
+        * Set the variable table that contains information about variables that are connected \r
+        * to this expression\r
+        * @param table\r
+        */\r
+       public void setVariableTable(Table table) {\r
+               this.variableTable = table;\r
+       }\r
+\r
+       /**\r
+        * Set timed field validation with default delay time\r
+        */\r
+    public void validateFieldsTimed() {        \r
+       validateFieldsTimed(VALIDATION_DELAY_TIME);\r
+    }\r
+    \r
+    /**\r
+     * Set timed field validation\r
+     * @param delay Delay time for validation\r
+     */\r
+    public void validateFieldsTimed(int delay) {\r
+        validationTimer.setDelay(delay);\r
+        if(!validationTimer.isRunning())\r
+            validationTimer.start();\r
+        else\r
+            validationTimer.restart();\r
+    }\r
+    \r
+    /**\r
+     * Validates expression fields in current IExpression\r
+     */\r
+       public void validateFields() {\r
+               if(this.variableTable == null) return;\r
+        \r
+               try {\r
+                   // Find the variable for this experession\r
+                       Resource variable = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       return graph.getPossibleObject(expr, l0.PartOf);\r
+                               }\r
+                       });\r
+                       // Validate the variable\r
+                       if(variable != null)\r
+                               ExpressionUtils.validateExpressionFields(variable, expression, variableTable, resourceManager);\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+       public void addModifyListener(ModifyListener listener) {\r
+               this.modifyListener = listener;\r
+       }\r
+\r
+       public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+               this.verifyKeyListener = listener;\r
+       }\r
+       \r
+       public void addFocusListener(FocusListener listener) {\r
+               this.focusListener = listener;\r
+       }\r
+\r
+       public void save() {\r
+               if(this.expression != null)\r
+                       this.expression.save(expr, data);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontModifyListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontModifyListener.java
new file mode 100644 (file)
index 0000000..eb1e11b
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.Font;\r
+\r
+import org.eclipse.swt.graphics.FontData;\r
+\r
+/**\r
+ * Font change listening interface\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public interface FontModifyListener {\r
+    \r
+    /**\r
+     * Called when font is changed\r
+     * @param font New font as AWT font\r
+     */\r
+    public void awtFontChanged(Font font);\r
+    \r
+    /**\r
+     * Called when font is changed\r
+     * @param font New font data as SWT font data\r
+     */\r
+    public void swtFontDataChanged(FontData font);\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FontSelectionComposite.java
new file mode 100644 (file)
index 0000000..9a8f438
--- /dev/null
@@ -0,0 +1,681 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.awt.Font;\r
+import java.awt.GraphicsEnvironment;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Locale;\r
+import java.util.TreeMap;\r
+\r
+import org.eclipse.core.runtime.ListenerList;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.FontDescriptor;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\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.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.FontData;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.ScrollBar;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.swt.widgets.Text;\r
+\r
+/**\r
+ * Composite for displaying font selection tools. By default, the composite contains\r
+ * font family, font style and font size.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class FontSelectionComposite extends Composite {\r
+\r
+\r
+    protected Text fontName, fontStyle, fontSize;\r
+    protected ArrayList<String> familyIndex = new ArrayList<String>();\r
+    protected TreeMap<String, ArrayList<Font>> fonts = getFonts(familyIndex);\r
+    protected Table fontFamilyTable, fontStyleTable, fontSizeTable;\r
+    protected String[] sizes = new String[] {"8", "9", "10", "11", "12", "14", "16", "18", "20", "24", "26", "28", "36", "48", "72"};\r
+\r
+    private ListenerList modifyListeners;\r
+    \r
+    private final LocalResourceManager resourceManager;\r
+\r
+    /**\r
+     * Gets all available fonts\r
+     * @param familyIndex Optional list for indexing font families\r
+     * @return Tree where key is font family name and object a list of fonts belonging to that family\r
+     */\r
+    private static TreeMap<String, ArrayList<Font>> getFonts(ArrayList<String> familyIndex) {\r
+        TreeMap<String, ArrayList<Font>> fonts = new TreeMap<String, ArrayList<Font>>();\r
+\r
+        GraphicsEnvironment gEnv = GraphicsEnvironment\r
+                .getLocalGraphicsEnvironment();\r
+        Font allFonts[] = gEnv.getAllFonts();\r
+\r
+        for(Font font : allFonts) {\r
+            String family = font.getFamily(Locale.ROOT);\r
+            if(!fonts.containsKey(family)) {\r
+                if(familyIndex != null)\r
+                    familyIndex.add(family);\r
+                fonts.put(family, new ArrayList<Font>());\r
+            }\r
+\r
+            boolean add = true;\r
+            for(Font f : fonts.get(family)) {\r
+                if(f.getFontName().equals(font.getFontName())) {\r
+                    add = false;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if(add)\r
+                fonts.get(family).add(font);\r
+        }\r
+        return fonts;\r
+    }\r
+\r
+    /**\r
+     * Composite containing components for selecting a font\r
+     * \r
+     * @param parent Parent composite\r
+     * @param style SWT style\r
+     */\r
+    public FontSelectionComposite(Composite parent, int style) {\r
+        super(parent, style);\r
+        \r
+        // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this);\r
+\r
+        modifyListeners = new ListenerList();\r
+\r
+        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(this);\r
+        GridDataFactory.fillDefaults().applyTo(this);\r
+\r
+        /*\r
+         * Two-row layout. First row consists of editable text boxes,\r
+         * second row consists of tables containing possible options\r
+         */\r
+\r
+        // First row\r
+        fontName = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontName);\r
+\r
+        fontStyle = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontStyle);\r
+\r
+        fontSize = new Text(this, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().applyTo(fontSize);\r
+\r
+        // Second row\r
+        fontFamilyTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontFamilyTable.setLinesVisible (false);\r
+        fontFamilyTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontFamilyTable);\r
+        fontFamilyTable.setItemCount(familyIndex.size());\r
+        TableColumn column = new TableColumn (fontFamilyTable, SWT.NONE);\r
+        column.setWidth(200);\r
+\r
+\r
+        fontStyleTable = new Table (this, SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontStyleTable.setLinesVisible (false);\r
+        fontStyleTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(100, 100).applyTo(fontStyleTable);\r
+        column = new TableColumn (fontStyleTable, SWT.NONE);\r
+        setFontStyleTableWidth();\r
+\r
+\r
+\r
+        fontSizeTable = new Table (this, SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);\r
+        fontSizeTable.setLinesVisible (false);\r
+        fontSizeTable.setHeaderVisible (false);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 100).applyTo(fontSizeTable);\r
+        column = new TableColumn (fontSizeTable, SWT.NONE);\r
+        column.setWidth(70);\r
+        for(String size : sizes) {\r
+            TableItem item = new TableItem(fontSizeTable, SWT.NONE);\r
+            item.setText(0, size);\r
+        }\r
+\r
+        // Listeners for components\r
+        addFontFamilyListeners();\r
+        addFontStyleListeners();\r
+        addFontSizeListeners();\r
+    }\r
+\r
+\r
+    /**\r
+     * Set controls to display given font\r
+     */\r
+    public void setFont(Font font, boolean notify) {\r
+        if(font == null)\r
+            return;\r
+        \r
+        Object[] listeners = new Object[0];\r
+        if(!notify) {\r
+            listeners = modifyListeners.getListeners();\r
+            for(Object listener : listeners)\r
+                modifyListeners.remove(listener);\r
+        }\r
+\r
+        String fontFamily = font.getFamily(Locale.ROOT);\r
+        String fontName = font.getFontName(Locale.ROOT);\r
+        this.fontName.setText(fontFamily);\r
+        this.fontFamilyTable.setTopIndex(this.fontFamilyTable.getSelectionIndex());\r
+\r
+        String style = "Regular";\r
+        if(fontName.length() > fontFamily.length())\r
+            style = fontName.substring(fontFamily.length() + 1);\r
+        this.fontStyle.setText(style);\r
+\r
+        int size = font.getSize();\r
+        fontSize.setText("" + size);\r
+\r
+        for(int i = 0; i < sizes.length; i++) {\r
+            if(sizes[i].equals("" + size)) {\r
+                fontSizeTable.select(i);\r
+                fontSizeTable.setTopIndex(i);\r
+                fontChanged();\r
+                break;\r
+            }\r
+        }  \r
+        \r
+        if(!notify) {\r
+            for(Object listener : listeners)\r
+                modifyListeners.add(listener);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the AWT font defined in this composite\r
+     * @return AWT font\r
+     */\r
+    public Font getAWTFont() {\r
+        String family = fontName.getText();\r
+        String style = fontStyle.getText();\r
+        if(style.equals("Regular"))\r
+            style = null;\r
+        \r
+        int stylebits = 0;\r
+        if(style != null) {\r
+            if(style.toLowerCase().contains("bold"))\r
+                stylebits |= SWT.BOLD;\r
+            if(style.toLowerCase().contains("italic"))\r
+                stylebits |= SWT.ITALIC;\r
+        }\r
+\r
+        String name = family + (style != null ? " " + style : "");\r
+\r
+        int size = 10;\r
+        try {\r
+            size = Integer.parseInt(fontSize.getText());\r
+        } catch (NumberFormatException e) {\r
+        }\r
+\r
+        if(name != null && name.length() > 0)\r
+            return new Font(name, stylebits, size);\r
+        else\r
+            return null;\r
+    }\r
+    \r
+    /**\r
+     * Adds listeners for font family name text and table\r
+     */\r
+    protected void addFontFamilyListeners() {\r
+\r
+        // Font name modify listener\r
+        fontName.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String name = text.getText();\r
+                fontFamilyTextModified(name, false);\r
+            }\r
+        });\r
+\r
+        // Font name key listener for auto-completion\r
+        fontName.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.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
+                    fontFamilyTextModified(fontName.getText(), true);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+        \r
+        // Call listener when editing has ended\r
+        fontName.addListener(SWT.FocusOut, new Listener() {\r
+            public void handleEvent(Event e) {\r
+                fontChanged();\r
+            }\r
+        });\r
+\r
+        // Font family data listener for lazy initialization of the table\r
+        fontFamilyTable.addListener (SWT.SetData, new Listener () {\r
+            public void handleEvent (Event event) {\r
+                TableItem item = (TableItem) event.item;\r
+                int index = fontFamilyTable.indexOf (item);\r
+\r
+                String family = familyIndex.get(index);\r
+                item.setText (family);\r
+\r
+                Font font = fonts.get(family).get(0);\r
+                if(font.canDisplay('a')) {\r
+                    FontData fontData =  toSwtFontData(font, 10);\r
+                    org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData));\r
+                    item.setFont(swtFont);\r
+                }\r
+            }\r
+        });\r
+\r
+\r
+        // Updates selected font to font name text\r
+        fontFamilyTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TableItem[] selection = fontFamilyTable.getSelection();\r
+\r
+                if(selection.length > 0) {\r
+                    String family = selection[0].getText();\r
+                    fontName.setText(family);\r
+                    fontChanged();\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        /*\r
+         *  Forces focus to font name texts and starts editing it, \r
+         *  if user presses a letter when focus is in font family table\r
+         */\r
+        fontFamilyTable.addKeyListener(new KeyListener() {\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isLetter(e.character)) {\r
+                    fontName.forceFocus();\r
+                    fontName.setTextChars(new char[] {e.character});\r
+                    fontName.setSelection(1, 1);\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+    /**\r
+     * Implements interactions between font name text and font family table, when \r
+     * the text in font name text has been changed.\r
+     * @param name New name\r
+     * @param autoComplete Has autocomplete been called\r
+     */\r
+    protected void fontFamilyTextModified(String name, boolean autoComplete) {\r
+        if(name.isEmpty())\r
+            return;\r
+        for(int i = 0; i < familyIndex.size(); i++) {\r
+            String family = familyIndex.get(i);\r
+            if(family.equals(name)) {\r
+                //complete match\r
+                fontFamilyTable.select(i);\r
+                selectFontFamily(name);\r
+                break;\r
+            } else if(family.toLowerCase().equals(name.toLowerCase())) {\r
+                // Wrong case but correct name\r
+                fontName.setText(family);\r
+                fontName.setSelection(family.length(), family.length());\r
+                fontFamilyTable.setTopIndex(i);\r
+                fontChanged();\r
+                break;\r
+            } else if(family.toLowerCase().startsWith(name.toLowerCase())) {\r
+                if(autoComplete) {\r
+                    // Fill in the rest of the name\r
+                    fontName.setText(family);\r
+                    fontName.setSelection(family.length());\r
+                    fontChanged();\r
+                    // The beginning is correct, help user by displaying the nearest name\r
+                } else { \r
+                    fontFamilyTable.setTopIndex(i);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Adds listeners for font style text and table\r
+     */\r
+    protected void addFontStyleListeners() {\r
+\r
+        // Font style modify listener\r
+        fontStyle.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String name = text.getText();\r
+                fontStyleTextModified(name, false);\r
+            }\r
+        });\r
+\r
+        // Font style key listener for auto-complete\r
+        fontStyle.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.character == ' ') && ((e.stateMask & SWT.CTRL) != 0) ) {\r
+                    fontStyleTextModified(fontStyle.getText(), true);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+\r
+        // Update selected style to font style text\r
+        fontStyleTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                TableItem[] selection = fontStyleTable.getSelection();\r
+\r
+                if(selection.length > 0) {\r
+                    String family = selection[0].getText();\r
+                    fontStyle.setText(family);\r
+                    fontChanged();\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        /*\r
+         *  Forces focus to font style text and starts editing it, \r
+         *  if user presses a letter when focus is in font style table\r
+         */\r
+        fontStyleTable.addKeyListener(new KeyListener() {\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isLetter(e.character)) {\r
+                    fontStyle.forceFocus();\r
+                    fontStyle.setTextChars(new char[] {e.character});\r
+                    fontStyle.setSelection(1, 1);\r
+                    e.doit = false;\r
+                } else if(e.keyCode == SWT.CR || e.keyCode == SWT.LF || e.keyCode == SWT.KEYPAD_CR) {\r
+                    fontChanged();\r
+                }\r
+            }\r
+        });\r
+    }\r
+\r
+    /**\r
+     * Handles interactions between font style text and font style table, when\r
+     * font style text has been changed\r
+     * \r
+     * @param name New text for font style \r
+     * @param autoComplete is auto-completion used\r
+     */\r
+    protected void fontStyleTextModified(String name, boolean autoComplete) {\r
+        if(name.isEmpty())\r
+            return;\r
+\r
+        for(int i = 0; i < fontStyleTable.getItemCount(); i++) {\r
+            TableItem item = fontStyleTable.getItem(i);\r
+            String style = item.getText();\r
+\r
+            if(style.equals(name)) {\r
+                //complete match\r
+                fontStyleTable.select(i);\r
+                break;\r
+            } else if(style.toLowerCase().equals(name.toLowerCase())) {\r
+                // Wrong case, correct style. -> fix the case\r
+                fontStyle.setText(style);\r
+                fontStyle.setSelection(style.length());\r
+                fontStyleTable.setTopIndex(i);\r
+                fontChanged();\r
+                break;\r
+            } else if(style.toLowerCase().startsWith(name.toLowerCase())) {\r
+                // The beginning of the word is correct\r
+                fontStyleTable.setTopIndex(i);\r
+                if(autoComplete) {\r
+                    // Fill in the rest of the name\r
+                    fontStyle.setText(style);\r
+                    fontStyle.setSelection(style.length());\r
+                    fontChanged();\r
+                    // The beginning is correct, help user by displaying the nearest name\r
+                } else { \r
+                    fontStyleTable.setTopIndex(i);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Listeners for font size text and font size table\r
+     */\r
+    protected void addFontSizeListeners() {\r
+\r
+        // Select an item from size table, if there is a matching item \r
+        fontSize.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) {\r
+                Text text = (Text) e.widget;\r
+                String size = text.getText();\r
+\r
+                for(int i = 0; i < sizes.length; i++) {\r
+                    if(sizes[i].equals(size)) {\r
+                        fontSizeTable.select(i);\r
+                        fontSizeTable.setTopIndex(i);\r
+                        fontChanged();\r
+                        break;\r
+                    }\r
+                }  \r
+            }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+            }\r
+        });\r
+\r
+        // Change the text in size text according to the selection in size table\r
+        fontSizeTable.addSelectionListener(new SelectionListener() {\r
+\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                fontSize.setText(fontSizeTable.getSelection()[0].getText());\r
+                fontChanged();\r
+            }\r
+\r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+\r
+        // Change focus from table to text, if user starts to write a number \r
+        fontSizeTable.addKeyListener(new KeyListener() {\r
+\r
+            @Override\r
+            public void keyReleased(KeyEvent e) { }\r
+\r
+            @Override\r
+            public void keyPressed(KeyEvent e) {\r
+                if(Character.isDigit(e.character)) {\r
+                    fontSize.setTextChars(new char[]{e.character});\r
+                    fontSize.setSelection(1);\r
+                    fontSize.forceFocus();\r
+                    e.doit = false;\r
+                }\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    /**\r
+     * Creates the contents of fontStyleTable according to the selected font family \r
+     * @param family Selected font family\r
+     */\r
+    protected void selectFontFamily(String family) {\r
+        String old = fontStyle.getText();\r
+        String selection = null, optionalSelection = null;\r
+\r
+        // Clear the table\r
+        fontStyleTable.removeAll();\r
+\r
+        if(familyIndex.indexOf(family) > -1) {\r
+            for(int i = 0; i < fonts.get(family).size(); i++) {\r
+                Font font = fonts.get(family).get(i);\r
+\r
+                String name = font.getFontName(Locale.ROOT);\r
+\r
+                // Style is "Regular", unless otherwise defined\r
+                String style = "Regular";\r
+                if(name.length() > family.length())\r
+                    style = name.substring(family.length() + 1);\r
+\r
+                // If previous font was bold, try to conserve the style\r
+                if(old.equals(style))\r
+                    selection  = style;\r
+                else if((!old.isEmpty() && style.contains(old)) || optionalSelection == null)\r
+                    optionalSelection = style;\r
+\r
+                TableItem item = new TableItem (fontStyleTable, SWT.NONE);\r
+                item.setText (0, style);\r
+                item.setData(font);\r
+\r
+                // If the font is not symbolic, use the font in the created item\r
+                if(font.canDisplay('a')) {\r
+                    FontData fontData = toSwtFontData(font, 10);\r
+                    org.eclipse.swt.graphics.Font swtFont = resourceManager.createFont(FontDescriptor.createFrom(fontData));\r
+                    item.setFont(swtFont);\r
+                }\r
+            }\r
+            fontStyleTable.setItemCount(fonts.get(family).size());\r
+\r
+            if(selection == null)\r
+                selection = optionalSelection;\r
+\r
+            fontStyle.setText(selection);\r
+            fontStyle.setSelection(selection.length(), selection.length());\r
+\r
+            setFontStyleTableWidth();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Set width for style table column. Width can change, if scroll bar appears \r
+     */\r
+    protected void setFontStyleTableWidth() {\r
+        Rectangle area = fontStyleTable.getClientArea();\r
+        Point size = fontStyleTable.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+        ScrollBar vBar = fontStyleTable.getVerticalBar();\r
+        int width = 100;\r
+        if (area.height == 0 || size.y <= area.height) {\r
+            Point vBarSize = vBar.getSize();\r
+            width += vBarSize.x;\r
+        }\r
+        fontStyleTable.getColumn(0).setWidth(width);\r
+    }\r
+\r
+\r
+    /**\r
+     * Builds SWT FontData from AWT font. Simple conversion.\r
+     * \r
+     * @param font AWT font\r
+     * @param height Height for the created data (or -1 if inherited directly from awt font, size matching not guaranteed)\r
+     * @return\r
+     */\r
+    protected static FontData toSwtFontData(Font font, int height) {\r
+        FontData fontData = new FontData();\r
+        fontData.setName(font.getFontName());\r
+        fontData.setStyle(font.getStyle());\r
+        fontData.setHeight(height > 0 ? height : font.getSize());\r
+        return fontData;\r
+    }\r
+\r
+\r
+    public void addFontModifiedListener(FontModifyListener listener) {\r
+        modifyListeners.add(listener);\r
+    }\r
+\r
+    public void removeFontModifiedListener(FontModifyListener listener) {\r
+        modifyListeners.remove(listener);\r
+    }\r
+\r
+    public List<FontModifyListener> getFontModifiedListener() {\r
+        ArrayList<FontModifyListener> listeners = new ArrayList<FontModifyListener>(modifyListeners.size());\r
+        for(Object l : modifyListeners.getListeners())\r
+            listeners.add((FontModifyListener)l);\r
+        return listeners;\r
+    }\r
+\r
+    /**\r
+     * Called when some property of the font definiton has changed.\r
+     * Calls font change listeners.\r
+     */\r
+    protected void fontChanged() {\r
+        Font font = getAWTFont();\r
+        if(font != null) {\r
+            \r
+            int style = 0;\r
+            style |= (font.getFontName(Locale.ROOT).contains("Bold") ? SWT.BOLD : 0);\r
+            style |= (font.getFontName(Locale.ROOT).contains("Italic") ? SWT.ITALIC : 0);\r
+            FontData fontData = new FontData(font.getFamily(Locale.ROOT), font.getSize(), style);\r
+            \r
+            Object[] listenersArray = modifyListeners.getListeners();\r
+            for (int i = 0; i < listenersArray.length; i++) {\r
+                ((FontModifyListener)listenersArray[i]).awtFontChanged(font);\r
+                ((FontModifyListener)listenersArray[i]).swtFontDataChanged(fontData);\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/FunctionLabelFactory.java
new file mode 100644 (file)
index 0000000..2b4cdcb
--- /dev/null
@@ -0,0 +1,49 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\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.Quad;\r
+\r
+\r
+\r
+public class FunctionLabelFactory  extends ReadFactoryImpl<Resource, String> {\r
+\r
+    private final String propertyURI;\r
+    private boolean end;\r
+    \r
+    public FunctionLabelFactory(String propertyURI, boolean end) {\r
+        this.propertyURI = propertyURI;\r
+        this.end = end;\r
+    }\r
+\r
+    @Override\r
+    public Object getIdentity(Object inputContents) {\r
+        return new Quad<Resource, String, Object, Boolean>((Resource) inputContents, propertyURI, getClass(), end);\r
+    }\r
+\r
+       \r
+    @Override\r
+    public String perform(ReadGraph graph, Resource resource) throws DatabaseException {\r
+        String value = graph.getPossibleRelatedValue(resource, graph.getResource(propertyURI));\r
+        if(end) {\r
+               return "end " + value + ";";\r
+        } else {\r
+               return "function " + value;\r
+        }\r
+    }\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..40fe24c
--- /dev/null
@@ -0,0 +1,89 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.ReadFactoryImpl;\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.databoard.Bindings;\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.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.layer0.Layer0;\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.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                return graph.hasStatement(variable, sr.IsOutput);\r
+            }\r
+        });\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
+        isOutputButton.setInput(context, input);\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
+                    Layer0Utils.addCommentMetadata(graph, "Modified Is Output for " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to False");\r
+                } else {\r
+                    graph.claim(input, SysdynResource.getInstance(graph).IsOutput, null, input);\r
+                    Layer0Utils.addCommentMetadata(graph, "Modified Is Output for " + graph.getPossibleRelatedValue2(input, Layer0.getInstance(graph).HasName, Bindings.STRING) + " to True");\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/ShortcutTabWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ShortcutTabWidget.java
new file mode 100644 (file)
index 0000000..56488ec
--- /dev/null
@@ -0,0 +1,322 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.text.Collator;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Locale;\r
+import java.util.concurrent.CopyOnWriteArrayList;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\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.graphics.Image;\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.AsyncReadGraph;\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.request.PossibleModel;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.AsyncListener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.validation.ValidationUtils;\r
+import org.simantics.sysdyn.utils.Function;\r
+import org.simantics.ui.SimanticsUI;\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
+    Composite composite;\r
+    TableItem item2;\r
+    \r
+       CopyOnWriteArrayList<Runnable> dependencyListeners =\r
+               new CopyOnWriteArrayList<Runnable>();\r
+       \r
+    private final LocalResourceManager resourceManager;\r
+\r
+    public ShortcutTabWidget(Composite parent, WidgetSupport support, int style) {\r
+       if(support!=null)\r
+               support.register(this);\r
+\r
+        composite = new Composite(parent, style);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
+        \r
+        tabFolder = new TabFolder (composite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, 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 | SWT.NO_FOCUS | SWT.HIDE_SELECTION);\r
+        \r
+        variables.setControl(variableTable);\r
+\r
+        functions = new TabItem(tabFolder, SWT.NULL);\r
+        functions.setText("Functions"); \r
+\r
+        functionTable = new Table (tabFolder, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_FOCUS | SWT.HIDE_SELECTION);\r
+        \r
+        // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), functionTable);\r
+        \r
+        functions.setControl(functionTable);\r
+        \r
+        // Add the functions only after we know which variable is connected to this widget.\r
+    }\r
+\r
+    public Composite getWidget() {\r
+       return composite;\r
+    }\r
+    \r
+    private void addFunctions(Resource model) {\r
+        TableItem item;\r
+        \r
+        ArrayList<Function> functionList = Function.getUserDefinedFunctions(model);\r
+        functionList.addAll(Function.getSharedFunctions(model));        \r
+        functionList.addAll(Function.getAllBuiltInFunctions());        \r
+        \r
+        Collections.sort(functionList);\r
+        \r
+        for(Function function : functionList){\r
+            item = new TableItem(functionTable, SWT.NONE);\r
+            item.setText(function.getName() + "()");\r
+            String parameterList = Function.inputListToString(function.getInputList());\r
+            item.setData(function.getName() + "(" + parameterList + ")");\r
+            item.setImage(getImage(this.resourceManager, function));\r
+        }\r
+        \r
+    }\r
+    \r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        if(input instanceof IStructuredSelection) {\r
+            final Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+            if(variable != null) {\r
+                \r
+                // Fill the function table\r
+                try { \r
+                    Resource model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                        @Override\r
+                        public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                            return graph.syncRequest(new PossibleModel(variable));\r
+                        }\r
+                    });\r
+                    addFunctions(model);\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                }\r
+\r
+                // Fill the variable table\r
+               SimanticsUI.getSession().asyncRequest(new Read<HashSet<String>>() {\r
+\r
+                                       @Override\r
+                                       public HashSet<String> perform(ReadGraph graph)\r
+                                                       throws DatabaseException {\r
+                                               return ValidationUtils.getDependencies(graph, variable);\r
+                                       }\r
+                               }, new AsyncListener<HashSet<String>>() {\r
+\r
+                                       @Override\r
+                                       public void execute(AsyncReadGraph graph,\r
+                                                       HashSet<String> result) {\r
+                                               \r
+                                               final HashSet<String> dependencies = result;\r
+                                               variableTable.getDisplay().asyncExec(new Runnable() {\r
+                                                       \r
+                                                       @Override\r
+                                                       public void run() {\r
+                                                               if(variableTable.isDisposed()) return;\r
+                                                               \r
+                                                               TableItem[] items = variableTable.getItems();\r
+                                                               \r
+                                                               // Remove deleted dependencies and create the list of current dependencies (itemStrings)\r
+                                                               ArrayList<String> itemStrings = new ArrayList<String>();\r
+                                               for(TableItem i : items) {\r
+                                                       String text = i.getText();\r
+                                                       if(dependencies.contains(text))\r
+                                                               itemStrings.add(text);\r
+                                                       else\r
+                                                               variableTable.remove(variableTable.indexOf(i));\r
+                                               }\r
+                                               \r
+                                               // Add all new dependencies\r
+                                               TableItem item;\r
+                                               for(String d : dependencies) {\r
+                                                       if(!itemStrings.contains(d)) {\r
+                                                               item = new TableItem(variableTable, SWT.NONE);\r
+                                                               item.setText(d);\r
+                                                               item.setData(d);\r
+                                                       }\r
+                                               }\r
+                                               \r
+                                               sort();\r
+                                               \r
+                                               String selfName = getName();\r
+\r
+                                               // Time and self are not added if selfName (we have an error or a stock).\r
+                                               if (selfName != null)\r
+                                               {\r
+                                    item = new TableItem(variableTable, SWT.NONE);\r
+                                    item.setText(selfName);\r
+                                    item.setData(selfName);\r
+                                    \r
+                                    item = new TableItem(variableTable, SWT.NONE);\r
+                                    item.setText("time");\r
+                                    item.setData("time");\r
+                                               }\r
+                                               \r
+                                                               synchronized(dependencyListeners) {\r
+                                                                       for(Runnable listener : dependencyListeners)\r
+                                                                               listener.run();\r
+                                                               }                                                               \r
+                                                       }\r
+                                               });\r
+                                       }\r
+                                       \r
+                                       /**\r
+                                        * Sort items to alphabetical order.\r
+                                        */\r
+                                       private void sort() {\r
+                                           TableItem[] connectedVariables = variableTable.getItems();\r
+                                           Collator collator = Collator.getInstance(Locale.getDefault());\r
+                                           for (int i = 1; i < connectedVariables.length; i++) {\r
+                                               String value1 = connectedVariables[i].getText(0);\r
+                                               for (int j = 0; j < i; j++) {\r
+                                                   String value2 = connectedVariables[j].getText(0);\r
+                                                   if (collator.compare(value1, value2) < 0) {\r
+                                                       String value = connectedVariables[i].getText(0);\r
+                                                       connectedVariables[i].dispose();\r
+                                                       TableItem item2 = new TableItem(variableTable, SWT.NONE, j);\r
+                                                       item2.setText(value);\r
+                                                       item2.setData(value);\r
+                                                       connectedVariables = variableTable.getItems();\r
+                                                       break;\r
+                                                   }\r
+                                               }\r
+                                           }\r
+                                       }\r
+                                       \r
+                                       /**\r
+                                        * Get the name of the respective variable.\r
+                                        */\r
+                                       private String getName() {\r
+                                           String selfName = null;\r
+                        try {\r
+                                               selfName = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+                                @Override\r
+                                public String perform(ReadGraph graph)\r
+                                        throws DatabaseException {\r
+                                    Layer0 l0 = Layer0.getInstance(graph);\r
+                                    Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName);\r
+                                    if (selfName instanceof String) {\r
+                                        return (String)selfName;\r
+                                    }\r
+                                    return null;\r
+                                }\r
+                            });\r
+                        }\r
+                        catch (DatabaseException e) {\r
+                            e.printStackTrace();\r
+                        }\r
+                                           return selfName;\r
+                                       }\r
+\r
+                                       @Override\r
+                                       public void exception(AsyncReadGraph graph,\r
+                                                       Throwable throwable) {\r
+                                               throwable.printStackTrace();\r
+                                       }\r
+\r
+                                       @Override\r
+                                       public boolean isDisposed() {\r
+                                               return variableTable.isDisposed();\r
+                                       }\r
+                               });\r
+            }\r
+        }\r
+    }\r
+\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 void addDependencyListener(Runnable listener) {\r
+               synchronized(dependencyListeners) {\r
+                       dependencyListeners.add(listener);\r
+               }\r
+       }\r
+\r
+       public void removeDependencyListener(Runnable listener) {\r
+               synchronized(dependencyListeners) {\r
+                       dependencyListeners.remove(listener);\r
+               }\r
+       }\r
+    \r
+    public Table getVariableTable() {\r
+        return variableTable;\r
+    }\r
+\r
+    /**\r
+     * Get the icon image for each type of Modelica function.\r
+     * @param rm LocalResourceManager for which the image is created.\r
+     * @param function Modelica function\r
+     * @return Image to be shown e.g. in assistive text feed and ShortcutTab\r
+     */\r
+    public static Image getImage(LocalResourceManager rm, Function function) {\r
+        switch (function.getType()) {\r
+            case USER_DEFINED:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/function.png")));\r
+            case SHARED:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/functionLink.png")));\r
+            case VENSIM:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/vensimFunction.png")));\r
+            case SYSDYN:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/sysdynFunction.png")));\r
+            case MODELICA:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaFunction.png")));\r
+            case MODELICA_ARRAY:\r
+                return rm.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/modelicaArrayFunction.png")));\r
+            default:\r
+                return null;\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/UnitComboWidget.java
new file mode 100644 (file)
index 0000000..d2a770f
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedCombo;\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.WidgetSupport;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+public class UnitComboWidget extends TrackedCombo {\r
+\r
+    public UnitComboWidget(Composite parent, WidgetSupport support, int style) {\r
+        super(parent, support, style);\r
+        \r
+        \r
+        // Add all units used in the model to the unit combo\r
+        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
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                Resource model = graph.getPossibleObject(input, l0.PartOf);\r
+                if (model != null) {\r
+                    Collection<Resource> variables = graph.getObjects(model, l0.ConsistsOf);\r
+                    for(Resource v : variables) {\r
+                        Object unit = graph.getPossibleRelatedValue(v, sr.Variable_unit);\r
+                        if (unit != null && !map.keySet().contains(unit)) {\r
+                            map.put((String)unit, (String)unit);\r
+\r
+                        }\r
+                    }\r
+                }\r
+                return map;\r
+            }\r
+        });\r
+        \r
+        // Set initial selection of unit combo\r
+        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).Variable_unit);\r
+                if(unit == null)\r
+                    return "";\r
+                else \r
+                    return unit;\r
+            }\r
+        });\r
+\r
+        // Modify unit\r
+        addModifyListener(new ComboModifyListenerImpl<Resource>() {\r
+\r
+            @Override\r
+            public void applyText(WriteGraph graph, Resource input, String text) throws DatabaseException {\r
+                graph.denyValue(input, SysdynResource.getInstance(graph).Variable_unit);\r
+                graph.claimLiteral(input, SysdynResource.getInstance(graph).Variable_unit, text);\r
+                \r
+                Resource conf = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf);\r
+                SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+                SysdynModel sm = smm.getModel(graph, conf);\r
+                sm.getMapping().domainModified(input);\r
+                sm.update(graph);\r
+            }\r
+        });\r
+\r
+    }\r
+    \r
+    \r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveOrientationGroup.java
new file mode 100644 (file)
index 0000000..dbdf951
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\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.Control;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.WidgetImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\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.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.Quad;\r
+\r
+public class ValveOrientationGroup extends WidgetImpl {\r
+\r
+    Group group;\r
+    Button vertical, horizontal;\r
+    \r
+    public ValveOrientationGroup(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(support);\r
+        group = new Group(parent, SWT.NONE);\r
+        group.setText("Valve orientation");\r
+        GridDataFactory.fillDefaults().applyTo(group);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(group);\r
+        \r
+        horizontal = new Button(group, support, SWT.RADIO);\r
+        horizontal.setText("Horizontal");\r
+        horizontal.setSelectionFactory(new OrientationSelectionFactory(horizontal, SysdynResource.URIs.Horizontal, true));\r
+        horizontal.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Horizontal));\r
+        \r
+        vertical = new Button(group, support, SWT.RADIO);\r
+        vertical.setText("Vertical");\r
+        vertical.setSelectionFactory(new OrientationSelectionFactory(vertical, SysdynResource.URIs.Vertical));\r
+        vertical.addSelectionListener(new OrientationSelectionListener(context, SysdynResource.URIs.Vertical));\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        horizontal.setInput(context, input);\r
+        vertical.setInput(context, input);\r
+    }\r
+\r
+    @Override\r
+    public Control getControl() {\r
+        return this.group;\r
+    }\r
+    \r
+    private class OrientationSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        \r
+        boolean defaultSelected;\r
+        String uri;\r
+        Button button;\r
+        \r
+        public OrientationSelectionFactory(Button button, String uri) {\r
+            this(button, uri, false);\r
+        }\r
+\r
+        public OrientationSelectionFactory(Button button, String uri, boolean defaultSelected) {\r
+            this.uri = uri;\r
+            this.defaultSelected = defaultSelected;\r
+            this.button = button;\r
+        }\r
+        \r
+        public Object getIdentity(Object inputContents) {\r
+            return new Quad<Object, Object, Object, Class<?>>(button, uri, defaultSelected, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return Boolean.FALSE;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return Boolean.FALSE;\r
+            \r
+            Resource orientation = graph.getPossibleObject(symbol, sr.ValveSymbol_orientation);\r
+            \r
+            if(orientation == null)\r
+                return defaultSelected;\r
+            \r
+            return orientation.equals(graph.getResource(uri));\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    private class OrientationSelectionListener extends SelectionListenerImpl<Resource> {\r
+        \r
+        String uri;\r
+        \r
+        public OrientationSelectionListener(ISessionContext context, String uri) {\r
+            super(context);\r
+            this.uri = uri;\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return;\r
+            \r
+            if(graph.hasStatement(symbol, sr.ValveSymbol_orientation))\r
+                graph.deny(symbol, sr.ValveSymbol_orientation);\r
+            graph.claim(symbol, sr.ValveSymbol_orientation, graph.getResource(uri));\r
+            \r
+            if(graph.hasStatement(symbol, sr.ValveSymbol_textLocation))\r
+                graph.deny(symbol, sr.ValveSymbol_textLocation);\r
+            if(sr.Vertical.equals(graph.getResource(uri)))\r
+                graph.claim(symbol, sr.ValveSymbol_textLocation, sr.Right);\r
+                \r
+        }\r
+        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/ValveTextLocationGroup.java
new file mode 100644 (file)
index 0000000..8761596
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets;\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.Control;\r
+import org.eclipse.swt.widgets.Group;\r
+import org.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.WidgetImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\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.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.Quad;\r
+\r
+public class ValveTextLocationGroup extends WidgetImpl {\r
+\r
+    Group group;\r
+    Button top, bottom, left, right;\r
+    \r
+    public ValveTextLocationGroup(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(support);\r
+        \r
+        group = new Group(parent, SWT.NONE);\r
+        group.setText("Text location");\r
+        GridDataFactory.fillDefaults().applyTo(group);\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).applyTo(group);\r
+        \r
+        top = new Button(group, support, SWT.RADIO);\r
+        top.setText("Top");\r
+        top.setSelectionFactory(new LocationSelectionFactory(top, SysdynResource.URIs.Top));\r
+        top.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Top));\r
+        \r
+        bottom = new Button(group, support, SWT.RADIO);\r
+        bottom.setText("Bottom");\r
+        bottom.setSelectionFactory(new LocationSelectionFactory(bottom, SysdynResource.URIs.Bottom, true));\r
+        bottom.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Bottom));\r
+        \r
+        left = new Button(group, support, SWT.RADIO);\r
+        left.setText("Left");\r
+        left.setSelectionFactory(new LocationSelectionFactory(left, SysdynResource.URIs.Left));\r
+        left.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Left));\r
+        \r
+        right = new Button(group, support, SWT.RADIO);\r
+        right.setText("Right");\r
+        right.setSelectionFactory(new LocationSelectionFactory(right, SysdynResource.URIs.Right));\r
+        right.addSelectionListener(new LocationSelectionListener(context, SysdynResource.URIs.Right));\r
+        \r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        top.setInput(context, input);\r
+        bottom.setInput(context, input);\r
+        left.setInput(context, input);\r
+        right.setInput(context, input);\r
+    }\r
+\r
+    @Override\r
+    public Control getControl() {\r
+        return this.group;\r
+    }\r
+    \r
+    \r
+    private class LocationSelectionFactory extends ReadFactoryImpl<Resource, Boolean> {\r
+        \r
+        boolean defaultSelected;\r
+        String uri;\r
+        Button button;\r
+        \r
+        public LocationSelectionFactory(Button button, String uri) {\r
+            this(button, uri, false);\r
+        }\r
+\r
+        public LocationSelectionFactory(Button button, String uri, boolean defaultSelected) {\r
+            this.uri = uri;\r
+            this.defaultSelected = defaultSelected;\r
+            this.button = button;\r
+        }\r
+        \r
+        public Object getIdentity(Object inputContents) {\r
+            return new Quad<Object, Object, Object, Class<?>>(button, uri, defaultSelected, getClass());\r
+        }\r
+\r
+        @Override\r
+        public Boolean perform(ReadGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return Boolean.FALSE;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return Boolean.FALSE;\r
+            \r
+            Resource location = graph.getPossibleObject(symbol, sr.ValveSymbol_textLocation);\r
+            \r
+            if(location == null)\r
+                return defaultSelected;\r
+            \r
+            return location.equals(graph.getResource(uri));\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    private class LocationSelectionListener extends SelectionListenerImpl<Resource> {\r
+        \r
+        String uri;\r
+        \r
+        public LocationSelectionListener(ISessionContext context, String uri) {\r
+            super(context);\r
+            this.uri = uri;\r
+        }\r
+\r
+        @Override\r
+        public void apply(WriteGraph graph, Resource valve) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            if(!graph.isInstanceOf(valve, sr.Valve))\r
+                return;\r
+            \r
+            Resource symbol = graph.getPossibleObject(valve, mr.ComponentToElement);\r
+            if(symbol == null)\r
+                return;\r
+            \r
+            if(graph.hasStatement(symbol, sr.ValveSymbol_textLocation))\r
+                graph.deny(symbol, sr.ValveSymbol_textLocation);\r
+            graph.claim(symbol, sr.ValveSymbol_textLocation, graph.getResource(uri));\r
+        }\r
+        \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/AvailableEnumerations.java
new file mode 100644 (file)
index 0000000..76a46f0
--- /dev/null
@@ -0,0 +1,53 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class AvailableEnumerations extends ViewpointContributorImpl<ResourceArray> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, ResourceArray input)\r
+                       throws DatabaseException {\r
+               Resource[] selection = input.resources;\r
+               if(selection.length < 1)\r
+                   return Collections.emptyList();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               Resource configuration = null;\r
+               \r
+               // Variables need to be from the same configuration\r
+               for(Resource r : selection) {\r
+                   Resource conf = graph.getPossibleObject(r, l0.PartOf);\r
+                   if(configuration == null || conf.equals(configuration))\r
+                       configuration = conf;\r
+                   else\r
+                       return Collections.emptyList();\r
+               }\r
+               \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        if(configuration == null) \r
+               return result;\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
+                result.add(new EnumerationNode(r));\r
+        }\r
+        return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Available enumerations";\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ComboBoxModifier.java
new file mode 100644 (file)
index 0000000..d45b1a2
--- /dev/null
@@ -0,0 +1,136 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.common.modifiers.EnumeratedValue;\r
+import org.simantics.browsing.ui.common.modifiers.Enumeration;\r
+import org.simantics.browsing.ui.content.Labeler.CustomModifier;\r
+import org.simantics.db.Session;\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.utils.ObjectUtils;\r
+\r
+public abstract class ComboBoxModifier<T> implements CustomModifier {\r
+\r
+       private final Enumeration<T> enumeration;\r
+       private final EnumeratedValue<T> value;\r
+       private final List<String> values;\r
+       private final Session session;\r
+       private Combo combo;\r
+       int select;\r
+\r
+       public ComboBoxModifier(Session session, Enumeration<T> enumeration, T value) {\r
+               this(session, enumeration, enumeration.find(value));\r
+       }\r
+\r
+       public ComboBoxModifier(Session session, Enumeration<T> enumeration,\r
+                       EnumeratedValue<T> value) {\r
+               if (session == null)\r
+                       throw new NullPointerException("null session");\r
+               if (enumeration == null)\r
+                       throw new NullPointerException("null enumeration");\r
+               if (enumeration.size() == 0)\r
+                       throw new IllegalArgumentException("");\r
+\r
+               this.enumeration = enumeration;\r
+               this.value = value;\r
+               this.session = session;\r
+\r
+               select = 0;\r
+               boolean found = false;\r
+               \r
+               this.values = new ArrayList<String>();\r
+               for (EnumeratedValue<T> v : enumeration.values()) {\r
+                       values.add(v.getName());\r
+                       \r
+                       if(v == value) \r
+                               found = true;\r
+                       \r
+                       if(found == false)\r
+                               select++;\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public Object createControl(Object parentControl, Object controlItem,\r
+                       int columnIndex, NodeContext context) {\r
+\r
+               combo = new Combo((Composite) parentControl, SWT.DROP_DOWN\r
+                               | SWT.BORDER | SWT.READ_ONLY);\r
+\r
+               for (String item : values) {\r
+                       combo.add(item);\r
+               }\r
+               \r
+               combo.addSelectionListener(new SelectionAdapter() {\r
+                       @Override\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               String index = ((Combo) e.getSource()).getText();\r
+                               modify(index);\r
+                       }\r
+               });\r
+               \r
+               combo.select(select);\r
+               \r
+               return combo;\r
+\r
+       }\r
+\r
+       @Override\r
+       public String getValue() {\r
+               return enumeration.values().get(0).getName();\r
+       }\r
+\r
+    @Override\r
+    public final String isValid(String label) {\r
+        if (enumeration.findByName(label) == null)\r
+            return "Value '" + label + "' is not among the enumerated values " + enumeration.values();\r
+        return null;\r
+    }\r
+\r
+       @Override\r
+       public void modify(String label) {\r
+               \r
+        int index = values.indexOf(label);\r
+        if (index == -1)\r
+            throw new IllegalArgumentException("Cannot modify enumeration with value '" + label + "', not among the enumerated values " + values);\r
+               \r
+        EnumeratedValue<T> oldEnumValue = value;\r
+        EnumeratedValue<T> newEnumValue = enumeration.values().get(index);\r
+        \r
+        final T oldObject = oldEnumValue != null ? oldEnumValue.getObject() : null;\r
+        final T newObject = newEnumValue != null ? newEnumValue.getObject() : null;\r
+        \r
+        if (ObjectUtils.objectEquals(oldObject, newObject))\r
+            return;\r
+\r
+        try {\r
+            session.getSession().syncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException {\r
+                    modifyWithObject(graph, oldObject, newObject);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            handleException(e);\r
+        }\r
+        \r
+               combo.dispose();                \r
+       }\r
+       \r
+       protected abstract void modifyWithObject(WriteGraph graph, T oldEnumObject, T enumObject) throws DatabaseException;\r
+       \r
+    protected void handleException(DatabaseException e) {\r
+        throw new RuntimeException(e);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationLabeler.java
new file mode 100644 (file)
index 0000000..4fa7ef9
--- /dev/null
@@ -0,0 +1,41 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+\r
+public class ConflictingEnumerationLabeler extends ColumnLabelerContributorImpl<ConflictingEnumerationNode>{\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, ConflictingEnumerationNode input)\r
+            throws DatabaseException {\r
+        HashMap<String, String> map = new HashMap<String, String>();\r
+\r
+        boolean first = true;\r
+        StringBuilder names = new StringBuilder();\r
+        for(Resource r : (Resource[])input.data) {\r
+            if(!first)\r
+                names.append(", ");\r
+            first = false;\r
+\r
+            String name = "empty";\r
+            if(r != null)\r
+                name =  NameUtils.getSafeName(graph, r);\r
+            names.append(name);\r
+        }\r
+        map.put(ColumnKeys.ENUMERATION, names.toString());\r
+\r
+        map.put(ColumnKeys.INDEXES, "Conflicting enumerations");\r
+        \r
+        return map;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ConflictingEnumerationNode.java
new file mode 100644 (file)
index 0000000..b93f849
--- /dev/null
@@ -0,0 +1,11 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+\r
+public class ConflictingEnumerationNode extends AbstractNode<Object> {\r
+\r
+    public ConflictingEnumerationNode(Object resources) {\r
+        super(resources);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexLabeler.java
new file mode 100644 (file)
index 0000000..a740831
--- /dev/null
@@ -0,0 +1,20 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\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.layer0.Layer0;\r
+\r
+public class EnumerationIndexLabeler  extends LabelerContributor<EnumerationIndexNode>{\r
+\r
+    @Override\r
+    public String getLabel(ReadGraph graph, EnumerationIndexNode index) throws DatabaseException {\r
+       Resource r = index.data;\r
+       if(r == null) return "Null resource";\r
+       String name = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasName);\r
+        return name == null ? "No name" : name;\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexNode.java
new file mode 100644 (file)
index 0000000..b2ca447
--- /dev/null
@@ -0,0 +1,97 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+\r
+public class EnumerationIndexNode  extends AbstractNode<Resource> implements IModifiableNode, IDoubleClickableNode {\r
+\r
+       public EnumerationIndexNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+       \r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+        Modifier modifier = new Modifier() {\r
+\r
+            @Override\r
+            public String getValue() {\r
+                Read<String> request =\r
+                    new Read<String>() {\r
+\r
+                    @Override\r
+                    public String perform(ReadGraph graph) throws DatabaseException {\r
+                        String name = graph.getPossibleRelatedValue(data, Layer0.getInstance(graph).HasName);\r
+                        return name != null ? name : "";\r
+                    }\r
+\r
+                };\r
+                try {\r
+                    return Simantics.getSession().syncRequest(request);\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                    return "";\r
+                }\r
+            }\r
+\r
+            @Override\r
+            public String isValid(String label) {\r
+               if(!new VariableNameValidator().isValidModelica(label, true))\r
+                       return "Not valid";\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public void modify(final String label) {\r
+               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        graph.claimLiteral(data, Layer0.getInstance(graph).HasName, label);\r
+                    }\r
+                });\r
+            }\r
+\r
+        };\r
+        \r
+        return modifier;\r
+        \r
+        \r
+        \r
+        \r
+       }\r
+\r
+       @Override\r
+       public boolean handleDoubleClick() {\r
+               return true;\r
+       }\r
+       \r
+       public void setShowInChartsSelected(final boolean selected) {\r
+       try {\r
+                       Simantics.getSession().syncRequest(new WriteRequest() {\r
+                           @Override\r
+                           public void perform(WriteGraph graph) throws DatabaseException {\r
+                               graph.markUndoPoint();\r
+                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                               graph.claimLiteral(data, sr.EnumerationIndex_showEnumerationIndexInCharts, selected);\r
+                               Layer0Utils.addCommentMetadata(graph, "Modified show in chart of " + NameUtils.getSafeName(graph, data) +  " to " + selected);\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/arrays/EnumerationIndexes.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationIndexes.java
new file mode 100644 (file)
index 0000000..a4758fc
--- /dev/null
@@ -0,0 +1,40 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class EnumerationIndexes extends ViewpointContributorImpl<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+               if(input == null) \r
+                       return null;\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               if(!graph.isInstanceOf(input, sr.Enumeration))\r
+                       return null;\r
+               Resource enumerationIndexList = graph.getPossibleObject(input, sr.Enumeration_enumerationIndexList);\r
+               if(enumerationIndexList == null)\r
+                       return null;\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+        for(Resource r : ListUtils.toList(graph, enumerationIndexList)) {\r
+            result.add(new EnumerationIndexNode(r));\r
+    }\r
+        return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Enumeration indexes";\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationLabeler.java
new file mode 100644 (file)
index 0000000..f274331
--- /dev/null
@@ -0,0 +1,52 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+\r
+public class EnumerationLabeler extends ColumnLabelerContributorImpl<EnumerationNode>{\r
+\r
+       @Override\r
+       public Map<String, String> getLabel(ReadGraph graph, EnumerationNode input)\r
+                       throws DatabaseException {\r
+               \r
+               String name =  NameUtils.getSafeName(graph, input.data);\r
+               HashMap<String, String> map = new HashMap<String, String>();\r
+               map.put(ColumnKeys.ENUMERATION, name);\r
+               \r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               Resource enumerationIndexes = graph.getPossibleObject(input.data, sr.Enumeration_enumerationIndexList);\r
+               Iterator<Resource> indexes = ListUtils.toList(graph, enumerationIndexes).iterator();\r
+               StringBuilder sb = new StringBuilder();\r
+               sb.append("[");\r
+               while(indexes.hasNext()) {\r
+                       Resource i = indexes.next();\r
+                       sb.append(NameUtils.getSafeName(graph, i));\r
+                       if(indexes.hasNext())\r
+                               sb.append(", ");\r
+               }\r
+               sb.append("]");\r
+               \r
+               Boolean relaceable = graph.getPossibleRelatedValue(input.data, sr.Enumeration_isReplaceable);\r
+               if(Boolean.TRUE.equals(relaceable)) {\r
+                       sb.append(" Replaceable");\r
+               }\r
+               \r
+               map.put(ColumnKeys.INDEXES, sb.toString());\r
+               \r
+               return map;\r
+       }\r
+\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/EnumerationNode.java
new file mode 100644 (file)
index 0000000..2d96005
--- /dev/null
@@ -0,0 +1,12 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.db.Resource;\r
+\r
+public class EnumerationNode  extends AbstractNode<Resource> {\r
+\r
+       public EnumerationNode(Resource resource) {\r
+               super(resource);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/NameAndArrayRangeModifyListener.java
new file mode 100644 (file)
index 0000000..6807d49
--- /dev/null
@@ -0,0 +1,149 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.LinkedHashMap;\r
+import java.util.StringTokenizer;\r
+\r
+import org.eclipse.swt.widgets.Combo;\r
+import org.simantics.Simantics;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ComboModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\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.Session;\r
+import org.simantics.db.VirtualGraph;\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.request.Read;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ArrayExpressionCombo;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Modification listener ONLY for ArrayExpressionCombos in EquationTabs.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class NameAndArrayRangeModifyListener extends ComboModifyListenerImpl<Resource> implements Widget {\r
+\r
+       Resource lastExpression; \r
+       ExpressionWidget expressionWidget;\r
+       ArrayExpressionCombo arrayExpressionCombo;\r
+       Object lastInput;\r
+\r
+       public NameAndArrayRangeModifyListener(WidgetSupport support, ExpressionWidget expressionWidget, ArrayExpressionCombo arrayExpressionCombo) {\r
+               support.register(this);\r
+               this.expressionWidget = expressionWidget;\r
+               this.arrayExpressionCombo = arrayExpressionCombo;\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               super.setInput(context, input);\r
+               this.lastInput = input;\r
+       } \r
+               \r
+       @Override\r
+    public void modifyText(TrackedModifyEvent e) {             \r
+               Combo combo = (Combo)e.getWidget();\r
+               LinkedHashMap<?, ?> data = (LinkedHashMap<?, ?>) combo.getData();\r
+               \r
+               Resource activeExpression = null;\r
+               try {\r
+               final Object input = lastInput;\r
+                       activeExpression = Simantics.getSession().syncRequest(new Read<Resource>() {\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource variable = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+                                       return graph.getPossibleObject(variable, SysdynResource.getInstance(graph).IndependentVariable_activeExpression);\r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+\r
+               Resource expression = (Resource) data.get(combo.getText());\r
+               if(expression != null) {\r
+                       lastExpression = expression;\r
+                       arrayExpressionCombo.setLastSelectedIndex(combo.getSelectionIndex());\r
+               } else {\r
+                       for(Object key : data.keySet()) {\r
+                               int index = arrayExpressionCombo.getLastSelectedIndex() < 0 ? 0 : arrayExpressionCombo.getLastSelectedIndex();\r
+                               if((Integer)combo.getData((String)key) == index) {\r
+                                       lastExpression =  (Resource) data.get(key);\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               // If expression has changed (i.e. user actually selects a different item in the combo), save the previous \r
+               if(lastExpression != null \r
+                               && !lastExpression.equals(activeExpression)\r
+                               && expressionWidget != null) {\r
+                       expressionWidget.save();\r
+               }\r
+\r
+               super.modifyText(e);\r
+       }\r
+\r
+       @Override\r
+       public void applyText(WriteGraph graph, final Resource variable, String text)\r
+                       throws DatabaseException {\r
+               StringTokenizer st = new StringTokenizer(text, "[]");\r
+               final String newName = st.nextToken();\r
+               String range = null;\r
+               if(st.hasMoreTokens()) {\r
+                       range = st.nextToken();\r
+               }\r
+               String originalName = graph.getRelatedValue(variable, Layer0.getInstance(graph).HasName);\r
+               if(!originalName.equals(newName)) {\r
+                   Resource configuration = graph.getPossibleObject(variable, Layer0.getInstance(graph).PartOf);\r
+                   new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, newName);\r
+                       graph.claimLiteral(variable, Layer0.getInstance(graph).HasName, newName);\r
+               }\r
+\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+               if(range != null && lastExpression != null) {\r
+                       String oldRange = graph.getPossibleRelatedValue(lastExpression, sr.Expression_arrayRange);\r
+                       if(oldRange == null || !range.equals(oldRange)) {\r
+                               graph.claimLiteral(lastExpression, sr.Expression_arrayRange, "[" + range + "]");\r
+                       }\r
+               } else if (range == null && lastExpression != null && graph.hasStatement(lastExpression, sr.Expression_arrayRange)) {\r
+                       graph.deny(lastExpression, sr.Expression_arrayRange);\r
+               }\r
+\r
+               Resource activeExpression = graph.getPossibleObject(variable, sr.IndependentVariable_activeExpression);\r
+\r
+               if(lastExpression != null && !lastExpression.equals(activeExpression)) {\r
+                       VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
+                       final Session session = graph.getSession();\r
+                       session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {\r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       VirtualGraph runtime = graph.getService(VirtualGraph.class);\r
+                                       session.asyncRequest(new WriteRequest(runtime) {\r
+                                               @Override\r
+                                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                       if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
+                                                               graph.deny(variable, sr.IndependentVariable_activeExpression);\r
+                                                       graph.claim(variable, sr.IndependentVariable_activeExpression, lastExpression);\r
+                                               }\r
+                                       });\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/RedeclarationNode.java
new file mode 100644 (file)
index 0000000..6c2b678
--- /dev/null
@@ -0,0 +1,172 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.browsing.ui.common.modifiers.EnumeratedValue;\r
+import org.simantics.browsing.ui.common.modifiers.Enumeration;\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.IModifiableNode;\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\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.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class RedeclarationNode  extends AbstractNode<Resource> implements IModifiableNode {\r
+\r
+       private Resource module;\r
+       \r
+       public RedeclarationNode(ReadGraph graph, final Resource module, Resource enumeration) {\r
+               super(enumeration);\r
+               this.module = module;\r
+       }\r
+       \r
+       /**\r
+        * \r
+        * @param graph\r
+        * @return\r
+        */\r
+       public Resource getReplacingEnumeration(ReadGraph graph) {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource result = null;\r
+               try {\r
+                       Resource redeclaration = getRedeclaration(graph);\r
+                       if(redeclaration != null) {\r
+                               result = graph.getSingleObject(redeclaration, sr.Redeclaration_replacingEnumeration);\r
+                       }\r
+               } catch(DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+               return result;\r
+       }\r
+       \r
+\r
+       public Resource getModule() {\r
+               return module;\r
+       }\r
+\r
+       public void setModule(Resource module) {\r
+               this.module = module;\r
+       }\r
+\r
+       public Resource getRedeclaration(ReadGraph graph) {\r
+               try {\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                       for(Resource redeclaration : graph.syncRequest(new ObjectsWithType(module, sr.Module_redeclaration, sr.Redeclaration))) {\r
+                               Resource replacedEnumeration = graph.getPossibleObject(redeclaration, sr.Redeclaration_replacedEnumeration);\r
+                               if(replacedEnumeration != null && replacedEnumeration.equals(getReplacedEnumeration())) {\r
+                                       return redeclaration;\r
+                               }\r
+                       }\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       public void setRedeclaration(WriteGraph graph, Resource redeclaration) {\r
+               try {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource oldRedeclaration = getRedeclaration(graph);\r
+               if(oldRedeclaration != null || redeclaration == null) {\r
+                       graph.deny(module, sr.Module_redeclaration, oldRedeclaration);\r
+               }\r
+               \r
+               if(redeclaration != null)\r
+                       graph.claim(module, sr.Module_redeclaration, redeclaration);\r
+               \r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       public Resource getReplacedEnumeration() {\r
+               return this.data;\r
+       }\r
+\r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+               \r
+               if(!ColumnKeys.REPLACED_WITH.equals(columnId))\r
+                       return null;\r
+               \r
+               ComboBoxModifier<Resource> cbm = null;\r
+               \r
+               try {\r
+                       cbm = SimanticsUI.getSession().syncRequest(new Read<ComboBoxModifier<Resource>>() {\r
+                               \r
+                               @Override\r
+                               public ComboBoxModifier<Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       \r
+                                       ArrayList<EnumeratedValue<Resource>> values = new ArrayList<EnumeratedValue<Resource>>();\r
+                                       \r
+                                       \r
+                               Resource configuration = graph.getSingleObject(module, l0.PartOf);\r
+                               \r
+                                       for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
+                                               String name = NameUtils.getSafeName(graph, enumeration);\r
+                                               values.add(new EnumeratedValue<Resource>(name, enumeration));                                   \r
+                                       }\r
+\r
+                                       if(values.size() == 0)\r
+                                               return null;\r
+                                       \r
+                                       values.add(0, new EnumeratedValue<Resource>("", null));\r
+                                       Enumeration<Resource> enumeration = new Enumeration<Resource>(values);  \r
+                                       \r
+                                       ComboBoxModifier<Resource> cbm = new ComboBoxModifier<Resource>(graph.getSession(), enumeration, getReplacingEnumeration(graph)) {\r
+                                               \r
+                                               @Override\r
+                                               protected void modifyWithObject(WriteGraph graph, Resource oldEnumObject,\r
+                                                               Resource enumObject) throws DatabaseException {\r
+                                                       \r
+                                                       if(enumObject == null) {\r
+                                                               setRedeclaration(graph, null);\r
+                                                       } else if(!enumObject.equals(oldEnumObject)) {\r
+                                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                               Resource redeclaration = GraphUtils.create2(graph, \r
+                                                                               sr.Redeclaration, \r
+                                                                               sr.Redeclaration_replacedEnumeration, getReplacedEnumeration(),\r
+                                                                               sr.Redeclaration_replacingEnumeration, enumObject);\r
+                                                               setRedeclaration(graph, redeclaration);\r
+                                                       }\r
+                                                       \r
+                                               }\r
+                                       };\r
+                                       \r
+                                       return cbm;\r
+                                       \r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+\r
+               return cbm;\r
+       }\r
+       \r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerations.java
new file mode 100644 (file)
index 0000000..7f8a1fa
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ReplaceableEnumerations  extends ViewpointContributorImpl<Resource> {\r
+       \r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+        ArrayList<RedeclarationNode> result = new ArrayList<RedeclarationNode>();\r
+        if(input == null)\r
+               return result;\r
+        \r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+        \r
+        Resource moduleType = graph.getPossibleObject(input, l0.InstanceOf);\r
+        if(moduleType == null)\r
+            return result;\r
+        Resource configuration = graph.getPossibleObject(moduleType, sr2.IsDefinedBy);\r
+        if(configuration == null)\r
+            return result;\r
+        \r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
+                       if(Boolean.TRUE.equals(graph.getRelatedValue(r, sr.Enumeration_isReplaceable)))\r
+                               result.add(new RedeclarationNode(graph, input, r));\r
+               }\r
+               \r
+        return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Replaceable enumerations";\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableEnumerationsLabeler.java
new file mode 100644 (file)
index 0000000..68a44db
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.ColumnLabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+\r
+public class ReplaceableEnumerationsLabeler extends ColumnLabelerContributorImpl<RedeclarationNode>{\r
+\r
+       @Override\r
+       public Map<String, String> getLabel(ReadGraph graph, RedeclarationNode input)\r
+                       throws DatabaseException {\r
+               HashMap<String, String> map = new HashMap<String, String>();\r
+               \r
+               String name = NameUtils.getSafeName(graph, input.data);\r
+               map.put(ColumnKeys.ENUMERATION, name);\r
+               \r
+               Resource replacingEnumeration = input.getReplacingEnumeration(graph); \r
+               String replacingEnumerationName = "";\r
+               if(replacingEnumeration != null)\r
+                       replacingEnumerationName = NameUtils.getSafeName(graph, replacingEnumeration);\r
+               \r
+               map.put(ColumnKeys.REPLACED_WITH, replacingEnumerationName);\r
+               return map;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ReplaceableIndexesWidget.java
new file mode 100644 (file)
index 0000000..d5403ac
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\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.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\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.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+public class ReplaceableIndexesWidget implements Widget {\r
+       \r
+    Resource variable = null; \r
+    boolean selected = false;\r
+    org.simantics.browsing.ui.swt.widgets.Button isReplaceableButton;\r
+    \r
+    public ReplaceableIndexesWidget(Composite parent, WidgetSupport support, int style) {\r
+        support.register(this);\r
+        isReplaceableButton = new org.simantics.browsing.ui.swt.widgets.Button(parent, support, style |= SWT.CHECK);\r
+        isReplaceableButton.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource input) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                return graph.getPossibleRelatedValue(variable, sr.Enumeration_isReplaceable);\r
+            }\r
+        });\r
+        isReplaceableButton.setText("Can be replaced by parent module");\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
+        isReplaceableButton.setInput(context, input);\r
+        \r
+        isReplaceableButton.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
+                Boolean replaceable = graph.getPossibleRelatedValue(input, sr.Enumeration_isReplaceable);\r
+                if(Boolean.TRUE.equals(replaceable)) {\r
+                    graph.claimLiteral(input, sr.Enumeration_isReplaceable, false);\r
+                    selected = false;\r
+                } else {\r
+                       graph.claimLiteral(input, sr.Enumeration_isReplaceable, true);\r
+                       selected = true;\r
+                }\r
+                Layer0Utils.addCommentMetadata(graph, "Modified " + NameUtils.getSafeName(graph, input) + " can be replaced to " + selected);\r
+            }\r
+        });\r
+    }\r
+    \r
+    public Button getWidget() {\r
+        return isReplaceableButton.getWidget();\r
+    }\r
+    \r
+    public boolean getSelection() {\r
+       return selected;\r
+    }\r
+    \r
+    public void addSelectionListener(SelectionListener listener) {\r
+       isReplaceableButton.addSelectionListener(listener);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/ShowInChartsCheckBox.java
new file mode 100644 (file)
index 0000000..da412f4
--- /dev/null
@@ -0,0 +1,21 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import org.simantics.browsing.ui.CheckedState;\r
+import org.simantics.browsing.ui.graph.contributor.labeler.CheckedStateContributor;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ShowInChartsCheckBox extends CheckedStateContributor<EnumerationIndexNode> {\r
+\r
+       @Override\r
+       public CheckedState getState(ReadGraph graph, EnumerationIndexNode input)\r
+                       throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Boolean selected = graph.getPossibleRelatedValue(input.data, sr.EnumerationIndex_showEnumerationIndexInCharts, Bindings.BOOLEAN);\r
+               return selected ? CheckedState.CHECKED : CheckedState.NOT_CHECKED;\r
+       }\r
+       \r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerations.java
new file mode 100644 (file)
index 0000000..2940291
--- /dev/null
@@ -0,0 +1,115 @@
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class UsedEnumerations extends ViewpointContributorImpl<ResourceArray> {\r
+\r
+               @Override\r
+               public Collection<?> getContribution(ReadGraph graph, ResourceArray input)\r
+                               throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               Resource[] selection = input.resources;\r
+               if(selection.length < 1)\r
+                   return Collections.emptyList();\r
+               \r
+               /* Collect enumerations for all variables\r
+                * var1\r
+                *     - enum1\r
+                *     - enum2\r
+                * var2\r
+                *     - enum1\r
+                *     - enum2\r
+                *     - enum3\r
+                */\r
+               ArrayList<List<Resource>> variableEnumerations = new ArrayList<List<Resource>>();\r
+               for(Resource variable : selection) {\r
+                   Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+                   if(arrayIndexes != null) {\r
+                       variableEnumerations.add(ListUtils.toList(graph, arrayIndexes));\r
+                   } else {\r
+                       variableEnumerations.add(new ArrayList<Resource>());\r
+                   }\r
+               }\r
+\r
+\r
+               /* Construct a list of enumerations\r
+                * FirstEnumeration\r
+                *     - var1.first\r
+                *     - var2.first\r
+                *     - var3.first\r
+                * SecondEnumeration\r
+                *     - var1.second\r
+                *     - ...\r
+                */\r
+               ArrayList<List<Resource>> enumerations = new ArrayList<List<Resource>>();\r
+\r
+               int index = 0;\r
+               while(true) {\r
+\r
+                   // Break loop if enumerations for all variables have been recorded\r
+                   boolean b = true;\r
+                   for(List<Resource> varEnums : variableEnumerations) {\r
+                       if(index < varEnums.size()) {\r
+                           b = false;\r
+                           break;\r
+                       }\r
+                   }\r
+                   \r
+                   if(b) break;\r
+                   \r
+                   for(List<Resource> current : variableEnumerations) {\r
+                       if(index == enumerations.size())\r
+                           enumerations.add(index, new ArrayList<Resource>());\r
+                       Resource enumeration =  index < current.size()? current.get(index) : null;\r
+                       enumerations.get(index).add(enumeration);\r
+                   }\r
+                   \r
+                   index++;\r
+               }\r
+               \r
+               // Build nodes\r
+               ArrayList<AbstractNode<?>> result = new ArrayList<AbstractNode<?>>();\r
+\r
+               if(enumerations.size() == 1 && (enumerations.get(0).size() == 0 || (enumerations.get(0).size() == 1 && enumerations.get(0).get(0) == null)))\r
+                   return result;\r
+               \r
+               for(List<Resource> enumeration : enumerations) {\r
+                   boolean same = true;\r
+                   for(int i = 0; i < enumeration.size() - 1; i++) {\r
+                       if(enumeration.get(i) == null || enumeration.get(i + 1) == null ||\r
+                               !enumeration.get(i).equals(enumeration.get(i + 1))) {\r
+                           same = false;\r
+                           break;\r
+                       }\r
+                   }\r
+                   \r
+                   if(!same) {\r
+                       result.add(new ConflictingEnumerationNode(enumeration.toArray(new Resource[enumeration.size()])));\r
+                   } else {\r
+                       result.add(new EnumerationNode(enumeration.get(0)));\r
+                   }\r
+               }\r
+               \r
+\r
+               \r
+               return result;\r
+               }\r
+\r
+               @Override\r
+               public String getViewpointId() {\r
+                       return "Used enumerations";\r
+               }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/arrays/UsedEnumerationsManyVariables.java
new file mode 100644 (file)
index 0000000..28defab
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.arrays;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class UsedEnumerationsManyVariables  extends ViewpointContributorImpl<List<Resource>> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, List<Resource> input)\r
+                       throws DatabaseException {\r
+               \r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+\r
+        return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Available enumerations";\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..48a5e7d
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Table;\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(ExpressionWidgetInput input) {\r
+        super(input);\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
+    @Override\r
+    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
+        // Create the single field\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, allowedVariables, true, input);\r
+        expression.setExpression(equation);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\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..a1c6549
--- /dev/null
@@ -0,0 +1,246 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.jface.text.IUndoManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.Table;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Basic expression that is used with parameter, auxiliary and constant\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class BasicExpression implements IExpression {\r
+\r
+    protected ExpressionField expression;\r
+    protected Resource expressionType;\r
+    protected ExpressionWidgetInput input;\r
+    \r
+    public BasicExpression(ExpressionWidgetInput input) {\r
+        this.input = input;\r
+    }\r
+    \r
+    @Override\r
+    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
+        // Create the single field\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, null, false, input);\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 expression, Map<String, Object> data) {\r
+        String equation = null;\r
+        if (expression != 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
+                        if (expression != null) {\r
+                            String equation = graph.getPossibleRelatedValue(expression, sr.Expression_equation);\r
+                            if(equation != null)\r
+                               return equation;\r
+                        }\r
+                        \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 expression, Map<String, Object> data) {\r
+        final String currentText = this.expression.getExpression();\r
+        final String oldEquation = (String)data.get("equation");\r
+\r
+        if(oldEquation == null || \r
+                (currentText != null && expressionType != 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
+                    Layer0 l0 = Layer0.getInstance(g);\r
+\r
+                    // If nothing has changed, do nothing\r
+                    if (oldEquation != null \r
+                            && expression != null \r
+                            && g.isInstanceOf(expression, expressionType) \r
+                            && currentText.equals(oldEquation)) {\r
+                        return;\r
+                    }\r
+                    \r
+                    // Force change to parameter, if the equation is a parameter\r
+                    if(ExpressionUtils.isParameter(currentText)) {\r
+                       if(!expressionType.equals(sr.ConstantExpression))\r
+                               expressionType = sr.ParameterExpression;\r
+                    } else {\r
+                       expressionType = sr.NormalExpression;\r
+                    }\r
+                    \r
+                    g.markUndoPoint();\r
+                               CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
+                               g.addMetadata(cm.add("Set equation"));\r
+\r
+                    // If the current expression type is different than the target expression type, create a new expression\r
+                    if(!g.isInstanceOf(expression, expressionType)) {\r
+\r
+                       final Resource newExpression = GraphUtils.create2(g, expressionType, \r
+                                       sr.Expression_equation, currentText);\r
+                       String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING);\r
+                       if(arrayRange != null)\r
+                               g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange);\r
+                       \r
+                       final Resource variable = g.getPossibleObject(expression, l0.PartOf);\r
+                       if(variable == null)\r
+                           return;\r
+                       Resource ownerList = g.getPossibleObject(variable, sr.Variable_expressionList);\r
+                       if(ownerList == null)\r
+                           return;\r
+                       \r
+                       ListUtils.replace(g, ownerList, expression, newExpression);\r
+                       \r
+                       g.deny(expression, l0.PartOf);\r
+                       \r
+                       g.claim(newExpression, l0.PartOf, variable);\r
+                       \r
+                       \r
+                        VirtualGraphSupport support = g.getService(VirtualGraphSupport.class);\r
+                                               g.syncRequest(new WriteRequest(support.getWorkspacePersistent("expressions")) {\r
+                                                       @Override\r
+                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                                               if(variable != null) {\r
+                                                                       if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
+                                                                               graph.deny(variable, sr.IndependentVariable_activeExpression);\r
+                                                                       graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression);\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                               );\r
+                    } else {\r
+                        // Claim value for the expression\r
+                       g.claimLiteral(expression, sr.Expression_equation, currentText);\r
+                    }\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
+       @Override\r
+       public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+               this.expression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+       }\r
+\r
+    @Override\r
+    public IUndoManager getUndoManager() {\r
+        // TODO Auto-generated method stub\r
+        return null;\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..a25d215
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import gnu.trove.THashMap;\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
+    THashMap<RGB,Color> map = new THashMap<RGB,Color>();\r
+\r
+    @Override\r
+    public void dispose() {\r
+        for(Color c : map.values())\r
+            c.dispose();\r
+        map.clear();\r
+    }\r
+\r
+    @Override\r
+    public Color getColor(RGB rgb) {\r
+        Color color = map.get(rgb);\r
+        if (color == null) {\r
+            color = new Color(Display.getCurrent(), rgb);\r
+            map.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/CompletionProcessor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/CompletionProcessor.java
new file mode 100644 (file)
index 0000000..d2d78a5
--- /dev/null
@@ -0,0 +1,348 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.text.ITextViewer;\r
+import org.eclipse.jface.text.contentassist.CompletionProposal;\r
+import org.eclipse.jface.text.contentassist.ICompletionProposal;\r
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;\r
+import org.eclipse.jface.text.contentassist.IContextInformation;\r
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;\r
+import org.eclipse.swt.graphics.Image;\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.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.properties.widgets.ShortcutTabWidget;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.sysdyn.utils.Function;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+\r
+/**\r
+ * IContentAssistProcessor to determine which options (the functions and \r
+ * variables available) are shown for ContentAssistant; this assist of\r
+ * text field allows long variable names to be selected from a popup menu.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class CompletionProcessor implements IContentAssistProcessor {\r
+       \r
+    private final Table allowedVariables;\r
+    private ArrayList<Function> functions;\r
+    private ArrayList<String> variables = null;\r
+    private ArrayList<String> timeAndSelfVariables = null;\r
+    private final ExpressionWidgetInput input;\r
+    \r
+    private LocalResourceManager resourceManager;\r
+    \r
+       private static final char[] ALLOWED_CHARACTERS = {\r
+               'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','Ã¥','ä','ö',\r
+               'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Ã…','Ä','Ö',\r
+               '1','2','3','4','5','6','7','8','9','0','.','(',')'};\r
+           \r
+       private static final String ALLOWED_CONNECTED_CHARACTERS_REG_EXP = "[\\Q({[:;,<=>+-*/^\\E]";\r
+       \r
+       private static final ArrayList<String> ALLOW_ALL_COMPLETIONS_LIST = new ArrayList<String>();\r
+       static {\r
+               ALLOW_ALL_COMPLETIONS_LIST.add("");\r
+       }\r
+       \r
+       public CompletionProcessor(Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
+               this.allowedVariables = allowedVariables;\r
+               this.input = input;\r
+               this.functions = new ArrayList<Function>();\r
+               \r
+               if (allowFunctions) {\r
+                   if (input != null && CompletionProcessor.this.input.variable != null) {\r
+                       // Get the respective model\r
+                       Resource model = null;\r
+                   try {\r
+                    model = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                        @Override\r
+                        public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                            return Variables.getModel(graph, CompletionProcessor.this.input.variable);\r
+                        }\r
+                    });\r
+                    \r
+                    //User defined functions\r
+                    functions.addAll(Function.getUserDefinedFunctions(model));\r
+                    // Shared functions\r
+                    functions.addAll(Function.getSharedFunctions(model));\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                }\r
+                   }\r
\r
+                   // Collect built in functions and sort all functions.\r
+               functions.addAll(Function.getAllBuiltInFunctions());\r
+            Collections.sort(functions);\r
+       }\r
+       }\r
+    \r
+       /**\r
+        * Collect and sort all variables.\r
+        */\r
+       private void findVariables() {\r
+           if (variables == null) {\r
+            variables = new ArrayList<String>();\r
+            timeAndSelfVariables = new ArrayList<String>();\r
+            if(allowedVariables != null && !allowedVariables.isDisposed()) {\r
+                TableItem[] connectedVariables = allowedVariables.getItems();\r
+                for(TableItem ti : connectedVariables) {\r
+                    // The status of the variable is determined using the color of its table item :(\r
+                    if (ExpressionUtils.variableTimeAndSelfColor(resourceManager).equals(ti.getForeground())) {\r
+                        this.timeAndSelfVariables.add(ti.getText());\r
+                    } else {\r
+                        this.variables.add(ti.getText());\r
+                    }\r
+                    \r
+                }\r
+            }\r
+            Collections.sort(variables);\r
+            Collections.sort(timeAndSelfVariables);\r
+        }\r
+       }\r
+       \r
+       /**\r
+        * Create CompletionProposals of the variables and add them to array. Do not allow duplicates.\r
+        * @param array result array of CompletionProposals\r
+        * @param token current token\r
+        * @param offset an offset within the document for which completions should be computed\r
+        */\r
+       private void addVariables(ArrayList<ICompletionProposal> array, String token, int offset) {\r
+           Image imageVariable = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variable.png")));\r
+        Image imageVariableGray = resourceManager.createImage(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/variableGray.png")));\r
+        \r
+        for (String variable : variables) {\r
+            if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase()))\r
+                       && !listContainsVariable(array, variable)) {\r
+               array.add(new CompletionProposal(variable, \r
+                        offset - token.length(),\r
+                        token.length(), \r
+                        variable.length(), \r
+                        imageVariable, \r
+                        variable, \r
+                        null, \r
+                        null));\r
+            }   \r
+        }\r
+        for (String variable : timeAndSelfVariables) {\r
+            if ((token.length() == 0 || variable.toUpperCase().startsWith(token.toUpperCase()))\r
+                       && !listContainsVariable(array, variable)) {\r
+                array.add(new CompletionProposal(variable, \r
+                        offset - token.length(),\r
+                        token.length(), \r
+                        variable.length(), \r
+                        imageVariableGray, \r
+                        variable, \r
+                        null, \r
+                        null));\r
+            }   \r
+        }\r
+       }\r
+       \r
+       private boolean listContainsVariable(ArrayList<ICompletionProposal> array,\r
+                       String variable) {\r
+               for (ICompletionProposal proposal : array) {\r
+                       if (proposal.getDisplayString().equals(variable))\r
+                               return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       /**\r
+     * Create CompletionProposals of the functions and add them to array.\r
+     * @param array result array of CompletionProposals\r
+     * @param token current token\r
+     * @param offset an offset within the document for which completions should be computed\r
+     */\r
+       private void addFunctions(ArrayList<ICompletionProposal> array, String token, int offset) {\r
+           // Parameters don't have functions\r
+           if (functions == null)\r
+               return;\r
+           \r
+           // Create CompletionProposals out of Functions\r
+        for (Function function : functions) {\r
+            if (token.length() == 0 || function.getName().toUpperCase().startsWith(token.toUpperCase())) {\r
+                Image image = ShortcutTabWidget.getImage(resourceManager, function);\r
+                String parameterList = Function.inputListToString(function.getInputList());\r
+                array.add(new CompletionProposal(\r
+                        function.getName() + "(" + parameterList + ")", \r
+                        offset - token.length(),\r
+                        token.length(), \r
+                        function.getName().length() + 1,\r
+                        image, \r
+                        function.getName() + "(" + parameterList + ")", \r
+                        null, \r
+                        function.getDescriptionHTML()));\r
+            }   \r
+        }\r
+       }\r
+       \r
+       /**\r
+     * Collect all matching proposals. Duplicates are removed; the one with the longest token stays.\r
+     * @param possibleLabelBeginnings sets of whitespace delimited tokens (as Strings)\r
+     * @param offset an offset within the document for which completions should be computed\r
+     * @return Array of matching proposals\r
+     */\r
+    private ICompletionProposal[] collectProposals(ArrayList<String> possibleLabelBeginnings, int offset) {\r
+           ArrayList<ICompletionProposal> resultArray = new ArrayList<ICompletionProposal>();\r
+        \r
+           // Find variables and functions and create CompletionProposals out of them.\r
+           findVariables();\r
+           \r
+           // Sort the list based on the length of the tokens (descending) to get "" to end.\r
+           Collections.sort(possibleLabelBeginnings, new Comparator<String>(){\r
+                       @Override\r
+                       public int compare(String o1, String o2) {\r
+                               if (o1.length() > o2.length()) {\r
+                                       return -1;\r
+                               } else if (o1.length() < o2.length()) {\r
+                                       return 1;\r
+                               }\r
+                               return 0;\r
+                       }\r
+               });\r
+           \r
+           for (String possibleLabelBeginning : possibleLabelBeginnings) {\r
+               addVariables(resultArray, possibleLabelBeginning, offset);\r
+           }\r
\r
+           // No support for whitespace in function names; get shortest beginning\r
+       addFunctions(resultArray, possibleLabelBeginnings.get(possibleLabelBeginnings.size() - 1), offset);\r
+\r
+       ICompletionProposal[] result = new ICompletionProposal[resultArray.size()];\r
+               for (int i = 0; i < result.length; ++i) {\r
+                       result[i] = resultArray.get(i);\r
+               }\r
+               return result;\r
+       }\r
+       \r
+    @Override\r
+       public ICompletionProposal[] computeCompletionProposals(\r
+                       ITextViewer viewer, int offset) {\r
+               String equation = viewer.getDocument().get();\r
+               Control control = viewer.getTextWidget();\r
+               this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), control);\r
+               \r
+               if (equation.length() == 0 || offset == 0) {\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
+               }\r
+               \r
+               equation = equation.substring(0, offset);\r
+               \r
+           // Split the equation on '+', '-', etc. characters\r
+        String stringsBetweenConnectedCharacters[] = equation.split(ALLOWED_CONNECTED_CHARACTERS_REG_EXP);\r
+               if (stringsBetweenConnectedCharacters.length == 0) {\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
+               }\r
+               String stringAfterLastConnectedCharacter = stringsBetweenConnectedCharacters[stringsBetweenConnectedCharacters.length - 1];\r
+               String stringAfterWhitespaceAfterLastConnectedCharacter = removeLeadingWhitespace(stringAfterLastConnectedCharacter);\r
+                               \r
+               // Split into tokens on whitespace characters, include also the trailing empty strings\r
+               String[] tokens = stringAfterWhitespaceAfterLastConnectedCharacter.split("[\\s]", -42);\r
+               \r
+               // Only whitespace after the last connection character\r
+               if (allTokensAreEmpty(tokens))\r
+                       return collectProposals(ALLOW_ALL_COMPLETIONS_LIST, offset);\r
+                       \r
+               return collectProposals(getPossibleLabelBeginnings(tokens), offset);\r
+       }\r
+\r
+       /**\r
+        * Collect all possible strings (with each whitespace replaced by a space character)\r
+        * which may be a beginning of a variable. \r
+        * Create the beginnings by adding whitespace between. E.g.:\r
+        *       {"multi", "part", "variab"}\r
+        *   -> { "multi part variab",\r
+        *        "part variab",\r
+        *        "variab" }\r
+        * @param tokens list of tokens\r
+     * @return all possible label beginnings\r
+        */\r
+    private ArrayList<String> getPossibleLabelBeginnings(String[] tokens) {\r
+               ArrayList<String> possibleLabelBeginnings = new ArrayList<String>();\r
+               for (int i = 0; i < tokens.length; ++i) {\r
+                       String token = new String();\r
+                       for (int j = i; j < tokens.length; ++j) {\r
+                               token += " " + tokens[j];\r
+                       }\r
+                       // Remove the excess space character from the beginning\r
+                       token = token.substring(1);\r
+                       \r
+                       possibleLabelBeginnings.add(token);\r
+               }\r
+               return possibleLabelBeginnings;\r
+       }\r
+\r
+       /**\r
+     * Remove leading whitespace\r
+     * @param input\r
+     * @return\r
+     */\r
+       private String removeLeadingWhitespace(String input) {\r
+               for (int i = 0; i < input.length(); ++i) {\r
+                       if (!Character.isWhitespace(input.charAt(i))) {\r
+                               return input.substring(i);\r
+                       }\r
+               }\r
+               return "";\r
+       }\r
+\r
+       private boolean allTokensAreEmpty(String[] tokens) {\r
+               for (String token : tokens)\r
+                       if (!token.equals(""))\r
+                               return false;\r
+               return true;\r
+       }\r
+\r
+       @Override\r
+       public IContextInformation[] computeContextInformation(\r
+                       ITextViewer viewer, int offset) {\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public char[] getCompletionProposalAutoActivationCharacters() {\r
+               return ALLOWED_CHARACTERS;\r
+       }\r
+\r
+       @Override\r
+       public char[] getContextInformationAutoActivationCharacters() {\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public String getErrorMessage() {\r
+               return "Error in CompletionProcessor";\r
+       }\r
+\r
+       @Override\r
+       public IContextInformationValidator getContextInformationValidator() {\r
+               return null;\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..28a502d
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Table;\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(ExpressionWidgetInput input) {\r
+        super(input);\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
+    \r
+    @Override\r
+    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
+        // Create the single field\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
+        //System.out.println("ConstantExpression");\r
+        expression = new ExpressionField(parent, SWT.BORDER, null, false, input);\r
+        expression.setExpression(equation);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\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..5e778c9
--- /dev/null
@@ -0,0 +1,392 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.jface.text.IUndoManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.widgets.Combo;\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.swt.widgets.Table;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * IExpression for displaying fields of DelayExpression\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class DelayExpression implements IExpression {\r
+\r
+    private ExpressionField equation, delayTime, initialValue;\r
+    private ExpressionField lastSelectedText;\r
+    private Spinner order;\r
+    private final ExpressionWidgetInput input;\r
+    private Resource expression;\r
+       private Combo delayTypeCombo;\r
+\r
+    /**\r
+     * Creates a new DelayExpression\r
+     * @param expression\r
+     */\r
+    public DelayExpression(ExpressionWidgetInput input) {\r
+        this.input = input;\r
+        this.expression = input.expression;\r
+    }\r
+\r
+    /**\r
+     * Displays the fields for delayExpression\r
+     */\r
+    @Override\r
+    public void createExpressionFields(Composite parent, final Map<String, Object> data, Table allowedVariables) {\r
+        // Get possible existing data\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(parent);\r
+        String eq = data.get("equation") != null ? (String)data.get("equation") : "";\r
+        String dt = data.get("delayTime") != null ? (String)data.get("delayTime") : "";\r
+        String iv = data.get("initialValue") != null ? (String)data.get("initialValue") : "";\r
+        int o = data.get("order") != null ? (Integer)data.get("order") : 3;\r
+\r
+        Label l = new Label(parent, SWT.NONE);\r
+        l.setText("Expression");\r
+\r
+        // Equation that is delayed\r
+        equation = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
+        equation.setExpression(eq);\r
+        GridDataFactory.fillDefaults().span(4, 1).grab(true, true).applyTo(equation);\r
+        equation.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                lastSelectedText = equation;\r
+            }\r
+        });\r
+\r
+        l = new Label(parent, SWT.NONE);\r
+        l.setText("Delay time");\r
+\r
+        // How much the equation is delayed\r
+        delayTime = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
+        delayTime.setExpression(dt);\r
+        GridDataFactory.fillDefaults().span(4, 1).grab(true, true).applyTo(delayTime);\r
+\r
+        delayTime.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                lastSelectedText = delayTime;\r
+            }\r
+        });\r
+\r
+        l = new Label(parent, SWT.NONE);\r
+        l.setText("Initial value");\r
+\r
+        // What is the initial value of the delay (empty == same as equation)\r
+        initialValue = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
+        initialValue.setExpression(iv);\r
+        GridDataFactory.fillDefaults().span(4, 1).grab(true, true).applyTo(initialValue);\r
+\r
+        initialValue.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                lastSelectedText = initialValue;\r
+            }\r
+        });\r
+\r
+\r
+        l = new Label(parent, SWT.NONE);\r
+        l.setText("Order");\r
+\r
+        // The order of the delay (default == 3)\r
+        order = new Spinner(parent, SWT.BORDER);\r
+        order.setMinimum(1);\r
+        order.setSelection(o);\r
+        order.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                save(expression, data);\r
+            }\r
+        });\r
+        GridDataFactory.fillDefaults().grab(false, false).applyTo(order);\r
+        \r
+        l = new Label(parent, SWT.NONE);\r
+        l.setText("Delay type");\r
+        GridDataFactory.fillDefaults().grab(true, false).align(SWT.END, SWT.CENTER).applyTo(l);\r
+        \r
+        // The type of the delay (material / information delay)\r
+        delayTypeCombo = new Combo(parent, SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY);\r
+        delayTypeCombo.add("Material");\r
+        delayTypeCombo.add("Information");\r
+        GridDataFactory.fillDefaults().applyTo(delayTypeCombo);\r
+        \r
+               // Initial selection to the combo\r
+        try {\r
+                       boolean isInformationDelay = SimanticsUI.getSession().syncRequest(new Read<Boolean>(){\r
+\r
+                               @Override\r
+                               public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       return graph.hasStatement(expression, sr.DelayExpression_isInformationDelay, expression);\r
+                               }\r
+                       });\r
+                       delayTypeCombo.select(isInformationDelay ? 1 : 0);\r
+           } catch (DatabaseException e1) {\r
+                       delayTypeCombo.select(0);\r
+               e1.printStackTrace();\r
+               }\r
+        \r
+        // Modify listener for selecting the delay type\r
+        delayTypeCombo.addModifyListener(new ModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               save(expression, data);\r
+                       }\r
+               });\r
+        \r
+        lastSelectedText = equation;\r
+    }\r
+\r
+    @Override\r
+    public void focus() {\r
+        lastSelectedText.setFocus();\r
+    }\r
+\r
+    @Override\r
+    public List<ExpressionField> getExpressionFields() {\r
+        return Arrays.asList(equation, delayTime, initialValue);\r
+    }\r
+\r
+    @Override\r
+    public void readData(final Resource expression, Map<String, Object> data) {\r
+        class Auxiliary {\r
+            String equation, delayTime, initialValue;\r
+            Integer order;\r
+            Boolean isInformationDelay;\r
+        }\r
+\r
+        Auxiliary results = null;\r
+\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
+                    if (expression != null && graph.isInstanceOf(expression, sr.DelayExpression)) {\r
+                        results.equation = graph.getPossibleRelatedValue(expression, sr.DelayExpression_expression);\r
+                        results.delayTime = graph.getPossibleRelatedValue(expression, sr.DelayExpression_delayTime);\r
+                        results.initialValue = graph.getPossibleRelatedValue(expression, sr.DelayExpression_initialValue);\r
+                        results.order = graph.getPossibleRelatedValue(expression, sr.DelayExpression_order);\r
+                        results.isInformationDelay = graph.hasStatement(expression, sr.DelayExpression_isInformationDelay, expression);\r
+                    } else {\r
+                        results.equation = "";\r
+                        results.delayTime = "";\r
+                        results.order = 1;\r
+                        results.isInformationDelay = false;\r
+                    }\r
+                    return results;\r
+                }\r
+            });\r
+        } catch (DatabaseException e1) {\r
+            e1.printStackTrace();\r
+        }\r
+        if(results.equation != null)\r
+            data.put("equation", results.equation);\r
+        if(results.delayTime != null)\r
+            data.put("delayTime", results.delayTime);\r
+        if(results.initialValue != null)\r
+            data.put("initialValue", results.initialValue);\r
+        if(results.order != null)\r
+            data.put("order", results.order);\r
+        if(results.isInformationDelay != null)\r
+            data.put("isInformationDelay", results.isInformationDelay);\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(Resource expr, Map<String, Object> data) {\r
+        this.expression = expr;\r
+        final String currentEquation = this.equation.getExpression();\r
+        final String currentDelayTime =  this.delayTime.getExpression();\r
+        final String currentInitialValue = this.initialValue.getExpression();\r
+        final Integer currentOrder = this.order.getSelection();\r
+        final Boolean currentIsInformationDelay = (this.delayTypeCombo.getSelectionIndex() == 1);\r
+\r
+        String oldEquation = (String)data.get("equation");\r
+        String oldDelayTime = (String)data.get("delayTime");\r
+        String oldInitialValue = (String)data.get("initialValue");\r
+        Integer oldOrder = (Integer)data.get("order");\r
+        Boolean oldIsInformationDelay = (Boolean)data.get("isInformationDelay");\r
+\r
+        if(oldEquation == null || oldDelayTime == null || oldOrder == null \r
+                       || oldInitialValue == null || oldIsInformationDelay == null \r
+                       || !oldEquation.equals(currentEquation) || !oldDelayTime.equals(currentDelayTime) \r
+                       || !oldOrder.equals(currentOrder) || !oldInitialValue.equals(currentInitialValue)\r
+                       || !oldIsInformationDelay.equals(currentIsInformationDelay)) {\r
+            // old value was null or value has changed -> Do save\r
+\r
+            data.putAll(data);\r
+            data.put("equation", currentEquation);\r
+            data.put("delayTime", currentDelayTime);\r
+            data.put("initialValue", currentInitialValue);\r
+            data.put("order", currentOrder);\r
+            data.put("isInformationDelay", currentIsInformationDelay);\r
+\r
+            SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                @Override\r
+                public void perform(WriteGraph g)\r
+                        throws DatabaseException {\r
+                    SysdynResource sr = SysdynResource.getInstance(g);\r
+                    Layer0 l0 = Layer0.getInstance(g);\r
+\r
+                    if(!g.isInstanceOf(expression, sr.DelayExpression)) {\r
+                        // Create a new DelayExpression, if the old expression was something else\r
+                        final Resource newExpression = GraphUtils.create2(g, sr.DelayExpression);\r
+                        String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING);\r
+                        if(arrayRange != null)\r
+                            g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange);\r
+\r
+                        final Resource variable = g.getPossibleObject(expression, l0.PartOf);\r
+                        Resource ownerList = g.getPossibleObject(variable, sr.Variable_expressionList);\r
+                        ListUtils.replace(g, ownerList, expression, newExpression);\r
+                        g.deny(expression, l0.PartOf);\r
+                        g.claim(newExpression, l0.PartOf, variable);\r
+\r
+                        VirtualGraph runtime = g.getService(VirtualGraph.class);\r
+                        g.syncRequest(new WriteRequest(runtime) {\r
+                            @Override\r
+                            public void perform(WriteGraph graph) throws DatabaseException {\r
+                                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
+                                    graph.deny(variable, sr.IndependentVariable_activeExpression);\r
+                                graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression);\r
+                            }\r
+                        });\r
+                        expression = newExpression;\r
+                    }\r
+                    \r
+                    // Claim values\r
+                    g.claimLiteral(expression, sr.DelayExpression_expression, currentEquation);\r
+                    g.claimLiteral(expression, sr.DelayExpression_delayTime, currentDelayTime);\r
+                    g.claimLiteral(expression, sr.DelayExpression_initialValue, currentInitialValue);\r
+                    g.claimLiteral(expression, sr.DelayExpression_order, currentOrder);\r
+                    if (currentIsInformationDelay)\r
+                       g.claim(expression, sr.DelayExpression_isInformationDelay, expression);\r
+                    else\r
+                       g.deny(expression, sr.DelayExpression_isInformationDelay, expression);\r
+                    \r
+                    g.markUndoPoint();\r
+                               CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
+                               g.addMetadata(cm.add("Set delay expression"));\r
+                    \r
+                }\r
+            });\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public void updateData(Map<String, Object> data) {\r
+        if(this.equation != null && this.equation.getExpression() != null)\r
+            data.put("equation", this.equation.getExpression());\r
+        if(this.delayTime != null && this.delayTime.getExpression() != null)\r
+            data.put("delayTime", this.delayTime.getExpression());   \r
+        if(this.initialValue != null && this.initialValue.getExpression() != null)\r
+            data.put("initialValue", this.initialValue.getExpression());   \r
+        if(this.order != null)\r
+            data.put("order", this.order.getSelection());   \r
+        if(this.delayTypeCombo != null)\r
+            data.put("isInformationDelay", (this.delayTypeCombo.getSelectionIndex() == 1));\r
+    }\r
+\r
+    @Override\r
+    public void addKeyListener(KeyListener listener) {\r
+        this.equation.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+        this.delayTime.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+        this.initialValue.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+    }\r
+\r
+    @Override\r
+    public void addModifyListener(ModifyListener listener) {\r
+        this.equation.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+        this.delayTime.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+        this.initialValue.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+    }\r
+\r
+    @Override\r
+    public void addFocusListener(FocusListener listener) {\r
+        this.equation.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+        this.delayTime.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+        this.initialValue.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+    }\r
+\r
+    @Override\r
+    public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+        this.equation.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+        this.delayTime.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+        this.initialValue.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+    }\r
+\r
+    @Override\r
+    public IUndoManager getUndoManager() {\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/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..8a38274
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.text.IUndoManager;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.eclipse.swt.widgets.Table;\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, Table allowedVariables) {\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
+       @Override\r
+       public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+               // TODO Auto-generated method stub\r
+               \r
+       }\r
+\r
+    @Override\r
+    public IUndoManager getUndoManager() {\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/properties/widgets/expressions/ExpressionComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionComposite.java
new file mode 100644 (file)
index 0000000..6459dab
--- /dev/null
@@ -0,0 +1,27 @@
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.sysdyn.ui.properties.widgets.ExpressionWidget;\r
+\r
+/**\r
+ * A composite class for access to save equation in expressionWidget.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExpressionComposite extends Composite {\r
+\r
+    private ExpressionWidget expressionWidget;\r
+    \r
+    public ExpressionComposite(Composite parent, int style) {\r
+        super(parent, style);\r
+\r
+    }\r
+\r
+    public void saveExpression() {\r
+        expressionWidget.save();\r
+    }\r
+\r
+    public void setExpressionWidget(ExpressionWidget expressionWidget) {\r
+        this.expressionWidget = expressionWidget;\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..5b5b3af
--- /dev/null
@@ -0,0 +1,300 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\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.custom.VerifyKeyListener;\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.VerifyEvent;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
+\r
+/**\r
+ * Field for displaying a part of an expression. Expression field uses SourceViewer\r
+ * to display annotations and other visual elements just like any other\r
+ * source viewer in eclipse.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ExpressionField extends Composite {\r
+\r
+    protected SourceViewer                  _sourceViewer;\r
+    protected IDocument                     _document;\r
+    protected AnnotationModel               _annotationModel;\r
+    \r
+    public static final String MISSING_LINK = "MissingLink";\r
+    public static final String NO_SUCH_VARIABLE = "NoSuchVariable";\r
+    public static final String SYNTAX_ERROR = "SyntaxError";\r
+    public static final String SYNTAX_WARNING = "SyntaxWarning";\r
+\r
+    String oldExpression;\r
+\r
+    IAnnotationAccess annotationAccess = new DefaultMarkerAnnotationAccess();\r
+\r
+    ExpressionFieldConfiguration expressionFieldConfiguration;\r
+    \r
+    private final LocalResourceManager resourceManager;\r
+    private final RGB warningRGB = new RGB(255,215,0);\r
+    private final RGB errorRGB = new RGB(255,0,0);\r
+\r
+    /**\r
+     * Create a new expression field\r
+     * @param parent\r
+     * @param style\r
+     */\r
+    public ExpressionField(Composite parent, int style, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
+        super(parent, style);\r
+        \r
+        // Create a ResourceManager to dispose images when the widget is disposed.\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(), this);\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
+        \r
+        // Configuration for color management\r
+        expressionFieldConfiguration = new ExpressionFieldConfiguration(\r
+                new LocalResourceManager(JFaceResources.getResources(), _sourceViewer.getControl()), \r
+                allowedVariables, allowFunctions, input);\r
+        _sourceViewer.configure(expressionFieldConfiguration);\r
+        AnnotationPainter painter = new AnnotationPainter(_sourceViewer, annotationAccess);\r
+        _sourceViewer.addPainter(painter);\r
+\r
+        // Annotation types\r
+        Color warningColor =  resourceManager.createColor(warningRGB);\r
+        Color errorColor = resourceManager.createColor(errorRGB);\r
+        painter.addAnnotationType(MISSING_LINK);\r
+        painter.setAnnotationTypeColor(MISSING_LINK, warningColor);\r
+        painter.addAnnotationType(NO_SUCH_VARIABLE);\r
+        painter.setAnnotationTypeColor(NO_SUCH_VARIABLE, errorColor);\r
+        painter.addAnnotationType(SYNTAX_ERROR);\r
+        painter.setAnnotationTypeColor(SYNTAX_ERROR, errorColor);        \r
+        painter.addAnnotationType(SYNTAX_WARNING);\r
+        painter.setAnnotationTypeColor(SYNTAX_WARNING, warningColor);\r
+        \r
+        _sourceViewer.setDocument(_document, _annotationModel);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(_sourceViewer.getControl());\r
+\r
+        // Parenthesis matching\r
+        PaintManager paintManager = new PaintManager(_sourceViewer);\r
+        MatchingCharacterPainter matchingCharacterPainter = new MatchingCharacterPainter(_sourceViewer,\r
+                new DefaultCharacterPairMatcher( new char[] {'(', ')', '{', '}', '[', ']'} ));\r
+        matchingCharacterPainter.setColor(resourceManager.createColor(new RGB(160, 160, 160)));\r
+        paintManager.addPainter(matchingCharacterPainter);\r
+        \r
+        \r
+        // Listener for canceling editing. ESC -> revert back to original text\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
+               // Check if the expression field has an active completion assistant\r
+                               if (!isAssistSessionActive()) {\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
+        /* Focus listener saving and restoring selections\r
+         * When focus is lost, current selection is saved, but the selection is removed.\r
+         * When focus is gained back, the selection is restored\r
+         */\r
+        _sourceViewer.getTextWidget().addFocusListener(new FocusListener() {\r
+            \r
+            Point selection = null;\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                selection = ((StyledText)e.widget).getSelection();\r
+                ((StyledText)e.widget).setSelection(0);\r
+            }\r
+            \r
+            @Override\r
+            public void focusGained(FocusEvent e) {\r
+                if(selection != null)\r
+                    ((StyledText)e.widget).setSelection(selection);\r
+            }\r
+        });\r
+        \r
+        _sourceViewer.appendVerifyKeyListener(new VerifyKeyListener() {\r
+                       @Override\r
+                       public void verifyKey(VerifyEvent event) {\r
+                               // Check for Ctrl+Spacebar\r
+                               if (event.stateMask == SWT.CTRL && event.character == ' ') {\r
+                                       // Check if source viewer is able to perform operation\r
+                                       if (_sourceViewer.canDoOperation(SourceViewer.CONTENTASSIST_PROPOSALS)) {\r
+                                               // Perform operation\r
+                                               _sourceViewer.doOperation(SourceViewer.CONTENTASSIST_PROPOSALS);\r
+                                       }\r
+                                       // Veto this key press to avoid further processing\r
+                                       event.doit = false;\r
+                               }\r
+                       }\r
+\r
+               });\r
+        \r
+    }\r
+\r
+    /**\r
+     * Returns the {@link SourceViewer} of this ExpressionField\r
+     * @return Returns the {@link SourceViewer} of this ExpressionField\r
+     */\r
+    public SourceViewer getSourceViewer() {\r
+        return this._sourceViewer;\r
+    }\r
+    \r
+       public boolean isAssistSessionActive() {\r
+               return expressionFieldConfiguration.isAssistSessionActive();\r
+       }\r
+\r
+    /**\r
+     * Sets missing link annotations to given positions\r
+     * @param positions Positions for missing link annotations\r
+     */\r
+    public void setMissingLinkAnnotations(List<Position> positions){\r
+        for(Position p : positions) {\r
+            Annotation annotation = new Annotation(false);\r
+            annotation.setType(MISSING_LINK);\r
+            annotation.setText("No link to this variable");\r
+            _annotationModel.addAnnotation(annotation, p);        \r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Sets no such variable annotations to given positions\r
+     * @param positions Positions for no such variable annotations\r
+     */\r
+    public void setNoSuchVariableAnnotations(List<Position> positions){\r
+        for(Position p : positions) {\r
+            Annotation annotation = new Annotation(false);\r
+            annotation.setType(NO_SUCH_VARIABLE);\r
+            annotation.setText("No such variable in model");\r
+            _annotationModel.addAnnotation(annotation, p);        \r
+        }\r
+    }\r
+\r
+    \r
+    /**\r
+     * Sets a syntax error annoattion to the expression field\r
+     * @param syntaxError\r
+     */\r
+    public void setSyntaxError(SyntaxError syntaxError) {\r
+        Annotation annotation = new Annotation(false);\r
+        annotation.setType(syntaxError.getType());\r
+        annotation.setText(syntaxError.getMessage());\r
+        Position p = new Position(syntaxError.getStart(_document), syntaxError.getOffset(_document));\r
+        _annotationModel.addAnnotation(annotation, p);      \r
+    }\r
+\r
+    /**\r
+     * Resets all annotations\r
+     */\r
+    public void resetAnnotations() {\r
+        _annotationModel.removeAllAnnotations();\r
+    }\r
+    \r
+    /**\r
+     * Sets an expression to this expression field\r
+     * @param expression\r
+     */\r
+    public void setExpression(String expression) {\r
+        _document.set(expression);\r
+        this.oldExpression = expression;\r
+    }\r
+\r
+    /**\r
+     * Returns the expression of this expression field\r
+     * @return\r
+     */\r
+    public String getExpression() {\r
+        return this._document.get();\r
+    }\r
+\r
+    /**\r
+     * Returns the current selection\r
+     * @return current selection\r
+     */\r
+    public Point getSelection() {\r
+        return _sourceViewer.getSelectedRange();\r
+    }\r
+\r
+    /**\r
+     * Set selection for this expression field. The length of the selection is 0\r
+     * @param selection Selection location\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
+    /**\r
+     * Focus to this expression field\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..205d41d
--- /dev/null
@@ -0,0 +1,204 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import org.eclipse.jface.internal.text.html.HTMLTextPresenter;\r
+import org.eclipse.jface.resource.ResourceManager;\r
+import org.eclipse.jface.text.DefaultInformationControl;\r
+import org.eclipse.jface.text.DefaultTextHover;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.eclipse.jface.text.IInformationControl;\r
+import org.eclipse.jface.text.IInformationControlCreator;\r
+import org.eclipse.jface.text.ITextHover;\r
+import org.eclipse.jface.text.TextAttribute;\r
+import org.eclipse.jface.text.contentassist.ContentAssistEvent;\r
+import org.eclipse.jface.text.contentassist.ContentAssistant;\r
+import org.eclipse.jface.text.contentassist.ICompletionListener;\r
+import org.eclipse.jface.text.contentassist.ICompletionProposal;\r
+import org.eclipse.jface.text.contentassist.IContentAssistant;\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.MultiLineRule;\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
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.simantics.sysdyn.ui.modelica.ModelicaSourceViewerConfiguration;\r
+\r
+@SuppressWarnings("restriction")\r
+public class ExpressionFieldConfiguration extends SourceViewerConfiguration {\r
+\r
+       private final long WAIT_BEFORE_STATUS_CHANGE = 100;\r
+       \r
+       Table allowedVariables;\r
+       boolean allowFunctions;\r
+       boolean assistSessionActive; \r
+       CompletionProcessor completionProcessor;\r
+       ResourceManager resourceManager;\r
+\r
+       private final ExpressionWidgetInput input;\r
+       \r
+       public ExpressionFieldConfiguration(ResourceManager resourceManager, Table allowedVariables, boolean allowFunctions, ExpressionWidgetInput input) {\r
+               super();\r
+               this.resourceManager = resourceManager;\r
+               this.allowedVariables = allowedVariables;\r
+               this.allowFunctions = allowFunctions;\r
+               this.assistSessionActive = false;\r
+               this.completionProcessor = null;\r
+               this.input = input;\r
+       }\r
+       \r
+       public boolean isAssistSessionActive() {\r
+               return assistSessionActive;\r
+       }\r
+       \r
+       @Override\r
+    public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {\r
+               return new String[] {\r
+                               IDocument.DEFAULT_CONTENT_TYPE\r
+               };\r
+       }\r
+\r
+       @Override\r
+    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {\r
+               PresentationReconciler reconciler = new PresentationReconciler();\r
+\r
+               DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getTokenScanner());\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
+       ITokenScanner getTokenScanner() {\r
+               RuleBasedScanner scanner = new RuleBasedScanner();\r
+\r
+               final Token reserved = new Token(\r
+                               new TextAttribute(\r
+                                       resourceManager.createColor(new RGB(127, 0, 85)),\r
+                                               null,\r
+                                               SWT.BOLD\r
+                               ));\r
+           final Token defaultToken = new Token(new TextAttribute(resourceManager.createColor(new RGB(0, 0, 0))));\r
+\r
+                final Token comment = new Token(new TextAttribute(resourceManager.createColor(new RGB(63, 127, 95))));\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
+               }, defaultToken);\r
+               \r
+\r
+               for(String s : ModelicaSourceViewerConfiguration.keywords) {\r
+                       reservedWord.addWord(s, reserved);\r
+               }\r
+\r
+               IRule[] rules = new IRule[] {\r
+                               reservedWord,\r
+                               new MultiLineRule("/*", "*/", comment),\r
+                               new MultiLineRule("\"", "\"", comment)\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
+       @Override\r
+       public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {\r
+               ContentAssistant assistant = new ContentAssistant();\r
+               completionProcessor = new CompletionProcessor(allowedVariables, allowFunctions, input);\r
+               assistant.setContentAssistProcessor(completionProcessor, IDocument.DEFAULT_CONTENT_TYPE);\r
+               assistant.enableAutoActivation(true);\r
+               assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));\r
+               assistant.enableAutoInsert(true);\r
+               assistant.setAutoActivationDelay(0);\r
+               assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);\r
+               assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);\r
+               assistant.addCompletionListener(new CompletionListener());\r
+               return assistant;\r
+       }\r
+       \r
+    @Override\r
+    public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {\r
+        return new IInformationControlCreator() {\r
+            @Override\r
+            public IInformationControl createInformationControl(Shell parent) {\r
+                return new DefaultInformationControl(parent,new HTMLTextPresenter(false));\r
+            }\r
+        };\r
+    }\r
+       \r
+       private class CompletionListener implements ICompletionListener {\r
+\r
+               @Override\r
+               public void assistSessionStarted(ContentAssistEvent event) {\r
+                       if (event.processor.equals(completionProcessor)) {\r
+                               assistSessionActive = true;\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public void assistSessionEnded(ContentAssistEvent event) {\r
+                       if (event.processor.equals(completionProcessor)) {\r
+                               Thread waitBeforeStateChange = new Thread() {\r
+                                       @Override\r
+                    public void run() {\r
+                                               try {\r
+                                                       sleep(WAIT_BEFORE_STATUS_CHANGE);\r
+                                                       assistSessionActive = false;\r
+                                               } catch (InterruptedException e) {\r
+                                                       assistSessionActive = false;\r
+                                               }\r
+                                       }\r
+                               };\r
+                               waitBeforeStateChange.start();\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public void selectionChanged(ICompletionProposal proposal,\r
+                               boolean smartToggle) {\r
+               }\r
+               \r
+       }\r
+       \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionWidgetInput.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ExpressionWidgetInput.java
new file mode 100644 (file)
index 0000000..9f6481c
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.layer0.variable.Variable;\r
+\r
+/**\r
+ * Inputs for expression widgets contain both Variable and the expression resource\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ExpressionWidgetInput {\r
+       public Variable variable;\r
+       public Resource expression;\r
+       \r
+       public ExpressionWidgetInput(Variable variable, Resource expression) {\r
+               this.variable = variable;\r
+               this.expression = expression;\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..bd0b0b7
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.text.IUndoManager;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.eclipse.swt.widgets.Table;\r
+import org.simantics.db.Resource;\r
+\r
+public interface IExpression {\r
+\r
+    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVaribles);\r
+\r
+    public void readData(final Resource expression, Map<String, Object> data);\r
+\r
+    public void save(final Resource expression, 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 addVerifyKeyListener(VerifyKeyListener listener);\r
+\r
+    public void addFocusListener(FocusListener listener);\r
+    \r
+    public IUndoManager getUndoManager();\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..44db3f0
--- /dev/null
@@ -0,0 +1,176 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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..db7311b
--- /dev/null
@@ -0,0 +1,100 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jface.text.IUndoManager;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.eclipse.swt.widgets.Table;\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, Table allowedVariables) {\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
+       @Override\r
+       public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+               // TODO Auto-generated method stub\r
+               \r
+       }\r
+\r
+    @Override\r
+    public IUndoManager getUndoManager() {\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/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..e6eb477
--- /dev/null
@@ -0,0 +1,279 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+import java.awt.geom.Point2D;\r
+import java.util.ArrayList;\r
+import java.util.Comparator;\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
+        @SuppressWarnings("rawtypes")\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("rawtypes")\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
+    public class InputOutputComparator extends ViewerComparator implements Comparator<InputOutput>{\r
+        @Override\r
+        public int compare(Viewer viewer, Object e1, Object e2) {\r
+            if ((e1 instanceof InputOutput) &&\r
+                    (e2 instanceof InputOutput)) {\r
+               return compare((InputOutput)e1, (InputOutput)e2);\r
+            } else {\r
+               return 0;\r
+            }\r
+        }\r
+\r
+               @Override\r
+               public int compare(InputOutput e1, InputOutput e2) {\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
+    }\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..772f083
--- /dev/null
@@ -0,0 +1,182 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.expressions;\r
+\r
+\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.WriteResultRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynGameExperimentBase;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ParameterExpression extends BasicExpression {\r
+\r
+       Variable variable;\r
+\r
+       public ParameterExpression(ExpressionWidgetInput input) {\r
+           super(input);\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
+           this.variable = input.variable;\r
+       }\r
+\r
+\r
+       @Override\r
+       public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\r
+               // Create the single field\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, null, false, input);\r
+               expression.setExpression(equation);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(expression);\r
+\r
+       }\r
+\r
+       @Override\r
+       public void readData(final Resource expression, Map<String, Object> data) {\r
+               IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+               IExperiment experiment = manager.getActiveExperiment();\r
+               if(experiment == null || !(experiment instanceof SysdynGameExperimentBase)) {\r
+                       super.readData(expression, data);\r
+               } else {\r
+                       Double value;\r
+                       ExperimentState state = ((SysdynGameExperimentBase)experiment).getSysdynExperimentState();\r
+                       if(ExperimentState.RUNNING.equals(state) || ExperimentState.STOPPED.equals(state)) {\r
+                           try {\r
+                               value = SimanticsUI.getSession().syncRequest(new Read<Double>() {\r
+\r
+                                   @Override\r
+                                   public Double perform(ReadGraph graph) throws DatabaseException {\r
+                                       try {\r
+                                           Variable valuesVariable = variable.browsePossible(graph, "#value#");\r
+                                           double[] res = valuesVariable.getValue(graph);\r
+                                           if(res != null && res.length == 1)\r
+                                               return res[0];\r
+                                           else\r
+                                               return null;\r
+                                       } catch (DatabaseException e) {\r
+                                           throw new DatabaseException(e.getMessage());\r
+                                       } \r
+                                   }\r
+                               });\r
+                               if(value != null)\r
+                                   data.put("equation", value.toString());\r
+                           } catch (DatabaseException e) {}\r
+                       }\r
+                       super.readData(expression, data);\r
+\r
+               }\r
+       }\r
+\r
+       @Override\r
+       public void save(final Resource expression, Map<String, Object> data) {\r
+\r
+               IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+               IExperiment experiment = manager.getActiveExperiment();\r
+               if(experiment != null && experiment instanceof SysdynGameExperimentBase) {\r
+                       final String currentText = this.expression.getExpression();\r
+                       final String oldEquation = (String)data.get("equation");\r
+                       if(oldEquation == null || \r
+                               (currentText != null && oldEquation != null && !currentText.equals(oldEquation) && expressionType != null)) {\r
+                           if(ExpressionUtils.isParameter(currentText)) {\r
+                               Boolean savedIntoFMU = false;\r
+\r
+                               ExperimentState state = ((SysdynGameExperimentBase)experiment).getSysdynExperimentState();\r
+                               // Set value to control only if the simulation is running or stopped, not before initialization\r
+                               if(ExperimentState.RUNNING.equals(state) || ExperimentState.STOPPED.equals(state)) {\r
+                                   try {\r
+                                       savedIntoFMU = SimanticsUI.getSession().syncRequest(new WriteResultRequest<Boolean>() {\r
+\r
+                                           @Override\r
+                                           public Boolean perform(WriteGraph graph)\r
+                                                   throws DatabaseException {\r
+                                               try {\r
+                                                   Variable valuesVariable = variable.browsePossible(graph, "#value#");\r
+                                                   if(valuesVariable == null)\r
+                                                       return false;\r
+                                                   valuesVariable.setValue(graph, new double[] {Double.parseDouble(currentText)});\r
+                                                   \r
+                                                   graph.markUndoPoint();\r
+                                                               CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+                                                               graph.addMetadata(cm.add("Set parameter"));\r
+                                                   \r
+                                                   return true;\r
+                                               } catch (Exception e) {\r
+                                                   return false;\r
+                                               }\r
+                                           }\r
+\r
+                                       });\r
+                                   } catch (DatabaseException e) {}\r
+                               }\r
+\r
+                               if(savedIntoFMU) {\r
+                                               data.put("equation", currentText);\r
+                                               return;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // If setting a parameter value was not succesful, use the normal save-method\r
+               super.save(expression, data);\r
+       }\r
+\r
+       public ParameterExpression() {\r
+           super(null);\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..14f87e9
--- /dev/null
@@ -0,0 +1,393 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.jface.text.IUndoManager;\r
+import org.eclipse.jface.text.TextViewerUndoManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.ModifyListener;\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.Event;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.Stock;\r
+import org.simantics.sysdyn.representation.Valve;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class StockExpression implements IExpression {\r
+\r
+    private final ExpressionWidgetInput input;\r
+    private ExpressionField integralExpression, initialExpression;\r
+    private ExpressionField lastSelectedText;\r
+    private TextViewerUndoManager undoManager;\r
+    \r
+    public StockExpression(ExpressionWidgetInput input) {\r
+        this.input = input;\r
+    }\r
+    \r
+    @Override\r
+    public void createExpressionFields(Composite parent, Map<String, Object> data, Table allowedVariables) {\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") : getDefaultIntegral(input.expression);\r
+\r
+\r
+        Label label = new Label(parent, SWT.NONE);\r
+        label.setText("Integral");\r
+\r
+        Composite integralComposite = new Composite(parent, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(integralComposite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(integralComposite);\r
+        \r
+        integralExpression = new ExpressionField(integralComposite, SWT.BORDER, allowedVariables, true, input);\r
+        integralExpression.setExpression(integralEquation);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(integralExpression);\r
+        integralExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                lastSelectedText = integralExpression;\r
+            }\r
+        });\r
+        \r
+        undoManager = new TextViewerUndoManager(100);\r
+        integralExpression.getSourceViewer().setUndoManager(undoManager);\r
+        undoManager.connect(integralExpression.getSourceViewer());\r
+        \r
+        Button defaultButton = new Button(integralComposite, SWT.PUSH);\r
+        defaultButton.setText("Use default");\r
+        defaultButton.addListener(SWT.Selection, new Listener() {\r
+\r
+               @Override\r
+               public void handleEvent(Event event) {\r
+                       switch (event.type) {\r
+                       case SWT.Selection:\r
+                               StockExpression.this.integralExpression.setExpression(getDefaultIntegral(input.expression));\r
+                               Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph)\r
+                                                       throws DatabaseException {\r
+                                               // Delete the possible integral expression from the database to note \r
+                                               // that we are in the "default" mode.\r
+                                               graph.markUndoPoint();\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               graph.deny(input.expression, sr.StockExpression_useCustomIntegral);\r
+                                               graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
+                                               \r
+                                       CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+                                       graph.addMetadata(cm.add("Use default"));\r
+                                               \r
+                                       }\r
+                               });\r
+                               break;\r
+                       }\r
+               }\r
+\r
+        });\r
+\r
+        label = new Label(parent, SWT.NONE);\r
+        label.setText("Initial\nValue");\r
+\r
+        initialExpression = new ExpressionField(parent, SWT.BORDER, allowedVariables, true, input);\r
+        initialExpression.setExpression(initialEquation);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(initialExpression);\r
+        initialExpression.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+\r
+            @Override\r
+            public void focusLost(FocusEvent e) {\r
+                lastSelectedText = initialExpression;\r
+            }\r
+        });\r
+\r
+        lastSelectedText = initialExpression;\r
+    }\r
+\r
+    @Override\r
+    public void focus() {\r
+        this.lastSelectedText.focus();\r
+    }\r
+\r
+    @Override\r
+    public List<ExpressionField> getExpressionFields() {\r
+        return Arrays.asList(this.integralExpression, this.initialExpression);\r
+    }\r
+\r
+    @Override\r
+    public void readData(final Resource expression, final Map<String, Object> data) {\r
+        Pair<String, String> equations = null;\r
+        if (expression != null && data.get("initialEquation") == null) {\r
+               try {\r
+                   equations = Simantics.getSession().syncRequest(new Read<Pair<String, String>>() {\r
+       \r
+                       @Override\r
+                       public Pair<String, String> perform(ReadGraph graph) throws DatabaseException {\r
+                           SysdynResource sr = SysdynResource.getInstance(graph);\r
+                           if (graph.isInstanceOf(expression, sr.StockExpression)) {\r
+                               String initialEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_initialEquation);\r
+                               String integralEquation = graph.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation);\r
+                               initialEquation = (initialEquation != null) ? initialEquation : "";\r
+                               return new Pair<String, String>(integralEquation, initialEquation);\r
+                           } else {\r
+                               return new Pair<String, String>(null, "");\r
+                           }\r
+                       }\r
+       \r
+                   });\r
+               } catch (DatabaseException e1) {\r
+                   e1.printStackTrace();\r
+               }\r
+               data.put("initialEquation", equations.second);\r
+        }\r
+\r
+        if (equations.first == null) {\r
+               try {\r
+                               Simantics.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       graph.claimLiteral(input.expression, sr.StockExpression_integralEquation, getDefaultIntegral(graph, input.expression));\r
+                                       graph.markUndoPoint();\r
+                               CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
+                               graph.addMetadata(cm.add("Set expression"));\r
+                                       }\r
+\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               // TODO Auto-generated catch block\r
+                               e.printStackTrace();\r
+                       }\r
+               \r
+               data.put("integral", getDefaultIntegral(expression));\r
+        } else {\r
+               try {\r
+                       final String integral = equations.first;\r
+                               Simantics.getSession().syncRequest(new ReadRequest() {\r
+\r
+                                       @Override\r
+                                       public void run(ReadGraph graph) throws DatabaseException {\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       if (graph.hasStatement(input.expression, sr.StockExpression_useCustomIntegral)) {\r
+                                               data.put("integral", integral);\r
+                                       } else {\r
+                                               data.put("integral", getDefaultIntegral(graph, expression));\r
+                                       }\r
+                                       }\r
+\r
+                               });\r
+                       } catch (DatabaseException e) {\r
+                               data.put("integral", equations.first);\r
+                               e.printStackTrace();\r
+                       }\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 expression, final Map<String, Object> data) {\r
+       final String currentInitial = this.initialExpression.getExpression();\r
+       final String currentIntegral = this.integralExpression.getExpression();\r
+       if (currentIntegral == null) {\r
+               this.integralExpression.setExpression(getDefaultIntegral(expression));\r
+        }\r
+        if(!currentInitial.equals(data.get("initialEquation"))\r
+                       || currentIntegral == null\r
+                       || !currentIntegral.equals(data.get("integral"))) {\r
+            Simantics.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph g)\r
+                throws DatabaseException {\r
+                    SysdynResource sr = SysdynResource.getInstance(g);\r
+                    Layer0 l0 = Layer0.getInstance(g);\r
+                    \r
+                    if(!g.isInstanceOf(expression, sr.StockExpression)) {\r
+                        Resource variable = g.getPossibleObject(expression, l0.PartOf);\r
+                        Resource expressionList = g.getPossibleObject(variable, sr.Variable_expressionList);\r
+                       Resource temp = g.newResource();\r
+                       ListUtils.replace(g, expressionList, expression, temp);\r
+                       \r
+                       for(Resource predicate : g.getPredicates(expression)) {\r
+                           g.deny(expression, predicate);\r
+                       }\r
+                       g.claim(expression, l0.InstanceOf, null, sr.StockExpression);\r
+\r
+                        ListUtils.replace(g, expressionList, temp, expression);\r
+\r
+                       RemoverUtil.remove(g, temp);\r
+\r
+                       g.claim(expression, l0.PartOf, variable);\r
+                    }\r
+                    g.claimLiteral(expression, sr.StockExpression_initialEquation, currentInitial);\r
+                    \r
+                    if (!currentIntegral.equals(g.getPossibleRelatedValue(expression, sr.StockExpression_integralEquation, Bindings.STRING))) {\r
+                       // If the value is not same as default, enable the custom tag\r
+                       g.claim(expression, sr.StockExpression_useCustomIntegral, expression);\r
+                    }\r
+                    g.claimLiteral(expression, sr.StockExpression_integralEquation, currentIntegral);\r
+                    \r
+                    updateData(data);\r
+                    \r
+                    g.markUndoPoint();\r
+                    \r
+                    Layer0Utils.addCommentMetadata(g, "Saved Stock Expression " + currentIntegral + " " + expression.toString() + " with Initial Value " + currentInitial);\r
+                }\r
+\r
+            });\r
+        }\r
+        this.initialExpression.setExpression(currentInitial);\r
+        this.integralExpression.setExpression(currentIntegral);\r
+    }\r
+\r
+    @Override\r
+    public void updateData(Map<String, Object> data) {\r
+       if(this.initialExpression != null && this.initialExpression.getExpression() != null)\r
+            data.put("initialEquation", this.initialExpression.getExpression());\r
+       if(this.integralExpression != null && this.integralExpression.getExpression() != null)\r
+            data.put("integral", this.integralExpression.getExpression());\r
+    }\r
+\r
+    \r
+    private static String getDefaultIntegral(ReadGraph graph, Resource expression) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+    \r
+           // find the variable\r
+           Resource variable = graph.getPossibleObject(expression, l0.PartOf);\r
+           if(variable == null)\r
+               return "";\r
+           \r
+               SysdynModelManager sdm = SysdynModelManager.getInstance(graph.getSession());\r
+               SysdynModel model = sdm.getModel(graph, graph.getSingleObject(variable, l0.PartOf));\r
+               model.update(graph);\r
+               \r
+               Stock stock = (Stock)model.getElement(variable);\r
+           \r
+               String range = graph.getPossibleRelatedValue(expression, sr.Expression_arrayRange);\r
+               if(range == null)\r
+                       range = "";\r
+       \r
+           StringBuilder builder = new StringBuilder();\r
+           builder.append("");\r
+           for(Valve in : stock.getIncomingValves()) {\r
+               builder.append(" + " + in.getName() + range);\r
+           }\r
+           for(Valve out : stock.getOutgoingValves()) {\r
+               builder.append(" - " + out.getName() + range);\r
+           }\r
+           if (builder.indexOf(" + ") == 0)\r
+               builder.delete(0, 3);\r
+           \r
+           return builder.toString().trim();   \r
+    }\r
+    \r
+    \r
+    private static String getDefaultIntegral(final Resource expression) {\r
+       \r
+        String integral = "";\r
+        if(expression == null)\r
+               return integral;\r
+        try {\r
+            integral = Simantics.getSession().syncRequest(new Read<String>() {\r
+\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+                       return getDefaultIntegral(graph, expression);\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.initialExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+        this.integralExpression.getSourceViewer().getTextWidget().addKeyListener(listener);\r
+\r
+    }\r
+\r
+    @Override\r
+    public void addModifyListener(ModifyListener listener) {\r
+        this.initialExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+        this.integralExpression.getSourceViewer().getTextWidget().addModifyListener(listener);\r
+\r
+    }\r
+\r
+    @Override\r
+    public void addFocusListener(FocusListener listener) {\r
+        this.initialExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+        this.integralExpression.getSourceViewer().getTextWidget().addFocusListener(listener);\r
+    }\r
+    \r
+       @Override\r
+       public void addVerifyKeyListener(VerifyKeyListener listener) {\r
+               this.initialExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+               this.integralExpression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+       }\r
+\r
+    @Override\r
+    public IUndoManager getUndoManager() {\r
+        return undoManager;\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..5051f5c
--- /dev/null
@@ -0,0 +1,469 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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.jface.text.IUndoManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.awt.SWT_AWT;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\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.eclipse.swt.widgets.Table;\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.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.CommentMetadata;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\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.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\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.utils.SyntaxError;\r
+import org.simantics.sysdyn.utils.SheetUtils;\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 final ExpressionWidgetInput input;\r
+    private Resource expr;\r
+\r
+    public WithLookupExpression(ExpressionWidgetInput input) {\r
+        this.input = input;\r
+        this.expr = input.expression;\r
+    }\r
+\r
+    @Override\r
+    public void createExpressionFields(Composite parent, final Map<String, Object> data, Table allowedVariables) {\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, allowedVariables, true ,input);\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, null, false, input);\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
+                save(expr, data);\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
+                String result = "";\r
+                if (expr != null && graph.isInstanceOf(expr, sr.WithLookupExpression)) {\r
+                    result = graph.getPossibleRelatedValue(expr, sr.WithLookupExpression_lookup);\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
+                            updateChart();\r
+                        }\r
+                    });\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 expression, Map<String, Object> data) {\r
+\r
+        class Auxiliary {\r
+            String equation, lookup;\r
+        }\r
+\r
+        Auxiliary results = null;\r
+\r
+        if (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
+                        if (expression != null && graph.isInstanceOf(expression, sr.WithLookupExpression)) {\r
+                            results.equation = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_expression);\r
+                            results.lookup = graph.getPossibleRelatedValue(expression, sr.WithLookupExpression_lookup);\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 == null ? "" : results.equation);\r
+            data.put("lookup", results.lookup == null ? "" : 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 expression, Map<String, Object> data) {\r
+        final String currentExpression = this.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
+                    Layer0 l0 = Layer0.getInstance(g);\r
+\r
+                    if(!g.isInstanceOf(expr, sr.WithLookupExpression)) {\r
+\r
+\r
+                        final Resource newExpression = GraphUtils.create2(g, sr.WithLookupExpression,\r
+                                sr.WithLookupExpression_minX, 0.0,\r
+                                sr.WithLookupExpression_maxX, 10.0,\r
+                                sr.WithLookupExpression_minY, 0.0,\r
+                                sr.WithLookupExpression_maxY, 10.0);\r
+                        String arrayRange = g.getPossibleRelatedValue(expression, sr.Expression_arrayRange, Bindings.STRING);\r
+                        if(arrayRange != null)\r
+                            g.claimLiteral(newExpression, sr.Expression_arrayRange, arrayRange);\r
+\r
+                        final Resource variable = g.getSingleObject(expression, l0.PartOf);\r
+                        Resource expressions = g.getPossibleObject(variable, sr.Variable_expressionList);\r
+                        Resource node = ListUtils.getNode(g, expressions, expression);\r
+                        g.deny(node, l0.List_Element);\r
+                        g.claim(node, l0.List_Element, newExpression);\r
+\r
+                        g.deny(expression, l0.PartOf);\r
+                        g.claim(newExpression, l0.PartOf, variable);\r
+\r
+                        VirtualGraph runtime = g.getService(VirtualGraph.class);\r
+                        g.syncRequest(new WriteRequest(runtime) {\r
+                            @Override\r
+                            public void perform(WriteGraph graph) throws DatabaseException {\r
+                                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                if(graph.hasStatement(variable, sr.IndependentVariable_activeExpression))\r
+                                    graph.deny(variable, sr.IndependentVariable_activeExpression);\r
+                                graph.claim(variable, sr.IndependentVariable_activeExpression, newExpression);\r
+                            }\r
+                        }\r
+                                );\r
+                        expr = newExpression;\r
+\r
+                    }\r
+                    g.claimLiteral(expr, sr.WithLookupExpression_expression, currentExpression);\r
+                    g.claimLiteral(expr, sr.WithLookupExpression_lookup, currentLookupTable);\r
+                    \r
+                    g.markUndoPoint();\r
+                               CommentMetadata cm = g.getMetadata(CommentMetadata.class);\r
+                               g.addMetadata(cm.add("Set lookup expression"));\r
+                    \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 addVerifyKeyListener(VerifyKeyListener listener) {\r
+        this.expression.getSourceViewer().getTextWidget().addVerifyKeyListener(listener);\r
+        this.lookup.getSourceViewer().getTextWidget().addVerifyKeyListener(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
+            if(lookup.getExpression().matches("[a-zA-Z0-9]*\\([a-zA-Z0-9:]*\\)")) {\r
+                // Might be a sheet reference\r
+                try {\r
+                    final String name = lookup.getExpression().substring(0, lookup.getExpression().indexOf("("));\r
+                    final String range = lookup.getExpression().substring(lookup.getExpression().indexOf("(") + 1, lookup.getExpression().indexOf(")"));\r
+                    String possibleTable = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                        @Override\r
+                        public String perform(ReadGraph graph) throws DatabaseException {\r
+                            Variable variable = input.variable;\r
+                            Resource model = Variables.getModel(graph, variable);\r
+                            return SheetUtils.getStringRepresentation(graph, model, name, range);\r
+                        }\r
+\r
+                    });\r
+                    \r
+\r
+                    try {\r
+                        if(possibleTable == null) {\r
+                            ParseException e = new ParseException(e1.getMessage());\r
+                            e.currentToken = e1.currentToken;\r
+                            throw e;\r
+                        }\r
+                            \r
+                        parser.ReInit(new StringReader(possibleTable));\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 e2) {\r
+                        this.lookup.setSyntaxError(new SyntaxError(e2.currentToken, "Syntax Error"));\r
+                        System.out.println("MESSAGE: " + e2.getMessage());\r
+                        return;\r
+                    }\r
+                } catch (DatabaseException e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\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
+    @Override\r
+    public IUndoManager getUndoManager() {\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/properties/widgets/externalFiles/ExternalFileImager.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileImager.java
new file mode 100644 (file)
index 0000000..9af9a0d
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.externalFiles;\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
+\r
+public class ExternalFileImager extends ImagerContributor<ExternalFileNode> {\r
+\r
+       @Override\r
+       public ImageDescriptor getDescriptor(ReadGraph graph, ExternalFileNode input)\r
+                       throws DatabaseException {\r
+               return null;\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileLabeler.java
new file mode 100644 (file)
index 0000000..ee94d5a
--- /dev/null
@@ -0,0 +1,27 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.externalFiles;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class ExternalFileLabeler extends LabelerContributorImpl<ExternalFileNode>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, ExternalFileNode input)\r
+                       throws DatabaseException {\r
+               return NameUtils.getSafeName(graph, input.data);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFileNode.java
new file mode 100644 (file)
index 0000000..1150817
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.externalFiles;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.request.Write;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ExternalFileNode extends AbstractNode<Resource> implements IModifiableNode, IDeletableNode {\r
+\r
+       public ExternalFileNode(Resource data) {\r
+               super(data);\r
+       }\r
+\r
+       @Override\r
+       public Modifier getModifier(String columnId) {\r
+               try {\r
+                       final Resource hasName = Layer0.getInstance(SimanticsUI.getSession()).HasName;\r
+                       LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), data, hasName) {\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
+                               @Override\r
+                               protected Write getWriteRequest(final String label) {\r
+                                       return new WriteRequest() {\r
+                                               @Override\r
+                                               public void perform(WriteGraph g) throws DatabaseException {\r
+                                                       g.claimLiteral(data, hasName, label);\r
+                                               }\r
+                                       };\r
+                               }\r
+                       };\r
+                       return modifier;\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               RemoverUtil.remove(graph, data);\r
+                       }\r
+               });\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/externalFiles/ExternalFiles.java
new file mode 100644 (file)
index 0000000..59ad535
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.externalFiles;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ExternalFiles extends ViewpointContributorImpl<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+               \r
+               if(input == null) \r
+                       return null;\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               \r
+               ArrayList<ExternalFileNode> result = new ArrayList<ExternalFileNode>();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.ExternalFunctionFile))) {\r
+                       result.add(new ExternalFileNode(r));\r
+               }\r
+               \r
+               return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "External Files";\r
+       }\r
+       \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ComboStringPropertyModifier.java
new file mode 100644 (file)
index 0000000..27b4907
--- /dev/null
@@ -0,0 +1,69 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.swt.widgets.Combo;\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.Widget;\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.utils.ReflectionUtils;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+abstract public class ComboStringPropertyModifier<T> implements TextModifyListener, Widget {\r
+\r
+       private ISessionContext context;\r
+       private Object lastInput = null;\r
+       \r
+    final private Class<?> clazz;\r
+       \r
+       public ComboStringPropertyModifier() {\r
+        clazz = ReflectionUtils.getSingleParameterType(getClass());\r
+       }\r
+       \r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               this.context = context;\r
+               lastInput = input;\r
+       }\r
+\r
+       @Override\r
+       public void modifyText(TrackedModifyEvent e) {\r
+               Combo text = (Combo)e.getWidget();\r
+               final String textValue = text.getText();\r
+               final Object input = lastInput;\r
+               \r
+               try {\r
+                       context.getSession().syncRequest(new WriteRequest() {\r
+\r
+                               @SuppressWarnings("unchecked")\r
+                @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                   graph.markUndoPoint();\r
+                                       T single = (T) ISelectionUtils.filterSingleSelection((ISelection)input, clazz);\r
+                                       applyText(graph, single, textValue);\r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               \r
+       }\r
+       \r
+       abstract public void applyText(WriteGraph graph, T input, String text) throws DatabaseException;\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..1cc23fe
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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..58dc654
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.databoard.Bindings;\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
+       if (text == null || text.equals("")) {\r
+               if(graph.hasStatement(input, graph.getResource(propertyURI)))\r
+                       graph.deny(input, graph.getResource(propertyURI));\r
+       } else {\r
+               graph.claimLiteral(input, graph.getResource(propertyURI), Double.parseDouble(text), Bindings.DOUBLE);\r
+       }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionLibraryNameInputValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionLibraryNameInputValidator.java
new file mode 100644 (file)
index 0000000..18c1a41
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\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.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.utils.FunctionLibraryNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Name validator container for user defined function libraries.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class FunctionLibraryNameInputValidator implements IInputValidator, Widget {\r
+\r
+    private Resource lastInput = null;\r
+    \r
+    public FunctionLibraryNameInputValidator(WidgetSupport support) {\r
+        support.register(this);\r
+    }\r
+    \r
+    /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other components that have the same name in the configuration.\r
+     */\r
+    @Override\r
+    public String isValid(final String newText) {\r
+        if (!new FunctionLibraryNameValidator().isValid(lastInput, newText))\r
+            return "Not valid";\r
+        else\r
+            return null;\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/FunctionNameInputValidator.java
new file mode 100644 (file)
index 0000000..a5cce2b
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\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.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.utils.FunctionNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Name validator container for user defined functions.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class FunctionNameInputValidator implements IInputValidator, Widget {\r
+\r
+    private Resource lastInput = null;\r
+    \r
+    public FunctionNameInputValidator(WidgetSupport support) {\r
+        support.register(this);\r
+    }\r
+    \r
+    /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other components that have the same name in the configuration.\r
+     */\r
+    @Override\r
+    public String isValid(final String newText) {\r
+        if (!new FunctionNameValidator().isValid(lastInput, newText))\r
+            return "Not valid";\r
+        else\r
+            return null;\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyFactory.java
new file mode 100644 (file)
index 0000000..d362956
--- /dev/null
@@ -0,0 +1,43 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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 IntegerPropertyFactory extends ReadFactoryImpl<Resource, String> {\r
+\r
+    final private String propertyURI;\r
+    \r
+    public IntegerPropertyFactory(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
+        Integer 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/IntegerPropertyModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/IntegerPropertyModifier.java
new file mode 100644 (file)
index 0000000..fb61240
--- /dev/null
@@ -0,0 +1,39 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.databoard.Bindings;\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 IntegerPropertyModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+    final private String propertyURI;\r
+    \r
+    public IntegerPropertyModifier(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
+       if (text == null || text.equals("")) {\r
+               if(graph.hasStatement(input, graph.getResource(propertyURI)))\r
+                       graph.deny(input, graph.getResource(propertyURI));\r
+       } else {\r
+               graph.claimLiteral(input, graph.getResource(propertyURI), Integer.parseInt(text), Bindings.INTEGER);\r
+       }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModelNameInputValidator.java
new file mode 100644 (file)
index 0000000..625e955
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\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.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.utils.ModelNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Name validator container for model.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ModelNameInputValidator implements IInputValidator, Widget {\r
+\r
+    private Resource lastInput = null;\r
+    \r
+    public ModelNameInputValidator(WidgetSupport support) {\r
+        support.register(this);\r
+    }\r
+    \r
+    /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other components that have the same name in the configuration.\r
+     */\r
+    @Override\r
+    public String isValid(final String newText) {\r
+        if (!new ModelNameValidator().isValid(lastInput, newText))\r
+            return "Not valid";\r
+        else\r
+            return null;\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/ModuleTypeNameInputValidator.java
new file mode 100644 (file)
index 0000000..1340525
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\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.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.utils.ModuleTypeNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Name validator container for module types.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ModuleTypeNameInputValidator implements IInputValidator, Widget {\r
+\r
+    private Resource lastInput = null;\r
+    \r
+    public ModuleTypeNameInputValidator(WidgetSupport support) {\r
+        support.register(this);\r
+    }\r
+    \r
+    /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other components that have the same name in the configuration.\r
+     */\r
+    @Override\r
+    public String isValid(final String newText) {\r
+        if (!new ModuleTypeNameValidator().isValid(lastInput, newText))\r
+            return "Not valid";\r
+        else\r
+            return null;\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNameInputValidator.java
new file mode 100644 (file)
index 0000000..3a6af0c
--- /dev/null
@@ -0,0 +1,53 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.eclipse.jface.dialogs.IInputValidator;\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.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Name validator container for module types.\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class VariableNameInputValidator implements IInputValidator, Widget {\r
+\r
+       private Resource lastInput = null;\r
+       \r
+       public VariableNameInputValidator(WidgetSupport support) {\r
+               support.register(this);\r
+       }\r
+       \r
+       /**\r
+        * Checks that the syntax of the given name is valid and there \r
+        * are no other components that have the same name in the configuration.\r
+        */\r
+       @Override\r
+       public String isValid(final String newText) {\r
+           if (!new VariableNameValidator().isValid(lastInput, newText, true))\r
+               return "Not valid";\r
+        else\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               lastInput = ISelectionUtils.filterSingleSelection(input, Resource.class);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/factories/VariableNamePropertyModifier.java
new file mode 100644 (file)
index 0000000..297b12b
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.factories;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.databoard.Bindings;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.ui.utils.VariableNameValidator;\r
+\r
+public class VariableNamePropertyModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+       final private String propertyURI;\r
+\r
+       public VariableNamePropertyModifier(ISessionContext context, String propertyURI) {\r
+               this.propertyURI = propertyURI;\r
+       }\r
+\r
+       /**\r
+        * Overrides the original applyText. Renames variables also in equations in the same configuration.\r
+        */\r
+       @Override\r
+       public void applyText(WriteGraph graph, Resource variable, String text) throws DatabaseException {\r
+               \r
+               // TODO: separate possible array indexes\r
+               \r
+               // TODO: add enumerations to the variable\r
+           Layer0 L0 = Layer0.getInstance(graph);\r
+               String originalName = graph.getRelatedValue(variable, L0.HasName);\r
+        Resource configuration = graph.getPossibleObject(variable, L0.PartOf);\r
+        new VariableNameValidator().renameInAllEquations(graph, configuration, originalName, text);\r
+               graph.claimLiteral(variable, graph.getResource(propertyURI), text, Bindings.STRING);\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/FunctionCodeWidget.java
new file mode 100644 (file)
index 0000000..1829495
--- /dev/null
@@ -0,0 +1,349 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.functions;\r
+\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+\r
+import javax.swing.Timer;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.StyledText;\r
+import org.eclipse.swt.custom.VerifyKeyListener;\r
+import org.eclipse.swt.events.FocusAdapter;\r
+import org.eclipse.swt.events.FocusEvent;\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.widgets.Composite;\r
+import org.eclipse.swt.widgets.Listener;\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.IsParent;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelParser.ModelParser;\r
+import org.simantics.sysdyn.modelParser.ModelParser.Parameter;\r
+import org.simantics.sysdyn.modelParser.ParseException;\r
+import org.simantics.sysdyn.modelParser.Token;\r
+import org.simantics.sysdyn.modelParser.TokenMgrError;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class FunctionCodeWidget implements Widget {\r
+       \r
+       private ExpressionField modelicaCode;\r
+       private Resource function;\r
+       \r
+    private Timer updateChartTimer;\r
+    private static int VALIDATION_DELAY_TIME = 500;\r
+       \r
+    private ArrayList<Parameter> inputs;\r
+    private ArrayList<Parameter> outputs;\r
+    \r
+       public FunctionCodeWidget(Composite parent, WidgetSupport support, int style) {\r
+               support.register(this);\r
+        modelicaCode = new ExpressionField(parent, SWT.BORDER, null, false, null);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(modelicaCode);\r
+        \r
+\r
+        // Support shift+enter for line change\r
+        modelicaCode.getSourceViewer().getTextWidget().addVerifyKeyListener(new VerifyKeyListener() {\r
+\r
+               @Override\r
+               public void verifyKey(VerifyEvent event) {\r
+                       if(event.keyCode == SWT.CR || event.keyCode == SWT.KEYPAD_CR) {\r
+                               if((event.stateMask & SWT.SHIFT) == 0) {\r
+                                       event.doit = false;\r
+                                       Listener[] listeners = modelicaCode.getSourceViewer().getTextWidget().getListeners(SWT.FocusOut);\r
+                                       for(Listener l : listeners) {\r
+                                               modelicaCode.getSourceViewer().getTextWidget().removeListener(SWT.FocusOut, l);\r
+                                       }\r
+                                       ((StyledText)event.widget).getParent().forceFocus();\r
+                                       save();\r
+                                       for(Listener l : listeners) {\r
+                                               modelicaCode.getSourceViewer().getTextWidget().addListener(SWT.FocusOut, l);\r
+                                       }\r
+                               \r
+                               }\r
+                       }\r
+               }\r
+        });\r
+        \r
+        \r
+        modelicaCode.getSourceViewer().getTextWidget().addModifyListener(new ModifyListener() {\r
+\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               validateFieldsTimed();\r
+                       }\r
+               });\r
+        \r
+        modelicaCode.getSourceViewer().getTextWidget().addFocusListener(new FocusAdapter() {\r
+                       @Override\r
+                       public void focusLost(FocusEvent e) {\r
+                               save();\r
+                       }\r
+               });\r
+               \r
+        \r
+        updateChartTimer = new Timer(VALIDATION_DELAY_TIME, new ActionListener() {\r
+\r
+            @Override\r
+            public void actionPerformed(ActionEvent e) {\r
+               if(modelicaCode == null || modelicaCode.isDisposed())\r
+                       return;\r
+               modelicaCode.getDisplay().asyncExec(new Runnable() {\r
+                               \r
+                               @Override\r
+                               public void run() {\r
+                                       validate();\r
+                               }\r
+                       });\r
+            }\r
+        });\r
+        updateChartTimer.setRepeats(false);\r
+       }\r
+\r
+       @Override\r
+       public void setInput(ISessionContext context, Object input) {\r
+               function = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+               \r
+               try {\r
+                       String code = context.getSession().syncRequest(new Read<String>() {\r
+\r
+                               @Override\r
+                               public String perform(ReadGraph graph) throws DatabaseException {\r
+                                       String code = graph.getPossibleRelatedValue(\r
+                                                       function, SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionCode);\r
+                                       if (code == null) {\r
+                                           code = graph.getPossibleRelatedValue(\r
+                                                   function, SysdynResource.getInstance(graph).SysdynModelicaFunction_modelicaFunctionInterface);\r
+                                           if (code == null) {\r
+                               code = new String("");\r
+                           }\r
+                                       }\r
+                                       return code;\r
+                               }\r
+                               \r
+                       });\r
+                       if(code != null) {\r
+                               modelicaCode.setExpression(code);\r
+                               \r
+                               boolean editable = context.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                    @Override\r
+                    public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                        boolean asd = new IsParent(SysdynResource.getInstance(graph).Built$in_Functions, function).perform(graph);\r
+                        return !asd;\r
+                    }\r
+                               });\r
+                           modelicaCode.getSourceViewer().setEditable(editable);\r
+                               validate();\r
+                       }\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+       \r
+       \r
+    public void validateFieldsTimed() {        \r
+       validateFieldsTimed(VALIDATION_DELAY_TIME);\r
+    }\r
+    \r
+    public void validateFieldsTimed(int delay) {\r
+       updateChartTimer.setDelay(delay);\r
+        if(!updateChartTimer.isRunning())\r
+            updateChartTimer.start();\r
+        else\r
+            updateChartTimer.restart();\r
+    }\r
+    \r
+    public void validate() {\r
+       modelicaCode.resetAnnotations();\r
+       String code = modelicaCode.getExpression();\r
+       StringReader sr = new StringReader(code);\r
+       ModelParser modelParser = new ModelParser(sr);\r
+       \r
+       try {\r
+                       modelParser.parse_composition();\r
+                       \r
+                       inputs = modelParser.getInputs();\r
+                   outputs = modelParser.getOutputs();\r
+\r
+               } catch (ParseException e1) {\r
+                       Token token = e1.currentToken;\r
+                       modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.beginLine, token.beginColumn, token.endLine, token.endColumn));\r
+               } catch (TokenMgrError err) {\r
+                       String message = err.getMessage();\r
+                       String line = message.substring(0, message.indexOf(","));\r
+                       line = line.substring(line.lastIndexOf(" ") + 1);\r
+                       String column = message.substring(message.indexOf(",") + 1, message.indexOf("."));\r
+                       column = column.substring(column.lastIndexOf(" ") + 1);\r
+                       try {\r
+                               Integer endLine = Integer.parseInt(line);\r
+                               Integer endColumn = Integer.parseInt(column);\r
+                               Token token = modelParser.token;\r
+                               modelicaCode.setSyntaxError(new SyntaxError(token.image, "Syntax error", token.endLine, token.endColumn, endLine, endColumn));\r
+                       } catch (NumberFormatException e) {\r
+                               \r
+                       }\r
+                       \r
+               }\r
+       }\r
+    \r
+    private void save() {\r
+        \r
+        if (!modelicaCode.getSourceViewer().isEditable())\r
+            return;\r
+        \r
+       final String code = modelicaCode.getExpression();\r
+       \r
+       // Update input and output lists.\r
+       validate();\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
+\r
+                // Remove the existing input list\r
+                removeInputList(graph);\r
+                // Create the new input list\r
+                createInputList(graph);\r
+\r
+                // Remove the existing output list\r
+                removeOutputList(graph);\r
+                // Create the new output list\r
+                createOutputList(graph);\r
+                \r
+                // Update the function code\r
+                graph.claimLiteral(\r
+                        function, \r
+                        sr.SysdynModelicaFunction_modelicaFunctionCode, \r
+                        code);\r
+            }\r
+            \r
+           private void removeInputList(WriteGraph graph) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                \r
+                Resource oldInputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_inputs);\r
+                if (oldInputList != null) {\r
+                    // Find all the inputs \r
+                    for (Resource input : ListUtils.toList(graph, oldInputList)) {\r
+                        // Check if we have a variable length input\r
+                        if (graph.isInstanceOf(input, sr.SysdynModelicaFunction_VariableLengthInput)) {\r
+                            // The variable length inputs are found here\r
+                            Resource variableLengthInputLabels = graph.getPossibleObject(input, sr.SysdynModelicaFunction_VariableLengthInput_shownLabels);\r
+                            if (variableLengthInputLabels != null) {\r
+                                // Find labels (strings)\r
+                                for (Resource label : ListUtils.toList(graph, variableLengthInputLabels)) {\r
+                                    //Remove string\r
+                                    RemoverUtil.remove(graph, label);\r
+                                }\r
+                                // Remove list\r
+                                RemoverUtil.remove(graph, variableLengthInputLabels);\r
+                            }\r
+                        }                       \r
+                        // Remove the input\r
+                        RemoverUtil.remove(graph, input);\r
+                    }\r
+                    // Remove the list\r
+                    RemoverUtil.remove(graph, oldInputList);\r
+                }\r
+           }\r
+           \r
+           private void createInputList(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+                \r
+                ArrayList<Resource> inputResources = new ArrayList<Resource>();\r
+                // Create inputs\r
+                if (inputs != null) {\r
+                    for (Parameter input : inputs) {\r
+                        Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Input,\r
+                                l0.HasName, input.name, \r
+                                sr.Variable_type, input.type,\r
+                                sr.SysdynModelicaFunction_optional, input.optional ? l0.True : l0.False);\r
+                        if (input.description != null) {\r
+                            // Description is optional\r
+                            graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, input.description);\r
+                        }\r
+                        inputResources.add(r);\r
+                    }\r
+                    graph.claim(\r
+                            function, \r
+                            sr.SysdynModelicaFunction_inputs, \r
+                            ListUtils.create(graph, inputResources));\r
+                }\r
+           }\r
+           \r
+           private void removeOutputList(WriteGraph graph) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                Resource oldOutputList = graph.getPossibleObject(function, sr.SysdynModelicaFunction_outputs);\r
+                if (oldOutputList != null) {\r
+                    // Find all the outputs \r
+                    for (Resource output : ListUtils.toList(graph, oldOutputList)) {\r
+                        // Remove the output\r
+                        RemoverUtil.remove(graph, output);\r
+                    }\r
+                    // Remove the list\r
+                    RemoverUtil.remove(graph, oldOutputList);\r
+                }\r
+           }\r
+                       \r
+           private void createOutputList(WriteGraph graph) throws DatabaseException {\r
+                Layer0 l0 = Layer0.getInstance(graph);\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                ArrayList<Resource> outputResources = new ArrayList<Resource>();\r
+                // Create outputs\r
+                if (outputs != null) {\r
+                    for (Parameter output : outputs) {\r
+                        Resource r = GraphUtils.create2(graph, sr.SysdynModelicaFunction_Output,\r
+                                l0.HasName, output.name, \r
+                                sr.Variable_type, output.type);\r
+                        if (output.description != null) {\r
+                            // Description is optional\r
+                            graph.claimLiteral(r, sr.SysdynModelicaFunction_definition, output.description);\r
+                        }\r
+                        outputResources.add(r);\r
+                    }\r
+                    graph.claim(\r
+                            function, \r
+                            sr.SysdynModelicaFunction_outputs, \r
+                            ListUtils.create(graph, outputResources));\r
+                }\r
+                \r
+           }\r
+\r
+               });\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SelectedSharedFunctionLibraries.java
new file mode 100644 (file)
index 0000000..255555b
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.functions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+\r
+public class SelectedSharedFunctionLibraries extends ViewpointContributor<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+        ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+\r
+        \r
+        for(Resource sharedLibrary : graph.syncRequest(new ObjectsWithType(\r
+                       input, \r
+                       Layer0.getInstance(graph).IsLinkedTo, \r
+                       SysdynResource.getInstance(graph).SharedFunctionOntology)))\r
+        {\r
+               result.add(new SharedFunctionLibraryNode(sharedLibrary));\r
+        }\r
+        \r
+               return result;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/functions/SharedFunctionLibraries.java
new file mode 100644 (file)
index 0000000..70dbb6f
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.functions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+\r
+public class SharedFunctionLibraries extends ViewpointContributor<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+       throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+\r
+               // Find shared ontologies. graph.getPossibleResource("http://SharedOntologies") does not update if it was null for the first time.\r
+               Resource sharedOntologies = null;\r
+               Resource root = input;\r
+               while(graph.getPossibleObject(root, l0.PartOf) != null)\r
+                       root = graph.getPossibleObject(root, l0.PartOf);\r
+               \r
+               for(Resource r : graph.getObjects(root, l0.ConsistsOf)) {\r
+                       if("SharedOntologies".equals(NameUtils.getSafeName(graph, r))) {\r
+                               sharedOntologies = r;\r
+                               break;\r
+                       }\r
+               }\r
+               \r
+               if(sharedOntologies == null) {\r
+                       return result;\r
+               }\r
+               \r
+               // Find all shared function ontologies. \r
+               // (Don't know why ObjectsWithType works only the first time, then gives nothing) \r
+               ArrayList<Resource> sharedFunctionLibraries = new ArrayList<Resource>();\r
+               for(Resource r : graph.getObjects(sharedOntologies, l0.ConsistsOf)) {\r
+                       if(graph.isInstanceOf(r, sr.SharedFunctionOntology))\r
+                               sharedFunctionLibraries.add(r);\r
+               }\r
+\r
+               // Find all shared function ontologies that have already been selected\r
+               Collection<Resource> selectedSharedFunctionLibraries = graph.syncRequest(new ObjectsWithType(\r
+                               input, l0.IsLinkedTo, sr.SharedFunctionOntology));\r
+\r
+               // Remove all selected ontologies from the shared function ontologies\r
+               sharedFunctionLibraries.removeAll(selectedSharedFunctionLibraries);\r
+\r
+               for(Resource ontology : sharedFunctionLibraries) {\r
+                       result.add(new SharedFunctionLibraryNode(ontology));\r
+               }\r
+\r
+               return result;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableChildRule.java
new file mode 100644 (file)
index 0000000..45b2924
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.historyDataset;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.manager.HistoryDatasetUtils;\r
+import org.simantics.sysdyn.ui.properties.HistoryDataTab;\r
+\r
+/**\r
+ * Variable child rule for GE in {@link HistoryDataTab}\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class VariableChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        ArrayList<String> result = new ArrayList<String>();\r
+        if(!(parent instanceof Resource))\r
+            return result;\r
+        result.addAll(HistoryDatasetUtils.getVariableNamesInRange(graph, (Resource)parent));\r
+        return result;\r
+\r
+\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return new ArrayList<Resource>();\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/historyDataset/VariableLabelRule.java
new file mode 100644 (file)
index 0000000..0cb9459
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.historyDataset;\r
+\r
+import java.util.Collections;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.labels.LabelRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.HistoryDataTab;\r
+\r
+/**\r
+ * Variable label rule for GE in {@link HistoryDataTab}\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class VariableLabelRule implements LabelRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(String.class);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, Object content) throws DatabaseException {\r
+        return Collections.singletonMap(ColumnKeys.SINGLE, (content instanceof String ? (String)content : "No content"));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleInputEditingSupport.java
new file mode 100644 (file)
index 0000000..42a751a
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\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.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.layer0.Layer0;\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
+                               Layer0 l0 = Layer0.getInstance(graph);\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.Variable_isHeadOf, sr.Dependency))) {\r
+                                if(graph.getPossibleObject(dependency, sr.Dependency_refersTo) == null ||\r
+                                        graph.getPossibleObject(dependency, sr.Dependency_refersTo).equals(inputVariable)) {\r
+                                    Resource output = graph.getSingleObject(dependency, sr.Variable_HasTail);\r
+                                    \r
+                                    if(graph.isInstanceOf(output, sr.Shadow)) {\r
+                                        output = graph.getPossibleObject(output, sr.Shadow_original);\r
+                                    }\r
+                                    \r
+                                    if(output != null)\r
+                                        result.put((String)graph.getRelatedValue(output, l0.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/modules/ModuleOutputEditingSupport.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleOutputEditingSupport.java
new file mode 100644 (file)
index 0000000..4b64f3b
--- /dev/null
@@ -0,0 +1,138 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\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.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.layer0.Layer0;\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
+                               Layer0 l0 = Layer0.getInstance(graph);\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.Variable_isTailOf, sr.Dependency))) {\r
+                                if(graph.getPossibleObject(dependency, sr.Dependency_refersTo) == null \r
+                                               || !graph.hasStatement(graph.getPossibleObject(dependency, sr.Dependency_refersTo), l0.HasName)\r
+                                               || graph.getPossibleObject(dependency, sr.Dependency_refersTo).equals(outputVariable)) {\r
+                                    Resource input = graph.getSingleObject(dependency, sr.Variable_HasHead);\r
+                                    result.put((String)graph.getRelatedValue(input, l0.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/modules/ModuleParameterOverrideUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ModuleParameterOverrideUtils.java
new file mode 100644 (file)
index 0000000..06a9e2b
--- /dev/null
@@ -0,0 +1,102 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import java.util.List;\r
+\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.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+\r
+/**\r
+ * Utilities for module parameter override functionalities\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleParameterOverrideUtils {\r
+\r
+    /**\r
+     * Get the parameter expression of a variable or null, if it does not contain a parameter expression,\r
+     * or there are many parameter expressions\r
+     * @param graph ReadGraph\r
+     * @param variable IndependentVariable\r
+     * @return parameter expression or null\r
+     * @throws DatabaseException\r
+     */\r
+    public static String getParameterExpression(IndependentVariable variable) throws DatabaseException {\r
+        String result = null;\r
+        try {\r
+            result = variable.getExpressions().get(0).getExpression();\r
+        if(result.contains("/* Actual value read from init file */"))\r
+            result = result.substring(0, result.indexOf("/* Actual value read from init file */"));\r
+        } catch (NullPointerException e) {\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Get the expression, or the overriding expression, of a parameter\r
+     * @param graph ReadGraph\r
+     * @param parent Parent resource\r
+     * @param variable IndependentVariable\r
+     * @return Overriding expression, or the default parameter expression, or null\r
+     * @throws DatabaseException\r
+     */\r
+    public static String getParameterExpressionOrOverride(ReadGraph graph, Resource parent, IndependentVariable variable)\r
+            throws DatabaseException {\r
+        String result = null;\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+        // Get possible override\r
+        for(Resource r : graph.syncRequest(new ObjectsWithType(parent, L0.ConsistsOf, sr.Module_ParameterOverride))) {\r
+            Resource overridden = graph.getPossibleObject(r, sr.Module_ParameterOverride_overriddenParameter);\r
+            if(variable.getName().equals(NameUtils.getSafeName(graph, overridden))) {\r
+                result = graph.getPossibleRelatedValue(r, sr.Module_ParameterOverride_overrideExpression);\r
+            }\r
+        }\r
+        \r
+        if(result == null) {\r
+            // Parameter is not overridden, find the actual expression\r
+            result = getParameterExpression(variable);\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Find out if a variable has a single parameter expression \r
+     * @param graph ReadGraph\r
+     * @param variable Variable\r
+     * @return does the variable have a single parameter expression\r
+     * @throws DatabaseException\r
+     */\r
+    public static boolean hasParameterExpression(ReadGraph graph, Resource variable) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        boolean result = false;\r
+        Resource expressionsResource = graph.getPossibleObject(variable, sr.Variable_expressionList);\r
+        if(expressionsResource != null) {\r
+            List<Resource> expressions = ListUtils.toList(graph, expressionsResource);\r
+            if(expressions.size() == 1 && graph.isInstanceOf(expressions.get(0), sr.ParameterExpression)) {\r
+                result = true;\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterChildRule.java
new file mode 100644 (file)
index 0000000..5d88453
--- /dev/null
@@ -0,0 +1,77 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\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.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\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.representation.Stock;\r
+import org.simantics.sysdyn.representation.Variability;\r
+\r
+public class ParameterChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        ArrayList<ParameterNode> result = new ArrayList<ParameterNode>();\r
+        if(!(parent instanceof Resource))\r
+            return result;\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        Resource moduleInstance = (Resource) parent;\r
+        \r
+        Resource type = graph.getSingleObject(moduleInstance, L0.InstanceOf);\r
+        Resource configuration = graph.getSingleObject(type, STR.IsDefinedBy);\r
+        SysdynModelManager sdm = SysdynModelManager.getInstance(graph.getSession());\r
+        SysdynModel model = sdm.getModel(graph, configuration);\r
+        \r
+        Resource varConfRes = graph.getSingleObject(moduleInstance, L0.PartOf);\r
+        Configuration varConf = sdm.getModel(graph, varConfRes).getConfiguration();\r
+        \r
+        for(Resource variable : graph.syncRequest(new ObjectsWithType(configuration, L0.ConsistsOf, sr.IndependentVariable))) {\r
+            IElement element = model.getElement(variable);\r
+            if(element instanceof IndependentVariable && !(element instanceof Stock)) \r
+                if(!Variability.CONTINUOUS.equals(Variability.getVariability((IndependentVariable)element, false, varConf)))\r
+                    result.add(new ParameterNode(moduleInstance, varConf, variable, (IndependentVariable)element));\r
+        }\r
+        \r
+        return result;\r
+\r
+\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return new ArrayList<Resource>();\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelDecorationRule.java
new file mode 100644 (file)
index 0000000..993d613
--- /dev/null
@@ -0,0 +1,57 @@
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import org.eclipse.jface.resource.ColorDescriptor;\r
+import org.eclipse.swt.graphics.RGB;\r
+import org.simantics.browsing.ui.content.LabelDecorator;\r
+import org.simantics.browsing.ui.model.labeldecorators.LabelDecorationRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+\r
+public class ParameterLabelDecorationRule implements LabelDecorationRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Object.class);\r
+    }\r
+\r
+    @Override\r
+    public LabelDecorator getLabelDecorator(ReadGraph graph, Object content) throws DatabaseException {\r
+        if(content instanceof ParameterNode) {\r
+            ParameterNode node = (ParameterNode) content;\r
+            String notOverriding = ModuleParameterOverrideUtils.getParameterExpression(node.getIndependentVariable());\r
+            String overriding = ModuleParameterOverrideUtils.getParameterExpressionOrOverride(graph, node.getParent(), node.getIndependentVariable());\r
+\r
+            if(notOverriding == null)\r
+                return null;\r
+\r
+            final boolean original = notOverriding.equals(overriding);\r
+\r
+            return new LabelDecorator.Stub() {\r
+                @Override\r
+                public String decorateLabel(String label, String column, int itemIndex) {\r
+                    if(ColumnKeys.VALUE.equals(column)) {\r
+                        return original ? label : label + " [Overridden]";\r
+                    } else {\r
+                        return label;\r
+                    }\r
+                }\r
+\r
+                @SuppressWarnings("unchecked")\r
+                @Override\r
+                public <Color> Color decorateForeground(Color color, String column, int itemIndex) {\r
+                    Color result = null;\r
+                    if(ColumnKeys.VALUE.equals(column)) {\r
+                        if(original)\r
+                            result = (Color) ColorDescriptor.createFrom(new RGB(125,125,125));\r
+                        else\r
+                            result = (Color) ColorDescriptor.createFrom(new RGB(0,0,0));\r
+                    }\r
+                    return result;\r
+                }\r
+            };\r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterLabelRule.java
new file mode 100644 (file)
index 0000000..0640bc3
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.model.labels.LabelRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+\r
+public class ParameterLabelRule implements LabelRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Object.class);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, Object content) throws DatabaseException {\r
+        Map<String, String> result = new HashMap<String, String>();\r
+\r
+        if(content instanceof ParameterNode) {\r
+            ParameterNode node = (ParameterNode) content;\r
+            String parameterExpression = ModuleParameterOverrideUtils.getParameterExpressionOrOverride(graph, node.getParent(), node.getIndependentVariable());\r
+            String name = node.getIndependentVariable().getName();\r
+\r
+            result.put(ColumnKeys.MODULE_PARAMETER, name);\r
+            result.put(ColumnKeys.VALUE, parameterExpression);\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterModifierRule.java
new file mode 100644 (file)
index 0000000..a964c5b
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import org.simantics.browsing.ui.content.Labeler.Modifier;\r
+import org.simantics.browsing.ui.model.modifiers.ModifierRule;\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.db.layer0.util.RemoverUtil;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.representation.Variability;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ParameterModifierRule implements ModifierRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Object.class);\r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(ReadGraph graph, Object content, String columnKey) throws DatabaseException {\r
+        if(content instanceof ParameterNode && ColumnKeys.VALUE.equals(columnKey)) {\r
+            final ParameterNode node = (ParameterNode) content;\r
+            return new Modifier() {\r
+\r
+                @Override\r
+                public String getValue() {\r
+                    Read<String> request =\r
+                            new Read<String>() {\r
+\r
+                        @Override\r
+                        public String perform(ReadGraph graph) throws DatabaseException {\r
+                            String parameterExpression =  ModuleParameterOverrideUtils.getParameterExpressionOrOverride(\r
+                                    graph, \r
+                                    node.getParent(), \r
+                                    node.getIndependentVariable());\r
+\r
+                            return parameterExpression != null ? parameterExpression : "";\r
+                        }\r
+\r
+                    };\r
+                    try {\r
+                        return SimanticsUI.getSession().syncRequest(request);\r
+                    } catch (DatabaseException e) {\r
+                        e.printStackTrace();\r
+                        return "";\r
+                    }\r
+                }\r
+\r
+                @Override\r
+                public String isValid(String label) {\r
+                    if(label.isEmpty())\r
+                        return null;\r
+                    \r
+                    if(Variability.CONTINUOUS.equals(Variability.getVariability(node.getIndependentVariable(), label, false, node.getParentConfiguration()))) \r
+                        return "Not valid";\r
+                    else\r
+                        return null;\r
+                }\r
+\r
+                @Override\r
+                public void modify(final String label) {\r
+                    SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                        @Override\r
+                        public void perform(WriteGraph graph) throws DatabaseException {\r
+                            SysdynResource sr = SysdynResource.getInstance(graph);\r
+                            Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+                            // Remove possible old override\r
+                            for(Resource r : graph.syncRequest(new ObjectsWithType(node.getParent(), L0.ConsistsOf, sr.Module_ParameterOverride))) {\r
+                                if(node.getVariableResource().equals(graph.getPossibleObject(r, sr.Module_ParameterOverride_overriddenParameter))) {\r
+                                    RemoverUtil.remove(graph, r);\r
+                                    break;\r
+                                }\r
+                            }\r
+\r
+                            // Write the new override, if there is one\r
+                            if(label != null && !label.isEmpty()) {\r
+                                GraphUtils.create2(graph, sr.Module_ParameterOverride,\r
+                                        sr.Module_ParameterOverride_overriddenParameter, node.getVariableResource(),\r
+                                        sr.Module_ParameterOverride_overrideExpression, label,\r
+                                        L0.PartOf, node.getParent()\r
+                                        );\r
+                            }\r
+                        }\r
+                    });\r
+                }\r
+\r
+            };\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterNode.java
new file mode 100644 (file)
index 0000000..49e3586
--- /dev/null
@@ -0,0 +1,48 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+\r
+public class ParameterNode {\r
+    \r
+    private Resource moduleInstance;\r
+    private Resource variableResource;\r
+    private IndependentVariable independentVariable;\r
+    private Configuration parentConfiguration;\r
+    \r
+    public ParameterNode(Resource parent, Configuration parentConfiguration, Resource variableResource, IndependentVariable independentVariable) {\r
+        this.moduleInstance = parent;\r
+        this.variableResource = variableResource;\r
+        this.independentVariable = independentVariable;\r
+        this.parentConfiguration = parentConfiguration;\r
+    }\r
+\r
+    public Resource getParent() {\r
+        return moduleInstance;\r
+    }\r
+\r
+    public Resource getVariableResource() {\r
+        return variableResource;\r
+    }\r
+    \r
+    public IndependentVariable getIndependentVariable() {\r
+        return independentVariable;\r
+    }\r
+    \r
+    public Configuration getParentConfiguration() {\r
+        return parentConfiguration;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorter.java
new file mode 100644 (file)
index 0000000..802e193
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
+import org.simantics.browsing.ui.model.sorters.AbstractSorter;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.properties.widgets.ColumnKeys;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+/**\r
+ * Sorter for sorting module parameters into alphabetic order.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ParameterSorter  extends AbstractSorter<String> {\r
+    \r
+    public static ParameterSorter INSTANCE = new ParameterSorter();\r
+\r
+    @Override\r
+    public String getSortingCriterion(ReadGraph graph, BrowseContext context,\r
+            NodeContext node) throws DatabaseException {\r
+        Map<String,String> labels = context.getLabel(graph, node);\r
+        String label = labels.get(ColumnKeys.MODULE_PARAMETER);\r
+        return label;\r
+    }\r
+\r
+    @Override\r
+    public int compare(String a, String b) {\r
+        return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(a, b);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ParameterSorterRule.java
new file mode 100644 (file)
index 0000000..20db86b
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import org.simantics.browsing.ui.model.sorters.Sorter;\r
+import org.simantics.browsing.ui.model.sorters.SorterRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+/**\r
+ * SorterRule for sorting module parameters into alphabetic order.\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ParameterSorterRule implements SorterRule {    \r
+        \r
+        @Override\r
+        public boolean isCompatible(Class<?> contentType) {\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public Sorter getSorter(ReadGraph graph, Object content)\r
+                throws DatabaseException {\r
+            return ParameterSorter.INSTANCE;\r
+        }\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRow.java
new file mode 100644 (file)
index 0000000..e668512
--- /dev/null
@@ -0,0 +1,118 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\r
+\r
+import org.simantics.databoard.Bindings;\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.layer0.Layer0;\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(), Layer0.getInstance(graph).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
+                    Layer0 l0 = Layer0.getInstance(graph);\r
+                    SysdynResource sr = SysdynResource.getInstance(graph);\r
+                    Resource valueResource = graph.getPossibleObject(dependency, sr.Variable_HasTail);\r
+                    if(!graph.isInstanceOf(valueResource, sr.Variable))\r
+                        valueResource = graph.getPossibleObject(dependency, sr.Variable_HasHead);\r
+                    \r
+                    if(graph.isInstanceOf(valueResource, sr.Shadow))\r
+                        valueResource = graph.getPossibleObject(valueResource, sr.Shadow_original);\r
+                    \r
+                    if(valueResource == null || !graph.isInstanceOf(valueResource, sr.Variable))\r
+                        return "";\r
+                    \r
+                    return (String)graph.getRelatedValue(valueResource, l0.HasName, Bindings.STRING);\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.Dependency_refersTo))\r
+                    graph.deny(getDependency(), sr.Dependency_refersTo);\r
+                if(dependency != null && graph.hasStatement(dependency, sr.Dependency_refersTo))\r
+                       graph.deny(dependency, sr.Dependency_refersTo);\r
+                setDependency(null);\r
+                if(dependency != null) {\r
+                    setDependency(dependency);\r
+                    graph.claim(getDependency(), SysdynResource.getInstance(graph).Dependency_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/modules/ReferenceRowLabelProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceRowLabelProvider.java
new file mode 100644 (file)
index 0000000..763e841
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\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/modules/ReferenceTable.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/ReferenceTable.java
new file mode 100644 (file)
index 0000000..aeb5daf
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\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/modules/RowProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/modules/RowProvider.java
new file mode 100644 (file)
index 0000000..9b424d2
--- /dev/null
@@ -0,0 +1,22 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.modules;\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/sensitivity/DistributionPropertyWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/DistributionPropertyWidget.java
new file mode 100644 (file)
index 0000000..93a62b2
--- /dev/null
@@ -0,0 +1,118 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.StructuredSelection;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\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.request.Read;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class DistributionPropertyWidget extends Composite implements Widget {\r
+    \r
+    private IDistributionProperties distributionProperties = null;\r
+    private WidgetSupportImpl distributionSupport = new WidgetSupportImpl();\r
+    private HashMap<String, String> cache = new HashMap<String, String>();\r
+    private Resource oldInput;\r
+\r
+    public DistributionPropertyWidget(Composite parent, ISessionContext context, WidgetSupport support, int style) {\r
+        super(parent, style);\r
+        GridLayoutFactory.fillDefaults().applyTo(this);\r
+        support.register(this);\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        if(resource == null)\r
+            return;\r
+\r
+        IDistributionProperties newProperties = null;\r
+        Resource distribution = null;\r
+        try {\r
+            distribution = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                @Override\r
+                public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                    Resource distribution = graph.getPossibleObject(\r
+                            resource, \r
+                            SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_propabilityDistribution\r
+                            );\r
+                    \r
+                    return distribution;\r
+                }\r
+\r
+            });\r
+            \r
+            newProperties = SimanticsUI.getSession().syncRequest(new Read<IDistributionProperties>() {\r
+\r
+                @Override\r
+                public IDistributionProperties perform(ReadGraph graph) throws DatabaseException {\r
+                    Resource distribution = graph.getPossibleObject(\r
+                            resource, \r
+                            SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_propabilityDistribution\r
+                            );\r
+                    \r
+                    return graph.adapt(distribution, IDistributionProperties.class);\r
+                }\r
+\r
+            });\r
+            \r
+            // Create a PropertyComposite for the selected node\r
+            if(newProperties != null) {\r
+\r
+                if(distributionProperties != null)\r
+                    distributionProperties.getCachedValues(cache);\r
+                \r
+                if(oldInput != null && !oldInput.equals(resource))\r
+                    cache.clear();\r
+                \r
+                oldInput = resource;\r
+                \r
+                for(Control child : this.getChildren()) {\r
+                    child.dispose();\r
+                }\r
+                \r
+                newProperties.createContent(this, context, distributionSupport);\r
+                distributionProperties = newProperties;\r
+                \r
+                SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                    \r
+                    @Override\r
+                    public void perform(WriteGraph graph) throws DatabaseException {\r
+                        distributionProperties.applyCache(graph, cache);\r
+                        \r
+                    }\r
+                });\r
+                \r
+                distributionSupport.fireInput(context, new StructuredSelection(distribution));\r
+            }\r
+            \r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IDistributionProperties.java
new file mode 100644 (file)
index 0000000..0c628e9
--- /dev/null
@@ -0,0 +1,30 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.management.ISessionContext;\r
+\r
+public interface IDistributionProperties {\r
+    \r
+    public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support);\r
+    \r
+    public void getCachedValues(HashMap<String, String> cachedValues);\r
+    \r
+    public void applyCache(WriteGraph graph, HashMap<String, String> cachedValues) throws DatabaseException;\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/IntervalProperties.java
new file mode 100644 (file)
index 0000000..9f3b7bc
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.DoubleValidator;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class IntervalProperties implements IDistributionProperties {\r
+\r
+    private Resource resource;\r
+    private TrackedText minValue; \r
+    private TrackedText maxValue;\r
+    \r
+    public IntervalProperties(Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+    \r
+    @Override\r
+    public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) {\r
+        Composite composite = new Composite(parent, SWT.NONE);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
+        \r
+        // minValue\r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Min value");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        minValue = new TrackedText(composite, support, SWT.BORDER);\r
+        minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Interval_minValue));\r
+        minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Interval_minValue));\r
+        minValue.setInputValidator(new DoubleValidator(false));\r
+        minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget());\r
+\r
+        // maxValue\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Max value");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        maxValue = new TrackedText(composite, support, SWT.BORDER);\r
+        maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Interval_maxValue));\r
+        maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Interval_maxValue));\r
+        maxValue.setInputValidator(new DoubleValidator(false));\r
+        maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget());\r
+        \r
+        return composite;\r
+    }\r
+    \r
+\r
+    @Override\r
+    public void getCachedValues(HashMap<String, String> cahcedValues) {\r
+        if(!minValue.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText());\r
+        if(!maxValue.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText());\r
+    }\r
+\r
+\r
+\r
+    @Override\r
+    public void applyCache(WriteGraph graph, HashMap<String, String> cachedValues) throws DatabaseException {\r
+        if(resource == null)\r
+            return;\r
+        \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        String min = cachedValues.get(SensitivityDistributionKeys.MIN);\r
+        if(min != null) {\r
+            try {\r
+                Double d = Double.parseDouble(min);\r
+                graph.claimLiteral(resource, SR.Interval_minValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+        \r
+        String max = cachedValues.get(SensitivityDistributionKeys.MAX);\r
+        if(max != null) {\r
+            try {\r
+                Double d = Double.parseDouble(max);\r
+                graph.claimLiteral(resource, SR.Interval_maxValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/NormalDistributionProperties.java
new file mode 100644 (file)
index 0000000..ccb5fb2
--- /dev/null
@@ -0,0 +1,158 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.DoubleValidator;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class NormalDistributionProperties implements IDistributionProperties {\r
+\r
+    private TrackedText minValue; \r
+    private TrackedText maxValue;\r
+    private TrackedText mean;\r
+    private TrackedText stdDeviation;\r
+    private Resource resource;\r
+    \r
+    public NormalDistributionProperties(Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+    \r
+    @Override\r
+    public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) {\r
+        Composite composite = new Composite(parent, SWT.NONE);\r
+        GridLayoutFactory.fillDefaults().numColumns(4).applyTo(composite);\r
+        \r
+        // mean\r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Mean (\u03BC)");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        mean = new TrackedText(composite, support, SWT.BORDER);\r
+        mean.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_mean));\r
+        mean.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_mean));\r
+        mean.setInputValidator(new DoubleValidator(true));\r
+        mean.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), mean.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(mean.getWidget());\r
+        \r
+        // minValue\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Min value");\r
+        GridDataFactory.fillDefaults().indent(15, 0).align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        minValue = new TrackedText(composite, support, SWT.BORDER);\r
+        minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_minValue));\r
+        minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_minValue));\r
+        minValue.setInputValidator(new DoubleValidator(true));\r
+        minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget());\r
+\r
+        // stdDeviation\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Standard deviation (\u03C3)");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        stdDeviation = new TrackedText(composite, support, SWT.BORDER);\r
+        stdDeviation.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_stdDeviation));\r
+        stdDeviation.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_stdDeviation));\r
+        stdDeviation.setInputValidator(new DoubleValidator(true));\r
+        stdDeviation.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), stdDeviation.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(stdDeviation.getWidget());\r
+        \r
+        // maxValue\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Max value");\r
+        GridDataFactory.fillDefaults().align(SWT.END, SWT.CENTER).applyTo(label);\r
+        \r
+        maxValue = new TrackedText(composite, support, SWT.BORDER);\r
+        maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.NormalDistribution_maxValue));\r
+        maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.NormalDistribution_maxValue));\r
+        maxValue.setInputValidator(new DoubleValidator(true));\r
+        maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget());\r
+        \r
+        return composite;\r
+    }\r
+\r
+    @Override\r
+    public void getCachedValues(HashMap<String, String> cahcedValues) {\r
+        if(!minValue.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText());\r
+        if(!maxValue.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText());\r
+        if(!mean.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.MEAN, mean.getText());\r
+        if(!stdDeviation.isDisposed())\r
+            cahcedValues.put(SensitivityDistributionKeys.STD_DEVIATION, stdDeviation.getText());\r
+    }\r
+\r
+\r
+\r
+    @Override\r
+    public void applyCache(WriteGraph graph, HashMap<String, String> cachedValues) throws DatabaseException {\r
+        if(resource == null)\r
+            return;\r
+        \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        String min = cachedValues.get(SensitivityDistributionKeys.MIN);\r
+        if(min != null) {\r
+            try {\r
+                Double d = Double.parseDouble(min);\r
+                graph.claimLiteral(resource, SR.NormalDistribution_minValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+        \r
+        String max = cachedValues.get(SensitivityDistributionKeys.MAX);\r
+        if(max != null) {\r
+            try {\r
+                Double d = Double.parseDouble(max);\r
+                graph.claimLiteral(resource, SR.NormalDistribution_maxValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+        \r
+        String mean = cachedValues.get(SensitivityDistributionKeys.MEAN);\r
+        if(mean != null) {\r
+            try {\r
+                Double d = Double.parseDouble(mean);\r
+                graph.claimLiteral(resource, SR.NormalDistribution_mean, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+        \r
+        String stdDeviation = cachedValues.get(SensitivityDistributionKeys.STD_DEVIATION);\r
+        if(stdDeviation != null) {\r
+            try {\r
+                Double d = Double.parseDouble(stdDeviation);\r
+                graph.claimLiteral(resource, SR.NormalDistribution_stdDeviation, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterChildRule.java
new file mode 100644 (file)
index 0000000..30274d6
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+import org.simantics.browsing.ui.model.children.ChildRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ParameterChildRule implements ChildRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getChildren(ReadGraph graph, Object parent) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        Resource experiment = (Resource) parent;\r
+        Resource parameterList = graph.getPossibleObject(experiment, SR.SensitivityAnalysisExperiment_parameterList);\r
+        \r
+        if(parameterList != null)\r
+            return ListUtils.toList(graph, parameterList);\r
+        else\r
+            return Collections.emptyList();\r
+    }\r
+\r
+    @Override\r
+    public Collection<?> getParents(ReadGraph graph, Object child) throws DatabaseException {\r
+        return Collections.emptyList();\r
+    }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterLabelRule.java
new file mode 100644 (file)
index 0000000..fd67dc8
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.model.labels.LabelRule;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class ParameterLabelRule implements LabelRule {\r
+\r
+    @Override\r
+    public boolean isCompatible(Class<?> contentType) {\r
+        return contentType.equals(Resource.class);\r
+    }\r
+\r
+    @Override\r
+    public Map<String, String> getLabel(ReadGraph graph, Object content) throws DatabaseException {\r
+        HashMap<String, String> result = new HashMap<String, String>();\r
+        \r
+        String variable = graph.getPossibleRelatedValue((Resource)content, SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_variable);\r
+        \r
+        StringBuilder sb = new StringBuilder();\r
+        \r
+        if(variable != null)\r
+            sb.append(variable);\r
+        else\r
+            sb.append("No variable");\r
+        \r
+        result.put(ColumnKeys.SINGLE, sb.toString()) ;\r
+        \r
+        return result;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/ParameterProposalProvider.java
new file mode 100644 (file)
index 0000000..84b0c21
--- /dev/null
@@ -0,0 +1,16 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+public class ParameterProposalProvider {\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityDistributionKeys.java
new file mode 100644 (file)
index 0000000..d1019b2
--- /dev/null
@@ -0,0 +1,21 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+public class SensitivityDistributionKeys {\r
+    \r
+    public static String MAX = "MAX";\r
+    public static String MIN = "MIN";\r
+    public static String STD_DEVIATION = "STD_DEVIATION";\r
+    public static String MEAN = "MEAN";\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/SensitivityRangeHandlerFactory.java
new file mode 100644 (file)
index 0000000..aca7931
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.Map;\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.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.trend.SysdynRangeHandlerFactory;\r
+\r
+public class SensitivityRangeHandlerFactory extends SysdynRangeHandlerFactory {\r
+\r
+    @Override\r
+    protected Resource getRVIRelation(ReadGraph graph) {\r
+        return SysdynResource.getInstance(graph).SensitivityAnalysisExperiment_Parameter_variable;\r
+    }\r
+    \r
+    @Override\r
+    public ReadFactoryImpl<Resource, Map<String, Object>> getRangeItemFactory(int index, Resource res) {\r
+        return new RangeItemFactory(index, res, false);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/UniformDistributionProperties.java
new file mode 100644 (file)
index 0000000..2b78a9d
--- /dev/null
@@ -0,0 +1,110 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.DoubleValidator;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+\r
+public class UniformDistributionProperties implements IDistributionProperties{\r
+\r
+    private TrackedText minValue; \r
+    private TrackedText maxValue;\r
+    private Resource resource;\r
+    \r
+    public UniformDistributionProperties(Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+    \r
+    @Override\r
+    public Composite createContent(Composite parent, ISessionContext context, WidgetSupport support) {\r
+        Composite composite = new Composite(parent, SWT.NONE);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
+        \r
+        // minValue\r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Min value");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        minValue = new TrackedText(composite, support, SWT.BORDER);\r
+        minValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.UniformDistribution_minValue));\r
+        minValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.UniformDistribution_minValue));\r
+        minValue.setInputValidator(new DoubleValidator(false));\r
+        minValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), minValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(minValue.getWidget());\r
+\r
+        // maxValue\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Max value");\r
+        GridDataFactory.fillDefaults().applyTo(label);\r
+        \r
+        maxValue = new TrackedText(composite, support, SWT.BORDER);\r
+        maxValue.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.UniformDistribution_maxValue));\r
+        maxValue.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.UniformDistribution_maxValue));\r
+        maxValue.setInputValidator(new DoubleValidator(false));\r
+        maxValue.setColorProvider(new SysdynBasicColorProvider(new LocalResourceManager(JFaceResources.getResources(), maxValue.getWidget())));\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(maxValue.getWidget());\r
+        \r
+        return composite;\r
+    }\r
+\r
+    @Override\r
+    public void getCachedValues(HashMap<String, String> cahcedValues) {\r
+        cahcedValues.put(SensitivityDistributionKeys.MIN, minValue.getText());\r
+        cahcedValues.put(SensitivityDistributionKeys.MAX, maxValue.getText());\r
+    }\r
+\r
+\r
+\r
+    @Override\r
+    public void applyCache(WriteGraph graph, HashMap<String, String> cachedValues) throws DatabaseException {\r
+        if(resource == null)\r
+            return;\r
+        \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        String min = cachedValues.get(SensitivityDistributionKeys.MIN);\r
+        if(min != null) {\r
+            try {\r
+                Double d = Double.parseDouble(min);\r
+                graph.claimLiteral(resource, SR.UniformDistribution_minValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+        \r
+        String max = cachedValues.get(SensitivityDistributionKeys.MAX);\r
+        if(max != null) {\r
+            try {\r
+                Double d = Double.parseDouble(max);\r
+                graph.claimLiteral(resource, SR.UniformDistribution_maxValue, d, Bindings.DOUBLE);\r
+            } catch (NumberFormatException e) {}\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/sensitivity/VariableNameModifier.java
new file mode 100644 (file)
index 0000000..eaac45d
--- /dev/null
@@ -0,0 +1,121 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.properties.widgets.sensitivity;\r
+\r
+import org.eclipse.jface.bindings.keys.KeyStroke;\r
+import org.eclipse.jface.bindings.keys.ParseException;\r
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;\r
+import org.eclipse.jface.fieldassist.IContentProposal;\r
+import org.eclipse.jface.fieldassist.IContentProposalListener;\r
+import org.eclipse.jface.fieldassist.IContentProposalListener2;\r
+import org.eclipse.jface.fieldassist.TextContentAdapter;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TextModifyListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.TrackedModifyEvent;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\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.jfreechart.chart.properties.VariableProposalProvider;\r
+\r
+public class VariableNameModifier extends TextModifyListenerImpl<Resource> {\r
+\r
+    private boolean active;\r
+    private Control control;\r
+    private String variableNameRelationUri;\r
+    private String indexUri;\r
+    \r
+    private char[] alphaNumericCharacters = {\r
+        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','Ã¥','ä','ö',\r
+        'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Ã…','Ä','Ö',\r
+        '1','2','3','4','5','6','7','8','9','0','.'};\r
+    \r
+        \r
+    public VariableNameModifier(Control control, WidgetSupport support, String variableNameRelationUri, String indexUri) {\r
+        this.variableNameRelationUri = variableNameRelationUri;\r
+        this.indexUri = indexUri;\r
+        \r
+        this.control = control;\r
+        this.active = true;\r
+        \r
+        KeyStroke keyStroke = null;\r
+        try {\r
+            keyStroke = KeyStroke.getInstance("Ctrl+Space");\r
+        } catch (ParseException e1) {\r
+            e1.printStackTrace();\r
+        }\r
+        \r
+        //SimpleContentProposalProvider scpp = new VariableProposalProvider(control, support);\r
+        VariableProposalProvider scpp = new VariableProposalProvider(control, support);\r
+        scpp.setFiltering(true);\r
+\r
+        ContentProposalAdapter adapter = new ContentProposalAdapter(\r
+                control, new TextContentAdapter(), scpp, keyStroke, alphaNumericCharacters);\r
+        adapter.setAutoActivationDelay(0);\r
+        adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);\r
+        adapter.addContentProposalListener(new IContentProposalListener2() {\r
+\r
+            @Override\r
+            public void proposalPopupOpened(ContentProposalAdapter adapter) {\r
+                if(VariableNameModifier.this != null)\r
+                    VariableNameModifier.this.deactivate();\r
+            }\r
+\r
+            @Override\r
+            public void proposalPopupClosed(ContentProposalAdapter adapter) {\r
+                if(VariableNameModifier.this != null)\r
+                    VariableNameModifier.this.activate();\r
+            }\r
+        });\r
+\r
+        adapter.addContentProposalListener(new IContentProposalListener() {\r
+\r
+            @Override\r
+            public void proposalAccepted(IContentProposal proposal) {\r
+                if(VariableNameModifier.this.control != null && !VariableNameModifier.this.control.isDisposed())\r
+                    VariableNameModifier.this.modifyText(new TrackedModifyEvent(VariableNameModifier.this.control, proposal.getContent()));\r
+            }\r
+        });\r
+    \r
+    \r
+    }\r
+    \r
+\r
+    @Override\r
+    public void applyText(WriteGraph graph, Resource resource, String text) throws DatabaseException {\r
+        if(active) {\r
+            graph.claimLiteral(resource, getVariableNameRelation(graph), text, Bindings.STRING);\r
+            graph.deny(resource, getIndexRelation(graph));\r
+        } else {\r
+            System.out.println("NÄHÄÄ");\r
+        }\r
+    }\r
+    \r
+    private Resource getVariableNameRelation(ReadGraph graph) throws DatabaseException {\r
+        return graph.getResource(variableNameRelationUri);\r
+    }\r
+    \r
+    private Resource getIndexRelation(ReadGraph graph) throws DatabaseException {\r
+        return graph.getResource(indexUri);\r
+    }\r
+\r
+    public void deactivate() {\r
+        active = false;\r
+    }\r
+\r
+    public void activate() {\r
+        active = true;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Dependencies.java
new file mode 100644 (file)
index 0000000..02e052d
--- /dev/null
@@ -0,0 +1,113 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CTabFolder;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionAdapter;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.layout.RowLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Spinner;\r
+import org.simantics.db.Resource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class Dependencies extends StructureTabItem {\r
+    \r
+    private boolean isInverted = false;\r
+    private Button bButton, fButton;\r
+    private int levels = 3;\r
+\r
+    private static int MAXLEVELS = 4;\r
+    private static int MINLEVELS = 1;\r
+\r
+    public Dependencies(CTabFolder parent, int style) {\r
+        super(parent, style);\r
+        \r
+        Label line = new Label(structureComposite, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(line);\r
+        \r
+        Composite composite = new Composite(structureComposite, SWT.NONE);\r
+        RowLayout layout = new RowLayout();\r
+        layout.center = true;\r
+        composite.setLayout(layout);\r
+\r
+        Label label = new Label(composite, SWT.NONE);\r
+        label.setText("Direction: ");\r
+\r
+        bButton = new Button(composite, SWT.RADIO);\r
+        bButton.setText("Backward");\r
+        bButton.setSelection(true);\r
+        bButton.addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent event) {\r
+                if(bButton.getSelection())\r
+                    isInverted = false;\r
+                else \r
+                    isInverted = true;\r
+                if(currentSelection != null) {\r
+                    readGraph(currentSelection);\r
+                }\r
+            }\r
+        });\r
+\r
+        fButton = new Button(composite, SWT.RADIO);\r
+        fButton.setText("Forward");\r
+\r
+        label = new Label(composite, SWT.NONE);\r
+        label.setText("Steps: ");\r
+\r
+        Spinner spinner = new Spinner(composite, SWT.BORDER);\r
+        spinner.setMaximum(MAXLEVELS);\r
+        spinner.setMinimum(MINLEVELS);\r
+        spinner.setTextLimit(1);\r
+        spinner.setSelection(levels);\r
+\r
+        spinner.addModifyListener(new ModifyListener() {\r
+\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                Spinner s = (Spinner)e.widget;\r
+                int lvls = Integer.parseInt(s.getText());\r
+                if(lvls > MAXLEVELS)\r
+                    levels = MAXLEVELS;\r
+                else if (lvls < MINLEVELS)\r
+                    levels = MINLEVELS;\r
+                levels = lvls;\r
+                if(currentSelection != null) {\r
+                    readGraph(currentSelection);\r
+                }\r
+\r
+            }\r
+        });\r
+        \r
+        this.setText("Dependencies");\r
+        this.setControl(structureComposite);\r
+    }\r
+\r
+    protected void readGraph(Resource resource) {\r
+        if(graphListener != null)\r
+            graphListener.dispose();\r
+        \r
+        graphListener = new GraphListener();\r
+        SimanticsUI.getSession().asyncRequest(new DependencyGraphRequest(\r
+                resource, levels, isInverted), graphListener);\r
+    }\r
+\r
+    protected String getJobLabel() {\r
+       return "Loading dependencies graph";\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/DependencyGraphRequest.java
new file mode 100644 (file)
index 0000000..2907559
--- /dev/null
@@ -0,0 +1,192 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+\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.graphviz.Edge;\r
+import org.simantics.graphviz.Graph;\r
+import org.simantics.graphviz.IGraph;\r
+import org.simantics.graphviz.Node;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Builds a graph of the dependencies of a selected variable\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class DependencyGraphRequest implements Read<Graph> {\r
+\r
+       protected Resource root;\r
+       protected HashMap<Resource, Node> nodes;\r
+       protected boolean isInverted;\r
+       protected int levels;\r
+\r
+       /**\r
+        * Builds a graph of the dependencies of a selected variable\r
+        * \r
+        * @param root Variable from which to find dependencies\r
+        * @param levels How many steps of dependencies are calculated from the variable\r
+        * @param isInverted true => variables that affect root; false => variables that are affected by root \r
+        */\r
+       public DependencyGraphRequest(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
+\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
+                       setRoot(g, graph, root);\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(setDependencies(g, graph, r));\r
+                               }\r
+                               resources = new ArrayList<Resource>(newResources);\r
+                       }\r
+               }\r
+               return graph;\r
+       }\r
+\r
+       /**\r
+        * Create a root node and set appearance settings for it\r
+        * @param g ReadGraph\r
+        * @param graph Graphviz graph\r
+        * @param root Root resource\r
+        * @throws DatabaseException\r
+        */\r
+       protected void setRoot(ReadGraph g, IGraph graph, Resource root) throws DatabaseException {\r
+               Node n;\r
+               n = new Node(graph, getName(g, root));\r
+               setShape(g, root, n);\r
+               n.set("style", "filled");\r
+               n.setFillColor("#d3d3d3");\r
+               nodes.put(root, n);\r
+       }\r
+\r
+\r
+       /**\r
+        * Call for calculating  \r
+        * @param g\r
+        * @param graph\r
+        * @param r\r
+        * @param toDependency\r
+        * @param fromDependency\r
+        * @param connectionType\r
+        * @return\r
+        * @throws DatabaseException\r
+        */\r
+       private Collection<Resource> getDependants(ReadGraph g, IGraph graph, Resource r, Resource toDependency, Resource fromDependency, Resource connectionType) throws DatabaseException {\r
+               SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+               Collection<Resource> dependencies = g.syncRequest(new ObjectsWithType(r, toDependency, connectionType));\r
+\r
+               Collection<Resource> dependants = new ArrayList<Resource>();\r
+               Node n;\r
+               for(Resource d : dependencies) {\r
+                       Resource dependant = g.getPossibleObject(d, fromDependency);\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
+                       }\r
+\r
+                       if(isInverted) {\r
+                               new Edge(graph, nodes.get(r), nodes.get(dependant));\r
+                       } else {\r
+                               new Edge(graph, nodes.get(dependant), nodes.get(r));\r
+                       }\r
+               }\r
+               return dependants;\r
+       }\r
+       \r
+       private Collection<Resource> setDependencies(ReadGraph g, IGraph graph, Resource r) throws DatabaseException{\r
+               SysdynResource sr = SysdynResource.getInstance(g);\r
+\r
+               // stop here if element is a module\r
+               if (g.isInstanceOf(r, sr.Module))\r
+                       return Collections.emptyList();\r
+\r
+               Collection<Resource> dependants;\r
+               if(isInverted) {\r
+                   dependants = getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Dependency);\r
+                   if (g.isInstanceOf(r, sr.Valve)) {\r
+                       dependants.addAll(getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Flow));\r
+                       dependants.addAll(getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Flow));\r
+                   }\r
+               } else {\r
+                   dependants = getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Dependency);\r
+                   if (g.isInstanceOf(r, sr.Stock)) {\r
+                       dependants.addAll(getDependants(g, graph, r, sr.Variable_isTailOf, sr.Variable_HasHead, sr.Flow));\r
+                       dependants.addAll(getDependants(g, graph, r, sr.Variable_isHeadOf, sr.Variable_HasTail, sr.Flow));\r
+                   }\r
+               }\r
+\r
+               return dependants;\r
+       }\r
+       \r
+       /**\r
+        * Set shape for a node. Rectangle for stocks, ellipse for auxiliaries and rounded rectangle for modules. \r
+        * @param g ReadGraph\r
+        * @param r Resource\r
+        * @param n Node\r
+        * @throws DatabaseException\r
+        */\r
+       protected 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
+                       n.setStyle("rounded"); \r
+               }\r
+               else\r
+                       n.setShape("ellipse");\r
+       }\r
+\r
+       protected String getName(ReadGraph g, Resource r) throws DatabaseException {\r
+               return (String)g.getRelatedValue(r, Layer0.getInstance(g).HasName);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/LoopGraphRequest.java
new file mode 100644 (file)
index 0000000..6063be5
--- /dev/null
@@ -0,0 +1,125 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\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.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
+import org.simantics.sysdyn.utils.LoopUtils;\r
+import org.simantics.utils.datastructures.MapList;\r
+\r
+/**\r
+ * Builds a graph of the loops of a selected variable\r
+ * \r
+ * @author Tuomas Miettinen\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class LoopGraphRequest extends DependencyGraphRequest {\r
+\r
+       MapList<Resource, Edge> edges;\r
+\r
+       /**\r
+        * Builds a graph of the dependencies of a selected variable\r
+        * \r
+        * @param root Variable from which to find dependencies\r
+        * @param levels How many steps of dependencies are calculated from the variable\r
+        * @param isInverted true => variables that affect root; false => variables that are affected by root \r
+        */\r
+       public LoopGraphRequest(Resource root) {\r
+               super(root, 999, false);\r
+       }\r
+\r
+       @Override\r
+       public Graph perform(ReadGraph g) throws DatabaseException {\r
+\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
+                       // Get ALL loops in the diagram in which the root exists.\r
+                       List<List<Resource>> loops = LoopUtils.getLoops(g, root);\r
+                       setRoot(g, graph, root);\r
+                       \r
+                       // Add the edges to the graph.\r
+                       edges = new MapList<Resource, Edge>();\r
+                       for (List<Resource> loop : loops) {\r
+                               Resource prev = null;\r
+                               for (Resource r : loop) {\r
+                                       // Add node if not already added.\r
+                                       if(!nodes.containsKey(r)) {\r
+                                               Node n = new Node(graph, getName(g, r));\r
+                                               setShape(g, r, n);\r
+                                               nodes.put(r, n);\r
+                                       }\r
+                                       // Add edge if not already added.\r
+                                       if (prev != null)\r
+                                               claimEdge(g, graph, prev, r);\r
+                                       \r
+                                       prev = r;\r
+                               }\r
+                               // Add edge between the last and first node in the loop.\r
+                               if (prev != null && loop.get(0) != null)\r
+                                       claimEdge(g, graph, prev, loop.get(0));\r
+                       }\r
+               }\r
+               return graph;\r
+       }\r
+\r
+       /**\r
+        * Create and edge between _tail and _head nodes. If the edge already exists, do nothing.\r
+        * If an opposite direction edge exists, draw an arrow also to the tail of the edge.\r
+        * @param g \r
+        * @param graph Graph in which the nodes lie.\r
+        * @param tail The tail node.\r
+        * @param head The head node.\r
+        * @throws DatabaseException \r
+        */\r
+       private void claimEdge(ReadGraph g, IGraph graph, Resource tail, Resource head) throws DatabaseException {\r
+               // If edge exists, increase the size of the arrowhead and return.\r
+               for (Edge e : edges.getValues(tail)) {\r
+                       if (((Node)e.getHead()).get("label").equals(getName(g, head))) {\r
+                               // Change the size of the arrowhead (fancily :-)\r
+                               String arrowsize = e.get("arrowsize");\r
+                               if (arrowsize == null)\r
+                                       arrowsize = "1.0";\r
+                               e.setArrowsize(Math.min(2.2, Math.sqrt(Double.valueOf(arrowsize) + 0.8)));\r
+                               return;\r
+                       }\r
+               }\r
+\r
+               for (Edge e : edges.getValues(head)) { // Seek for opposite edges\r
+                       if (((Node)e.getHead()).get("label").equals(getName(g, tail))) {\r
+                               e.setDir("both");\r
+                               return;\r
+                       }\r
+               }\r
+               \r
+               // If no edge has been found, add one. \r
+               edges.add(tail, new Edge(graph, nodes.get(tail), nodes.get(head)));\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/Loops.java
new file mode 100644 (file)
index 0000000..798b504
--- /dev/null
@@ -0,0 +1,44 @@
+/*******************************************************************************\r
+ * Copyright (c) 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import org.eclipse.swt.custom.CTabFolder;\r
+import org.simantics.db.Resource;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Tab for loops.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class Loops extends StructureTabItem {\r
+\r
+    public Loops(CTabFolder parent, int style) {\r
+        super(parent, style);\r
+        this.setText("Loops");\r
+        this.setControl(structureComposite);\r
+    }\r
+\r
+    protected void readGraph(Resource resource) {\r
+        if(graphListener != null)\r
+            graphListener.dispose();\r
+        \r
+        graphListener = new GraphListener();\r
+        SimanticsUI.getSession().asyncRequest(new LoopGraphRequest(\r
+                resource), graphListener);\r
+    }\r
+\r
+    protected String getJobLabel() {\r
+       return "Loading loops graph";\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructure.java
new file mode 100644 (file)
index 0000000..c3b2799
--- /dev/null
@@ -0,0 +1,135 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CTabFolder;\r
+import org.eclipse.swt.custom.CTabItem;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.graphviz.Graph;\r
+import org.simantics.graphviz.ui.GraphvizComponent;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.RunnableWithObject;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Tab for displaying hierarchical model structure\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleStructure extends CTabItem {\r
+\r
+    private GraphvizComponent component;\r
+    private GraphListener graphListener;\r
+\r
+    \r
+    public ModuleStructure(CTabFolder parent, int style) {\r
+        super(parent, style);\r
+        \r
+        Composite moduleStructure = new Composite(parent, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(moduleStructure);\r
+        GridLayoutFactory.fillDefaults().applyTo(moduleStructure);\r
+\r
+        component = new GraphvizComponent(moduleStructure, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
+        \r
+        this.setText("Model Hierarchy");\r
+        this.setControl(moduleStructure);\r
+\r
+    }\r
+\r
+    /**\r
+     * Draw a graph about the model of the selected resource\r
+     * @param selection\r
+     */\r
+    public void drawSelection(ISelection selection) {\r
+        if(selection == null || selection.isEmpty())\r
+            return;\r
+\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
+                    // Read graph for the resource\r
+                    if(graphListener != null)\r
+                        graphListener.dispose(); // Dispose possible previous listener\r
+                    \r
+                    graphListener = new GraphListener();\r
+                    SimanticsUI.getSession().asyncRequest(new ModuleStructureGraphRequest(r), graphListener);\r
+                }\r
+            }\r
+        }           \r
+    }\r
+    \r
+    /**\r
+     * Listener for updating hierarchical model graph\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class GraphListener implements Listener<Graph> {\r
+        private boolean disposed = false;\r
+        \r
+        public void dispose() {\r
+            disposed = true;\r
+        }\r
+        \r
+        @Override\r
+        public void exception(Throwable e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        @Override\r
+        public void execute(final Graph graph) {\r
+            Job job = new Job("Loading model structure graph") {\r
+\r
+                @Override\r
+                protected IStatus run(IProgressMonitor monitor) {\r
+                    if(!isDisposed()) {\r
+                        component.getDisplay().asyncExec(new RunnableWithObject(graph) {\r
+                            \r
+                            @Override\r
+                            public void run() {\r
+                                if (component.isDisposed()) return;\r
+                                component.setGraph((Graph)getObject(), "dot");\r
+                                component.fit();    \r
+                            }\r
+                        });\r
+                     \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
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/ModuleStructureGraphRequest.java
new file mode 100644 (file)
index 0000000..c32a300
--- /dev/null
@@ -0,0 +1,148 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.utils.NameUtils;\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.Node;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Builds a graph about the modular structure of the model where a selected object is located.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ModuleStructureGraphRequest implements Read<Graph> {\r
+\r
+    private Resource resource;\r
+\r
+    /**\r
+     * Request a hierarchical graph about the model of resource\r
+     * @param resource\r
+     */\r
+    public ModuleStructureGraphRequest(Resource resource) {\r
+        this.resource = resource;\r
+    }\r
+\r
+    @Override\r
+    public Graph perform(ReadGraph graph) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+        Graph g = new Graph();\r
+        g.setRankdir("TB");\r
+\r
+        // Find model resource, the root of this\r
+        Resource model = resource;\r
+        while(model != null && !graph.isInstanceOf(model, sr.SysdynModel)) {\r
+            model = graph.getPossibleObject(model, l0.PartOf);\r
+        }\r
+\r
+        // Model root was not found, return empty graph\r
+        if(model == null)\r
+            return g;\r
+        \r
+        // Find the parent module/model of the selected resource\r
+        Resource parentResource = graph.getPossibleObject(resource, l0.PartOf);\r
+        if(graph.isInstanceOf(parentResource, sr.ConfigurationDiagram)) {\r
+               parentResource = graph.getPossibleObject(parentResource, ModelingResources.getInstance(graph).DiagramToComposite);\r
+        } else if(graph.isInstanceOf(parentResource, sr.SysdynModel)) {\r
+               parentResource = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
+        }\r
+\r
+        // Set root node\r
+        Node rootNode = new Node(g, NameUtils.getSafeLabel(graph, model));\r
+        rootNode.setShape("rectangle");\r
+        HashSet<Resource> visited = new HashSet<Resource>();\r
+        visited.add(model);\r
+        findChildModules(g, rootNode, graph, model, parentResource, visited);\r
+\r
+\r
+        return g;\r
+    }\r
+\r
+    /**\r
+     * Recursive call for finding child modules \r
+     * @param g GraphViz graph\r
+     * @param parent Parent module or model\r
+     * @param graph ReadGraph\r
+     * @param resource Module type or model\r
+     * @param parent2 \r
+     * @param visited All visited modules. Needed to check for loops in the structure. Loops are not allowed.\r
+     * @throws DatabaseException\r
+     */\r
+    private void findChildModules(Graph g, Node parent, ReadGraph graph, Resource resource, Resource parentResource, HashSet<Resource> visited) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+        Resource configuration = graph.syncRequest(new PossibleObjectWithType(resource, l0.ConsistsOf, sr.Configuration));\r
+\r
+        // Set the parent color different, if it is the parent of the selected resource\r
+        if(configuration.equals(parentResource))\r
+               parent.setColor("#ff8c00");\r
+        \r
+        HashMap<Resource, Integer> modules = new HashMap<Resource, Integer>();\r
+\r
+        // Find all module children\r
+        for(Resource m : graph.getObjects(configuration, l0.ConsistsOf)) {\r
+            Resource type = graph.getPossibleObject(m, l0.InstanceOf);\r
+            if(graph.isInheritedFrom(type, sr.Module)) {\r
+                if(!modules.containsKey(type))\r
+                    modules.put(type, 0);\r
+                modules.put(type, modules.get(type) + 1);\r
+            }\r
+        }\r
+\r
+        // Display module children in graph\r
+        for(Resource type : modules.keySet()) {\r
+\r
+            Node node = new Node(g, NameUtils.getSafeName(graph, type));\r
+            node.setShape("rectangle");\r
+            Edge edge = new Edge(g, parent, node);\r
+            edge.set("labeldistance", "1.5");\r
+            edge.set("labelfontsize", "7");\r
+            edge.setFontColor("#4f4f4f");\r
+            if(modules.get(type) > 1)\r
+                edge.setHeadLabel(modules.get(type).toString());\r
+            \r
+            if(visited.contains(type)) {\r
+                // Found a loop. Stop recursive call and display error.\r
+                edge.setFontColor("#FF0000");\r
+                edge.setColor("#FF000");\r
+                edge.setLabel("Error: loop");\r
+                node.setColor("#FF0000");\r
+                node.setFontColor("#FF0000");\r
+                continue;\r
+            } else {\r
+               HashSet<Resource> copy = new HashSet<Resource>(visited);\r
+               copy.add(type);\r
+                findChildModules(g, node, graph, type, parentResource, copy);\r
+            }\r
+            \r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureTabItem.java
new file mode 100644 (file)
index 0000000..ceadd9d
--- /dev/null
@@ -0,0 +1,115 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CTabFolder;\r
+import org.eclipse.swt.custom.CTabItem;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.graphviz.Graph;\r
+import org.simantics.graphviz.ui.GraphvizComponent;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Super class for certain kinds of structure tabs.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public abstract class StructureTabItem extends CTabItem {\r
+    \r
+    protected GraphvizComponent component;\r
+    protected GraphListener graphListener;\r
+    protected Composite structureComposite;\r
+    protected Resource currentSelection;\r
+    \r
+    public StructureTabItem(CTabFolder parent, int style) {\r
+        super(parent, style);\r
+        \r
+        structureComposite = new Composite(parent, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(structureComposite);\r
+        GridLayoutFactory.fillDefaults().spacing(0,0).applyTo(structureComposite);\r
+\r
+        component = new GraphvizComponent(structureComposite, SWT.NONE);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(component);\r
+    }\r
+\r
+\r
+    public void drawSelection(ISelection selection) {\r
+        if(selection == null || selection.isEmpty())\r
+            return;\r
+        if(selection instanceof IStructuredSelection) {                    \r
+            Object[] els = ((IStructuredSelection) selection).toArray();\r
+            if(els.length == 1) {\r
+                Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
+                if(ress.isEmpty()) return;\r
+                Resource r = (ress.toArray(Resource.NONE))[0];\r
+                if(r != null && !r.equals(currentSelection)) {\r
+                    currentSelection = r;\r
+                    readGraph(currentSelection);\r
+                }\r
+            }\r
+        }           \r
+    }\r
+\r
+    abstract protected void readGraph(Resource resource);\r
+\r
+    class GraphListener implements Listener<Graph> {\r
+        \r
+        private boolean disposed = false;\r
+        \r
+        public void dispose() {\r
+            disposed = true;\r
+        }\r
+        \r
+        @Override\r
+        public void exception(Throwable e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        @Override\r
+        public void execute(final Graph graph) {\r
+            Job job = new Job(getJobLabel()) {\r
+\r
+                @Override\r
+                protected IStatus run(IProgressMonitor monitor) {\r
+                    if(!isDisposed()) {\r
+                        component.setGraph(graph, "dot");\r
+                        component.fit();                            \r
+                    }\r
+                    return Status.OK_STATUS;\r
+                }\r
+            };\r
+            job.schedule();\r
+        }\r
+\r
+        @Override\r
+        public boolean isDisposed() {\r
+            return disposed;\r
+        }\r
+    }\r
+    \r
+    protected String getJobLabel() {\r
+       return "Loading dependencies graph";\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/structure/StructureView.java
new file mode 100644 (file)
index 0000000..39dc59d
--- /dev/null
@@ -0,0 +1,132 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.structure;\r
+\r
+import 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.custom.CTabFolder;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\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
+\r
+/**\r
+ * View for displaying different types of structural visualizations\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class StructureView extends ViewPart {\r
+\r
+    private CTabFolder tabFolder;\r
+    private ISelectionListener selectionListener;\r
+    private StructureTabItem dependencies;\r
+    private ModuleStructure moduleStructure;\r
+    private Loops loops;\r
+    \r
+    @Override\r
+    public void createPartControl(Composite parent) {\r
+        tabFolder = new CTabFolder(parent, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(tabFolder);\r
+        GridLayoutFactory.fillDefaults().applyTo(tabFolder);\r
+\r
+        final ISelection currentSeletion = getSite().getWorkbenchWindow().getSelectionService().getSelection();\r
+        \r
+        // Dependencies\r
+        dependencies = new Dependencies(tabFolder, SWT.NONE);\r
+        dependencies.drawSelection(currentSeletion);\r
+        \r
+        // Hierarchical model structure\r
+        moduleStructure = new ModuleStructure(tabFolder, SWT.NONE);\r
+\r
+        // Loops\r
+        loops = new Loops(tabFolder, SWT.NONE);\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
+        // Listener for refreshing module structure visualization on first loading\r
+        tabFolder.addSelectionListener(new SelectionListener() {\r
+            \r
+            private boolean openedOnce = false;\r
+            \r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                if(!openedOnce && e.item.equals(moduleStructure)) {\r
+                    openedOnce = true;\r
+                    moduleStructure.drawSelection(currentSeletion);\r
+                }\r
+            }\r
+            \r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+        \r
+        // Listener for refreshing module structure visualization on first loading\r
+        tabFolder.addSelectionListener(new SelectionListener() {\r
+            \r
+            private boolean openedOnce = false;\r
+            \r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                if(!openedOnce && e.item.equals(loops)) {\r
+                    openedOnce = true;\r
+                    loops.drawSelection(currentSeletion);\r
+                }\r
+            }\r
+            \r
+            @Override\r
+            public void widgetDefaultSelected(SelectionEvent e) {\r
+            }\r
+        });\r
+    }\r
+    \r
+    /**\r
+     * Draw structural visualizations for selected object(s)\r
+     * \r
+     * @param selection Current selection\r
+     */\r
+    private void drawSelection(ISelection selection) {\r
+        dependencies.drawSelection(selection);\r
+        moduleStructure.drawSelection(selection);\r
+        loops.drawSelection(selection);\r
+    }\r
+    \r
+\r
+    @Override\r
+    public void setFocus() {\r
+        if(tabFolder != null && !tabFolder.isDisposed()) {\r
+            tabFolder.setFocus();\r
+        }\r
+    }\r
+\r
+\r
+    @Override\r
+    public void dispose() {\r
+        super.dispose();\r
+        getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllParametersOfModel.java
new file mode 100644 (file)
index 0000000..de84ecf
--- /dev/null
@@ -0,0 +1,132 @@
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.jfreechart.chart.properties.ChartVariable;\r
+import org.simantics.jfreechart.chart.properties.IAllVariablesOfModel;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.Variability;\r
+\r
+/**\r
+ * Request for getting all variables of a model in a String array. Includes also \r
+ * variables inside modules.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class AllParametersOfModel implements IAllVariablesOfModel {\r
+    \r
+    protected final Resource model;\r
+    \r
+    public AllParametersOfModel(Resource model) {\r
+        this.model = model;\r
+    }\r
+\r
+       @Override\r
+       public Read<Collection<ChartVariable>> getVariablesQuery() {\r
+               return new VariableQuery();\r
+       }   \r
+       \r
+       \r
+    private class VariableQuery implements Read<Collection<ChartVariable>> {\r
+        @Override\r
+           public Collection<ChartVariable> perform(ReadGraph graph) throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SimulationResource simu = SimulationResource.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               List<ChartVariable> result = new ArrayList<ChartVariable>();\r
+               // Find the model of this resource\r
+               Resource model = AllParametersOfModel.this.model;\r
+               while(model != null && !graph.isInstanceOf(model, sr.SysdynModel))\r
+                   model = graph.getPossibleObject(model, l0.PartOf);\r
+               \r
+               if(model == null)\r
+                   return result;\r
+               \r
+               // Find the models configuration\r
+               Resource conf = graph.getSingleObject(model, simu.HasConfiguration);\r
+              \r
+               // Recursively read all configurations and add items\r
+               ReadConfiguration(graph, conf, "", result);\r
+                               \r
+               // Finally sort the results\r
+               Collections.sort(result, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               return result;\r
+           }\r
+    }\r
+    \r
+    \r
+    \r
+    /**\r
+     * Read components in a configuration and recursively all module configurations\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param configuration Resource to be read\r
+     * @param path Current path from base realization\r
+     * @param items Found variables\r
+     * @throws DatabaseException\r
+     */\r
+    private void ReadConfiguration(ReadGraph graph, Resource configuration, String path, Collection<ChartVariable> items) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+\r
+        SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+        SysdynModel sm = sdm.getModel(graph, configuration);\r
+        try {\r
+            sm.update(graph);\r
+        } catch (DatabaseException e1) {\r
+            e1.printStackTrace();\r
+        }\r
+        \r
+        String name;\r
+        for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.IndependentVariable))) {\r
+            name = path + NameUtils.getSafeName(graph, resource);\r
+            IElement element = sm.getElement(resource);\r
+            if (element instanceof IndependentVariable) {\r
+               IndependentVariable variable = (IndependentVariable)element; \r
+               Variability variability = Variability.getVariability(variable, false, null);\r
+               if (variability == Variability.PARAMETER) {\r
+                       items.add(new ChartVariable(name, name));\r
+               }\r
+            }\r
+        }\r
+        \r
+        for(Resource module : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) {\r
+            Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf);\r
+            Resource conf = graph.getPossibleObject(instanceOf, sr2.IsDefinedBy);\r
+            if(conf != null) {\r
+                String p = path + NameUtils.getSafeName(graph, module)  + ".";\r
+                ReadConfiguration(graph, conf, p, items);\r
+            }\r
+        }\r
+    }\r
+       \r
+       @Override\r
+    public String getVariablesLabel(ReadGraph graph, String variableId)\r
+                       throws DatabaseException {\r
+                  return variableId.substring(1).replace('/', '.');\r
+       }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/AllVariablesOfModel.java
new file mode 100644 (file)
index 0000000..241b7cb
--- /dev/null
@@ -0,0 +1,120 @@
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.jfreechart.chart.properties.ChartVariable;\r
+import org.simantics.jfreechart.chart.properties.IAllVariablesOfModel;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+/**\r
+ * Request for getting all variables of a model in a String array. Includes also \r
+ * variables inside modules.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class AllVariablesOfModel implements IAllVariablesOfModel{\r
+    \r
+    private final Resource model;\r
+    \r
+    public AllVariablesOfModel(Resource model) {\r
+        this.model = model;\r
+    }\r
+\r
+       @Override\r
+       public Read<Collection<ChartVariable>> getVariablesQuery() {\r
+               return new VariableQuery();\r
+       }   \r
+       \r
+       \r
+       @Override\r
+    public String getVariablesLabel(ReadGraph graph, String variableId)\r
+                       throws DatabaseException {\r
+                  return variableId.substring(1).replace('/', '.');\r
+       }\r
+    \r
+    private class VariableQuery implements Read<Collection<ChartVariable>> {\r
+        @Override\r
+           public Collection<ChartVariable> perform(ReadGraph graph) throws DatabaseException {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SimulationResource simu = SimulationResource.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               List<ChartVariable> result = new ArrayList<ChartVariable>();\r
+               // Find the model of this resource\r
+               Resource model = AllVariablesOfModel.this.model;\r
+               while(model != null && !graph.isInstanceOf(model, sr.SysdynModel))\r
+                   model = graph.getPossibleObject(model, l0.PartOf);\r
+               \r
+               if(model == null)\r
+                   return result;;\r
+               \r
+               // Find the models configuration\r
+               Resource conf = graph.getSingleObject(model, simu.HasConfiguration);\r
+              \r
+               \r
+               // Recursively read all configurations and add items\r
+               ReadConfiguration(graph, conf, "", result);\r
+               \r
+               // Add time to the variable list\r
+               result.add(new ChartVariable("time", "time"));\r
+               \r
+               // Finally sort the results\r
+               Collections.sort(result, AlphanumComparator.CASE_INSENSITIVE_COMPARATOR);\r
+               return result;\r
+           }\r
+    }\r
+    \r
+    \r
+    \r
+    /**\r
+     * Read components in a configuration and recursively all module configurations\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param configuration Resource to be read\r
+     * @param path Current path from base realization\r
+     * @param items Found variables\r
+     * @throws DatabaseException\r
+     */\r
+    private void ReadConfiguration(ReadGraph graph, Resource configuration, String path, Collection<ChartVariable> items) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+\r
+        String name;\r
+        for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.IndependentVariable))) {\r
+            name = path + NameUtils.getSafeName(graph, resource);\r
+            items.add(new ChartVariable(name, name));\r
+        }\r
+        \r
+        for(Resource resource : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Input))) {\r
+            name = path + NameUtils.getSafeName(graph, resource);\r
+            items.add(new ChartVariable(name, name));\r
+        }\r
+\r
+        for(Resource module : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) {\r
+            Resource instanceOf = graph.getPossibleObject(module, l0.InstanceOf);\r
+            Resource conf = graph.getPossibleObject(instanceOf, sr2.IsDefinedBy);\r
+            if(conf != null) {\r
+                String p = path + NameUtils.getSafeName(graph, module)  + ".";\r
+                ReadConfiguration(graph, conf, p, items);\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
+\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/CategoryDataset.java
new file mode 100644 (file)
index 0000000..4a5f80f
--- /dev/null
@@ -0,0 +1,315 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.jfree.chart.plot.DefaultDrawingSupplier;\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.chart.renderer.category.BarRenderer;\r
+import org.jfree.data.category.DefaultCategoryDataset;\r
+import org.jfree.data.general.Dataset;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.request.PossibleActiveExperiment;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.jfreechart.chart.AbstractDataset;\r
+import org.simantics.jfreechart.chart.IRenderer;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.adapter.VariableRVIUtils;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Class representing a JFreeChart.CategoryDataset\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class CategoryDataset extends AbstractDataset implements org.simantics.jfreechart.chart.CategoryDataset{\r
+\r
+    private List<Resource> seriesList;\r
+    private String realizationURI;\r
+    private IRenderer renderer;\r
+    private DefaultCategoryDataset dataset;\r
+\r
+    public CategoryDataset(ReadGraph graph, Resource resource) throws DatabaseException  {\r
+        super(graph, resource);\r
+\r
+       \r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+            // Find the model where the chart is located\r
+            Resource model = resource;\r
+            do {\r
+                model = graph.getPossibleObject(model, l0.PartOf);\r
+            } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel));\r
+\r
+            // Find the variable realization of the current experiment\r
+            realizationURI = null;\r
+            Resource realization = graph.syncRequest(new PossibleActiveExperiment(model));\r
+            if (realization == null) {\r
+                Layer0X L0X = Layer0X.getInstance(graph);\r
+                realization = graph.getPossibleObject(model, L0X.HasBaseRealization);\r
+            }\r
+            if (realization != null)\r
+                realizationURI = graph.getURI(realization);\r
+\r
+            if(realizationURI == null)\r
+                return; // No experiment -> No results\r
+\r
+            Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList);\r
+            if(seriesList != null)\r
+                this.seriesList = ListUtils.toList(graph, seriesList);\r
+\r
+            Resource rendererResource = graph.getPossibleObject(resource, jfree.Dataset_renderer);\r
+            renderer = graph.adapt(rendererResource, IRenderer.class);\r
+\r
+       \r
+    }\r
+\r
+    private DatasetListener listener;\r
+\r
+    @Override\r
+    public Dataset getDataset() {\r
+\r
+        if(seriesList == null || seriesList.isEmpty() || SimanticsUI.getSession() == null)\r
+            return null;\r
+\r
+        if(dataset == null) {\r
+            dataset = new DefaultCategoryDataset();\r
+        }\r
+\r
+        if(listener == null || listener.isDisposed()) {\r
+            listener = new DatasetListener();\r
+            SimanticsUI.getSession().asyncRequest(new Read<ArrayList<TempSeries>>() {\r
+\r
+                @Override\r
+                public ArrayList<TempSeries> perform(ReadGraph graph) throws DatabaseException {\r
+                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                    ArrayList<TempSeries> series = new ArrayList<TempSeries>();\r
+                    // Get properties for all series\r
+                    if(seriesList != null) {\r
+                        for(Resource r : seriesList) {\r
+                            String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI);\r
+                            if(rvi == null)\r
+                                continue;\r
+\r
+                            try {\r
+                                // Get a variable for the series\r
+                                Variable v = Variables.getVariable(graph, realizationURI + rvi);\r
+                                // Get values\r
+                                Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#");\r
+                                if(dsVariable == null)\r
+                                       return series;\r
+                                \r
+                                Object object = dsVariable.getValue(graph);\r
+                                \r
+                                if(object == null || !(object instanceof ArrayList<?>))\r
+                                    return series;\r
+\r
+                                ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+\r
+                                for(Object o : (ArrayList<?>)object) {\r
+                                    if(o instanceof SysdynDataSet)\r
+                                        datasets.add((SysdynDataSet)o);\r
+                                }\r
+\r
+                                String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter);\r
+                                if(filter != null) {\r
+                                    ArrayList<SysdynDataSet> result2 = VariableRVIUtils.getDataset(datasets, filter);\r
+                                    if(result2 != null) {\r
+                                        datasets = result2;\r
+                                    }\r
+                                }\r
+\r
+                                // Find if a specific time is set for this chart\r
+                                Double chartTime = null;\r
+                                if(!datasets.isEmpty()) {\r
+                                    Layer0 l0 = Layer0.getInstance(graph);\r
+                                    Resource datasetResource = graph.getPossibleObject(r, l0.PartOf);\r
+                                    if(datasetResource != null) {\r
+                                        Resource plot = graph.getPossibleObject(datasetResource, l0.PartOf);\r
+                                        if(plot != null) {\r
+                                            Resource chart = graph.getPossibleObject(plot, l0.PartOf);\r
+                                            if(chart != null)\r
+                                                chartTime = graph.getPossibleRelatedValue(chart, jfree.Chart_time);\r
+                                        }\r
+                                    }\r
+                                }\r
+\r
+                                for(SysdynDataSet dataset : datasets) {\r
+                                    double[] va = dataset.values;\r
+\r
+\r
+                                    if(va == null || va.length == 0)\r
+                                        continue;\r
+\r
+                                    /*\r
+                                     *  Time\r
+                                     *  \r
+                                     *  1. find time for the individual series.\r
+                                     *  2. find time for the whole chart\r
+                                     *  3. find simulation time\r
+                                     */\r
+                                    Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE);\r
+                                    if(time == null)\r
+                                        time = chartTime;\r
+                                    if(time == null) {\r
+                                        // Get a variable for the experiment run\r
+                                        Variable run = Variables.getVariable(graph, realizationURI);\r
+                                        if(run == null)\r
+                                            return null;\r
+                                        Variable timeVar = run.browsePossible(graph, "#" + Functions.TIME + "#");\r
+                                        if(timeVar != null)\r
+                                            time = timeVar.getValue(graph, Bindings.DOUBLE);\r
+            \r
+                                    }\r
+\r
+                                    // Value\r
+                                    Double value = null;\r
+                                    if(time == null) {\r
+                                        value = va[va.length - 1];\r
+                                    } else {\r
+                                        double[] ta = dataset.times;\r
+                                        for(int i = 0; i < ta.length; i++) {\r
+                                            double t = ta[i];\r
+                                            if(time <= t) {\r
+                                                value = va[i]; \r
+                                                break;\r
+                                            }\r
+                                        }\r
+\r
+                                        if(value == null)\r
+                                            value = va[va.length - 1];\r
+                                    }\r
+                                    String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel); // Called to refresh paints when label changes\r
+                                    String name = label == null || label.isEmpty() ? dataset.name : label;\r
+                                    if (dataset.resultIndex != null) {\r
+                                       name += "(" + dataset.resultIndex + ")"; \r
+                                    }\r
+                                    series.add(new TempSeries(name, dataset.result, value));\r
+                                }\r
+                            } catch (MissingVariableException e) {\r
+                                // Do nothing, if variable was not found. Move on to the next series\r
+                            }\r
+                        }\r
+                    }\r
+                    return series;\r
+                }\r
+\r
+            }, listener);\r
+        }\r
+        return dataset;\r
+    }\r
+\r
+    @Override\r
+    public AbstractRenderer getRenderer() {\r
+        return renderer.getRenderer();\r
+    }\r
+\r
+    private class DatasetListener implements Listener<ArrayList<TempSeries>> {\r
+        private boolean disposed = false;\r
+\r
+        public void dispose() {\r
+            disposed = true;\r
+        }\r
+\r
+        @Override\r
+        public void execute(final ArrayList<TempSeries> series) {\r
+            // Modify series in AWT thread to avoid synchronization problems\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    // Remove all unused series\r
+                    dataset.clear();\r
+                    BarRenderer renderer = ((BarRenderer)getRenderer());\r
+                    renderer.getPlot().setDrawingSupplier(new DefaultDrawingSupplier());\r
+\r
+                    // Add found series\r
+                    for(int i = 0; i < series.size(); i++) {\r
+                        TempSeries s = series.get(i);\r
+                        if(renderer instanceof org.jfree.chart.renderer.category.StackedBarRenderer && s.name.contains("[")) {\r
+                            String category = s.name.substring(0, s.name.indexOf('['));\r
+                            if(s.result != null)\r
+                                category = category + " : " + s.result;\r
+                            String series = s.name.substring(s.name.indexOf('['));\r
+                            dataset.addValue(s.value, series, category);\r
+                        } else {\r
+                            dataset.addValue(s.value, s.result == null ? "Current" : s.result, s.name);\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 disposed;\r
+        }\r
+    };\r
+\r
+    @Override\r
+    public void dispose() {\r
+        super.dispose();\r
+        if(listener != null) {\r
+            listener.dispose();\r
+            listener = null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Auxiliary class containing all information needed to define a single series\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class TempSeries {\r
+        public String name;\r
+        public String result;\r
+        public Double value;\r
+\r
+        public TempSeries(String name, String result, Double value) {\r
+            this.name = name;\r
+            this.value = value;\r
+            this.result = result;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return "TempSeries: " + name + ", " + value + ", " + result;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBound.java
new file mode 100644 (file)
index 0000000..1dc7869
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.Color;\r
+\r
+/**\r
+ * Container class for confidence bound properties\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ConfidenceBound implements Comparable<ConfidenceBound> {\r
+    \r
+    private double percent;\r
+    private Color color;\r
+    \r
+    public ConfidenceBound(double percent, Color color) {\r
+        this.percent = percent;\r
+        this.color = color;\r
+    }\r
+    \r
+    public double getPercent() {\r
+        return percent;\r
+    }\r
+    \r
+    public Color getColor() {\r
+        return color;\r
+    }\r
+\r
+    @Override\r
+    public int compareTo(ConfidenceBound other) {\r
+        return Double.compare(percent, other.getPercent());\r
+//        return Double.compare(other.getPercent(), percent);\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/ConfidenceBoundWidget.java
new file mode 100644 (file)
index 0000000..b7d009b
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\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.viewers.StructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\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.jfreechart.chart.properties.ColorPicker;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.properties.SysdynBasicColorProvider;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyFactory;\r
+import org.simantics.sysdyn.ui.properties.widgets.factories.DoublePropertyModifier;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+import org.simantics.utils.ui.validators.DoubleValidator;\r
+\r
+/**\r
+ * Widget for setting percentage and color for a confidence bound\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ConfidenceBoundWidget extends Composite implements Widget {\r
+\r
+    private WidgetSupportImpl confidenceBoundSupport;\r
+    private int index;\r
+    \r
+    public ConfidenceBoundWidget(Composite parent, ISessionContext context, WidgetSupport support, int style, int index) {\r
+        super(parent, style);\r
+        this.index = index;\r
+        \r
+        support.register(this);\r
+        \r
+        GridLayoutFactory.fillDefaults().applyTo(this);\r
+        \r
+        confidenceBoundSupport = new WidgetSupportImpl();\r
+        \r
+        ColorPicker colorPicker = new ColorPicker(this, context, confidenceBoundSupport, SWT.NONE, false) {\r
+            @Override\r
+            protected Resource getColorRelation(ReadGraph graph) throws DatabaseException {\r
+                return SysdynResource.getInstance(graph).Charts_SensitivityDataset_ConfidenceBound_color;\r
+            }\r
+        };\r
+        GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.BEGINNING).applyTo(colorPicker);\r
+        \r
+        TrackedText variable = new TrackedText(this, confidenceBoundSupport, SWT.BORDER);\r
+        variable.setTextFactory(new DoublePropertyFactory(SysdynResource.URIs.Charts_SensitivityDataset_ConfidenceBound_percent));\r
+        variable.addModifyListener(new DoublePropertyModifier(context, SysdynResource.URIs.Charts_SensitivityDataset_ConfidenceBound_percent));\r
+        variable.setColorProvider(new SysdynBasicColorProvider(variable.getResourceManager()));\r
+        variable.setInputValidator(new DoubleValidator() {\r
+            public String isValid(String newText) {\r
+                if(newText == null || newText.isEmpty())\r
+                    return null;\r
+                else\r
+                    return super.isValid(newText);\r
+            }\r
+\r
+        });\r
+        GridDataFactory.fillDefaults().hint(27, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(variable.getWidget());\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        try {\r
+            Resource confidenceBound = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                @Override\r
+                public Resource perform(ReadGraph graph) throws DatabaseException {\r
+                    return getResource(graph, resource);\r
+                }\r
+                \r
+            });\r
+            \r
+            if(confidenceBound != null)\r
+                confidenceBoundSupport.fireInput(context, new StructuredSelection(confidenceBound));\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+    \r
+    private Resource getResource(ReadGraph graph, Resource input) throws DatabaseException {\r
+        Resource dataset = graph.getPossibleObject(input, Layer0.getInstance(graph).PartOf);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        Resource confidenceBoundsList = graph.getPossibleObject(dataset, SR.Charts_SensitivityDataset_confidenceBounds);\r
+        if(confidenceBoundsList == null)\r
+            return null;\r
+        List<Resource> confidenceBounds = ListUtils.toList(graph, confidenceBoundsList);\r
+        return confidenceBounds.get(index);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/PieDataset.java
new file mode 100644 (file)
index 0000000..81d7310
--- /dev/null
@@ -0,0 +1,333 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.data.general.Dataset;\r
+import org.jfree.data.general.DefaultPieDataset;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.request.PossibleActiveExperiment;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.jfreechart.chart.AbstractDataset;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.adapter.VariableRVIUtils;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Class representing a PieDataset in JFreeChart ontology\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class PieDataset extends AbstractDataset implements org.simantics.jfreechart.chart.PieDataset<String> {\r
+\r
+    private List<Resource> seriesList;\r
+    private String realizationURI;\r
+    private DefaultPieDataset dataset;\r
+\r
+    private HashMap<String, Color> colorMap;\r
+    private HashMap<String, Boolean> explodedMap;\r
+\r
+    public PieDataset(ReadGraph graph, Resource resource) throws DatabaseException {\r
+        super(graph, resource);\r
+\r
+       \r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+            // Find the model where the chart is located\r
+            Resource model = resource;\r
+            do {\r
+                model = graph.getPossibleObject(model, l0.PartOf);\r
+            } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel));\r
+\r
+            // Find the variable realization of the current experiment\r
+            realizationURI = null;\r
+            Resource realization = graph.syncRequest(new PossibleActiveExperiment(model));\r
+            if (realization == null) {\r
+                Layer0X L0X = Layer0X.getInstance(graph);\r
+                realization = graph.getPossibleObject(model, L0X.HasBaseRealization);\r
+            }\r
+            if (realization != null)\r
+                realizationURI = graph.getURI(realization);\r
+\r
+            if(realizationURI == null)\r
+                return; // No experiment -> No results\r
+\r
+            Resource seriesList = graph.getPossibleObject(resource, jfree.Dataset_seriesList);\r
+            if(seriesList != null) {\r
+                this.seriesList = ListUtils.toList(graph, seriesList);\r
+            }\r
+        \r
+\r
+    }\r
+\r
+    /**\r
+     * Map of colors for different slices in a pie chart. Name \r
+     * indicates the key of the value.\r
+     * @return  Map of colors for different slices in a pie chart\r
+     */\r
+    public HashMap<String, Color> getColorMap() {\r
+        return colorMap;\r
+    }\r
+\r
+    /**\r
+     * Map of exploded statuses for slices in a pie chart. Name\r
+     * indicates the key of the slice.\r
+     * @return\r
+     */\r
+    public HashMap<String, Boolean> getExplodedMap() {\r
+        return explodedMap;\r
+    }\r
+\r
+    @Override\r
+    public Dataset getDataset() {\r
+        if(seriesList == null || seriesList.isEmpty() ||  SimanticsUI.getSession() == null)\r
+            return null;\r
+\r
+        if(dataset == null) {\r
+            dataset = new DefaultPieDataset();\r
+        }\r
+\r
+        if(listener == null) {\r
+            listener = new DatasetListener();\r
+            SimanticsUI.getSession().asyncRequest(new Read<ArrayList<TempSeries>>() {\r
+\r
+                @Override\r
+                public ArrayList<TempSeries> perform(ReadGraph graph) throws DatabaseException {\r
+                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+                    ArrayList<TempSeries> series = new ArrayList<TempSeries>();\r
+                    // Get properties for all series\r
+                    if(seriesList != null) {\r
+\r
+                        colorMap = new HashMap<String, Color>();\r
+                        explodedMap = new HashMap<String, Boolean>();\r
+\r
+                        for(Resource r : seriesList) {\r
+                            String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel);\r
+                            String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI);\r
+                            if(rvi == null)\r
+                                continue;\r
+\r
+                            try {\r
+                                // Get visual properties\r
+                                Resource c = graph.getPossibleObject(r, jfree.color);\r
+                                Color color = c == null ? null : G2DUtils.getColor(graph, c);\r
+                                Boolean exploded = graph.getPossibleRelatedValue(r, jfree.Series_exploded, Bindings.BOOLEAN);\r
+\r
+                                // Get a variable for the series\r
+                                Variable v = Variables.getVariable(graph, realizationURI + rvi);\r
+\r
+                                // Get values\r
+                                Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#");\r
+                                if(dsVariable == null)\r
+                                       return series;\r
+                                \r
+                                Object object = dsVariable.getValue(graph);\r
+                                if(object == null || !(object instanceof ArrayList<?>))\r
+                                    return series;\r
+\r
+                                ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+\r
+                                for(Object o : (ArrayList<?>)object) {\r
+                                    if(o instanceof SysdynDataSet)\r
+                                        datasets.add((SysdynDataSet)o);\r
+                                }\r
+\r
+                                String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter);\r
+                                if(filter != null) {\r
+                                    ArrayList<SysdynDataSet> result2 = VariableRVIUtils.getDataset(datasets, filter);\r
+                                    if(result2 != null) {\r
+                                        datasets = result2;\r
+                                    }\r
+                                }\r
+\r
+                                // Find if a specific time is set for this chart\r
+                                Double chartTime = null;\r
+                                if(!datasets.isEmpty()) {\r
+                                    Layer0 l0 = Layer0.getInstance(graph);\r
+                                    Resource datasetResource = graph.getPossibleObject(r, l0.PartOf);\r
+                                    if(datasetResource != null) {\r
+                                        Resource plot = graph.getPossibleObject(datasetResource, l0.PartOf);\r
+                                        if(plot != null) {\r
+                                            Resource chart = graph.getPossibleObject(plot, l0.PartOf);\r
+                                            if(chart != null)\r
+                                                chartTime = graph.getPossibleRelatedValue(chart, jfree.Chart_time);\r
+                                        }\r
+                                    }\r
+                                }\r
+                                \r
+                                for(SysdynDataSet dataset : datasets) {\r
+                                    double[] va = dataset.values;\r
+\r
+                                    if(va == null || va.length == 0)\r
+                                        continue;\r
+\r
+                                    /*\r
+                                     *  Time\r
+                                     *  \r
+                                     *  1. find time for the individual series.\r
+                                     *  2. find time for the whole chart\r
+                                     *  3. find simulation time\r
+                                     */\r
+                                    Double time = graph.getPossibleRelatedValue(r, jfree.Series_time, Bindings.DOUBLE);\r
+                                    if(time == null)\r
+                                        time = chartTime;\r
+                                    if(time == null) {\r
+                                        // Get a variable for the experiment run\r
+                                        Variable run = Variables.getVariable(graph, realizationURI);\r
+                                        if(run == null)\r
+                                            return null;\r
+                                        Variable timeVar = run.browsePossible(graph, "#" + Functions.TIME + "#");\r
+                                        if(timeVar != null)\r
+                                            time =  timeVar.getValue(graph, Bindings.DOUBLE);\r
+                                    }\r
+                                    \r
+                                    // Value\r
+                                    Double value = null;\r
+                                    if(time == null) {\r
+                                        value = va[va.length - 1];\r
+                                    } else {\r
+                                        double[] ta = dataset.times;\r
+                                        for(int i = 0; i < ta.length; i++) {\r
+                                            double t = ta[i];\r
+                                            if(time <= t) {\r
+                                                value = va[i]; \r
+                                                break;\r
+                                            }\r
+                                        }\r
+\r
+                                        if(value == null)\r
+                                            value = va[va.length - 1];\r
+                                    }\r
+\r
+                                    String name = label == null || label.isEmpty() ? dataset.name : label;\r
+                                    if (dataset.resultIndex != null) {\r
+                                       name += "(" + dataset.resultIndex + ")"; \r
+                                    }\r
+                                    if(dataset.result != null)\r
+                                        name = name + " : " + dataset.result; \r
+                                    colorMap.put(name, color);\r
+                                    explodedMap.put(name, exploded);\r
+                                    series.add(new TempSeries(name, value));\r
+                                }\r
+                            } catch (MissingVariableException e) {\r
+                                // Do nothing, if variable was not found. Move on to the next series\r
+                            }\r
+                        }\r
+                    }\r
+                    return series;\r
+                }\r
+\r
+            }, listener);\r
+        }\r
+        return dataset;\r
+    }\r
+\r
+    private DatasetListener listener;\r
+\r
+    private class DatasetListener implements Listener<ArrayList<TempSeries>> {\r
+\r
+        private boolean disposed = false;\r
+\r
+        @Override\r
+        public void execute(final ArrayList<TempSeries> series) {\r
+            // Modify series in AWT thread to avoid synchronization problems\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    // Remove all series\r
+                    dataset.clear();\r
+\r
+                    // Add found series\r
+                    for(int i = 0; i < series.size(); i++) {\r
+                        TempSeries s = series.get(i);\r
+                        dataset.setValue(s.name, s.value);\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 disposed;\r
+        }\r
+\r
+        public void dispose() {\r
+            disposed = true;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public AbstractRenderer getRenderer() {\r
+        // No renderer for pie chart\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        super.dispose();\r
+        if(listener != null) {\r
+            listener.dispose();\r
+            listener = null;\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Auxiliary class containing all information needed to define a single series\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class TempSeries {\r
+        public String name;\r
+        public Double value;\r
+\r
+        public TempSeries(String name, Double value) {\r
+            this.name = name;\r
+            this.value = value;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return "TempSeries: " + name + ", " + value;\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..a350998
--- /dev/null
@@ -0,0 +1,47 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.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/SensitivityChartAxisAndVariablesTab.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityChartAxisAndVariablesTab.java
new file mode 100644 (file)
index 0000000..c414bf9
--- /dev/null
@@ -0,0 +1,162 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.ScrolledComposite;\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.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.simantics.browsing.ui.swt.SingleSelectionInputSource;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl;\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.jfreechart.chart.properties.AdjustableTab;\r
+import org.simantics.jfreechart.chart.properties.xyline.AxisAndVariablesExplorerComposite;\r
+import org.simantics.jfreechart.chart.properties.xyline.AxisPropertyComposite;\r
+import org.simantics.jfreechart.chart.properties.xyline.SeriesPropertyComposite;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class SensitivityChartAxisAndVariablesTab extends AdjustableTab {\r
+\r
+    private GraphExplorerComposite explorer;\r
+    private ScrolledComposite propertyContainer;\r
+    private WidgetSupportImpl additionalSupport;\r
+\r
+    public SensitivityChartAxisAndVariablesTab(Object id) {\r
+        super(id);\r
+        additionalSupport = new WidgetSupportImpl();\r
+    }\r
+\r
+    /**\r
+     * Updates the content of propertyContainer  \r
+     * @param context\r
+     */\r
+    private void updateSelection(ISessionContext context) {\r
+        ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+        IStructuredSelection selection = (IStructuredSelection)selectionProvider.getSelection();\r
+        final Resource resource = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
+        if(resource == null)\r
+            return;\r
+\r
+        // Get the type of the selected node (axis or series)\r
+        String typeUri = null;\r
+        try {\r
+            typeUri = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                    if(graph.isInstanceOf(resource, jfree.Axis))\r
+                        return graph.getURI(jfree.Axis);\r
+                    else if (graph.isInstanceOf(resource, jfree.Series))\r
+                        return graph.getURI(jfree.Series);\r
+                    return null;\r
+                }\r
+\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        // Create a PropertyComposite for the selected node\r
+        if(typeUri != null) {\r
+\r
+            for(Control child : propertyContainer.getChildren()) {\r
+                child.dispose();\r
+            }\r
+\r
+            if(typeUri.equals(JFreeChartResource.URIs.Axis)) {\r
+                AxisPropertyComposite apc = new AxisPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE, isVertical());\r
+                propertyContainer.setContent(apc);\r
+                Point size = apc.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                propertyContainer.setMinSize(size);\r
+            } else if(typeUri.equals(JFreeChartResource.URIs.Series)) {\r
+                SeriesPropertyComposite spc = new SensitivitySeriesPropertyComposite(propertyContainer, context, additionalSupport, SWT.NONE);\r
+                propertyContainer.setContent(spc);\r
+                Point size = spc.computeSize(SWT.DEFAULT, SWT.DEFAULT);\r
+                propertyContainer.setMinSize(size);\r
+            }\r
+        }\r
+\r
+        additionalSupport.fireInput(context, selection);\r
+    }\r
+\r
+       @Override\r
+       protected void createAndAddControls(Composite body, IWorkbenchSite site,\r
+                       final ISessionContext context, WidgetSupport support) {\r
+               composite = new Composite(body, SWT.NONE);\r
+\r
+        // (Ontology-based) GraphExplorer displaying range axis and variables mapped to those axis\r
+        explorer = new AxisAndVariablesExplorerComposite(ArrayMap.keys(\r
+                "displaySelectors", "displayFilter").values(false, false), site, composite, support, SWT.FULL_SELECTION | SWT.BORDER | SWT.SINGLE);\r
+        explorer.setBrowseContexts(JFreeChartResource.URIs.ChartAxisAndVariablesBrowseContext);\r
+        explorer.setInputSource(new SingleSelectionInputSource(\r
+                Resource.class));\r
+        explorer.getExplorer().setAutoExpandLevel(2); // Expand everything in the beginning\r
+        explorer.finish();\r
+\r
+        ((Tree)explorer.getExplorerControl()).addSelectionListener(new SelectionAdapter() {\r
+            public void widgetSelected(SelectionEvent e) {\r
+                updateSelection(context);\r
+            }\r
+        });\r
+\r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        propertyContainer = new ScrolledComposite(composite, SWT.H_SCROLL | SWT.V_SCROLL);\r
+        propertyContainer.setExpandHorizontal(true);\r
+        propertyContainer.setExpandVertical(true);\r
+\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutVertical() {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(1).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().hint(220, SWT.DEFAULT).grab(false, true).applyTo(explorer);\r
+\r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        GridDataFactory.fillDefaults().span(1, 1).hint(SWT.DEFAULT, 210).grab(true, false).applyTo(propertyContainer);\r
+        GridLayoutFactory.fillDefaults().applyTo(propertyContainer);\r
+       }\r
+\r
+       @Override\r
+       protected void createControlLayoutHorizontal(boolean wideScreen) {\r
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
+        GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(composite);\r
+\r
+        GridDataFactory.fillDefaults().hint(250, SWT.DEFAULT).grab(false, true).applyTo(explorer);\r
+\r
+        // Scrolled composite for displaying properties of a selection in explorer\r
+        GridDataFactory.fillDefaults().span(1, 2).hint(SWT.DEFAULT, SWT.DEFAULT).grab(true, true).applyTo(propertyContainer);\r
+        GridLayoutFactory.fillDefaults().applyTo(propertyContainer);\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDataset.java
new file mode 100644 (file)
index 0000000..c4aba21
--- /dev/null
@@ -0,0 +1,292 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.jfree.chart.LegendItem;\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.chart.renderer.xy.DeviationRenderer;\r
+import org.jfree.data.general.Dataset;\r
+import org.jfree.data.xy.YIntervalSeries;\r
+import org.jfree.data.xy.YIntervalSeriesCollection;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.procedure.adapter.DisposableListener;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.jfreechart.chart.IRenderer;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * Dataset for sensitivity analysis fan charts.\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SensitivityDataset extends XYDataset {\r
+\r
+    DeviationRenderer renderer;\r
+    \r
+    public SensitivityDataset(ReadGraph graph, Resource resource) throws DatabaseException {\r
+        super(graph, resource);\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Override\r
+    public Dataset getDataset() {\r
+        if(dataset == null) {\r
+            dataset = new YIntervalSeriesCollection();\r
+        }   \r
+\r
+        if(datasetListener == null || datasetListener.isDisposed()) {\r
+            datasetListener = new SensitivityDatasetListener();\r
+            SimanticsUI.getSession().asyncRequest(\r
+                    new SensitivityDatasetRequest(resource), \r
+                    (DisposableListener<Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties>>) datasetListener); \r
+        }\r
+\r
+        if(timeListener == null || timeListener.isDisposed()) {\r
+            SimanticsUI.getSession().asyncRequest(getTimeRequest(), getTimeListener());\r
+        }\r
+        return dataset;\r
+    }\r
+    \r
+    /**\r
+     * SensitivityDatasetRequest uses {@link XYDatasetRequest} to get values for all sensitivity analysis runs.\r
+     * \r
+     * In addition, the request finds fan chart properties from dataset resource and passes them to {@link SensitivityDatasetListener}\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class SensitivityDatasetRequest implements Read<Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties>> {\r
+\r
+        private Resource dataset;\r
+        \r
+        public SensitivityDatasetRequest(Resource dataset) {\r
+            this.dataset = dataset;\r
+        }\r
+        \r
+        @Override\r
+        public Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties> perform(ReadGraph graph) throws DatabaseException {\r
+            \r
+            Pair<ArrayList<XYDatasetTempSeries>, IRenderer> XYDatasetRequestResult = graph.syncRequest(new XYDatasetRequest(dataset));\r
+            \r
+            SysdynResource SR = SysdynResource.getInstance(graph);\r
+            Boolean median = graph.getPossibleRelatedValue(dataset, SR.Charts_SensitivityDataset_median);\r
+            if (median == null)\r
+               median = false;\r
+            \r
+            Resource confidenceBoundsList = graph.getPossibleObject(dataset, SR.Charts_SensitivityDataset_confidenceBounds);\r
+            ArrayList<ConfidenceBound> confidenceBounds = new ArrayList<ConfidenceBound>();\r
+\r
+            if(confidenceBoundsList != null) {\r
+                List<Resource> confidenceBoundResources = ListUtils.toList(graph, confidenceBoundsList);\r
+\r
+                for(Resource cb : confidenceBoundResources) {\r
+                    Double percent = graph.getPossibleRelatedValue(cb, SR.Charts_SensitivityDataset_ConfidenceBound_percent);\r
+                    Resource c = graph.getPossibleObject(cb, SR.Charts_SensitivityDataset_ConfidenceBound_color);\r
+                    Color color = c == null ? null : G2DUtils.getColor(graph, c);\r
+                    if(percent != null && color != null)\r
+                        confidenceBounds.add(new ConfidenceBound(percent, color));\r
+                }\r
+            }\r
+            \r
+            SensitivityDatasetProperties properties = new SensitivityDatasetProperties(median, confidenceBounds);\r
+            \r
+            return new Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties> (XYDatasetRequestResult.first, properties);\r
+        }\r
+        \r
+    }\r
+\r
+    @Override\r
+    public AbstractRenderer getRenderer() {\r
+        if(renderer == null)\r
+            renderer = new DeviationRenderer(true, false) {\r
+            private static final long serialVersionUID = 633310754812851862L;\r
+\r
+            /* \r
+             * Overridden getLegendElement to provide thick lines for legend.\r
+             */\r
+            @Override\r
+            public LegendItem getLegendItem(int datasetIndex, int series) {\r
+                LegendItem item = super.getLegendItem(datasetIndex, series);\r
+                return new LegendItem(item.getLabel(), item.getDescription(), item.getToolTipText(), item.getURLText(), item.getLine(), new BasicStroke(5F), item.getLinePaint());\r
+            }\r
+        };\r
+        return renderer;\r
+    }\r
+    \r
+    /**\r
+     * SensitivityDatasetListener calculates confidence bounds from all sensitivity analysis run results.\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    private class SensitivityDatasetListener extends DisposableListener<Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties>> {\r
+\r
+        @Override\r
+        public void execute(Pair<ArrayList<XYDatasetTempSeries>, SensitivityDatasetProperties> result) {\r
+            final ArrayList<XYDatasetTempSeries> series = result.first;\r
+            final SensitivityDatasetProperties properties = result.second;\r
+            \r
+            // Modify series in AWT thread to avoid synchronization problems\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+\r
+                    if(dataset == null || !(dataset instanceof YIntervalSeriesCollection))\r
+                        return;\r
+                    \r
+                    YIntervalSeriesCollection ds = (YIntervalSeriesCollection)dataset;\r
+\r
+                    DeviationRenderer dr = (DeviationRenderer)getRenderer();\r
+                    \r
+                    ArrayList<ConfidenceBound> confidenceBounds = properties.getConfidenceBounds();\r
+\r
+                    \r
+                    // CONFIDENCE BOUND PAINTS\r
+                    for(int i = 1; i <= confidenceBounds.size(); i++) {\r
+                        dr.setSeriesStroke(i, new BasicStroke(0F));\r
+                        dr.setSeriesPaint(i, confidenceBounds.get(i-1).getColor());\r
+                        dr.setSeriesFillPaint(i, confidenceBounds.get(i-1).getColor());\r
+                    }\r
+                    \r
+                    Color medianColor = Color.RED;\r
+                    // MEDIAN PAINTS\r
+                    dr.setSeriesStroke(0, new BasicStroke(2F));\r
+                    dr.setSeriesPaint(0, medianColor);\r
+                    dr.setSeriesFillPaint(0, medianColor);\r
+                    dr.setSeriesVisibleInLegend(0, true);\r
+\r
+                    \r
+                    if(!properties.displayMedian()) {\r
+                        /*\r
+                         *  Median is in the first index position. If it\r
+                         *  is not visible, make it the same color as\r
+                         *  the next series and hide it from legend\r
+                         */\r
+                        dr.setSeriesVisibleInLegend(0, false);\r
+                        dr.setSeriesPaint(0, dr.getSeriesPaint(1));\r
+                    }\r
+                    \r
+                    dr.setAlpha(1);\r
+                    \r
+                    // Remove all series\r
+                    for(int i = ds.getSeriesCount() - 1; i >= 0; i-- ) {\r
+                        ds.removeSeries(ds.getSeries(i));\r
+                    }\r
+                    \r
+                    int n = series.size();\r
+                    if(n < 1)\r
+                        return;\r
+                    \r
+                    int length = series.get(0).values[0].length;\r
+                    \r
+                    \r
+                    YIntervalSeries median = new YIntervalSeries("Median");\r
+                    \r
+                    YIntervalSeries[] yIntervalSeries = new YIntervalSeries[confidenceBounds.size()];\r
+                    for(int i = 0; i < confidenceBounds.size(); i++) {\r
+                        yIntervalSeries[i] = new YIntervalSeries(confidenceBounds.get(i).getPercent() + "%");\r
+                    }\r
+\r
+                    ArrayList<Double> sorter = new ArrayList<Double>();\r
+                    for(int i = 0; i < length; i++) {\r
+                        sorter.clear();\r
+                        for(int j = 0; j < n; j++) {\r
+                            if(series.get(j).values[1].length == 0)\r
+                                continue; // If there are no values, move on to next dataset\r
+                            sorter.add(series.get(j).values[1][i]); // values is a two-dimensional array. 0 dimension == times, 1 == values\r
+                        }\r
+                        Collections.sort(sorter);\r
+                        \r
+                        int sorterSize = sorter.size();\r
+                        int intervals = sorterSize - 1;\r
+                       \r
+                        // MEDIAN\r
+                        double medianX = series.get(0).values[0][i];\r
+                        double medianY = sorter.get(sorterSize/2);\r
+                        median.add(\r
+                                       medianX, \r
+                                medianY,\r
+                                medianY,\r
+                                medianY\r
+                                );\r
+\r
+                        // CONFIDENCE BOUNDS\r
+                        for(int j = 0; j < yIntervalSeries.length; j++) {\r
+                               YIntervalSeries yis = yIntervalSeries[j];\r
+                            double percent = properties.getConfidenceBounds().get(j).getPercent() / 100;\r
+                            if(n >= (1 / percent) * 2) {\r
+                               // Estimate the confidence limits\r
+                               double indexLow = (1 - percent) * intervals / 2;\r
+                               int indexLowLow = (int)Math.floor(indexLow);\r
+                               int indexLowHigh = (int)Math.ceil(indexLow);\r
+                               double valueLowLow = sorter.get(indexLowLow);\r
+                               double valueLowHigh = sorter.get(indexLowHigh);\r
+                               double decimalLow = indexLow - indexLowLow;\r
+                               // Linear interpolation; to decrease execution time, use interpolation of degree 0, \r
+                               // but I didn't find the current approach too time consuming in a simple test. \r
+                               double estimateLow = (valueLowHigh - valueLowLow) * decimalLow + valueLowLow;\r
+                               \r
+                               double indexHigh = (1 + percent) * intervals / 2;;\r
+                               int indexHighLow = (int)Math.floor(indexHigh);\r
+                               int indexHighHigh = (int)Math.ceil(indexHigh);\r
+                               double valueHighLow = sorter.get(indexHighLow);\r
+                               double valueHighHigh = sorter.get(indexHighHigh);\r
+                               double decimalHigh = 1 - decimalLow;  \r
+                               double estimateHigh = (valueHighHigh - valueHighLow) * decimalHigh + valueHighLow;\r
+                               yis.add(\r
+                                               medianX, \r
+                                               medianY,\r
+                                               estimateLow,\r
+                                               estimateHigh\r
+                                               );\r
+                            }\r
+                        }\r
+                    }\r
+                    \r
+                    // ADD MEDIAN\r
+                    ds.addSeries(median);\r
+                    \r
+                    // ADD OTHERS\r
+                    // CONFIDENCE BOUNDS\r
+                    for(int j = 0; j < yIntervalSeries.length; j++) {\r
+                        YIntervalSeries yis = yIntervalSeries[j];\r
+                        double percent = properties.getConfidenceBounds().get(j).getPercent();\r
+                        if(n >= (1 / percent) * 2)\r
+                            ds.addSeries(yis);\r
+                    }\r
+                }\r
+            });\r
+        }\r
+\r
+        @Override\r
+        public void exception(Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivityDatasetProperties.java
new file mode 100644 (file)
index 0000000..a216b52
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+\r
+public class SensitivityDatasetProperties {\r
+    \r
+    private boolean median;\r
+    private ArrayList<ConfidenceBound> confidenceBounds;\r
+    \r
+    public SensitivityDatasetProperties(boolean median, ArrayList<ConfidenceBound> confidenceBounds) {\r
+        this.median = median;\r
+        this.confidenceBounds = new ArrayList<ConfidenceBound>(confidenceBounds);\r
+        Collections.sort(this.confidenceBounds);\r
+    }\r
+    \r
+    public boolean displayMedian() {\r
+        return median;\r
+    }\r
+    \r
+    public ArrayList<ConfidenceBound> getConfidenceBounds() {\r
+        return confidenceBounds;\r
+    }\r
+    \r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SensitivitySeriesPropertyComposite.java
new file mode 100644 (file)
index 0000000..b6c5aed
--- /dev/null
@@ -0,0 +1,110 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\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.simantics.browsing.ui.swt.widgets.Button;\r
+import org.simantics.browsing.ui.swt.widgets.impl.ReadFactoryImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.SelectionListenerImpl;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.jfreechart.chart.properties.xyline.SeriesPropertyComposite;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * UI for setting properties for sensitivity analysis series. Sensitivity analysis \r
+ * charts display only one variable as a "fan" chart.\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SensitivitySeriesPropertyComposite extends SeriesPropertyComposite {\r
+\r
+    public SensitivitySeriesPropertyComposite(Composite parent, ISessionContext context, WidgetSupport support,\r
+            int style) {\r
+        super(parent, context, support, style);\r
+    }\r
+\r
+    @Override\r
+    protected void createContent(ISessionContext context, WidgetSupport support) {\r
+        GridLayoutFactory.fillDefaults().margins(3, 3).numColumns(2).applyTo(this);\r
+\r
+        // Variable for the series\r
+        variable(this, context, support);\r
+\r
+        // Range\r
+        range(this, context, support);\r
+\r
+        // Label to be displayed in chart for this series \r
+//        seriesLabel(this, context, support);\r
+        \r
+        Button validateUnits = new Button(this, support, SWT.CHECK);\r
+        validateUnits.setText("Display median");\r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(validateUnits.getWidget());\r
+        validateUnits.setSelectionFactory(new ReadFactoryImpl<Resource, Boolean>() {\r
+\r
+            @Override\r
+            public Boolean perform(ReadGraph graph, Resource series) throws DatabaseException {\r
+                Resource dataset = graph.getPossibleObject(series, Layer0.getInstance(graph).PartOf);\r
+                Boolean result = graph.getPossibleRelatedValue(dataset, SysdynResource.getInstance(graph).Charts_SensitivityDataset_median, Bindings.BOOLEAN);\r
+                return Boolean.TRUE.equals(result);\r
+            }\r
+        });\r
+        \r
+        validateUnits.addSelectionListener(new SelectionListenerImpl<Resource>(context){\r
+\r
+            @Override\r
+            public void apply(WriteGraph graph, Resource series) throws DatabaseException {\r
+                SysdynResource SR = SysdynResource.getInstance(graph);\r
+                Resource dataset = graph.getPossibleObject(series, Layer0.getInstance(graph).PartOf);\r
+                if(dataset == null)\r
+                    return;\r
+                \r
+                Boolean result = graph.getPossibleRelatedValue(dataset, SR.Charts_SensitivityDataset_median, Bindings.BOOLEAN);\r
+                if(result == null)\r
+                    result = false;\r
+                boolean newValue = Boolean.FALSE.equals(result);\r
+                graph.claimLiteral(dataset, SR.Charts_SensitivityDataset_median, newValue);\r
+                Layer0Utils.addCommentMetadata(graph, "Display Median for " + NameUtils.getSafeName(graph, series) + " to " + newValue);\r
+            }\r
+        });\r
+        \r
+        Composite c = new Composite(this, SWT.NONE);\r
+        GridDataFactory.fillDefaults().span(2, 1).applyTo(c);\r
+        GridLayoutFactory.fillDefaults().numColumns(5).applyTo(c);\r
+        ConfidenceBoundWidget cbWidget = new ConfidenceBoundWidget(c, context, support, SWT.NONE, 0);\r
+        GridDataFactory.fillDefaults().applyTo(cbWidget);\r
+        cbWidget = new ConfidenceBoundWidget(c, context, support, SWT.NONE, 1);\r
+        GridDataFactory.fillDefaults().applyTo(cbWidget);\r
+        cbWidget = new ConfidenceBoundWidget(c, context, support, SWT.NONE, 2);\r
+        GridDataFactory.fillDefaults().applyTo(cbWidget);\r
+        cbWidget = new ConfidenceBoundWidget(c, context, support, SWT.NONE, 3);\r
+        GridDataFactory.fillDefaults().applyTo(cbWidget);\r
+        cbWidget = new ConfidenceBoundWidget(c, context, support, SWT.NONE, 4);\r
+        GridDataFactory.fillDefaults().applyTo(cbWidget);\r
+        \r
+    }\r
+    \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/SysdynRangeHandlerFactory.java
new file mode 100644 (file)
index 0000000..9f804e5
--- /dev/null
@@ -0,0 +1,166 @@
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.util.HashMap;\r
+import java.util.LinkedHashMap;\r
+import java.util.List;\r
+import java.util.Map;\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.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\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.db.request.Read;\r
+import org.simantics.jfreechart.chart.ChartUtils;\r
+import org.simantics.jfreechart.chart.properties.RangeHandlerFactory;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.utils.datastructures.Quad;\r
+\r
+public class SysdynRangeHandlerFactory implements RangeHandlerFactory {\r
+    \r
+    protected Resource getRVIRelation(ReadGraph graph) {\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+        return jfree.variableRVI;\r
+    }\r
+       \r
+       @Override\r
+       public Read<LinkedHashMap<String, Resource>> getRequest(final Resource series) {\r
+               // TODO Auto-generated method stub\r
+               return new Read<LinkedHashMap<String, Resource>>() {\r
+\r
+            @Override\r
+            public LinkedHashMap<String, Resource> perform(ReadGraph graph) throws DatabaseException {\r
+                SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+                String realizationURI = ChartUtils.getCurrentRealizationURI(graph, series);\r
+                String rvi = graph.getPossibleRelatedValue(series, getRVIRelation(graph));\r
+                if(rvi == null)\r
+                    return null;\r
+                \r
+                rvi = rvi.replace(".", "/");\r
+                \r
+                if(!rvi.startsWith("/"))\r
+                    rvi = "/" + rvi;\r
+                \r
+                try {\r
+                    // Find the variable for the current variableRVI\r
+                    Variable v = Variables.getVariable(graph, realizationURI + rvi.trim());\r
+                    if(v == null)\r
+                        return null;\r
+                    \r
+                    // Find all enumeration replacements in the variable's path\r
+                    HashMap<Resource, Resource> redeclarations = new HashMap<Resource, Resource>();\r
+                    Variable parent = v;\r
+                    while((parent = parent.getParent(graph)) != null) {\r
+                       Resource represents = parent.getRepresents(graph);\r
+                       Resource type = graph.getSingleObject(represents, Layer0.getInstance(graph).InstanceOf);\r
+                       if(!graph.isInheritedFrom(type, sr.Module))\r
+                               break;\r
+                       \r
+                       for(Resource redeclaration : graph.getObjects(represents, sr.Module_redeclaration)) {\r
+                               redeclarations.put(\r
+                                               graph.getPossibleObject(redeclaration, sr.Redeclaration_replacedEnumeration), \r
+                                               graph.getPossibleObject(redeclaration, sr.Redeclaration_replacingEnumeration)\r
+                                               );\r
+                       }\r
+                    }\r
+                    \r
+                    \r
+                    \r
+                    \r
+                    Resource variable = v.getRepresents(graph);\r
+                    \r
+                    // Return the enumerations assigned to that variable\r
+                    Resource arrayIndexes = graph.getPossibleObject(variable, sr.Variable_arrayIndexesList);\r
+                    if(arrayIndexes != null) {\r
+                        LinkedHashMap<String, Resource> result = new LinkedHashMap<String, Resource>();\r
+                        for(Resource enumeration : ListUtils.toList(graph, arrayIndexes)) {\r
+                               \r
+                               // Find possible redeclarations for enumeration\r
+                               Resource redeclaration = enumeration;\r
+                               while(redeclarations.get(redeclaration) != null)\r
+                                       redeclaration = redeclarations.get(redeclaration);\r
+                               \r
+                            String enumerationName = NameUtils.getSafeName(graph, redeclaration);\r
+                            result.put(enumerationName, redeclaration);\r
+                        }\r
+                        return result;\r
+                    }\r
+                } catch (DatabaseException e) {\r
+                    // No variable was found, return null\r
+                }\r
+                return null;\r
+            }\r
+\r
+        };\r
+       }\r
+       \r
+       @Override\r
+       public ReadFactoryImpl<Resource, Map<String, Object>> getRangeItemFactory(int index, Resource res) {\r
+               return new RangeItemFactory(index, res);\r
+       }\r
+       \r
+       \r
+    /**\r
+     * RangeItemFactory finds all inexes of a given enumeration \r
+     * and adds "Sum" and "All" to the returned indexes\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    public class RangeItemFactory extends ReadFactoryImpl<Resource, Map<String, Object>> {\r
+\r
+        private int index;\r
+        private Resource enumeration;\r
+        private boolean addCollections;\r
+\r
+        \r
+        /**\r
+         * \r
+         * @param index Index of the enumeration in the variable\r
+         * @param enumeration The enumeration\r
+         */\r
+        public RangeItemFactory(int index, Resource enumeration) {\r
+            this(index, enumeration, true);\r
+        }\r
+        \r
+        /**\r
+         * \r
+         * @param index Index of the enumeration in the variable\r
+         * @param enumeration The enumeration\r
+         * @param addCollections add "Sum" and "All"\r
+         */\r
+        public RangeItemFactory(int index, Resource enumeration, boolean addCollections) {\r
+            this.index = index;\r
+            this.enumeration = enumeration;\r
+            this.addCollections = addCollections;\r
+        }\r
+\r
+        public Object getIdentity(Object inputContents) {\r
+            return new Quad<Object, Integer, Resource, Class<?>>(inputContents, index, enumeration, getClass());\r
+        }\r
+        @Override\r
+        public Map<String, Object> perform(ReadGraph graph, Resource series) throws DatabaseException {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();\r
+            Resource enumerationIndexes = graph.getPossibleObject(enumeration, sr.Enumeration_enumerationIndexList);\r
+            List<Resource> indexes = ListUtils.toList(graph, enumerationIndexes);\r
+            if(addCollections) {\r
+                // First add "All" and "Sum", then all of the enumeration indexes in order\r
+                result.put("All", "All");\r
+                result.put("Sum", "Sum");\r
+            }\r
+            for(Resource index : indexes) {\r
+                String name = NameUtils.getSafeName(graph, index);\r
+                result.put(name, name);\r
+            }\r
+            \r
+            return result;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendEditor.java
new file mode 100644 (file)
index 0000000..258bae5
--- /dev/null
@@ -0,0 +1,32 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.simantics.jfreechart.chart.ChartComposite;\r
+import org.simantics.ui.workbench.ResourceEditorPart;\r
+\r
+public class TrendEditor extends ResourceEditorPart {\r
+\r
+    private ChartComposite chart;\r
+    \r
+    @Override\r
+    public void createPartControl(Composite parent) {\r
+        chart = new ChartComposite(parent, getResourceInput().getResource(), SWT.NONE);\r
+    }\r
+\r
+    @Override\r
+    public void setFocus() {\r
+        chart.forceFocus();\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToPng.java
new file mode 100644 (file)
index 0000000..dae65d7
--- /dev/null
@@ -0,0 +1,80 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\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.core.expressions.EvaluationContext;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.jfree.chart.ChartUtilities;\r
+import org.jfree.chart.JFreeChart;\r
+\r
+/**\r
+ * Exports the current chart in TrendView\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class TrendToPng extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        EvaluationContext c = (EvaluationContext)event.getApplicationContext();\r
+        Object o = c.getParent().getVariable("activePart");\r
+        if(o != null && o instanceof TrendView) {\r
+            TrendView trendView = (TrendView) o;\r
+            int width = trendView.getPanel().getSize().width;\r
+            int height =  trendView.getPanel().getSize().height;\r
+            int compressionLevel = 0;\r
+\r
+            final Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+\r
+            while(true) {\r
+                FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
+                fd.setText("Export trend to PNG");\r
+                String[] ext = {"*.png"};\r
+                fd.setFilterExtensions(ext);\r
+                String selected = fd.open();\r
+\r
+                if(selected == null)\r
+                    return null;\r
+\r
+                File file = new File(selected);\r
+\r
+                if(file.exists()) {\r
+                    MessageDialog dialog = new MessageDialog(shell, "Overwrite " + file.getName() + "?", null, file.getName() + " exits. Do you wan't to overwrite it?", 0,\r
+                            new String[] { "Yes", "No" }, 0);\r
+                    dialog.create();\r
+                    if (dialog.open() == 1)\r
+                        continue;\r
+                }\r
+\r
+                JFreeChart chart =  trendView.getPanel().getChart();\r
+                try {\r
+                    ChartUtilities.saveChartAsPNG(file, chart, width, height, null, true, compressionLevel);\r
+                } catch (IOException e) {\r
+                    e.printStackTrace();\r
+                }\r
+                return null;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendToSvg.java
new file mode 100644 (file)
index 0000000..9da9370
--- /dev/null
@@ -0,0 +1,73 @@
+package org.simantics.sysdyn.ui.trend;\r
+\r
+//import java.awt.geom.Rectangle2D;\r
+//import java.io.File;\r
+//import java.io.FileNotFoundException;\r
+//import java.io.FileOutputStream;\r
+//import java.io.OutputStreamWriter;\r
+//import java.io.UnsupportedEncodingException;\r
+//import java.io.Writer;\r
+\r
+import java.awt.geom.Rectangle2D;\r
+import java.io.File;\r
+import java.io.IOException;\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.core.expressions.EvaluationContext;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.jfreechart.chart.ChartUtils;\r
+\r
+public class TrendToSvg extends AbstractHandler {\r
+\r
+    @Override\r
+    public Object execute(ExecutionEvent event) throws ExecutionException {\r
+        EvaluationContext c = (EvaluationContext)event.getApplicationContext();\r
+        Object o = c.getParent().getVariable("activePart");\r
+        if(o != null && o instanceof TrendView) {\r
+            TrendView trendView = (TrendView) o;\r
+\r
+            Shell shell = HandlerUtil.getActiveShellChecked(event);\r
+            \r
+            while(true) {\r
+                FileDialog fd = new FileDialog(shell, SWT.SAVE);\r
+                fd.setText("Export trend to SVG");\r
+                String[] ext = {"*.svg"};\r
+                fd.setFilterExtensions(ext);\r
+                String selected = fd.open();\r
+\r
+                if(selected == null)\r
+                    return null;\r
+\r
+                File file = new File(selected);\r
+\r
+                if(file.exists()) {\r
+                    MessageDialog dialog = new MessageDialog(shell, "Overwrite " + file.getName() + "?", null, file.getName() + " exits. Do you wan't to overwrite it?", 0,\r
+                            new String[] { "Yes", "No" }, 0);\r
+                    dialog.create();\r
+                    if (dialog.open() == 1)\r
+                        continue;\r
+                }\r
+\r
+                try {\r
+                    ChartUtils.writeSVG(\r
+                            trendView.getPanel().getChart(), \r
+                            new Rectangle2D.Double(0, 0, trendView.getPanel().getWidth(), trendView.getPanel().getHeight()),\r
+                            file);\r
+                } catch (IOException e) {\r
+                    e.printStackTrace();\r
+                } \r
+                \r
+                return null;\r
+            }\r
+        }\r
+\r
+        return null;\r
+    }\r
+   \r
+}
\ No newline at end of file
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..ef13a42
--- /dev/null
@@ -0,0 +1,299 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.Frame;\r
+import java.util.Collection;\r
+\r
+import javax.swing.SwingUtilities;\r
+\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.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.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.jfreechart.chart.IJFreeChart;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener;\r
+import org.simantics.utils.RunnableWithObject;\r
+\r
+/**\r
+ * Trend view that shows all active simulation results for selected variables.\r
+ *  \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class TrendView extends ViewPart {\r
+\r
+    private Frame frame;\r
+    private ChartPanel panel;\r
+    private SysdynDatasets sysdynDatasets = new SysdynDatasets();\r
+    private SysdynDatasetSelectionListener sysdynDatasetSelectionListener;\r
+    private JFreeChart defaultchart;\r
+    private Composite composite;\r
+\r
+    \r
+    public Frame getFrame() {\r
+        return frame;\r
+    }\r
+\r
+    public ChartPanel getPanel() {\r
+        return panel;\r
+    }\r
+    \r
+    public void setPanel(ChartPanel panel) {\r
+        this.panel = panel;\r
+    }\r
+\r
+    public SysdynDatasets getSysdynDatasets() {\r
+        return sysdynDatasets;\r
+    }\r
+\r
+    /**\r
+     * Dataset for jFreeChart\r
+     * \r
+     * @author Teemu Lempinen\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
+            String name = sds.name;\r
+            if(sds.resultIndex != null)\r
+               name += "(" + sds.resultIndex + ")"; \r
+            if(sds.result == null)\r
+                return name;\r
+            else\r
+                return 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
+\r
+        composite = new Composite(parent,\r
+                SWT.NO_BACKGROUND | SWT.EMBEDDED);\r
+        frame = SWT_AWT.new_Frame(composite);\r
+\r
+        // Create the chart\r
+        displayDefaultChart();\r
+\r
+        // Add a dataset listener that updates datasets for the chart according to current selection \r
+        sysdynDatasetSelectionListener = new TrendViewSelectionListner(this);\r
+\r
+        getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(sysdynDatasetSelectionListener);\r
+\r
+    }\r
+    \r
+    private class TrendViewSelectionListner extends SysdynDatasetSelectionListener {\r
+        \r
+        private TrendView trendView;\r
+        private CustomChartListener listener;\r
+\r
+        public TrendViewSelectionListner(TrendView trendView) {\r
+            this.trendView = trendView;\r
+        }\r
+\r
+        @Override\r
+        protected void selectionChanged(final Collection<SysdynDataSet> activeDatasets) {\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    if(listener != null) {\r
+                        listener.dispose();\r
+                    }\r
+                    trendView.getSysdynDatasets().setDatasets(activeDatasets.toArray(new SysdynDataSet[activeDatasets.size()]));\r
+                    displayDefaultChart();\r
+                }\r
+\r
+            });\r
+        }\r
+\r
+        @Override\r
+        protected void selectionChanged(ReadGraph graph, final Resource chartResource) {\r
+\r
+            if(listener != null) {\r
+                listener.dispose();\r
+            }\r
+\r
+            listener = new CustomChartListener(trendView);\r
+\r
+            graph.asyncRequest(new Read<JFreeChart>() {\r
+\r
+                @Override\r
+                public JFreeChart perform(ReadGraph graph) throws DatabaseException {\r
+                    if(graph.hasStatement(chartResource)) {\r
+                        IJFreeChart chart = graph.adapt(chartResource, IJFreeChart.class);\r
+                        if(chart != null) {\r
+                            return chart.getChart();\r
+                        }\r
+                    }\r
+                    return null;\r
+                }\r
+            }, listener);\r
+        }\r
+    }\r
+\r
+    private class CustomChartListener implements Listener<JFreeChart> {\r
+\r
+        private boolean disposed = false;\r
+        private TrendView trendView;\r
+        \r
+        public CustomChartListener(TrendView trendView) {\r
+            this.trendView = trendView;\r
+        }\r
+\r
+        @Override\r
+        public void execute(JFreeChart result) {\r
+            if(!disposed)\r
+                displayChart(result, trendView);\r
+        }\r
+\r
+        @Override\r
+        public void exception(Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+        @Override\r
+        public boolean isDisposed() {\r
+            return disposed;\r
+        }\r
+\r
+        public void dispose() {\r
+            this.disposed = true;\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Displays jFreeChart\r
+     * @param jFreeChart\r
+     */\r
+    private void displayChart(JFreeChart jFreeChart, TrendView trendView) {\r
+        SwingUtilities.invokeLater(new RunnableWithObject(jFreeChart, trendView) {\r
+\r
+            @Override\r
+            public void run() {\r
+                if(count() != 2 || getObject(0) == null || getObject(1) == null)\r
+                    return;\r
+                \r
+                if(!(getObject(0) instanceof JFreeChart && getObject(1) instanceof TrendView))\r
+                    return;\r
+                \r
+                JFreeChart jFreeChart = (JFreeChart) getObject(0);\r
+                TrendView trendView = (TrendView) getObject(1);\r
+                \r
+                Frame frame = trendView.getFrame();\r
+                ChartPanel panel = trendView.getPanel();\r
+                \r
+                // Do not just simply frame.removeAll();\r
+                // Instead, use and reuse only the first component of the frame.\r
+                if(jFreeChart != null) {\r
+                    if (panel == null || frame.getComponentCount() == 0){\r
+                        panel = new ChartPanel(jFreeChart, false, true, true, true, true);\r
+                        trendView.setPanel(panel);\r
+                        frame.add(panel);\r
+                    } else {\r
+//                        panel.setChart(jFreeChart);\r
+                        if ( frame.getComponent(0) instanceof ChartPanel ){\r
+                            ChartPanel tempPanel = (ChartPanel)frame.getComponent(0);\r
+                            tempPanel.setChart(jFreeChart);\r
+                            trendView.setPanel(tempPanel);\r
+                        }\r
+                    }\r
+                }\r
+                frame.repaint();\r
+                frame.validate();\r
+                panel.requestFocusInWindow();\r
+                //panel.requestFocus();\r
+            }\r
+\r
+        });\r
+    }\r
+\r
+    /**\r
+     * displays a default chart\r
+     */\r
+    private void displayDefaultChart() {\r
+        if(defaultchart == null) {\r
+               NumberAxis domainAxis = new NumberAxis("time");\r
+               domainAxis.setAutoRangeIncludesZero(false);\r
+            XYPlot plot = new XYPlot(\r
+                    sysdynDatasets,\r
+                    domainAxis,\r
+                    new NumberAxis(""),\r
+                    new XYLineAndShapeRenderer(true, false)\r
+                    );\r
+            defaultchart = new JFreeChart(plot);\r
+        }\r
+        displayChart(defaultchart, this);\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        super.dispose();\r
+        getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(sysdynDatasetSelectionListener);\r
+    }\r
+\r
+    @Override\r
+    public void setFocus() {\r
+        if(panel != null)\r
+            panel.requestFocus();\r
+    }\r
+\r
+\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDataset.java
new file mode 100644 (file)
index 0000000..4866e21
--- /dev/null
@@ -0,0 +1,349 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.BasicStroke;\r
+import java.awt.Color;\r
+import java.awt.Paint;\r
+import java.awt.Stroke;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.jfree.chart.ChartColor;\r
+import org.jfree.chart.labels.StandardXYToolTipGenerator;\r
+import org.jfree.chart.plot.DefaultDrawingSupplier;\r
+import org.jfree.chart.plot.ValueMarker;\r
+import org.jfree.chart.renderer.AbstractRenderer;\r
+import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;\r
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;\r
+import org.jfree.data.general.Dataset;\r
+import org.jfree.data.xy.DefaultXYDataset;\r
+import org.jfree.ui.Layer;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.procedure.adapter.DisposableListener;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.request.PossibleActiveExperiment;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.jfreechart.chart.AbstractDataset;\r
+import org.simantics.jfreechart.chart.IRenderer;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.operation.Layer0X;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+/**\r
+ * Class representing a JFreeChart.XYDataset\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class XYDataset extends AbstractDataset implements org.simantics.jfreechart.chart.XYDataset{\r
+\r
+    protected IRenderer renderer;\r
+\r
+    public XYDataset(ReadGraph graph, final Resource datasetResource) throws DatabaseException {\r
+        super(graph, datasetResource);\r
+    }\r
+\r
+    protected Dataset dataset;\r
+    protected DisposableListener<?> datasetListener;\r
+    protected DisposableListener<Double> timeListener;\r
+    \r
+    protected DisposableListener<Double> getTimeListener() {\r
+        if(timeListener == null || timeListener.isDisposed()) {\r
+            timeListener = new TimeListener();\r
+        }\r
+        return timeListener;\r
+    }\r
+    \r
+    protected Read<Double> getTimeRequest() {\r
+        return new Read<Double>() {\r
+            @Override\r
+            public Double perform(ReadGraph graph) throws DatabaseException {\r
+                JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                // Get properties for all series\r
+                Resource series = graph.getPossibleObject(resource, jfree.Dataset_seriesList);\r
+                if(series != null) {\r
+                    List<Resource> seriesList = ListUtils.toList(graph, series);\r
+                    if(seriesList != null) {\r
+                        String realizationURI = getRealizationURI(graph, resource);\r
+                        for(Resource r : seriesList) {\r
+                            String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI);\r
+                            if(rvi == null)\r
+                                continue;\r
+                            try {\r
+                                // Get a variable for the experiment run\r
+                                Variable v = Variables.getVariable(graph, realizationURI);\r
+                                if(v == null)\r
+                                    return null;\r
+                                Variable timeVar = v.browsePossible(graph, "#" + Functions.TIME + "#");\r
+                                if(timeVar != null)\r
+                                    return timeVar.getValue(graph, Bindings.DOUBLE);\r
+                            } catch (MissingVariableException e) {\r
+                                // Do nothing, if variable was not found.\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                return null;\r
+            }\r
+\r
+        };\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Override\r
+    public Dataset getDataset() {\r
+        if(dataset == null) {\r
+            dataset = new DefaultXYDataset();\r
+        }   \r
+\r
+        if(datasetListener == null || datasetListener.isDisposed()) {\r
+            datasetListener = new DataSetListener();\r
+            SimanticsUI.getSession().asyncRequest(\r
+                    new XYDatasetRequest(resource), \r
+                    (DisposableListener<Pair<ArrayList<XYDatasetTempSeries>, IRenderer>>) datasetListener); \r
+\r
+        }\r
+\r
+        if(timeListener == null || timeListener.isDisposed()) {\r
+            SimanticsUI.getSession().asyncRequest(getTimeRequest(), getTimeListener());\r
+        }\r
+        return dataset;\r
+    }\r
+\r
+    /**\r
+     * Class for identifying a time marker in a plot\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    protected class TimeMarker extends ValueMarker {\r
+        private static final long serialVersionUID = 2018755066561629172L;\r
+\r
+        public TimeMarker(double value, Paint paint, Stroke stroke) {\r
+            super(value, paint, stroke);\r
+        }\r
+    }\r
+\r
+    private class DataSetListener extends DisposableListener<Pair<ArrayList<XYDatasetTempSeries>, IRenderer>> {\r
+\r
+        @Override\r
+        public void execute(Pair<ArrayList<XYDatasetTempSeries>, IRenderer> result) {\r
+            final ArrayList<XYDatasetTempSeries> series = result.first;\r
+            renderer = result.second;\r
+            \r
+            // Modify series in AWT thread to avoid synchronization problems\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+\r
+                    if(dataset == null || !(dataset instanceof DefaultXYDataset))\r
+                        return;\r
+                    \r
+                    DefaultXYDataset ds = (DefaultXYDataset)dataset;\r
+                    org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot();\r
+                    \r
+                    if(plot != null) {\r
+                        /*\r
+                         *  Drawing supplier with a modified first yellow. The default first\r
+                         *  yellow is too light to be visible against a white background\r
+                         */\r
+                        Paint[] paintSequence = ChartColor.createDefaultPaintArray();\r
+                        paintSequence[3] = new Color(0xFF, 0xDD, 0x00);\r
+                        DefaultDrawingSupplier drawingsupplier = new DefaultDrawingSupplier(\r
+                                paintSequence,\r
+                                DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE,\r
+                                DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,\r
+                                DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,\r
+                                DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,\r
+                                DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);\r
+                        plot.setDrawingSupplier(drawingsupplier);\r
+                    }\r
+                    // Remove all series\r
+                    for(int i = ds.getSeriesCount() - 1; i >= 0; i-- ) {\r
+                        ds.removeSeries(ds.getSeriesKey(i));\r
+                    }\r
+\r
+                    // Add found series\r
+                    for(int i = 0; i < series.size(); i++) {\r
+                        XYDatasetTempSeries s = series.get(i);\r
+                        String name = s.name;\r
+                        if(ds.indexOf(name) >= 0)\r
+                            name = name + (i + 1);\r
+                        ds.addSeries(name, s.values);\r
+                        getRenderer().setSeriesStroke(i, new BasicStroke((float)s.width));\r
+                        getRenderer().setSeriesPaint(i, s.color);\r
+                    } \r
+                }\r
+            });\r
+        }\r
+\r
+        @Override\r
+        public void exception(Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+    }\r
+\r
+\r
+    /**\r
+     * Listener for updating the time indicator for XY plots\r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    protected class TimeListener extends DisposableListener<Double> {\r
+\r
+        private ValueMarker marker;\r
+        private Stroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,\r
+                BasicStroke.JOIN_MITER, 10.0f, new float[] {5.0f, 3.0f, 1.0f, 3.0f}, 0.0f);\r
+\r
+        public TimeListener() {\r
+            this.marker = new TimeMarker(0.0, Color.red, dashStroke);\r
+        }\r
+\r
+        public void dispose() {\r
+            super.dispose();\r
+            if(marker != null) {\r
+                org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot();\r
+                if(plot != null)\r
+                    plot.removeDomainMarker(marker);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public void execute(final Double time) {\r
+            // Modify in AWT thread to avoid synchronization problems\r
+            SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                @Override\r
+                public void run() {\r
+                    org.jfree.chart.plot.XYPlot plot = ((AbstractXYItemRenderer)getRenderer()).getPlot();\r
+\r
+                    if(plot == null)\r
+                        return;\r
+\r
+                    plot.removeDomainMarker(marker);\r
+                    if(time != null) {\r
+                        marker.setValue(time);\r
+                        if(plot.getDomainMarkers(Layer.FOREGROUND) == null || !plot.getDomainMarkers(Layer.FOREGROUND).contains(marker)) {\r
+                            int i = 0;\r
+                            for(i = 0; i < plot.getDatasetCount(); i++) {\r
+                                if(plot.getDataset(i) != null && plot.getDataset(i).equals(dataset))\r
+                                    break;\r
+                            }\r
+                            plot.addDomainMarker(i, marker, Layer.FOREGROUND);\r
+                        }\r
+                    }\r
+\r
+                }\r
+            });\r
+        }\r
+\r
+        @Override\r
+        public void exception(Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        if(timeListener != null) {\r
+            timeListener.dispose();\r
+            timeListener = null;\r
+        }\r
+\r
+        if(datasetListener != null) {\r
+            datasetListener.dispose();\r
+            datasetListener = null;\r
+        }\r
+    }\r
+\r
+\r
+    @Override\r
+    public AbstractRenderer getRenderer() {\r
+        if(renderer == null) {\r
+\r
+            try {\r
+                renderer = SimanticsUI.getSession().syncRequest(new Read<IRenderer>() {\r
+\r
+                    @Override\r
+                    public IRenderer perform(ReadGraph graph) throws DatabaseException {\r
+                        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                        IRenderer renderer = null;\r
+                        Resource rendererResource = graph.getPossibleObject(resource, jfree.Dataset_renderer);\r
+                        if(rendererResource != null)\r
+                            renderer = graph.adapt(rendererResource, IRenderer.class);\r
+                        return renderer;\r
+                    }\r
+                });\r
+            } catch (DatabaseException e) {\r
+            }\r
+            if(renderer == null) {\r
+                XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);\r
+                renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());\r
+                return renderer;\r
+            } else {\r
+                return renderer.getRenderer();\r
+            }\r
+        } else {\r
+            return renderer.getRenderer();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the realization uri of the current dataset resource\r
+     * @param graph ReadGraph\r
+     * @return realization uri for current dataset resource\r
+     * @throws DatabaseException\r
+     */\r
+    public static String getRealizationURI(ReadGraph graph, Resource resource) throws DatabaseException {\r
+        if(resource == null)\r
+            return null;\r
+\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+\r
+        // Find the model where the chart is located\r
+        Resource model = resource;\r
+        do {\r
+            model = graph.getPossibleObject(model, l0.PartOf);\r
+        } while(model != null && !graph.isInstanceOf(model, mr.StructuralModel));\r
+\r
+        if(model == null)\r
+            return null;\r
+\r
+        // Find the variable realization of the current experiment\r
+        String realizationURI = null;\r
+        Resource realization = graph.syncRequest(new PossibleActiveExperiment(model));\r
+        if (realization == null) {\r
+            Layer0X L0X = Layer0X.getInstance(graph);\r
+            realization = graph.getPossibleObject(model, L0X.HasBaseRealization);\r
+        }\r
+        if (realization != null)\r
+            realizationURI = graph.getURI(realization);\r
+\r
+        return realizationURI;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetRequest.java
new file mode 100644 (file)
index 0000000..2a34593
--- /dev/null
@@ -0,0 +1,189 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.G2DUtils;\r
+import org.simantics.jfreechart.chart.IRenderer;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.adapter.VariableRVIUtils;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class XYDatasetRequest implements Read<Pair<ArrayList<XYDatasetTempSeries>, IRenderer>>{\r
+    \r
+    protected Resource dataset;\r
+    \r
+    public XYDatasetRequest(Resource dataset) {\r
+        this.dataset = dataset;\r
+    }\r
+    \r
+    @Override\r
+    public Pair<ArrayList<XYDatasetTempSeries>, IRenderer> perform(ReadGraph graph) throws DatabaseException {\r
+        JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+\r
+        // Renderer\r
+        IRenderer renderer = null;\r
+        Resource rendererResource = graph.getPossibleObject(dataset, jfree.Dataset_renderer);\r
+        if(rendererResource != null)\r
+            renderer = graph.adapt(rendererResource, IRenderer.class);\r
+\r
+        ArrayList<XYDatasetTempSeries> series = new ArrayList<XYDatasetTempSeries>();\r
+\r
+        String realizationURI = XYDataset.getRealizationURI(graph, dataset);\r
+\r
+        if(realizationURI == null)\r
+            return new Pair<ArrayList<XYDatasetTempSeries>, IRenderer>(series, renderer); // No experiment -> No results\r
+\r
+        // Get a variable for the x-axis (if not time)\r
+        double[] domainValues = null;\r
+        Resource domainAxis = graph.getPossibleObject(dataset, jfree.Dataset_mapToDomainAxis);\r
+        if(domainAxis != null) {\r
+            String rvi = graph.getPossibleRelatedValue(domainAxis, jfree.variableRVI);\r
+            if(rvi != null && !rvi.isEmpty()) {\r
+                try {\r
+                    Variable domainVariable = Variables.getVariable(graph, realizationURI + rvi);\r
+                    Variable valuesVariable = domainVariable.browsePossible(graph, "#" + Functions.VALUES +"#");\r
+                    if(valuesVariable != null) {\r
+                        double[][] valuesArray = valuesVariable.getValue(graph);\r
+                        if(valuesArray.length > 0)\r
+                            domainValues = valuesArray[0];\r
+                    }\r
+                } catch(MissingVariableException e) {\r
+                    //Do nothing, use time as domain axis\r
+                }\r
+            }\r
+        }\r
+\r
+        Resource seriesList = graph.getPossibleObject(dataset, jfree.Dataset_seriesList);\r
+\r
+        // Get properties for all series\r
+        if(seriesList != null) {\r
+            for(Resource r : ListUtils.toList(graph, seriesList)) {\r
+                String rvi = graph.getPossibleRelatedValue(r, jfree.variableRVI);\r
+                if(rvi == null)\r
+                    continue;\r
+\r
+                try {\r
+                    // Get visual properties\r
+                    Integer width = graph.getPossibleRelatedValue(r, jfree.Series_lineWidth, Bindings.INTEGER);\r
+                    if(width == null) width = 1;\r
+\r
+                    Resource c = graph.getPossibleObject(r, jfree.color);\r
+                    Color color = c == null ? null : G2DUtils.getColor(graph, c);\r
+                    \r
+                    String label = graph.getPossibleRelatedValue(r, Layer0.getInstance(graph).HasLabel);\r
+\r
+                    // Get a variable for the series\r
+                    Variable v = Variables.getVariable(graph, realizationURI + rvi);\r
+                    if(v == null)\r
+                        return new Pair<ArrayList<XYDatasetTempSeries>, IRenderer>(series, renderer);\r
+\r
+                    // Get values\r
+                    Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#");\r
+                    Object object = null;\r
+                    if(dsVariable != null)\r
+                         object = dsVariable.getValue(graph);\r
+\r
+                    if(object == null || !(object instanceof ArrayList<?>))\r
+                        return new Pair<ArrayList<XYDatasetTempSeries>, IRenderer>(series, renderer);\r
+\r
+                    ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+\r
+                    for(Object o : (ArrayList<?>)object) {\r
+                        if(o instanceof SysdynDataSet)\r
+                            datasets.add((SysdynDataSet)o);\r
+                    }\r
+\r
+\r
+                    String[] filter = graph.getPossibleRelatedValue(r, jfree.variableFilter);\r
+                    if(filter != null) {\r
+                        ArrayList<SysdynDataSet> result2 = VariableRVIUtils.getDataset(datasets, filter);\r
+                        if(result2 != null) {\r
+                            datasets = result2;\r
+                        }\r
+                    }\r
+\r
+                    for(SysdynDataSet dataset : datasets) {\r
+                        double[] va = dataset.values;\r
+\r
+                        // Get domain axis values (time OR other variable) \r
+                        double[] ta;\r
+                        if(domainValues != null) {\r
+                            ta = domainValues;\r
+\r
+                            // If domainAxis is other than time, parameter values size is different. \r
+                            if(domainValues.length > va.length) {\r
+                                double value = va[0];\r
+                                va = new double[domainValues.length];\r
+                                for(int i = 0; i < domainValues.length; i++)\r
+                                    va[i] = value;\r
+                            }\r
+\r
+                            // If domainAxis is a parameter, the domainValues array is too short\r
+                            if(domainValues.length < va.length && domainValues.length == 2 && domainValues[0] == domainValues[1]) {\r
+                                double value = domainValues[0];\r
+                                ta = new double[va.length];\r
+                                for(int i = 0; i < va.length; i++)\r
+                                    ta[i] = value;\r
+                            }\r
+\r
+                        } else {\r
+                            ta = dataset.times;\r
+                        }\r
+\r
+                        if(ta!=null && va!=null && (va.length == ta.length)) {\r
+                            // Add series if everything OK\r
+                            String name = dataset.name;\r
+                            if(label != null)\r
+                                name = label;\r
+                            if (dataset.resultIndex != null) {\r
+                               name += "(" + dataset.resultIndex + ")"; \r
+                            }\r
+                            if(dataset.result != null && !dataset.result.isEmpty())\r
+                                name = name + " : " + dataset.result;\r
+                            if(ta.length != 0 && va.length != 0) {\r
+                                XYDatasetTempSeries tempSeries = new XYDatasetTempSeries(name, new double[][] {ta, va}, width, color);\r
+                                getAdditionalSeriesProperties(graph, r, tempSeries);\r
+                                series.add(tempSeries);\r
+                                \r
+                            }\r
+                            \r
+                        }\r
+                    }\r
+\r
+                } catch (MissingVariableException e) {\r
+                    // Do nothing, if variable was not found. Move on to the next series\r
+                }\r
+            }\r
+        }\r
+        return new Pair<ArrayList<XYDatasetTempSeries>, IRenderer>(series, renderer);\r
+    }\r
+\r
+    \r
+    protected void getAdditionalSeriesProperties(ReadGraph graph, Resource r, XYDatasetTempSeries tempSeries) throws DatabaseException {\r
+        \r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/XYDatasetTempSeries.java
new file mode 100644 (file)
index 0000000..d919bae
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.trend;\r
+\r
+import java.awt.Color;\r
+import java.util.HashMap;\r
+\r
+/**\r
+ * Container class for holding XYDataset series\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class XYDatasetTempSeries {\r
+    \r
+    public double[][] values;\r
+    public String name;\r
+    public int width;\r
+    public Color color;\r
+    public HashMap<String, Object> properties = new HashMap<String, Object>();\r
+\r
+    public XYDatasetTempSeries(String name, double[][] values, int width, Color color) {\r
+        this.name = name;\r
+        this.values = values;\r
+        this.width = width;\r
+        this.color = color;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ArrayVariableUtils.java
new file mode 100644 (file)
index 0000000..73663c7
--- /dev/null
@@ -0,0 +1,201 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.representation.Enumeration;\r
+import org.simantics.sysdyn.representation.EnumerationIndex;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.utils.ModelUtils;\r
+\r
+public class ArrayVariableUtils {\r
+\r
+\r
+    /**\r
+     * Checks if the given range elements can be applied to the given variable.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param variable Resource of the variable \r
+     * @param range Range elements in the correct order. Elements are separated in range definition by ',' \r
+     * @return true if range is valid, false if not\r
+     * @throws DatabaseException\r
+     */\r
+    public static Map<Integer, SyntaxError> isRangeValid(ReadGraph graph, Variable variable, String[] elements) throws DatabaseException {\r
+        SyntaxError error;\r
+        if(variable == null)\r
+            return null;\r
+        Map<Integer, SyntaxError> result = new HashMap<Integer, SyntaxError>();\r
+        // Not an array variable\r
+        if(variable.getArrayIndexes() == null || \r
+                variable.getArrayIndexes() == null || \r
+                variable.getArrayIndexes().size() == 0) {\r
+            for(int i = 0; i < elements.length ; i++) {\r
+                error = new SyntaxError();\r
+                error.setMessage("Variable is not an array variable");\r
+                error.setType(ExpressionField.SYNTAX_ERROR);\r
+                result.put(i, error);\r
+            }\r
+\r
+            return result;\r
+        }\r
+        ArrayList<Enumeration> enumerations = variable.getArrayIndexes();\r
+        // Too many elements\r
+        if(elements.length > enumerations.size()) {\r
+            error = new SyntaxError();\r
+            error.setMessage( "Too many elements");\r
+            error.setType(ExpressionField.SYNTAX_ERROR);\r
+            result.put(enumerations.size(), error);\r
+        } else if(elements.length < enumerations.size()) {\r
+            error = new SyntaxError();\r
+            error.setMessage("Too few elements");\r
+            error.setType(ExpressionField.SYNTAX_ERROR);\r
+            result.put(elements.length > 0 ? elements.length - 1 : 0, error);\r
+        }\r
+\r
+        for(int i = 0; i < elements.length && i < enumerations.size(); i++) {\r
+               String trimmedElement = elements[i].trim();\r
+            if (trimmedElement.charAt(0) == '{' && trimmedElement.charAt(trimmedElement.length() - 1) == '}') {\r
+               // Something like "{a, b, c}"\r
+               String[] rangeComponents = trimmedElement.substring(1, trimmedElement.length() - 1).split(",");\r
+               // Single range component, equals to the enumeration at that index\r
+                if(rangeComponents.length == 1 && rangeComponents[0].trim().equals(enumerations.get(i).getName()))\r
+                       continue;\r
+                   // more than one range component, they all equal to individual indexes in the enumeration\r
+                result.putAll(areRangeComponentsValid(rangeComponents, enumerations, i));\r
+            } else if(trimmedElement.equals(":")) {\r
+                continue; // Just a ":"\r
+               } else if(elements[i].indexOf(":") != elements[i].lastIndexOf(":")) {\r
+                       // Something like "a : b : c"\r
+                error = new SyntaxError();\r
+                error.setMessage( "Too many ':' elements");\r
+                error.setType(ExpressionField.SYNTAX_ERROR);\r
+                result.put(i, error);\r
+                continue;\r
+            } else {\r
+               // Something like "a : c" OR "a"\r
+                   String[] rangeComponents = elements[i].split(":");\r
+                   if(rangeComponents.length > 2){\r
+                       error = new SyntaxError();\r
+                       error.setMessage( "Too many ':' elements");\r
+                       error.setType(ExpressionField.SYNTAX_ERROR);\r
+                       result.put(i, error);\r
+                       continue;\r
+                   }\r
+                   // Single range component, equals to the enumeration at that index\r
+                   if(rangeComponents.length == 1 && rangeComponents[0].trim().equals(enumerations.get(i).getName()))\r
+                       continue;\r
+                   // one or two range components, they all equal to individual indexes in the enumeration\r
+                   result.putAll(areRangeComponentsValid(rangeComponents, enumerations, i));\r
+            }\r
+        }\r
+        if(result.isEmpty())\r
+            return null;\r
+        else\r
+            return result;\r
+    }\r
+\r
+    private static Map<Integer, SyntaxError> areRangeComponentsValid(String[] rangeComponents, ArrayList<Enumeration> enumerations, int i) {\r
+       SyntaxError error;\r
+       Map<Integer, SyntaxError> result = new HashMap<Integer, SyntaxError>();\r
+        for(String r : rangeComponents) {\r
+            r = r.trim();\r
+            boolean componentIsValid = false;\r
+            Enumeration enumeration = enumerations.get(i);\r
+            for(EnumerationIndex ei : enumeration.getEnumerationIndexes()) {\r
+                if(ei.getName().equals(r)) {\r
+                    componentIsValid = true;\r
+                    break;\r
+                }\r
+            }\r
+            if(!componentIsValid  && r.length() > 0) {\r
+                // Check if the range is an integer that is between 0 and enumeration indexes size\r
+                try {\r
+                    int index = Integer.parseInt(r);\r
+                    int min = 1;\r
+                    int max = enumeration.getEnumerationIndexes().size();\r
+                    if(index >= min && index <= max || enumeration.isReplaceable()) {\r
+                        componentIsValid = true;\r
+                        error = new SyntaxError();\r
+                        error.setMessage("Using numbers as array indexes is not encouraged");\r
+                        error.setType(ExpressionField.SYNTAX_WARNING);\r
+                        result.put(i, error);\r
+                    } else {\r
+                        error = new SyntaxError();\r
+                        error.setMessage("Invalid array index " + index + ". Numbered index must be between " + min + " and " + max);\r
+                        error.setType(ExpressionField.SYNTAX_ERROR);\r
+                        result.put(i, error);\r
+                    }\r
+                } catch (NumberFormatException e) {\r
+                    error = new SyntaxError();\r
+                    error.setMessage("Invalid range");\r
+                    error.setType(ExpressionField.SYNTAX_ERROR);\r
+                    result.put(i, error);\r
+                }\r
+            }\r
+        }\r
+               return result;\r
+       }\r
+\r
+       /**\r
+     * Checks if the given range can be applied to the given variable.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param variable Resource of the variable \r
+     * @param range Range WITHOUT [ and ] brackets\r
+     * @return true if range is valid, false if not\r
+     * @throws DatabaseException\r
+     */\r
+    public static boolean isRangeValid(ReadGraph graph, Resource variable, String range) throws DatabaseException {\r
+        if(variable == null)\r
+            return true;\r
+        String[] elements = range.split(",");\r
+        // Connect arrays, e.g. {a,b,c}\r
+        ArrayList<String> connectedElements = new ArrayList<String>();\r
+        for (int i = 0; i < elements.length; ++i) {\r
+               String lastElement = elements[i];\r
+               String fullElement = new String();\r
+               if (lastElement.length() > 0 && lastElement.charAt(0) == '{') {\r
+                       while (lastElement.charAt(lastElement.length() - 1) != '}' && i < elements.length - 1) {\r
+                               fullElement += lastElement + ",";\r
+                               ++i;\r
+                               lastElement = elements[i];\r
+                       }\r
+               }\r
+               fullElement += lastElement;\r
+               connectedElements.add(fullElement);\r
+        }\r
+        String fullElements[] = connectedElements.toArray(new String[connectedElements.size()]);\r
+        \r
+        SysdynModel model = ModelUtils.getModel(graph, variable);\r
+        if(model == null)\r
+            return false;\r
+        IElement e = model.getElement(variable);\r
+        if(e != null && e instanceof Variable) {\r
+            Variable v = (Variable) e;\r
+            if(isRangeValid(graph, v, fullElements) == null)\r
+                return true;\r
+            else\r
+                return false;\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ExpressionUtils.java
new file mode 100644 (file)
index 0000000..70a0d43
--- /dev/null
@@ -0,0 +1,647 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import java.io.StringReader;\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.eclipse.jface.resource.ColorDescriptor;\r
+import org.eclipse.jface.resource.LocalResourceManager;\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.graphics.RGB;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableItem;\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.layer0.Layer0;\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.expressionParser.TokenMgrError;\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.Enumeration;\r
+import org.simantics.sysdyn.representation.EnumerationIndex;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Model;\r
+import org.simantics.sysdyn.representation.Module;\r
+import org.simantics.sysdyn.representation.Sheet;\r
+import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.IExpression;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ExpressionUtils {\r
+\r
+    /**\r
+     * Determines if the given expression is a parameter expression. Parameters are numbers.\r
+     * If the expression contains anything other than numbers, it is not a parameter.\r
+     * \r
+     * @param expression The expression to be checked\r
+     * @return is the expression a parameter\r
+     */\r
+    static public boolean isParameter(String expression) {\r
+        try {\r
+            /*\r
+                       StringTokenizer st = new StringTokenizer(expression, "{}[],;");\r
+                       while(st.hasMoreTokens()) {\r
+                               Double.parseDouble(st.nextToken().trim());\r
+                       }\r
+             */\r
+            Double.parseDouble(expression.trim());\r
+            return true;\r
+        } catch (NumberFormatException e) {\r
+            return false;\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Color for a variable found in an expression field, used in shortcut tab.\r
+     * This is a bit silly means of communicating the state of a variable using its color.\r
+     * @param resourceManager LocalResourceManager for which the color is created.\r
+     * @return Color for such variable.\r
+     */\r
+    public static Color variableFoundColor(LocalResourceManager resourceManager) {\r
+        return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(0,0,0)));\r
+    }\r
+    \r
+    /**\r
+     * Color for a variable not found in an expression field, used in shortcut tab.\r
+     * This is a bit silly means of communicating the state of a variable using its color.\r
+     * @param resourceManager LocalResourceManager for which the color is created.\r
+     * @return Color for such variable.\r
+     */\r
+    public static Color variableNotFoundColor(LocalResourceManager resourceManager) {\r
+        return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(255,125,0)));\r
+    }\r
+    \r
+    /**\r
+     * Color for a variable itself and for the time variable, used in shortcut tab.\r
+     * This is a bit silly means of communicating the state of a variable using its color.\r
+     * @param resourceManager LocalResourceManager for which the color is created.\r
+     * @return Color for such variable.\r
+     */\r
+    public static Color variableTimeAndSelfColor(LocalResourceManager resourceManager) {\r
+        return resourceManager.createColor(ColorDescriptor.createFrom(new RGB(127,127,127)));\r
+    }\r
+    \r
+    /**\r
+     * Validates the expressionfield of a given IExpression\r
+     * \r
+     * @param expression The expression whose fields are validated\r
+     * @param resourceManager \r
+     * @param connectedVariables Table items from the shortcut widget. (Items needed so that they can be coloured)\r
+     * @param configuration configuration where the variable is located\r
+     */\r
+    static public void validateExpressionFields(final Resource variable, \r
+            IExpression expression, \r
+            Table variableTable, \r
+            LocalResourceManager resourceManager) {\r
+       if(variable == null || expression == null || variableTable == null)\r
+               return;\r
+       \r
+        Resource configuration = null;\r
+        try {\r
+            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
+                    while (configuration != null) {\r
+                        configuration = graph.getPossibleObject(configuration, Layer0.getInstance(graph).PartOf);\r
+\r
+                        if(configuration == null || graph.isInstanceOf(configuration, sr.Configuration)) {\r
+                            break;\r
+                        }\r
+                    }\r
+                    return configuration;\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+            return;\r
+        }\r
+\r
+        if(configuration == null)\r
+            return;\r
+\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
+        final HashMap<ExpressionField, HashMap<String, List<List<Token>>>> ranges = new HashMap<ExpressionField, HashMap<String, List<List<Token>>>>();\r
+        HashMap<ExpressionField, HashMap<Token, List<Token>>> forIndices = new HashMap<ExpressionField, HashMap<Token, List<Token>>>();\r
+        HashMap<ExpressionField, HashMap<String, List<Token>>> enumerationReferences = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
+        HashMap<ExpressionField, HashMap<String, List<Token>>> functionReferences = new HashMap<ExpressionField, HashMap<String, List<Token>>>();\r
+\r
+        // Build references and variable array\r
+        boolean parsingSucceeded = false;\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>> refs = parser.getReferences();\r
+                references.put(ef, refs);\r
+                variables.addAll(refs.keySet());\r
+\r
+                ranges.put(ef, parser.getRanges());\r
+\r
+                forIndices.put(ef,  parser.getForIndices());\r
+\r
+                enumerationReferences.put(ef, parser.getEnumerationReferences());\r
+\r
+                functionReferences.put(ef, parser.getFunctionCallReferences());\r
+\r
+                parsingSucceeded = true;\r
+            } catch (ParseException e1) {\r
+                ef.setSyntaxError(new SyntaxError(e1.currentToken, "Syntax Error"));\r
+                \r
+                /* \r
+                 * If the equation is empty, set the parsingSucceeded = true\r
+                 * to allow the coloring of the variables succeed. \r
+                 */\r
+                if (textString.equals("")) {\r
+                    parsingSucceeded = true;\r
+                }\r
+            } catch (TokenMgrError err) {\r
+                ef.setSyntaxError(new SyntaxError(0, textString.length(), ExpressionField.SYNTAX_ERROR, "Expression contains unsupported characters"));\r
+            }\r
+        }\r
+\r
+\r
+        // Get model configuration\r
+        SysdynModelManager sdm = SysdynModelManager.getInstance(SimanticsUI.getSession());\r
+        SysdynModel model = sdm.getModel(configuration);\r
+//        try {\r
+//            model.update();\r
+//        } catch (DatabaseException e1) {\r
+//            e1.printStackTrace();\r
+//        }\r
+        Configuration conf = model.getConfiguration();\r
+        \r
+        // Check variable references\r
+        final HashMap<String, Variable> modelVariables = new HashMap<String, Variable>();\r
+        HashSet<String> ignoreVariables = new HashSet<String>();\r
+        if(!variables.isEmpty() || !functionReferences.isEmpty()) {\r
+            Set<String> noSuchVariables = new HashSet<String>();\r
+            ArrayList<IElement> elements = conf.getElements();\r
+            for(IElement e : elements) {\r
+                if(e instanceof Variable) {\r
+                    Variable v = (Variable) e;\r
+                    modelVariables.put(v.getName(), v);\r
+                } else if(e instanceof Module) {\r
+                    ignoreVariables.add(((Module)e).getName());\r
+                }\r
+            }\r
+\r
+            // VARIABLE NAMES\r
+\r
+            if(variables.contains("time"))\r
+                variables.remove("time");\r
+            \r
+            // Remove variable references to for indices\r
+            for(ExpressionField ef : forIndices.keySet()) {\r
+                for(Token t : forIndices.get(ef).keySet()) {\r
+                    if(variables.contains(t.image))\r
+                        variables.remove(t.image);\r
+                }\r
+            }\r
+\r
+            // Examine sheets\r
+            for(ExpressionField ef : functionReferences.keySet()) {\r
+                for(String key : functionReferences.get(ef).keySet()) {\r
+                    \r
+                    List<SyntaxError> errors = examineSheetReferences(conf, key, functionReferences.get(ef).get(key), ef.getExpression(), references.get(ef));\r
+                    if(errors != null) {\r
+                        for(SyntaxError error : errors)\r
+                            ef.setSyntaxError(error);\r
+                    }\r
+                }\r
+            }\r
+\r
+            // Examine variable references\r
+            for(String v : variables) {\r
+                ReferenceOption option = getReferenceOption(conf, v);\r
+                switch(option) {\r
+                    case DOES_NOT_EXIST:\r
+                        noSuchVariables.add(v);\r
+                        break;\r
+                    case CANNOT_BE_CONNECTED:\r
+                        ignoreVariables.add(v);\r
+                        break;\r
+                    case CAN_BE_CONNECTED:\r
+                }\r
+            }\r
+\r
+            if(!noSuchVariables.isEmpty()) {\r
+                noSuchVariables.removeAll(ignoreVariables);\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 there are syntax errors, keep the previous coloring.\r
+        String selfName = null;\r
+        if(variableTable != null && !variableTable.isDisposed()) {\r
+            \r
+            // Get the name of the variable itself\r
+            try {\r
+                selfName = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                    @Override\r
+                    public String perform(ReadGraph graph) throws DatabaseException {\r
+                        Layer0 l0 = Layer0.getInstance(graph);\r
+                        Object selfName = graph.getPossibleRelatedValue(variable, l0.HasName);\r
+                        if(selfName != null) {\r
+                            return (String)selfName;\r
+                        }\r
+                        return null;\r
+                    }\r
+                });\r
+            } catch (DatabaseException e) {\r
+                e.printStackTrace();\r
+            }\r
+  \r
+            // Color the items in the table\r
+            TableItem[] connectedVariables = variableTable.getItems();\r
+            for(TableItem ti : connectedVariables) {\r
+                if (ti.getText().equals("time") || ti.getText().equals(selfName)) {\r
+                    ti.setForeground(variableTimeAndSelfColor(resourceManager));\r
+                } else if (parsingSucceeded && !variables.contains(ti.getText())) {\r
+                    ti.setForeground(variableNotFoundColor(resourceManager));\r
+                } else if (parsingSucceeded) {\r
+                    ti.setForeground(variableFoundColor(resourceManager));\r
+                    variables.remove(ti.getText());\r
+                }\r
+            }\r
+\r
+            // Remove all enumerations and sheets, they cannot have connections\r
+            variables.removeAll(ignoreVariables);\r
+\r
+            // Always remove self\r
+            variables.remove(selfName);\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
+        for(final ExpressionField ef : ranges.keySet()) {\r
+            List<SyntaxError> errors = new ArrayList<SyntaxError>();\r
+            // RANGES\r
+            errors.addAll(examineArrayRanges(conf, ranges.get(ef), forIndices.get(ef)));\r
+            \r
+            // ENUMERATION REFERENCES IN FOR-LOOPS\r
+            errors.addAll(examineEnumerationReferences(conf, enumerationReferences.get(ef)));\r
+\r
+            for(SyntaxError error : errors)\r
+                ef.setSyntaxError(error);\r
+        }                                      \r
+    }\r
+    \r
+    \r
+    static public List<SyntaxError> examineArrayRanges(\r
+            final Configuration configuration,\r
+            final HashMap<String, List<List<Token>>> ranges,\r
+            final HashMap<Token, List<Token>> forIndices) {\r
+        \r
+        List<SyntaxError> result = Collections.emptyList();\r
+        try {\r
+            result = SimanticsUI.getSession().syncRequest(new Read<List<SyntaxError>>() {\r
+\r
+                @Override\r
+                public List<SyntaxError> perform(ReadGraph graph) throws DatabaseException {\r
+                    return examineArrayRanges(graph, configuration, ranges, forIndices);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return result;\r
+    }\r
+\r
+    static public List<SyntaxError> examineEnumerationReferences(Configuration configuration, HashMap<String, List<Token>> enumRefList) {\r
+        ArrayList<SyntaxError> result = new ArrayList<SyntaxError>();\r
+        for(String enumeration : enumRefList.keySet()) {\r
+            for(Token et : enumRefList.get(enumeration)) {\r
+                Object o = getElement(configuration, enumeration);\r
+                if(o != null && o instanceof Enumeration) {\r
+                    boolean isFound = false;\r
+                    Enumeration e = (Enumeration)o;\r
+\r
+                    if(enumeration.equals(et.image) ||\r
+                            "size".equals(et.image) || \r
+                            "elements".equals(et.image)){\r
+                        // The full enumeration\r
+                        isFound = true;\r
+                    } else {\r
+                        for(EnumerationIndex ei : e.getEnumerationIndexes()) {\r
+                            if(ei.getName().equals(et.image)) {\r
+                                isFound = true;\r
+                                break;\r
+                            }\r
+                        }\r
+                    }\r
+\r
+                    if(!isFound) {\r
+                        StringBuilder sb = new StringBuilder();\r
+                        sb.append("Enumeration ");\r
+                        sb.append(enumeration);\r
+                        sb.append(" has no such index.\nAvailable indexes are: ");\r
+                        Iterator<EnumerationIndex> iterator = e.getEnumerationIndexes().iterator();\r
+                        while(iterator.hasNext()) {\r
+                            sb.append(iterator.next().getName());\r
+                            if(iterator.hasNext()) \r
+                                sb.append(", ");\r
+                        }\r
+                        result.add(new SyntaxError(et, sb.toString()));\r
+                    }\r
+\r
+\r
+                } else {\r
+                    result.add(new SyntaxError(et, "No such enumeration (" + enumeration + ")")); \r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * \r
+     * @param graph\r
+     * @param configuration\r
+     * @param ranges\r
+     * @param forIndices\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    static public List<SyntaxError> examineArrayRanges(\r
+            ReadGraph graph, \r
+            Configuration configuration,\r
+            HashMap<String, List<List<Token>>> ranges,\r
+            HashMap<Token, List<Token>> forIndices) throws DatabaseException {\r
+        HashMap<Token, SyntaxError> errors = new HashMap<Token, SyntaxError>();\r
+        for(String name : ranges.keySet()) {\r
+            if(ranges.get(name) != null) {\r
+                for(List<Token> l : ranges.get(name)) {\r
+                    String[] rangeReferences = new String[l.size()];\r
+                    for(int i = 0; i < l.size(); i++) {\r
+                        rangeReferences[i] = l.get(i).image;\r
+                    }\r
+\r
+                    Object o = getElement(configuration, name);\r
+                    if(o != null && o instanceof Variable) {\r
+                        Map<Integer, SyntaxError> invalidRanges = ArrayVariableUtils.isRangeValid(graph, (Variable)o, rangeReferences);\r
+                        if(invalidRanges != null && !invalidRanges.isEmpty()) {\r
+                            for(Integer i : invalidRanges.keySet()) {\r
+                                SyntaxError error = invalidRanges.get(i);\r
+                                error.setToken(l.get(i));\r
+                                errors.put(l.get(i), error);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        } \r
+\r
+\r
+        // FOR-INDICES\r
+\r
+        HashSet<Token> removes = new HashSet<Token>();\r
+        for(Token t : forIndices.keySet()) {\r
+//            boolean isFound = false;\r
+            for(Token rt : errors.keySet()) {\r
+                if(rt.image.equals(t.image)) {\r
+//                    isFound = true;\r
+                    // remove range token from invalid ranges\r
+                    removes.add(rt);\r
+                }\r
+            }\r
+//            Why would this be invalid if the index just is not used anywhere?\r
+//            {1+2 for i in range} \r
+            \r
+//            if(!isFound) {\r
+//                SyntaxError error = new SyntaxError(t, "Invalid index"); \r
+//                errors.put(t, error);\r
+//            }\r
+        }\r
+        \r
+        for(Token t : removes)\r
+            errors.remove(t);\r
+\r
+        return new ArrayList<SyntaxError>(errors.values());\r
+    }\r
+\r
+\r
+    /**\r
+     * Examine if a given functionKey is a sheet reference and whether all the tokens in the function ( Sheet1(token1, token2) )\r
+     * are valid.\r
+     *  \r
+     * @param configuration Configuration where the function is called\r
+     * @param functionKey Function name\r
+     * @param functionTokens Function parameters (sheet reference, either a cell or cell range)\r
+     * @param expression The whole expression where the function reference is\r
+     * @param expressionReferences All variable references, including function parameters\r
+     * @return A list of possible errors\r
+     */\r
+    static public List<SyntaxError> examineSheetReferences(\r
+            Configuration configuration, \r
+            String functionKey, \r
+            List<Token> functionTokens,\r
+            String expression, \r
+            HashMap<String, List<Token>> expressionReferences) {\r
+        \r
+        List<SyntaxError> result = new ArrayList<SyntaxError>();\r
+        \r
+        String[] parts = functionKey.split("\\.");\r
+        Object current = configuration;\r
+        for(int i = 0; i < parts.length && current != null; i++) {\r
+            current = getElement(current, parts[i]);\r
+        }\r
+        \r
+        if(current == null && configuration.getModuleType() != null) {\r
+            // Sheets are currently located in the model root. Try to find the sheet.\r
+            current = configuration.getModuleType().getParent(); // Get module type parent (should be a model)\r
+            if(current instanceof Model)\r
+                current = getElement(((Model)current).getModelConfiguration(), parts[0]); // Try to get the sheet\r
+        }\r
+        \r
+        if(current != null && current instanceof Sheet) {\r
+            Sheet sheet = (Sheet) current;\r
+            int start = 0, end = 0, call = 0;\r
+            String cellOrRange = null;\r
+            while((call = expression.indexOf(functionKey, end)) >= 0) {\r
+                start = expression.indexOf("(", call) +1;\r
+                end = expression.indexOf(")", start);\r
+                if(start < 0 || end < 0 || end < start) {\r
+                    break;\r
+                }\r
+                Pattern p = Pattern.compile("[-\\+\\*\\/\\(\\)\\{\\}\\[\\],\\.\\t\\n\\r\\f]");\r
+                cellOrRange = expression.substring(start, end);\r
+                Matcher m = p.matcher(cellOrRange);\r
+                if (m.find() || cellOrRange.split(":").length > 2) {\r
+                    result.add(new SyntaxError(start, end - start, ExpressionField.SYNTAX_ERROR, "Not a valid cell or range", cellOrRange));\r
+                }\r
+            }\r
+            \r
+            \r
+            for(Token cell : functionTokens) {\r
+                List<Token> refs = expressionReferences.get(cell.image);\r
+                if(refs != null)\r
+                    refs.remove(cell);\r
+                if(!sheet.getCells().containsKey(cell.image))\r
+                    result.add(new SyntaxError(cell.image, "Invalid cell", cell.beginLine, cell.beginColumn, cell.endLine, cell.endColumn)); \r
+            }\r
+\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Option for a reference. Whether the reference does not exist, \r
+     * it can be connected (normal variable) or it cannot be \r
+     * connected even though it exists (e.g. enumeration index)\r
+     * \r
+     * @author Teemu Lempinen\r
+     *\r
+     */\r
+    static public enum ReferenceOption {DOES_NOT_EXIST, CAN_BE_CONNECTED, CANNOT_BE_CONNECTED};\r
+    \r
+    /**\r
+     * Get the reference option for a reference (name) in a configuration.\r
+     * \r
+     * @param conf Configuration\r
+     * @param name Referred variable\r
+     * @return The result tells does the referred name exist and can it be connected to \r
+     */\r
+    static public ReferenceOption getReferenceOption(Configuration conf, String name) {\r
+        \r
+        String[] parts = name.split("\\.");\r
+        Object element = conf;\r
+        for(int i = 0; i < parts.length && element != null; i++) {\r
+            element = getElement(element, parts[i]);\r
+        }\r
+        if(element == null)\r
+            return ReferenceOption.DOES_NOT_EXIST;\r
+        else if(Boolean.TRUE.equals(element))\r
+            return ReferenceOption.CANNOT_BE_CONNECTED;\r
+        else if(element instanceof Variable || element instanceof Module) {\r
+            if(element instanceof Enumeration || element instanceof Sheet || element instanceof Module || parts.length > 1)\r
+                return ReferenceOption.CANNOT_BE_CONNECTED;\r
+            else\r
+                return ReferenceOption.CAN_BE_CONNECTED;\r
+        }\r
+        else \r
+            return ReferenceOption.DOES_NOT_EXIST;\r
+    }\r
+\r
+    static private Object getElement(Object parent, String name) {\r
+        Configuration c = null;\r
+        if(parent instanceof Module) {\r
+            Module m = (Module)parent;\r
+            c = m.getType().getConfiguration();\r
+        } else if (parent instanceof Configuration) {\r
+            c = (Configuration)parent;\r
+        }\r
+\r
+        if(c != null) {\r
+            for(IElement e : c.getElements()) {\r
+                if(e instanceof Variable && ((Variable)e).getName().equals(name)) {\r
+                    return e;\r
+                } else if(e instanceof Module && ((Module)e).getName().equals(name)) {\r
+                    return e;\r
+                }\r
+            }\r
+        } else if(parent instanceof Sheet) {\r
+            Sheet s = (Sheet)parent;\r
+            for(String key : s.getCells().keySet()) {\r
+                if(key.equals(name)) {\r
+                    return Boolean.TRUE;\r
+                }\r
+            }\r
+\r
+        } else if(parent instanceof Enumeration) {\r
+            Enumeration e = (Enumeration)parent;\r
+            if(name.equals("size") || name.equals("elements"))\r
+                return Boolean.TRUE;\r
+\r
+            for(EnumerationIndex ei : e.getEnumerationIndexes()) {\r
+                if(ei.getName().equals(name)) {\r
+                    return Boolean.TRUE;\r
+                }\r
+            }\r
+\r
+        }\r
+\r
+        return null;\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
+                        if (st != null) {\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
+                    }\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
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionLibraryNameValidator.java
new file mode 100644 (file)
index 0000000..bf67e47
--- /dev/null
@@ -0,0 +1,74 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for function libraries.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class FunctionLibraryNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource functionLibrary, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        \r
+        if(functionLibrary == null)\r
+            return false;\r
+        \r
+        Resource containingLibrary = graph.getPossibleObject(functionLibrary, l0.PartOf);\r
+        if(containingLibrary == null)\r
+            return true;\r
+        \r
+        // Check if the function is right under the model.\r
+        if (graph.isInstanceOf(containingLibrary, sr.SysdynModel)) {\r
+            Resource configurationResource = graph.getPossibleObject(containingLibrary, SIMU.HasConfiguration);\r
+            if(configurationResource == null)\r
+                return true;\r
+            SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+            sysdynModel.update(graph);\r
+            \r
+            if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true;\r
+            \r
+            // Check that the functioLibrary name != model name (== containingLibrary name)\r
+            if (NameUtils.getSafeName(graph, containingLibrary).equals(name)) return true;\r
+            \r
+            if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+            if (nameTakenBySharedFunctionLibrary(graph, containingLibrary, null, name)) return true;\r
+            \r
+            if (nameTakenBySheet(sysdynModel, name)) return true;\r
+        }\r
+\r
+        // Containing library may also be the model\r
+        if (nameTakenByItemUnderLibrary(graph, containingLibrary, functionLibrary, name)) return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/FunctionNameValidator.java
new file mode 100644 (file)
index 0000000..95b7d97
--- /dev/null
@@ -0,0 +1,70 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for functions.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class FunctionNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) throws DatabaseException {\r
+        // TODO\r
+    }\r
+    \r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException {\r
+        // TODO\r
+    }\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource function, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        \r
+        if(function == null)\r
+            return false;\r
+        \r
+        Resource library = graph.getPossibleObject(function, l0.PartOf);\r
+        if(library == null)\r
+            return true;\r
+        \r
+        // Check if the function is right under the model.\r
+        if (graph.isInstanceOf(library, sr.SysdynModel)) {\r
+            Resource configurationResource = graph.getPossibleObject(library, SIMU.HasConfiguration);\r
+            if(configurationResource == null)\r
+                return true;\r
+            SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+            sysdynModel.update(graph);\r
+            \r
+            if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true;\r
+            \r
+            // Check that the function name != model name (== library name)\r
+            if (NameUtils.getSafeName(graph, library).equals(name)) return true;\r
+            \r
+            if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+            if (nameTakenBySharedFunctionLibrary(graph, library, null, name)) return true;\r
+            \r
+            if (nameTakenBySheet(sysdynModel, name)) return true;\r
+        }\r
+\r
+        // Containing library may also be the model\r
+        if (nameTakenByItemUnderLibrary(graph, library, function, name)) return true;\r
+\r
+        return false;\r
+    }\r
+
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/HandlerUtils.java
new file mode 100644 (file)
index 0000000..cfc8855
--- /dev/null
@@ -0,0 +1,49 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.eclipse.core.commands.ExecutionEvent;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Control;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.simantics.sysdyn.ui.properties.RemoveFocusBeforeExperimentComposite;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionComposite;\r
+\r
+/**\r
+ * Utility methods for handlers.\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class HandlerUtils {\r
+    \r
+    /**\r
+     * Save the equation of EquationTab, if the keyboard focus is somewhere inside an EquationTab.\r
+     * \r
+     * @param event ExecutionEvent of which triggering event is used to determine who has focus. \r
+     */\r
+    public static void saveBeforeExperimentRun(ExecutionEvent event) {\r
+        if (event.getTrigger() instanceof Event) {\r
+            Event trigger = (Event)event.getTrigger();\r
+            Control focusControl = trigger.display.getFocusControl();\r
+            if(focusControl == null) {\r
+                new Exception(\r
+                        "Could not determine, if equation needs to be saved before action. focusControl == null")\r
+                .printStackTrace();\r
+                return;\r
+            }\r
+            Composite parent = focusControl.getParent();\r
+            \r
+            /* Scan bottom-up if we come across an EquationTab. \r
+             * If so, ask it to save the expression.*/\r
+            while (parent != null) {\r
+                if (parent instanceof ExpressionComposite) {\r
+                    ExpressionComposite expressionComposite = (ExpressionComposite)parent;\r
+                    expressionComposite.saveExpression();\r
+                    break;\r
+                } else if(parent instanceof RemoveFocusBeforeExperimentComposite) {\r
+                    focusControl.getParent().forceFocus();\r
+                    break;\r
+                }\r
+                parent = parent.getParent();\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelNameValidator.java
new file mode 100644 (file)
index 0000000..ec53c88
--- /dev/null
@@ -0,0 +1,56 @@
+package org.simantics.sysdyn.ui.utils;\r
+\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.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for model.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class ModelNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource model, String name) throws DatabaseException {\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        \r
+        if(model == null)\r
+            return false;\r
+\r
+        if (nameTakenByFunctionFunctionLibraryOrModuleType(graph, model, name)) return true;\r
+        \r
+        Resource configurationResource = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
+        if(configurationResource == null)\r
+            return true;\r
+        SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+        sysdynModel.update(graph);\r
+        \r
+        if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true;\r
+        \r
+        if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+        if (nameTakenBySharedFunctionLibrary(graph, model, null, name)) return true;\r
+\r
+        if (nameTakenBySheet(sysdynModel, name)) return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName)\r
+            throws DatabaseException {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName)\r
+            throws DatabaseException {\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModuleTypeNameValidator.java
new file mode 100644 (file)
index 0000000..8a3c851
--- /dev/null
@@ -0,0 +1,84 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for module types.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class ModuleTypeNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource moduleTypeSymbol, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        if(moduleTypeSymbol == null)\r
+            return false;\r
+\r
+        Resource moduleType;\r
+        if (graph.isInheritedFrom(moduleTypeSymbol, sr.Module)) {\r
+            // Renamed in model browser\r
+            moduleType = moduleTypeSymbol;\r
+        } else {\r
+            // Renamed in ModuleTypeTab\r
+            moduleType = graph.getPossibleObject(moduleTypeSymbol, mr.SymbolToComponentType);\r
+        }\r
+        if(moduleType == null)\r
+            return true;\r
+        \r
+        // All ModuleTypes are under the top level model\r
+        Resource model = graph.getPossibleObject(moduleType, l0.PartOf);\r
+        if(model == null)\r
+            return true;\r
+\r
+        Resource configurationResource = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
+        if(configurationResource == null)\r
+            return true;\r
+        SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+        sysdynModel.update(graph);\r
+        \r
+        if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true;\r
+        \r
+        // Check that the module name != model name\r
+        if (NameUtils.getSafeName(graph, model).equals(name)) return true;\r
+        \r
+        if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+        if (nameTakenBySharedFunctionLibrary(graph, model, null, name)) return true;\r
+        \r
+        if (nameTakenBySheet(sysdynModel, name)) return true;\r
+\r
+        if (nameTakenByItemUnderLibrary(graph, model, moduleType, name)) return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/NameValidator.java
new file mode 100644 (file)
index 0000000..ff352c7
--- /dev/null
@@ -0,0 +1,378 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import java.util.Collection;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.spreadsheet.resource.SpreadsheetResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.representation.Configuration;\r
+import org.simantics.sysdyn.representation.IElement;\r
+import org.simantics.sysdyn.representation.Module;\r
+import org.simantics.sysdyn.representation.Shadow;\r
+import org.simantics.sysdyn.representation.Sheet;\r
+import org.simantics.sysdyn.representation.Variable;\r
+import org.simantics.sysdyn.ui.modelica.ModelicaSourceViewerConfiguration;\r
+import org.simantics.sysdyn.utils.Function;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+\r
+/**\r
+ * This class is used when renaming an element to check that there\r
+ * are no elements in the database that would cause a conflict. There\r
+ * are two kinds of different conflicts:\r
+ * 1) There is an element in the database which has the same URI.\r
+ *    Adding another causes damage or even a fatal corruption in the \r
+ *    database.\r
+ * 2) Multiple different elements in the database are accessed with\r
+ *    identical identifiers in the generated Modelica model. This will\r
+ *    prevent the simulation from running. \r
+ * \r
+ * @author Tuomas Miettinen\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public abstract class NameValidator {\r
+\r
+    /**\r
+     * This method tells the validator whether the proposed name is taken. To be more precise,\r
+     * it tells if the proposed name should not be used for any reason. E.g. similarly named\r
+     * resources cause problems in some occasions and are fine in others. In addition, there\r
+     * (at least )are two reasons to decline a name proposition: firstly, the data base might\r
+     * have a similarly named entity, and secondly, accepting a proposed name would lead in\r
+     * naming conflicts in the generated OpenModelica model.\r
+     * \r
+     * @param graph\r
+     * @param resource the Resource which is being renamed\r
+     * @param name the proposed name\r
+     * @return true iff the name proposition is denied\r
+     * @throws DatabaseException\r
+     */\r
+    protected abstract boolean nameIsTaken(ReadGraph graph, Resource resource, String name) throws DatabaseException;\r
+\r
+    /**\r
+     * Replaces variable names in all the expressions in the defined configuration. \r
+     * Replace doesn't have to replace words in other configurations than the configuration where the renamed variable is\r
+     * because input variables handle the transitions between configurations (modules).\r
+     * \r
+     * @param graph WriteGraph\r
+     * @param configuration The configuration where the renamed variable is located\r
+     * @param originalName The original name of the variable\r
+     * @param newName New name of the variable\r
+     */\r
+    public abstract void renameInEquations(WriteGraph graph, Resource resource, String originalName, String newName) throws DatabaseException;\r
+\r
+    public abstract void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException;\r
+\r
+    /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other functions that have the same name in neither the \r
+     * configuration nor among built in functions\r
+     *  \r
+     * @param graph ReadGraph\r
+     * @param resource The variable that is being renamed\r
+     * @param name The new name of the variable\r
+     * @return true iff the new name is valid\r
+     * @throws DatabaseException\r
+     */\r
+    public boolean isValid(ReadGraph graph, Resource resource, String name) throws DatabaseException {\r
+        // Decline empty string\r
+        if(name.length() < 1) return false;\r
+        \r
+        // Decline names based on the type of the resource\r
+        if(nameIsTaken(graph, resource, name)) return false;\r
+        \r
+        // Decline names which are against Modelica naming rules\r
+        boolean allowSpaces = doesResourceAllowSpacedName(graph, resource);\r
+        if(!isValidModelica(name, allowSpaces)) return false;\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Determine whether a Sysdyn Variable can have whitespace in its name (based on its type).\r
+     * @param graph\r
+     * @param resource Resource of the variable\r
+     * @return true iff spaces are allowed in the name\r
+     */\r
+    protected boolean doesResourceAllowSpacedName(ReadGraph graph,\r
+                       Resource resource) {\r
+           SysdynResource sr = SysdynResource.getInstance(graph);\r
+           SpreadsheetResource sheet = SpreadsheetResource.getInstance(graph);\r
+       try {\r
+               if (resource == null)\r
+                       return false;\r
+               // Function, FunctionLibrary, and SharedFunctionLibrary are not\r
+               // allowed to have whitespace.\r
+               if (graph.isInstanceOf(resource, sr.Variable)\r
+                                       || graph.isInstanceOf(resource, sr.Module)\r
+                                       || graph.isInheritedFrom(resource, sr.ModuleSymbol)\r
+                                       || graph.isInstanceOf(resource, sr.Enumeration)\r
+                                       || graph.isInstanceOf(resource, sr.EnumerationIndex)\r
+                                       || graph.isInstanceOf(resource, sheet.Spreadsheet)\r
+                                       || graph.isInstanceOf(resource, sr.SysdynModel)) {\r
+                               return true;\r
+                       }\r
+               } catch (ServiceException e) {\r
+                       // TODO Auto-generated catch block\r
+                       e.printStackTrace();\r
+               }\r
+       return false;\r
+       }\r
+\r
+       /**\r
+     * Checks that the syntax of the given name is valid and there \r
+     * are no other variables that have the same name in the configuration\r
+     *  \r
+     * @param variable The variable that is being renamed\r
+     * @param name The new name of the variable\r
+     * @return true iff the new name is valid\r
+     * @throws DatabaseException\r
+     */\r
+    public boolean isValid(final Resource resource, final String name) {\r
+        boolean result = false;\r
+\r
+        try {\r
+            result = SimanticsUI.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                @Override\r
+                public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                    return isValid(graph, resource, name);\r
+                }\r
+\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * Checks that the syntax of the given name is valid \r
+     * and that it is not a keyword in Modelica.\r
+     * \r
+     * @param name name that is validated\r
+     * @return true iff the syntax of the name is valid\r
+     */\r
+    public boolean isValidModelica(String name, boolean allowSpaces) {\r
+        String lowerCase = name.toLowerCase();\r
+        String pattern = "[a-zA-Z][a-zA-Z0-9]*" + (allowSpaces ? "( [a-zA-Z][a-zA-Z0-9]*)*" : "");\r
+        Pattern p = Pattern.compile(pattern);\r
+        Matcher m = p.matcher(lowerCase);\r
+        if (!m.matches()) {\r
+            return false;\r
+        } else {\r
+               String[] splitNames= name.split("\\s+");\r
+               for (String splitName : splitNames) {\r
+                       // Do not allow Modelica keywords to be a part of a whitespaced name\r
+                       if (ModelicaSourceViewerConfiguration.keywords.contains(splitName)) {\r
+                               return false;\r
+                       }\r
+               }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Checks that there is no similarly named spread sheet in the top level model.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param configurationResource Resource of the configuration of the model\r
+     * @param resource Resource being validated\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenBySheet(\r
+            ReadGraph graph, \r
+            Resource configurationResource, \r
+            Resource resource, \r
+            String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SpreadsheetResource SHEET = SpreadsheetResource.getInstance(graph);\r
+        for (Resource r : graph.getObjects(configurationResource, l0.ConsistsOf)) {\r
+            if (graph.isInstanceOf(r, SHEET.Book)) {\r
+                for (Resource s : graph.getObjects(r, l0.ConsistsOf)) {\r
+                    if (NameUtils.getSafeName(graph, s).equals(name) && !s.equals(resource)) {\r
+                        return true;\r
+                    }\r
+                }\r
+                // Assume only one book\r
+                break;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Checks that there is no similarly named spread sheet in the top level model.\r
+     * \r
+     * @param sysdynModel the model\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     */\r
+    public boolean nameTakenBySheet(\r
+            SysdynModel sysdynModel, \r
+            String name) {\r
+       Configuration configuration = sysdynModel.getConfiguration();\r
+        if (configuration == null)\r
+            return true;\r
+        for (IElement e : configuration.getElements()) {\r
+            if (e instanceof Sheet) {\r
+                if (((Sheet)e).getName().equals(name)) {\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Check that there are no similarly named functions, module types, or any\r
+     * other items in the same library. There are actually plenty of items that have\r
+     * to be avoided, probably all of them, they are all included in this test. \r
+     * \r
+     * @param graph ReadGraph\r
+     * @param library Resource which is studied\r
+     * @param resource Resource being validated\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenByItemUnderLibrary(\r
+            ReadGraph graph,\r
+            Resource library,\r
+            Resource resource,\r
+            String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        for (Resource r : graph.getObjects(library, l0.ConsistsOf)) {\r
+            if (NameUtils.getSafeName(graph, r).equals(name) && !r.equals(resource)) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Check that there is no similarly named function library among shared function libraries.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param model resource of the top level model under which the resource is\r
+     * @param resource Resource being validated\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenBySharedFunctionLibrary(\r
+            ReadGraph graph,\r
+            Resource model, \r
+            Resource resource,\r
+            String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Collection<Resource> linkedResources = graph.getObjects(model, l0.IsLinkedTo);\r
+        for (Resource r : linkedResources) {\r
+            // Find the "Shared functions" library \r
+            if (graph.isInstanceOf(r, sr.SharedFunctionOntology)) {\r
+                if (NameUtils.getSafeName(graph, r).equals(name) && !r.equals(resource)) {\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Check that there is no similarly named function among built-in functions\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param name name that is checked\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenByBuiltInFunction(\r
+            ReadGraph graph, \r
+            String name) throws DatabaseException {\r
+        for (Function f : Function.getAllBuiltInFunctions(graph)) {\r
+            if (f.getName().equals(name)) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Check that the top level of the model doesn't contain \r
+     * a variable or module with the same name.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param sysdynModel the model\r
+     * @param resource Resource being validated\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenByTopLevelVariableOrModule(\r
+            ReadGraph graph,\r
+            SysdynModel sysdynModel,\r
+            Resource resource,\r
+            String name) throws DatabaseException {\r
+        Configuration configuration = sysdynModel.getConfiguration();\r
+        if(configuration == null)\r
+            return true;\r
+        IElement current = sysdynModel.getElement(resource);\r
+        for(IElement e : configuration.getElements()) {\r
+            if(e instanceof Variable && !(e instanceof Shadow)) {\r
+                Variable v = (Variable) e;\r
+                if(!v.equals(current) && v.getName() != null && v.getName().equals(name)) {\r
+                    return true;\r
+                }\r
+            } else if (e instanceof Module) {\r
+                Module m = (Module)e;\r
+                if(!m.equals(current) && m.getName() != null && m.getName().equals(name)) {\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    /**\r
+     * Check that there is no similarly named function, function library,\r
+     * or module type directly under a library\r
+     * \r
+     * This function should not be used by functions, function libraries, or module types\r
+     *\r
+     * @param graph ReadGraph\r
+     * @param library Resource which is studied\r
+     * @param name proposed new name for resource\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    protected boolean nameTakenByFunctionFunctionLibraryOrModuleType(\r
+            ReadGraph graph,\r
+            Resource library,\r
+            String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        for (Resource r : graph.getObjects(library, l0.ConsistsOf)) {\r
+            if (graph.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)\r
+                    || graph.isInstanceOf(r, sr.SysdynModelicaFunction)\r
+                    || graph.isInheritedFrom(r, sr.Module)) {\r
+                if (NameUtils.getSafeName(graph, r).equals(name)) {\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/OldTransferableGraph1.java
new file mode 100644 (file)
index 0000000..558f5a3
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\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.utils;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.serialization.Serializer;\r
+import org.simantics.graph.representation.External;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.Internal;\r
+import org.simantics.graph.representation.Root;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.graph.representation.Value;\r
+\r
+\r
+/**\r
+ * Transferable graph datatype. \r
+ * See <a href="https://www.simantics.org/wiki/index.php/Graph_exchange_format">specification</a>. \r
+ * @author Hannu Niemistö\r
+ */\r
+public class OldTransferableGraph1 {\r
+       public static Binding BINDING = Bindings.getBindingUnchecked(TransferableGraph1.class);\r
+       public static Serializer SERIALIZER = Bindings.getSerializerUnchecked(BINDING);\r
+       \r
+       public int resourceCount;\r
+       public Identity[] identities;   \r
+       public int[] statements;\r
+       public Value[] values;  \r
+       \r
+       public OldTransferableGraph1() {\r
+       }\r
+       \r
+       public OldTransferableGraph1(int resourceCount, Identity[] identities,\r
+                       int[] statements, Value[] values) {\r
+               this.resourceCount = resourceCount;\r
+               this.identities = identities;\r
+               this.statements = statements;\r
+               this.values = values;\r
+       }\r
+\r
+       public void print() {\r
+               System.out.println("Identities");\r
+               for(Identity id : identities) {\r
+                       System.out.print("    " + id.resource + " = ");\r
+                       if(id.definition instanceof Root) {\r
+                               Root def = (Root)id.definition;\r
+                               System.out.println("ROOT(" + def.name + ")");\r
+                       }\r
+                       else if(id.definition instanceof External) {\r
+                               External def = (External)id.definition;\r
+                               System.out.println("EXTERNAL(" + def.parent + ", " + def.name + ")");\r
+                       }\r
+                       else if(id.definition instanceof Internal) {\r
+                               Internal def = (Internal)id.definition;\r
+                               System.out.println("INTERNAL(" + def.parent + ", " + def.name + ")");\r
+                       }\r
+               }\r
+               System.out.println("Statements:");\r
+               for(int i=0;i<statements.length;i+=4)\r
+                       System.out.println("    " + \r
+                                       statements[i] + " " +\r
+                                       statements[i+1] + " " +\r
+                                       statements[i+2] + " " +\r
+                                       statements[i+3]\r
+                                       );\r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SharedFunctionLibraryNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SharedFunctionLibraryNameValidator.java
new file mode 100644 (file)
index 0000000..d48e025
--- /dev/null
@@ -0,0 +1,70 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for shared function libraries.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class SharedFunctionLibraryNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource functionLibrary, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+        \r
+        if(functionLibrary == null)\r
+            return false;\r
+        \r
+        // Do the checking for all models that are linked to that shared function library\r
+        for (Resource model : graph.getObjects(functionLibrary, l0.IsLinkedTo_Inverse)) {\r
+            if(model == null)\r
+                return true;\r
+\r
+            Resource configurationResource = graph.getPossibleObject(model, SIMU.HasConfiguration);\r
+            if(configurationResource == null)\r
+                return true;\r
+            SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+            sysdynModel.update(graph);\r
+            \r
+            if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, null, name)) return true;\r
+\r
+            // Check that the functionLibrary name != model name\r
+            if (NameUtils.getSafeName(graph, model).equals(name)) return true;\r
+            \r
+            if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+            if (nameTakenBySharedFunctionLibrary(graph, model, functionLibrary, name)) return true;\r
+            \r
+            if (nameTakenBySheet(sysdynModel, name)) return true;\r
+            \r
+            if (nameTakenByItemUnderLibrary(graph, model, null, name)) return true;\r
+        }\r
+        \r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SheetNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SheetNameValidator.java
new file mode 100644 (file)
index 0000000..115f58e
--- /dev/null
@@ -0,0 +1,70 @@
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+\r
+/**\r
+ * Name validator for spread sheets.\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class SheetNameValidator extends NameValidator {\r
+\r
+    @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource sheet, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        \r
+        if(sheet == null)\r
+            return false;\r
+        \r
+        Resource book = graph.getPossibleObject(sheet, l0.PartOf);\r
+        if(book == null)\r
+            return true;\r
+        \r
+        Resource configurationResource = graph.getPossibleObject(book, l0.PartOf);\r
+        if(configurationResource == null)\r
+            return true;\r
+        SysdynModel sysdynModel = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configurationResource);\r
+        sysdynModel.update(graph);\r
+        \r
+        Resource model = graph.getPossibleObject(configurationResource, l0.PartOf);\r
+        if(model == null)\r
+            return true;\r
+\r
+        if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, sheet, name)) return true;\r
+        \r
+        // Check that the sheet name != model name\r
+        if (NameUtils.getSafeName(graph, model).equals(name)) return true;\r
+        \r
+        if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+        if (nameTakenBySharedFunctionLibrary(graph, model, null, name)) return true;\r
+        \r
+        if (nameTakenBySheet(graph, configurationResource, sheet, name)) return true;\r
+\r
+        if (nameTakenByItemUnderLibrary(graph, model, null, name)) return true;\r
+\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName)\r
+            throws DatabaseException {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SyntaxError.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SyntaxError.java
new file mode 100644 (file)
index 0000000..9497924
--- /dev/null
@@ -0,0 +1,224 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import org.eclipse.jface.text.BadLocationException;\r
+import org.eclipse.jface.text.IDocument;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+import org.simantics.sysdyn.ui.properties.widgets.expressions.ExpressionField;\r
+\r
+/**\r
+ * Class for containing errors caught in expression validation\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class SyntaxError {\r
+    \r
+    private String type, message, image;\r
+    private int beginLine, beginColumn, endLine, endColumn;\r
+    private Integer start, offset;\r
+    \r
+    /**\r
+     * A syntax error without any info. Remember to assign location, \r
+     * type and message information.\r
+     */\r
+    public SyntaxError() {\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Creates an error from expression parser token\r
+     * @param token expressionParser token\r
+     * @param message Error message\r
+     */\r
+    public SyntaxError(Token token, String message){\r
+        this(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+    }\r
+    \r
+    /**\r
+     * Creates an error from table parser token\r
+     * @param token tableParser token\r
+     * @param message Error message\r
+     */\r
+    public SyntaxError(org.simantics.sysdyn.tableParser.Token token, String message){\r
+        this(token.image, message, token.beginLine, token.beginColumn, token.endLine, token.endColumn);\r
+    }\r
+    \r
+    /**\r
+     * Create syntax error with full data\r
+     * @param image\r
+     * @param message\r
+     * @param beginLine\r
+     * @param beginColumn\r
+     * @param endLine\r
+     * @param endColumn\r
+     */\r
+    public SyntaxError(String image, String message, int beginLine, int beginColumn, int endLine, int endColumn) {\r
+        this.image = image;\r
+        this.message = message;\r
+        this.beginLine = beginLine;\r
+        this.beginColumn = beginColumn;\r
+        this.endLine = endLine;\r
+        this.endColumn = endColumn;\r
+        this.type = ExpressionField.SYNTAX_ERROR;\r
+    }\r
+    \r
+    /**\r
+     * Create syntax error with location, message and type data\r
+     * @param start\r
+     * @param offset\r
+     * @param type\r
+     * @param message\r
+     */\r
+    public SyntaxError(int start, int offset, String type, String message) {\r
+        this(start, offset, type, message, null);\r
+    }\r
+    \r
+    /**\r
+     * Create syntax error with location, message and type data\r
+     * @param start\r
+     * @param offset\r
+     * @param type\r
+     * @param message\r
+     */\r
+    public SyntaxError(int start, int offset, String type, String message, String image) {\r
+        this.image = image;\r
+        this.start = start;\r
+        this.offset = offset;\r
+        this.type = type;\r
+        this.message = message;\r
+    }\r
+    \r
+    /**\r
+     * Get start location of the issue. If start has not been set,\r
+     * document is used to calculate it.\r
+     * @param document\r
+     * @return\r
+     */\r
+    public int getStart(IDocument document) {\r
+        if(this.start != null)\r
+            return this.start;\r
+        else if(document != null){\r
+            int start = 0;\r
+            if(document.getLength() > 0) {\r
+                try {\r
+                    start = document.getLineOffset(beginLine - 1) + beginColumn - 1;\r
+                } catch (BadLocationException e) {\r
+                    //e.printStackTrace();\r
+                }\r
+            }\r
+            return start;\r
+        } else {\r
+            return 0;\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get offset data of the issue. If offset has not been set,\r
+     * document is used to calculate it.\r
+     * \r
+     * @param document\r
+     * @return\r
+     */\r
+    public int getOffset(IDocument document) {\r
+        if(this.offset != null) \r
+            return this.offset;\r
+        else if(document != null){\r
+            int start = getStart(document);\r
+            int offset = document.getLength();\r
+            if(document.getLength() > 0) {\r
+                try {\r
+                    offset = document.getLineOffset(endLine - 1) + endColumn - start;\r
+                } catch (BadLocationException e) {\r
+                    //e.printStackTrace();\r
+                }\r
+            }\r
+            return offset;\r
+        } else {\r
+            return 0;\r
+        }\r
+    }\r
+    \r
+    public void setToken(Token token){\r
+       this.image = token.image;\r
+       this.beginLine = token.beginLine;\r
+       this.beginColumn = token.beginColumn;\r
+       this.endLine = token.endLine;\r
+       this.endColumn = token.endColumn;\r
+    }\r
+    \r
+    public void setToken(org.simantics.sysdyn.tableParser.Token token){\r
+        this.image = token.image;\r
+        this.beginLine = token.beginLine;\r
+        this.beginColumn = token.beginColumn;\r
+        this.endLine = token.endLine;\r
+        this.endColumn = token.endColumn;\r
+    }\r
+    \r
+    public String getType() {\r
+        return type;\r
+    }\r
+\r
+    public void setType(String type) {\r
+        this.type = type;\r
+    }\r
+\r
+    public String getMessage() {\r
+        return message;\r
+    }\r
+\r
+    public void setMessage(String message) {\r
+        this.message = message;\r
+    }\r
+\r
+    public String getImage() {\r
+        return image;\r
+    }\r
+\r
+    public void setImage(String image) {\r
+        this.image = image;\r
+    }\r
+\r
+    public int getBeginLine() {\r
+        return beginLine;\r
+    }\r
+\r
+    public void setBeginLine(int beginLine) {\r
+        this.beginLine = beginLine;\r
+    }\r
+\r
+    public int getBeginColumn() {\r
+        return beginColumn;\r
+    }\r
+\r
+    public void setBeginColumn(int beginColumn) {\r
+        this.beginColumn = beginColumn;\r
+    }\r
+\r
+    public int getEndLine() {\r
+        return endLine;\r
+    }\r
+\r
+    public void setEndLine(int endLine) {\r
+        this.endLine = endLine;\r
+    }\r
+\r
+    public int getEndColumn() {\r
+        return endColumn;\r
+    }\r
+\r
+    public void setEndColumn(int endColumn) {\r
+        this.endColumn = endColumn;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/SysdynWorkbenchUtils.java
new file mode 100644 (file)
index 0000000..987fce9
--- /dev/null
@@ -0,0 +1,95 @@
+/*******************************************************************************\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.utils;\r
+\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.IToolMode;\r
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
+import org.simantics.sysdyn.ui.elements.SysdynElementHints;\r
+import org.simantics.utils.datastructures.hints.IHintContext;\r
+import org.simantics.utils.threads.ThreadUtils;\r
+\r
+/**\r
+ * Workbench utilities.\r
+ * \r
+ * @author Tuomas Miettinen\r
+ */\r
+public class SysdynWorkbenchUtils {\r
+\r
+       /**\r
+        * Get the active page of the diagram editor.\r
+        * \r
+        * @return active page of the diagram editor.\r
+        */\r
+       public static IWorkbenchPage getActivePageOfEditor() {\r
+               DiagramEditor editor = null;\r
+               IWorkbench workbench = PlatformUI.getWorkbench();\r
+               IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();\r
+               IWorkbenchPage page = null;\r
+               // To ask for the active window doesn't work, so browse through all\r
+               // windows and when an active editor is found, use that\r
+               for (IWorkbenchWindow window : windows) {\r
+                       page = window.getActivePage();\r
+                       if (page != null) {\r
+                               try {\r
+                           editor = (DiagramEditor)page.getActiveEditor();\r
+                           if (editor != null)\r
+                                       // Found one\r
+                                       break;\r
+                               } catch (ClassCastException e) {\r
+                                       continue;\r
+                   }\r
+                       }\r
+               }\r
+               return page;\r
+       }\r
+       \r
+       public static IToolMode getSysdynToolMode() {\r
+               IWorkbenchPage p = SysdynWorkbenchUtils.getActivePageOfEditor();\r
+               IEditorPart editor = p.getActiveEditor();\r
+               final ICanvasContext context = (ICanvasContext)(editor.getAdapter(ICanvasContext.class));\r
+               ToolQuery toolQuery = new ToolQuery(context);\r
+               ThreadUtils.syncExec(context.getThreadAccess(), toolQuery);\r
+               return toolQuery.getSysdynToolMode();\r
+       }\r
+\r
+       static class ToolQuery implements Runnable {\r
+\r
+               private IToolMode mode;\r
+               private ICanvasContext context;\r
+               \r
+               ToolQuery(ICanvasContext context) {\r
+                       this.context = context;\r
+                       this.mode = null;\r
+               }\r
+               \r
+               @Override\r
+               public void run() {\r
+                       IHintContext hc = context.getDefaultHintContext();\r
+                       if (hc == null)\r
+                               return;\r
+                       IToolMode sysdynMode = hc.getHint(SysdynElementHints.SYSDYN_KEY_TOOL);\r
+                       mode = sysdynMode;\r
+               }\r
+               \r
+               public IToolMode getSysdynToolMode() {\r
+                       return mode;\r
+               }\r
+               \r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/VariableNameValidator.java
new file mode 100644 (file)
index 0000000..b818a50
--- /dev/null
@@ -0,0 +1,267 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils;\r
+\r
+import java.io.StringReader;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.StringTokenizer;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\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.representation.Configuration;\r
+import org.simantics.sysdyn.representation.Model;\r
+import org.simantics.sysdyn.representation.ModuleType;\r
+import org.simantics.sysdyn.utils.ModelUtils;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+/**\r
+ * Name validator for variables, modules, and enumerations.\r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ * \r
+ */\r
+public class VariableNameValidator extends NameValidator {\r
+\r
+       @Override\r
+    public void renameInEquations(WriteGraph graph, Resource variable, String originalName, String newName) throws DatabaseException {\r
+               /*FIXME: \r
+                * How this works when range used in equations has the same string as\r
+                * the renamed variable? Should it be possible? \r
+                */ \r
+        if(originalName.equals(newName))\r
+            return; // Do nothing\r
+               \r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        Resource expressions = graph.getPossibleObject(variable, sr.Variable_expressionList);\r
+        if(expressions  != null) {\r
+            List<Resource> expressionList = ListUtils.toList(graph, expressions);\r
+            for(Resource s : expressionList) {\r
+                for(Resource p : graph.getPredicates(s)) {\r
+                    Resource o = graph.getPossibleObject(s, p);\r
+                    if(o != null && graph.isInstanceOf(o, l0.String) && !p.equals(sr.Expression_arrayRange)) {\r
+                        String string = graph.getRelatedValue(s, p);\r
+                        String replaced  = replaceAllWords(string, originalName, newName);\r
+                        if(!string.equals(replaced))\r
+                               graph.claimLiteral(s, p, replaced);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+       }\r
+       \r
+       @Override\r
+    public void renameInAllEquations(WriteGraph graph, Resource configuration, String originalName, String newName) throws DatabaseException {\r
+           if(originalName.equals(newName))\r
+               return; // Do nothing\r
+\r
+           Layer0 l0 = Layer0.getInstance(graph);\r
+           SysdynResource sr = SysdynResource.getInstance(graph);\r
+           for(Resource r : graph.getObjects(configuration, l0.ConsistsOf)) {\r
+               if(graph.isInstanceOf(r, sr.IndependentVariable)) {\r
+                   renameInEquations(graph, r, originalName, newName);\r
+               }\r
+           }\r
+       }\r
+\r
+       private static String replaceAllWords(String original, String find, String replacement) {\r
+               // Test if the new name (String find) is found in the original \r
+               // string in some format.\r
+               String pattern = "(.|\r|\n)*" + find.replace(" ", "\\s+") + "(.|\r|\n)*";\r
+               if(!original.matches(pattern)) return original;\r
+               if (find.equals(replacement)) return original;\r
+\r
+        ExpressionParser parser = new ExpressionParser(new StringReader(original));\r
+        try {\r
+                       parser.expr();\r
+               } catch (ParseException e) {\r
+                       // Best effort; if there are syntax errors, the replace may fail.\r
+               }\r
+        \r
+        // Collect all references\r
+        HashMap<String, List<Token>> allReferences = new HashMap<String, List<Token>>();\r
+        allReferences.putAll(parser.getReferences());\r
+        allReferences.putAll(parser.getFunctionCallReferences());\r
+        allReferences.putAll(parser.getEnumerationReferences());\r
+               \r
+        List<Token> replacedTokens = allReferences.get(find);\r
+        if (replacedTokens == null)\r
+               return original;\r
+        \r
+        // Sort the tokens so that they are in the reversed order based on\r
+        // their location in the expression.\r
+        Collections.sort(replacedTokens);\r
+        Collections.reverse(replacedTokens);\r
+        \r
+        // Go through the tokens in the reversed order\r
+        String result = new String(original);\r
+               for (Token token : replacedTokens) {\r
+               // Find the place where the last token points to in the original string\r
+               // First find where the correct line starts:\r
+               int startingPoint = 0;\r
+               for (int i = 0; i < token.beginLine - 1; ++i)\r
+                       startingPoint = result.indexOf('\n', startingPoint) + 1;\r
+               // Then where the replaced string starts: \r
+               startingPoint += token.beginColumn - 1;\r
+               \r
+               // Cut the string\r
+               String begin = result.substring(0, startingPoint);\r
+               String end = result.substring(startingPoint);\r
+               \r
+               // Replace the string\r
+               String regex = find.replaceAll(" ", "\\\\s+");\r
+               end = end.replaceFirst(regex, replacement);\r
+               result = begin + end;\r
+        }\r
+               \r
+               return result;\r
+       }\r
+\r
+\r
+       @Override\r
+    protected boolean nameIsTaken(ReadGraph graph, Resource variable, String name) throws DatabaseException {\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+        if(variable == null)\r
+                       return false;\r
+        \r
+               SysdynModel sysdynModel = ModelUtils.getModel(graph, variable);\r
+               if(sysdynModel == null)\r
+                       return true;\r
+               sysdynModel.update(graph);\r
+        \r
+               Configuration configuration = sysdynModel.getConfiguration();\r
+               if(configuration == null)\r
+                   return true;\r
+               \r
+               // Get the top level model\r
+        Model rootModel = null;\r
+        ModuleType moduleType = configuration.getModuleType();\r
+        if (moduleType != null) {\r
+            Object o = moduleType.getParent();\r
+            if (o instanceof Model) {\r
+                rootModel = (Model)o;\r
+            }\r
+        } else {\r
+            rootModel = configuration.getModel();\r
+        }\r
+        \r
+        // Get the top level model (SysdynModel)\r
+        // Resource library should be used with care if it is not instance of sr.SysdynModel\r
+        Resource library = graph.getPossibleObject(variable, l0.PartOf);\r
+        if(library == null) {\r
+            return true;\r
+        } else {\r
+            library = graph.getPossibleObject(library, l0.PartOf);\r
+            if(library == null) {\r
+                return true;\r
+            }\r
+        }\r
+\r
+               // Check if the function is right under the model.\r
+        if (graph.isInstanceOf(library, sr.SysdynModel)) {\r
+            // Check that the function name != model name (== library name)\r
+            if (NameUtils.getSafeName(graph, library).equals(name)) return true;\r
+            \r
+            if (nameTakenByBuiltInFunction(graph, name)) return true;\r
+\r
+            if (nameTakenBySharedFunctionLibrary(graph, library, null, name)) return true;\r
+            \r
+            if (nameTakenBySheet(sysdynModel, name)) return true;\r
+        }\r
+\r
+               if (nameTakenByTopLevelVariableOrModule(graph, sysdynModel, variable, name)) return true;\r
+\r
+               if (rootModel != null) {\r
+                   // Browse through all ModuleTypes within the whole model\r
+               if (rootModel.containsModuleType(name))\r
+                       return true;\r
+               }\r
+               \r
+               if (nameTakenByFunctionFunctionLibraryOrModuleType(graph, library, name)) return true;\r
+               \r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Checks that the syntax of the given name is valid and there \r
+        * are no other variables that have the same name in the configuration\r
+        *  \r
+        * @param graph ReadGraph\r
+        * @param variable The variable that is being renamed\r
+        * @param name The new name of the variable\r
+        * @return\r
+        * @throws DatabaseException\r
+        */\r
+       public boolean isValid(ReadGraph graph, Resource variable, String name, boolean hasRange) throws DatabaseException {\r
+           if(hasRange) {\r
+                       String range = null;\r
+                       if(name.contains("[")) {\r
+                               StringTokenizer st = new StringTokenizer(name, "[]", true);\r
+                               if(st.countTokens() != 4)\r
+                                       return false;\r
+                               name = st.nextToken();\r
+                               if(!st.nextToken().equals("[")) return false;\r
+                               range = st.nextToken();\r
+                               if(!st.nextToken().equals("]")) return false;\r
+                       }\r
+                       if(range != null && !ArrayVariableUtils.isRangeValid(graph, variable, range)) return false;\r
+               }\r
+               return isValid(graph, variable, name);\r
+       }\r
+\r
+       \r
+       /**\r
+        * Checks that the syntax of the given name is valid and there \r
+        * are no other variables that have the same name in the configuration\r
+        *  \r
+        * @param variable The variable that is being renamed\r
+        * @param name The new name of the variable\r
+        * @return\r
+        * @throws DatabaseException\r
+        */\r
+       public boolean isValid(final Resource variable, final String name, final boolean hasRange) {\r
+               if (variable == null || name == null)\r
+                       return false;\r
+               \r
+               boolean result = false;\r
+               try {\r
+                       result = SimanticsUI.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                               @Override\r
+                               public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                                       return isValid(graph, variable, name, hasRange);\r
+                               }\r
+\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return result;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/imports/ImportUtilsUI.java
new file mode 100644 (file)
index 0000000..9aa85f8
--- /dev/null
@@ -0,0 +1,63 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *     Semantum Oy - Bug #4192\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.utils.imports;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.utils.imports.ImportUtils;\r
+\r
+/**\r
+ * Utilities for importing tg files: Models, Modules and Function libraries\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ImportUtilsUI {\r
+\r
+    public static String IMPORTMODELTPATH = "IMPORT_MODEL_PATH";\r
+    public static String IMPORTMODULETPATH = "IMPORT_MODULE_PATH";\r
+    public static String IMPORTFUNCTIONLIBRARYPATH = "IMPORT_FUNCTION_LIBRARY_PATH";\r
+\r
+\r
+    /* ********************************* */\r
+    /* *******   IMPORT MODEL  ********* */\r
+    /* ********************************* */\r
+    public static IStatus importModelFile(String path, IProgressMonitor monitor) throws Exception {\r
+        Activator.getDefault().getPreferenceStore().setValue(IMPORTMODELTPATH, (new File(path)).getParent());\r
+        return ImportUtils.importModelFile(path, monitor);\r
+    }\r
+\r
+\r
+    /* ********************************* */\r
+    /* *******  IMPORT MODULE  ********* */\r
+    /* ********************************* */\r
+    public static IStatus importModuleFile(Resource model, String path, IProgressMonitor monitor) {\r
+        Activator.getDefault().getPreferenceStore().setValue(IMPORTMODULETPATH, (new File(path)).getParent());\r
+        return ImportUtils.importModuleFile(model, path, monitor);\r
+    }\r
+\r
+\r
+\r
+    /* ********************************* */\r
+    /* ***  IMPORT FUNCTION LIBRARY  *** */\r
+    /* ********************************* */\r
+\r
+    public static IStatus importFunctionLibrary(Resource functionLibrary, String path, IProgressMonitor monitor) {\r
+        Activator.getDefault().getPreferenceStore().setValue(IMPORTFUNCTIONLIBRARYPATH, (new File(path)).getParent());\r
+        return ImportUtils.importFunctionLibrary(functionLibrary, path, monitor);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java
new file mode 100644 (file)
index 0000000..99865d0
--- /dev/null
@@ -0,0 +1,350 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.Issue;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\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.ui.properties.widgets.expressions.ExpressionField;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils;\r
+import org.simantics.sysdyn.ui.utils.ExpressionUtils.ReferenceOption;\r
+import org.simantics.sysdyn.ui.utils.SyntaxError;\r
+import org.simantics.utils.datastructures.collections.CollectionUtils;\r
+\r
+/**\r
+ * Evaluates issues related to Dependencies (arrows)\r
+ * \r
+ * @author Teemu Lempinen\r
+ * \r
+ */\r
+public class DependencyFunction {\r
+       \r
+       // Set containing the names of variables that can be used everywhere, like "time"\r
+       private static Set<String> GLOBAL_VARIABLES = CollectionUtils.toSet("time");\r
+\r
+    /**\r
+     * Evaluates dependency-related issues for a component.\r
+     * \r
+     * Issues include: Unused dependency\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param component Evaluated component (Variable)\r
+     * @return list of issues related to component\r
+     * @throws DatabaseException\r
+     */\r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> dependencyValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+        if (!graph.isInstanceOf(component, sr.IndependentVariable))\r
+            return Collections.emptyList();\r
+\r
+        if (!graph.hasStatement(component) || !graph.hasStatement(component, l0.PartOf))\r
+            return Collections.emptyList();\r
+        \r
+        ArrayList<Issue> result = new ArrayList<Issue>();\r
+        Set<String> references = null;\r
+        \r
+        // Find all references in equations of component\r
+        try {\r
+            references = ValidationUtils.getAllReferences(graph, component).getVariableReferences();\r
+        } catch (Exception e) {\r
+            return result;\r
+        } \r
+\r
+        // Find all variables that are linked to component with arrows\r
+        Set<String> dependencies = ValidationUtils.getDependencies(graph, component);\r
+\r
+        // Check that all arrow dependencies are used in equations\r
+        if (dependencies != null) {\r
+            for (String dependency : dependencies) {\r
+                if (references == null || !references.contains(dependency)) {\r
+                    result.add(new IssueWithStringContext(sr.Validations_UnusedDependencyIssue, component, dependency));\r
+                }\r
+            }\r
+        }\r
+\r
+        return result;\r
+    }\r
+    \r
+\r
+    private static Configuration getConfiguration(ReadGraph graph, Resource component) throws DatabaseException {\r
+        Resource configuration = graph.getPossibleObject(component, Layer0.getInstance(graph).PartOf);\r
+        \r
+        if(configuration == null)\r
+            return null;\r
+        \r
+        SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+        SysdynModel sm = smm.getModel(graph, configuration);\r
+        if(sm == null)\r
+            return null;\r
+\r
+        sm.update(graph);\r
+        return sm.getConfiguration();\r
+    }\r
+\r
+    /**\r
+     * Evaluates dependency-related issues for a component.\r
+     * \r
+     * Issues include: Missing link No such variable\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param component Evaluated component (Variable)\r
+     * @return list of issues related to component\r
+     * @throws DatabaseException\r
+     */\r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> missingDependencyValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+        if (!graph.isInstanceOf(component, sr.IndependentVariable))\r
+            return Collections.emptyList();\r
+\r
+        if (!graph.hasStatement(component) || !graph.hasStatement(component, l0.PartOf))\r
+            return Collections.emptyList();\r
+\r
+        // Find all references in equations of component\r
+        References references = null;\r
+        try {\r
+            references = ValidationUtils.getAllReferences(graph, component);\r
+        } catch (Exception e) {\r
+            return Collections.emptyList();\r
+        }\r
+        \r
+        Configuration configuration = getConfiguration(graph, component);\r
+        ArrayList<Issue> result = new ArrayList<Issue>();\r
+        \r
+        // Examine possible for-index references. Remove if found\r
+        for(Resource expressionResource : references.forIndices.keySet()) {\r
+            if(references.forIndices.containsKey(expressionResource)) {\r
+                for(Token token : references.forIndices.get(expressionResource).keySet()) {\r
+                    if(references.references.containsKey(expressionResource) && \r
+                            references.references.get(expressionResource).containsKey(token.image)) {\r
+                        references.references.get(expressionResource).remove(token.image);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        \r
+        // Examine Sheet references\r
+        for(Resource expressionResource : references.functionReferences.keySet()) {\r
+            for(String functionKey : references.functionReferences.get(expressionResource).keySet()) {\r
+                List<SyntaxError> sheetErrors = ExpressionUtils.examineSheetReferences(\r
+                        configuration, \r
+                        functionKey, \r
+                        references.functionReferences.get(expressionResource).get(functionKey), \r
+                        references.expressions.get(expressionResource), \r
+                        references.references.get(expressionResource));\r
+                if(sheetErrors != null) {\r
+                    for(SyntaxError error : sheetErrors)\r
+                        result.add(new IssueWithStringContext(sr.Validations_InvalidSheetReferenceIssue, component, error.getMessage(), error.getImage()));\r
+                }\r
+            }\r
+        }\r
+        \r
+        \r
+        // Examine dependencies\r
+        Set<String> variablesReferences = references.getVariableReferences();\r
+        if(variablesReferences == null || variablesReferences.isEmpty())\r
+            return result;\r
+        \r
+        // Remove references to self\r
+        String name = NameUtils.getSafeName(graph, component);\r
+        if(name != null && variablesReferences.contains(name))\r
+            variablesReferences.remove(name);\r
+        \r
+        // Find all variables that are linked to component with arrows\r
+        Set<String> dependencies = ValidationUtils.getDependencies(graph, component);\r
+        dependencies.addAll(GLOBAL_VARIABLES);\r
+        \r
+        // Remove all dependency variables from reference maps \r
+        for(String dependency : dependencies)\r
+            variablesReferences.remove(dependency);\r
+\r
+        boolean isStock = isStock(graph, component);\r
+        ReferenceOption option;\r
+\r
+        for(String reference : variablesReferences) {\r
+            option = ExpressionUtils.getReferenceOption(configuration, reference);\r
+            switch(option) {\r
+                case DOES_NOT_EXIST:\r
+                    result.add(new IssueWithStringContext(sr.Validations_NoSuchVariableIssue, component, reference));\r
+                case CAN_BE_CONNECTED:\r
+                    if(isStock) {\r
+                        /* Stocks do not get incoming dependencies. They are allowed\r
+                        to have references without arrows */\r
+                    } else {\r
+                        result.add(new IssueWithStringContext(sr.Validations_MissingLinkIssue, component, reference));\r
+                    }\r
+                    break;\r
+                case CANNOT_BE_CONNECTED:\r
+            }\r
+        }\r
+        \r
+        \r
+        for(Resource expression : references.ranges.keySet()) {\r
+            List<SyntaxError> errors = new ArrayList<SyntaxError>();\r
+            // RANGES\r
+            errors.addAll(ExpressionUtils.examineArrayRanges(graph, configuration, references.ranges.get(expression), references.forIndices.get(expression)));\r
+            \r
+            // ENUMERATION REFERENCES IN FOR-LOOPS\r
+            errors.addAll(ExpressionUtils.examineEnumerationReferences(configuration, references.enumerationReferences.get(expression)));\r
+\r
+            for(SyntaxError error : errors) {\r
+                Resource type = sr.Validations_RangeIssue;\r
+                if(ExpressionField.SYNTAX_WARNING.equals(error.getType())) {\r
+                    type = sr.Validations_RangeWarning;\r
+                }\r
+                result.add(new IssueWithStringContext(type, component, error.getMessage()));\r
+\r
+            }\r
+        }   \r
+        \r
+        return result;\r
+\r
+    }\r
+    \r
+    private static boolean isStock(ReadGraph graph, Resource variable) throws DatabaseException {\r
+        List<Resource> expressionList = ValidationUtils.getExpressions(graph, variable);\r
+        if(expressionList == null || expressionList.isEmpty()) {\r
+            return false;\r
+        } else {\r
+            for(Resource expression : expressionList) {\r
+                if(!graph.isInstanceOf(expression, SysdynResource.getInstance(graph).StockExpression))\r
+                    return false;\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Missing link description\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param converter\r
+     * @param issue Issue\r
+     * @return issue description\r
+     * @throws DatabaseException\r
+     */\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String missingLinkIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+       \r
+        List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+        String result = "Missing a link to ";\r
+        if (contexts.size() > 0) {\r
+            result = result + contexts.get(0);\r
+        }\r
+\r
+        return result;\r
+        \r
+    }\r
+\r
+    /**\r
+     * Unused dependency description\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param converter\r
+     * @param issue Issue\r
+     * @return issue description\r
+     * @throws DatabaseException\r
+     */\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String unusedDependencyIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+        \r
+        List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+        String result = "Unused dependency: ";\r
+        if (contexts.size() > 0) {\r
+            result = result + contexts.get(0);\r
+        }\r
+\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * No such variable description. Finds all variables that the component\r
+     * refers to and adds their names to the issue description.\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param converter\r
+     * @param issue Issue\r
+     * @return issue description\r
+     * @throws DatabaseException\r
+     */\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String noSuchVariableIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+        \r
+        List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+        String result = "Refers to unexisting variable ";\r
+        if (contexts.size() > 0) {\r
+            result = result + contexts.get(0);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String invalidSheetReferenceIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+        \r
+        List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+        String result = "";\r
+        \r
+        if(contexts.size() == 2)\r
+            result = contexts.get(0) + ": " + contexts.get(1);\r
+        else\r
+            result = "Spreadsheet reference error";\r
+\r
+        return result;\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String rangeIssueDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+        \r
+        List<String> contexts = IssueWithStringContext.getStringContexts(graph, property);\r
+        if (contexts.size() > 0) {\r
+            return contexts.get(0);\r
+        } else {\r
+            return "Range Issue";\r
+        }\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String rangeWarningDescription(ReadGraph graph, Resource converter, Variable property)\r
+            throws DatabaseException {\r
+        return rangeIssueDescription(graph, converter, property);\r
+    }\r
+    \r
+    \r
+    \r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/EnumerationFunction.java
new file mode 100644 (file)
index 0000000..96b687c
--- /dev/null
@@ -0,0 +1,66 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Issue;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Functions for checking issues in Enumerations\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class EnumerationFunction  {\r
+\r
+    private static String NO_INDEXES = "Enumeration does not contain indexes.";\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> enumerationIndexValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
+\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+\r
+        if(!graph.isInstanceOf(component, sr.Enumeration)) {\r
+            return Collections.emptyList();\r
+        }\r
+\r
+        boolean noIndexes = false;\r
+\r
+        try {\r
+            Resource indexList = graph.getPossibleObject(component, sr.Enumeration_enumerationIndexList);\r
+            List<Resource> indexes = ListUtils.toList(graph, indexList);\r
+            if(indexes.size() == 0)\r
+                noIndexes = true;\r
+        } catch (DatabaseException e) {\r
+            noIndexes = true;\r
+        }\r
+\r
+        if(noIndexes)\r
+            return Collections.<Issue>singletonList(new StandardIssue(sr.Validations_EmptyEnumerationIssue, component));\r
+        else\r
+            return Collections.emptyList();\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String emptyEnumerationIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+        return NO_INDEXES;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ExpressionIssueFunction.java
new file mode 100644 (file)
index 0000000..8a55a52
--- /dev/null
@@ -0,0 +1,76 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.db.Issue;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.issues.common.IssueUtils;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Detects syntax errors, unsupported characters and undefined expressions from variables.\r
+ * \r
+ * @author tlteemu\r
+ *\r
+ */\r
+public class ExpressionIssueFunction {\r
+    \r
+    private static String SYNTAX_ERROR = "Syntax error";\r
+    private static String UNSUPPORTED_CHARACTERS = "Unsupported characters";\r
+    private static String UNDEFINED_EXPRESSION = "Undefined expression";\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> expressionValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
+        \r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+        if(!graph.isInstanceOf(component, sr.IndependentVariable)) {\r
+            return Collections.emptyList();\r
+        }\r
+        \r
+        // Try if there are any errors while parsing the expressions\r
+        try {\r
+            ValidationUtils.getAllReferences(graph, component);\r
+        } catch (Exception e) {\r
+            return Collections.<Issue>singletonList(new StandardIssue(sr.Validations_ExpressionIssue, component));\r
+        }\r
+        return Collections.emptyList();\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String expressionIssueDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+       \r
+       List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+        Resource component = contexts.get(0);\r
+        \r
+        // There should be an error\r
+        try {\r
+            ValidationUtils.getAllReferences(graph, component);\r
+        } catch (SyntaxErrorException e) {\r
+            return SYNTAX_ERROR;\r
+        } catch (UnsupportedCharactersException e) {\r
+            return UNSUPPORTED_CHARACTERS;\r
+        } catch (UndefinedExpressionException e) {\r
+            return UNDEFINED_EXPRESSION;\r
+        }   \r
+        return "Erroneus error";\r
+    }\r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/Functions.java
new file mode 100644 (file)
index 0000000..eca0810
--- /dev/null
@@ -0,0 +1,70 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.issues.common.IssueUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.ontology.ProjectResource;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Generic functions for validations\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class Functions {\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Resource")\r
+    public static Resource baseRealizationFunction(ReadGraph graph, Resource model) throws DatabaseException {\r
+        return model;\r
+    }\r
+\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String path(ReadGraph graph, Resource source, Variable property) throws DatabaseException {\r
+        List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+        if (contexts.size() > 0) {\r
+            Resource component = contexts.get(0);\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ProjectResource PROJECT = ProjectResource.getInstance(graph);\r
+            StringBuilder sb = new StringBuilder("");\r
+            Resource parent = graph.getPossibleObject(component, L0.PartOf);\r
+            boolean first = true;\r
+            while(parent != null && !graph.isInstanceOf(parent, PROJECT.Project)) {\r
+                if(!graph.isInstanceOf(parent, sr.Configuration)) {\r
+                    String name = NameUtils.getSafeName(graph, parent);\r
+                    if(first) {\r
+                        sb.append(name);\r
+                        first = false;\r
+                    } else {\r
+                        sb.insert(0, "/");\r
+                        sb.insert(0, name);\r
+                    }\r
+                }\r
+                parent = graph.getPossibleObject(parent, L0.PartOf);\r
+            }\r
+            return sb.toString();\r
+        } else {\r
+            return "";\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/IssueWithStringContext.java
new file mode 100644 (file)
index 0000000..906124f
--- /dev/null
@@ -0,0 +1,107 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+/**\r
+ * Issue that can have string contexts.\r
+ * \r
+ * String contexts are written to a graph like resource contexts and can be accessed \r
+ * in issue description functions. This eliminates the need for making complex calculations \r
+ * for obtaining values that have already been calculated in the issue source function. \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class IssueWithStringContext extends StandardIssue {\r
+\r
+    String[] stringContexts;\r
+\r
+    /**\r
+     * Creates an issue with one resource context and an arbitrary number of string contexts\r
+     * @param type\r
+     * @param context\r
+     * @param stringContexts\r
+     */\r
+    public IssueWithStringContext(Resource type, Resource context, String... stringContexts) {\r
+        super(type, context);\r
+        this.stringContexts = stringContexts;\r
+    }\r
+    \r
+    /**\r
+     * Get the string contexts of this issue\r
+     * @return string contexts\r
+     */\r
+    public String[] getStringContexts() {\r
+        return stringContexts;\r
+    }\r
+    \r
+    /**\r
+     * Overridden function from StandardResource. This writes a list of string contexts to the database.\r
+     */\r
+    public void writeAdditionalContext(WriteGraph graph, Resource issue) throws DatabaseException {\r
+        super.writeAdditionalContext(graph, issue);\r
+        \r
+        // Add possible string contexts to the contexts array\r
+        if(stringContexts != null && stringContexts.length > 0) {\r
+            SysdynResource SR = SysdynResource.getInstance(graph);\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            List<Resource> contexts = new ArrayList<Resource>();\r
+            for(String s : stringContexts) {\r
+                Resource r = graph.newResource();\r
+                graph.claim(r, L0.InstanceOf, L0.String);\r
+                graph.claimValue(r, s, Bindings.STRING);\r
+                contexts.add(r);\r
+            }\r
+            graph.claim(issue, SR.Validations_Issue_stringContexts, ListUtils.create(graph, L0.List, contexts));\r
+        }\r
+        \r
+    }\r
+    \r
+    /**\r
+     * Gets string contexts from IssueWithStringContexts\r
+     * @param graph ReadGraph\r
+     * @param property issue property\r
+     * @return String contexts of issue or empty list if none is found\r
+     * @throws DatabaseException\r
+     */\r
+    public static List<String> getStringContexts(ReadGraph graph, Variable property) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        Variable issueVariable = property.getParent(graph);\r
+        Resource issueResource = issueVariable.getRepresents(graph);\r
+        Resource list = graph.getPossibleObject(issueResource, SR.Validations_Issue_stringContexts);\r
+        if(list == null) {\r
+            return Collections.emptyList();\r
+        } else {\r
+            List<Resource> stringResources = ListUtils.toList(graph, list);\r
+            ArrayList<String> result = new ArrayList<String>(stringResources.size());\r
+            for(Resource r : stringResources) {\r
+                result.add((String)graph.getValue(r, Bindings.STRING));\r
+            }\r
+            return result;\r
+        }\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ModuleStandardIssue.java
new file mode 100644 (file)
index 0000000..4cbdf73
--- /dev/null
@@ -0,0 +1,37 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.issues.ontology.IssueResource;\r
+\r
+public class ModuleStandardIssue extends StandardIssue {\r
+\r
+    public ModuleStandardIssue(Resource type, Resource ... contexts) {\r
+        super(type, contexts);\r
+    }\r
+    \r
+    @Override\r
+    public void writeAdditionalContext(WriteGraph graph, Resource issue) throws DatabaseException {\r
+        super.writeAdditionalContext(graph, issue);\r
+\r
+        if(contexts.length >= 2) {\r
+            IssueResource IR = IssueResource.getInstance(graph);\r
+            // Input / output context\r
+            graph.claim(issue, IR.Issue_HasContext, IR.Issue_HasContext_Inverse, contexts[1]);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/NoSuchVariableException.java
new file mode 100644 (file)
index 0000000..4ec1176
--- /dev/null
@@ -0,0 +1,17 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+public class NoSuchVariableException extends RuntimeException {\r
+    private static final long serialVersionUID = -5766352512554068379L;\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ParameterExistsValidator.java
new file mode 100644 (file)
index 0000000..0fb44b6
--- /dev/null
@@ -0,0 +1,50 @@
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.jfreechart.chart.properties.AllVariablesOfModel;\r
+import org.simantics.jfreechart.chart.properties.ChartVariable;\r
+import org.simantics.jfreechart.chart.properties.VariableExistsValidator;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+public class ParameterExistsValidator extends VariableExistsValidator {\r
+\r
+       public ParameterExistsValidator(WidgetSupport support, TrackedText text) {\r
+               super(support, text);\r
+       }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        final Resource resource = AdaptionUtils.adaptToSingle(input, Resource.class);\r
+        if(resource == null)\r
+            return;\r
+        \r
+        SimanticsUI.getSession().asyncRequest(\r
+                new AllVariablesOfModel(resource)\r
+        , new Listener<Collection<ChartVariable>>() {\r
+\r
+            @Override\r
+            public void execute(Collection<ChartVariable> variables) {\r
+                ParameterExistsValidator.this.variables = variables;\r
+            }\r
+\r
+            @Override\r
+            public void exception(Throwable t) {\r
+                t.printStackTrace();\r
+            }\r
+\r
+            @Override\r
+            public boolean isDisposed() {\r
+                return ParameterExistsValidator.this.text.isDisposed();\r
+            }\r
+\r
+        }); \r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/References.java
new file mode 100644 (file)
index 0000000..0d9ed3d
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.expressionParser.Token;\r
+\r
+/**\r
+ * Container for different types of references got from expression parser\r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class References {\r
+    public HashMap<Resource, String> expressions = new HashMap<Resource, String>();\r
+    public HashMap<Resource, HashMap<String, List<Token>>> references = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+    public HashMap<Resource, HashMap<String, List<List<Token>>>> ranges = new HashMap<Resource, HashMap<String, List<List<Token>>>>();\r
+    public HashMap<Resource, HashMap<Token, List<Token>>> forIndices = new HashMap<Resource, HashMap<Token, List<Token>>>();\r
+    public HashMap<Resource, HashMap<String, List<Token>>> enumerationReferences = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+    public HashMap<Resource, HashMap<String, List<Token>>> functionReferences = new HashMap<Resource, HashMap<String, List<Token>>>();\r
+    \r
+    \r
+    /**\r
+     * Get all variable references from all expressions of the variable in a single set\r
+     * @return All variable references\r
+     */\r
+    public Set<String> getVariableReferences() {\r
+        HashSet<String> result = new HashSet<String>();\r
+        for(HashMap<String, List<Token>> map : references.values()) {\r
+            for(String key : map.keySet()) {\r
+                if(!map.get(key).isEmpty())\r
+                    result.add(key);\r
+            }\r
+        }\r
+        \r
+        return result;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/SyntaxErrorException.java
new file mode 100644 (file)
index 0000000..0592a5d
--- /dev/null
@@ -0,0 +1,18 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+public class SyntaxErrorException extends RuntimeException {\r
+    private static final long serialVersionUID = -6466653179001958636L;\r
+    \r
+    \r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UndefinedExpressionException.java
new file mode 100644 (file)
index 0000000..1c53cd8
--- /dev/null
@@ -0,0 +1,17 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+public class UndefinedExpressionException extends RuntimeException {\r
+    private static final long serialVersionUID = 7352486116119189105L;\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnitFunction.java
new file mode 100644 (file)
index 0000000..2eeadea
--- /dev/null
@@ -0,0 +1,300 @@
+/*******************************************************************************\r
+ * Copyright (c) 2013-2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     Semantum Oy - initial API and implementation\r
+ *     VTT Technical Research Centre of Finland\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\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
+\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Issue;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.issue.StandardIssue;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.issues.common.IssueUtils;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynModel;\r
+import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.representation.IndependentVariable;\r
+import org.simantics.sysdyn.representation.expressions.IExpression;\r
+import org.simantics.sysdyn.representation.utils.UnitUtils;\r
+import org.simantics.sysdyn.utils.Function;\r
+import org.simantics.sysdyn.utils.ModelUtils;\r
+\r
+public class UnitFunction {\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> unitValidator(ReadGraph graph, Resource component) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        if(graph.isInstanceOf(component, SR.Variable) && !graph.isInstanceOf(component, SR.Cloud))\r
+            return variableValidator(graph, component);\r
+        else if(graph.isInstanceOf(component, SR.Module))\r
+            return moduleValidator(graph, component);\r
+        else\r
+            return Collections.emptyList();\r
+    }\r
+    \r
+    private static List<Issue> variableValidator(ReadGraph graph, Resource variable) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph); \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+        Resource configuration = graph.getPossibleObject(variable, L0.PartOf);\r
+        if(configuration == null)\r
+            return Collections.emptyList();\r
+\r
+        // Make sure unit updates are listened to\r
+        String unit = null;\r
+        if (graph.isInstanceOf(variable, SR.Shadow)) {\r
+               Resource original = graph.getPossibleObject(variable, SR.Shadow_original);\r
+               if (original == null)\r
+                       return Collections.emptyList();\r
+               unit = graph.getPossibleRelatedValue(original, SR.Variable_unit);\r
+        } else {\r
+               unit = graph.getPossibleRelatedValue(variable, SR.Variable_unit);\r
+        }\r
+        if(unit == null || unit.trim().length() == 0)\r
+            return Collections.<Issue>singletonList(new StandardIssue(SR.Validations_UnitWarning, variable));\r
+\r
+        if(!graph.isInstanceOf(variable, SR.IndependentVariable))\r
+            return Collections.emptyList();\r
+        \r
+        Resource expressionList = graph.getPossibleObject(variable, SR.Variable_expressionList);\r
+\r
+        if(expressionList == null)\r
+            return Collections.emptyList();\r
+\r
+\r
+        SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+        SysdynModel sm = smm.getModel(graph, configuration);\r
+        sm.getMapping().domainModified(variable);\r
+\r
+        sm.update(graph);\r
+        Object var = sm.getMapping().get(variable);\r
+\r
+        ArrayList<Issue> issues = new ArrayList<Issue>();\r
+\r
+        for(Resource expression : ListUtils.toList(graph, expressionList)) {\r
+            for(Resource r : graph.getObjects(expression, SR.Expression_equation)) {\r
+                graph.getValue(r);\r
+            }\r
+\r
+            sm.getMapping().domainModified(expression);\r
+            sm.update(graph);\r
+\r
+            Object expr = sm.getMapping().get(expression);\r
+\r
+            if(expr != null && var != null && expr instanceof IExpression && var instanceof IndependentVariable) {\r
+                String result = ((IExpression)expr).validateUnits(graph, sm);\r
+                if(result != null) {\r
+                    Issue issue = new StandardIssue(SR.Validations_UnitWarning, variable, expression, graph.getPossibleObject(variable, SR.Variable_unit));\r
+                    issues.add(issue);\r
+                }\r
+            }\r
+        }\r
+        return issues;\r
+    }\r
+    \r
+    private static List<Issue> moduleValidator(ReadGraph graph, Resource module) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+\r
+        if(module == null)\r
+            return Collections.emptyList();\r
+\r
+        Resource configuration = graph.getPossibleObject(module, L0.PartOf);\r
+        if(configuration == null)\r
+            return Collections.emptyList();\r
+\r
+        SysdynModel model = ModelUtils.getModel(graph, module);\r
+        String result = null;\r
+        ArrayList<Issue> issues = new ArrayList<Issue>();\r
+        for(Resource outputRelation : graph.getObjects(module, SR.Variable_isTailOf)) {\r
+            Resource reference = graph.getPossibleObject(outputRelation, SR.Dependency_refersTo);\r
+            if(reference != null) {\r
+                Resource output = graph.getPossibleObject(outputRelation, SR.Variable_HasHead);\r
+                if(output == null)\r
+                    continue;\r
+                String left = graph.getPossibleRelatedValue(output, SR.Variable_unit);\r
+                String right = graph.getPossibleRelatedValue(reference, SR.Variable_unit);\r
+                ArrayList<Function> functions = Function.getAllBuiltInFunctions(graph);\r
+                result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model));\r
+                if(result != null)\r
+                    issues.add(new ModuleStandardIssue(SR.Validations_ModuleOutputUnitWarning, module, output, reference));\r
+            }\r
+        }\r
+        for(Resource inputRelation : graph.getObjects(module, SR.Variable_isHeadOf)) {\r
+            Resource reference = graph.getPossibleObject(inputRelation, SR.Dependency_refersTo);\r
+            if(reference != null) {\r
+                Resource variable = graph.getPossibleObject(inputRelation, SR.Variable_HasTail);\r
+                if(variable == null)\r
+                    continue;\r
+                String left = graph.getPossibleRelatedValue(variable, SR.Variable_unit);\r
+                String right = graph.getPossibleRelatedValue(reference, SR.Variable_unit);\r
+                ArrayList<Function> functions = Function.getAllBuiltInFunctions(graph);\r
+               result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model));\r
+                if(result != null)\r
+                    issues.add(new ModuleStandardIssue(SR.Validations_ModuleInputUnitWarning, module, variable, reference));\r
+            }\r
+        }\r
+        return issues;\r
+    }\r
+\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String unitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+        List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+\r
+        if(contexts.size() == 0)\r
+            return "Error, No contexts";\r
+\r
+        Resource variable = contexts.get(0);\r
+        String unit = graph.getPossibleRelatedValue(variable, SysdynResource.getInstance(graph).Variable_unit);\r
+\r
+        if(unit == null || unit.length() == 0)\r
+            return "No unit defined";\r
+        \r
+        if(contexts.size() < 2)\r
+            return "Error, not enough contexts";\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Resource configuration = graph.getPossibleObject(variable, L0.PartOf);\r
+        if(configuration == null)\r
+            return "Error, No Confiugration";\r
+\r
+\r
+        SysdynModelManager smm = SysdynModelManager.getInstance(graph.getSession());\r
+        SysdynModel sm = smm.getModel(graph, configuration);\r
+\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        for(Resource r : graph.getObjects(contexts.get(1), SR.Expression_equation)) {\r
+            graph.getValue(r);\r
+        }\r
+\r
+        Object expr = sm.getMapping().get(contexts.get(1));\r
+        String result = ((IExpression)expr).validateUnits(graph, sm);\r
+        \r
+        return result;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String moduleOutputUnitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+        List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+\r
+        if(contexts.size() < 3)\r
+            return "Error, No contexts";\r
+\r
+        Resource output = contexts.get(1);\r
+        Resource reference = contexts.get(2);\r
+\r
+        return moduleInterfaceDescription(graph, output, reference, "Module output has different unit. (", ")");\r
+\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
+    public static String moduleInputUnitWarningDescription(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {\r
+        List<Resource> contexts = IssueUtils.getContextsForProperty(graph, property);\r
+\r
+        if(contexts.size() < 3)\r
+            return "Error, No contexts";\r
+\r
+        Resource output = contexts.get(1);\r
+        Resource reference = contexts.get(2);\r
+\r
+        return moduleInterfaceDescription(graph, output, reference, "Module input has different unit. (", ")");\r
+\r
+    }\r
+    \r
+    private static String moduleInterfaceDescription(ReadGraph graph, Resource leftResource, Resource rightResource, String prefix, String suffix) throws DatabaseException {\r
+        if(leftResource == null)\r
+            return "Erroneus error: left == null";\r
+        \r
+        if(rightResource == null)\r
+            return "Erroneus error: right == null";\r
+        \r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        String left = graph.getPossibleRelatedValue(leftResource, SR.Variable_unit);\r
+        if(left == null || left.isEmpty())\r
+            return "No unit defined for " + NameUtils.getSafeName(graph, leftResource);\r
+        \r
+        String right = graph.getPossibleRelatedValue(rightResource, SR.Variable_unit);\r
+        if(right == null || right.isEmpty())\r
+            return "No unit defined for " + NameUtils.getSafeName(graph, rightResource);\r
+        \r
+        SysdynModel model = ModelUtils.getModel(graph, leftResource);\r
+        ArrayList<Function> functions = Function.getAllBuiltInFunctions(graph);\r
+       String result = UnitUtils.matchUnits(left, right, functions, UnitUtils.allowEquivalents(graph, model));\r
+        \r
+        if(result != null)\r
+            result = prefix + result + suffix;\r
+        \r
+        return result;\r
+    }\r
+    \r
+    \r
+    \r
+    \r
+    @SCLValue(type = "ReadGraph -> [Resource] -> [Resource]")\r
+    public static List<Resource> moduleInterfaceExtension(ReadGraph graph, List<Resource> rs) throws DatabaseException {\r
+        SysdynResource SR = SysdynResource.getInstance(graph);\r
+        \r
+        HashSet<Resource> components = new HashSet<Resource>();\r
+        HashSet<Resource> searchedModuleTypes = new HashSet<Resource>();\r
+        for(Resource r : rs) {\r
+            if(!graph.isInstanceOf(r, SR.Variable))\r
+                continue;\r
+            \r
+            if(graph.isInstanceOf(r, SR.Input)) {\r
+                Resource connection = graph.getPossibleObject(r, SR.Variable_isHeadOf);\r
+                if(connection != null)\r
+                    components.add(graph.getPossibleObject(connection, SR.Variable_HasTail));\r
+            }\r
+            \r
+            for(Resource connection :  graph.getObjects(r, SR.Variable_isTailOf)) {\r
+                Resource head = graph.getPossibleObject(connection, SR.Variable_HasHead);\r
+                if(head != null && graph.isInstanceOf(head, SR.Module)) {\r
+                    components.add(head);\r
+                }\r
+            }\r
+            \r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            Resource configuration = graph.getPossibleObject(r, L0.PartOf);\r
+            Resource possibleModule = graph.getPossibleObject(configuration, L0.PartOf);\r
+            if(graph.isInheritedFrom(possibleModule, SR.Module) && !searchedModuleTypes.contains(possibleModule)) {\r
+                searchedModuleTypes.add(possibleModule);\r
+                for(Resource model : graph.syncRequest(new ObjectsWithType(Simantics.getProject().get(), L0.ConsistsOf, SR.SysdynModel))) {\r
+                    Collection<Resource> found = org.simantics.db.indexing.IndexUtils.findByType(graph, model, possibleModule);\r
+                    components.addAll(found);\r
+                }\r
+            }\r
+\r
+        }\r
+        \r
+        if(!components.isEmpty()) {\r
+            rs.addAll(components);\r
+        }\r
+        \r
+        return rs;\r
+        \r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/UnsupportedCharactersException.java
new file mode 100644 (file)
index 0000000..b2aa82f
--- /dev/null
@@ -0,0 +1,17 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+public class UnsupportedCharactersException extends RuntimeException {\r
+    private static final long serialVersionUID = 8210873686720503188L;\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java
new file mode 100644 (file)
index 0000000..d90fd96
--- /dev/null
@@ -0,0 +1,166 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.validation;\r
+\r
+import java.io.StringReader;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\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.expressionParser.TokenMgrError;\r
+\r
+/**\r
+ * \r
+ * @author Teemu Lempinen\r
+ * @author Tuomas Miettinen\r
+ *\r
+ */\r
+public class ValidationUtils {\r
+    \r
+    /**\r
+     * Find all variables that are referred to in the expressions of variable r\r
+     * @param graph ReadGraph\r
+     * @param r Variable resource\r
+     * @return All names of the variables that are referred to in the expressions of r\r
+     * @throws DatabaseException\r
+     * @throws SyntaxErrorException\r
+     * @throws UnsupportedCharactersException\r
+     * @throws UndefinedExpressionException\r
+     */\r
+    public static References getAllReferences(ReadGraph graph, Resource r) throws DatabaseException, SyntaxErrorException, UnsupportedCharactersException, UndefinedExpressionException {\r
+        References result = new References();\r
+\r
+        ExpressionParser parser = new ExpressionParser(new StringReader(""));\r
+\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        List<Resource> expressionList = getExpressions(graph, r);\r
+        if(expressionList == null || expressionList.isEmpty())\r
+            throw new UndefinedExpressionException();\r
+        for(Resource expression : expressionList) {\r
+            \r
+            Collection<Statement> statements = graph.getStatements(expression, sr.Expression_equation);\r
+            if(statements.isEmpty())\r
+                throw new UndefinedExpressionException();\r
+\r
+            for(Statement statement : statements) {\r
+                Object v = graph.getValue(statement.getObject());\r
+                String value = v.toString();\r
+                \r
+                if(value.length() == 0) {\r
+                    // Empty might be allowed\r
+                    if(!graph.isSubrelationOf(statement.getPredicate(), sr.HasEquationOrEmpty))\r
+                        throw new UndefinedExpressionException();\r
+                }\r
+\r
+                parser.ReInit(new StringReader(value));\r
+                try {\r
+                    parser.expr();\r
+                    \r
+                    HashMap<String, List<Token>> refs = parser.getReferences();\r
+                    result.references.put(expression, refs);\r
+                    result.ranges.put(expression, parser.getRanges());\r
+                    result.forIndices.put(expression,  parser.getForIndices());\r
+                    result.enumerationReferences.put(expression, parser.getEnumerationReferences());\r
+                    result.functionReferences.put(expression, parser.getFunctionCallReferences());\r
+                    result.expressions.put(expression, value);\r
+                    \r
+                } catch (ParseException e1) {\r
+                    throw new SyntaxErrorException();\r
+                } catch (TokenMgrError err) {\r
+                    throw new UnsupportedCharactersException();\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Get all expressions of a variable r\r
+     * @param graph ReadGraph\r
+     * @param r Variable with expressions\r
+     * @return List of expression (resources)\r
+     * @throws DatabaseException\r
+     */\r
+    public static List<Resource> getExpressions(ReadGraph graph, Resource r) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(graph);\r
+        Resource hasExpressions = graph.getPossibleObject(r, sr.Variable_expressionList);\r
+        if(hasExpressions != null)\r
+            return ListUtils.toList(graph, hasExpressions);\r
+        else\r
+            return null;\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns the names of the related variables (dependencies)\r
+     * For stocks, find also both the incoming and outgoing flows\r
+     * \r
+     * @param graph\r
+     * @param r\r
+     * @return\r
+     * @throws DatabaseException\r
+     */\r
+    public static HashSet<String> getDependencies(ReadGraph graph, Resource r) throws DatabaseException {\r
+        HashSet<String> variables = new HashSet<String>();\r
+        if(graph != null && r != null) {\r
+            SysdynResource sr = SysdynResource.getInstance(graph);\r
+            Layer0 l0 = Layer0.getInstance(graph);\r
+\r
+            // Add incoming dependencies and flows\r
+            Collection<Resource> dependencies = graph.getObjects(r, sr.Variable_isHeadOf);\r
+            for(Resource d : dependencies) {\r
+                if(graph.isInstanceOf(d, sr.Dependency)\r
+                               || (graph.isInstanceOf(d, sr.Flow) && graph.isInstanceOf(r, sr.Stock))) {\r
+                    Resource tail = graph.getPossibleObject(d, sr.Variable_HasTail);\r
+                    if(tail != null) {\r
+                        \r
+                        if(graph.isInstanceOf(tail, sr.Shadow)) {\r
+                            tail = graph.getPossibleObject(tail, sr.Shadow_original);\r
+                            if(tail == null)\r
+                                continue;\r
+                        }\r
+                        \r
+                        Object name = graph.getPossibleRelatedValue(tail, l0.HasName);\r
+                        if(name != null)\r
+                            variables.add((String)name);\r
+                    }\r
+                }\r
+            }\r
+            \r
+            // Add also the outgoing flows \r
+            Collection<Resource> outgoingFlows = graph.getObjects(r, sr.Variable_isTailOf);\r
+            for(Resource f : outgoingFlows) {\r
+                if(graph.isInstanceOf(f, sr.Flow) && graph.isInstanceOf(r, sr.Stock)) {\r
+                    Resource head = graph.getPossibleObject(f, sr.Variable_HasHead);\r
+                    if(head != null) {\r
+\r
+                        Object name = graph.getPossibleRelatedValue(head, l0.HasName);\r
+                        if(name != null)\r
+                            variables.add((String)name);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return variables;\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/values/ValueView.java
new file mode 100644 (file)
index 0000000..6908c0e
--- /dev/null
@@ -0,0 +1,349 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.values;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\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.dnd.Clipboard;\r
+import org.eclipse.swt.dnd.TextTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\r
+import org.eclipse.swt.events.KeyEvent;\r
+import org.eclipse.swt.events.KeyListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Event;\r
+import org.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Table;\r
+import org.eclipse.swt.widgets.TableColumn;\r
+import org.eclipse.swt.widgets.TableItem;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.part.ViewPart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.ui.viewUtils.SysdynDatasetSelectionListener;\r
+\r
+/**\r
+ * A view that shows the values of currently selected variables in a table. \r
+ * One column (first by default) is always time values.\r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public class ValueView  extends ViewPart {\r
+\r
+       private boolean disposed;\r
+       private Composite baseComposite;\r
+       private ISelectionListener selectionListener;\r
+       private Table table;\r
+\r
+       @Override\r
+       public void createPartControl(Composite parent) {\r
+\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
+               // Result table\r
+               table = new Table (baseComposite, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);\r
+               GridDataFactory.fillDefaults().grab(true, true).applyTo(table);\r
+               table.setLinesVisible (true);\r
+               table.setHeaderVisible (true);\r
+               GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);\r
+               data.heightHint = 200;\r
+               table.setLayoutData(data);\r
+\r
+\r
+               // Add selectionListener for updating the table\r
+               selectionListener = new SysdynDatasetSelectionListener() {\r
+\r
+                       @Override\r
+                       protected void selectionChanged(final Collection<SysdynDataSet> activeDatasets) {\r
+                               if(disposed) return;\r
+                               table.getDisplay().asyncExec(new Runnable() {\r
+\r
+                                       @Override\r
+                                       public void run() {\r
+                                               updateTable(activeDatasets);\r
+                                       }\r
+                               });\r
+                       }\r
+\r
+            @Override\r
+            protected void selectionChanged(ReadGraph graph, Resource resource) {\r
+                // Do nothing\r
+            }\r
+\r
+               }; \r
+               getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(selectionListener);\r
+               \r
+               // Refreshes the table. There might be a selection already before the table is shown.\r
+               ISelection selection = getSite().getWorkbenchWindow().getSelectionService().getSelection();\r
+               if(selection != null)\r
+                   selectionListener.selectionChanged(getSite().getPart(), selection);\r
+               \r
+               \r
+               /*\r
+                * A primitive copy paste to support exporting data from table to excel\r
+                * \r
+                * columnName\tcolumnName\tcolumnName\n\r
+                * value\tvalue\tvalue\n\r
+                * ...\r
+                * value\tvalue\tvalue\n\r
+                * \r
+                */\r
+               KeyListener kl = 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.stateMask == SWT.CTRL && e.keyCode == 99)\r
+                {\r
+                    \r
+                    Clipboard cb = new Clipboard(e.display);\r
+                    \r
+                    TextTransfer textTransfer = TextTransfer.getInstance();\r
+                    \r
+                    // Add names of the columns first. Selection is always full, print all columns\r
+                    StringBuilder sb = new StringBuilder();\r
+                    int columnCount = table.getColumnCount();\r
+                    for(int i = 0; i < columnCount; i++) {\r
+                        TableColumn tc = table.getColumn(i);\r
+                        sb.append(tc.getText());\r
+                        if(i < columnCount - 1)\r
+                            sb.append("\t");\r
+                        else\r
+                            sb.append("\n");\r
+                    }\r
+                    \r
+                    // Print all selected rows. \r
+                    for(TableItem ti : table.getSelection())\r
+                        for(int i = 0; i < columnCount; i++) {\r
+                            sb.append(ti.getText(i));\r
+                            if(i < columnCount - 1)\r
+                                sb.append("\t");\r
+                            else\r
+                                sb.append("\n");\r
+                        }\r
+                    \r
+                    cb.setContents(new Object[]{sb.toString()}, new Transfer[]{textTransfer});\r
+                }\r
+            }\r
+        };\r
+        \r
+        table.addKeyListener(kl);\r
+        \r
+\r
+       }\r
+\r
+       /**\r
+        * Updates the table after selection has been changed\r
+        * \r
+        * @param activeDatasets\r
+        */\r
+       private void updateTable(Collection<SysdynDataSet> activeDatasets) {\r
+\r
+               if(activeDatasets.isEmpty() || !(activeDatasets instanceof ArrayList)) return;\r
+               \r
+               // Clear the old table\r
+               table.removeAll();\r
+               if(table.getColumnCount() > 0) {\r
+                       for(int i = table.getColumnCount() - 1; i>=0; i--) {\r
+                               table.getColumn(i).dispose();\r
+                       }\r
+               }\r
+               \r
+               // Create new columns\r
+               ArrayList<SysdynDataSet> datasets = (ArrayList<SysdynDataSet>) activeDatasets;\r
+               \r
+               ArrayList<String> titleList = new ArrayList<String>();\r
+               titleList.add("Time");\r
+               double[] times = new double[0];\r
+               for (int i=0; i<datasets.size(); i++) {\r
+                       String name = datasets.get(i).name;\r
+            if (datasets.get(i).resultIndex != null) {\r
+               name += "(" + datasets.get(i).resultIndex + ")"; \r
+            }\r
+                       if(datasets.get(i).result != null)\r
+                               name += " : " + datasets.get(i).result;\r
+                       titleList.add(name);\r
+                       if(times == null || datasets.get(i).values.length > times.length) {\r
+                               times = datasets.get(i).times;\r
+                       }\r
+               }\r
+\r
+               \r
+           Listener sortListener = new Listener() {\r
+               public void handleEvent(Event e) {\r
+                   TableItem[] items = table.getItems();\r
+                   TableColumn column = (TableColumn)e.widget;\r
+                   \r
+                               TableColumn sortColumn = table.getSortColumn();\r
+                               int dir = table.getSortDirection();\r
+                               if (sortColumn == column) {\r
+                                       dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;\r
+                               } else {\r
+                                       table.setSortColumn(column);\r
+                                       dir = SWT.UP;\r
+                               }\r
+                   \r
+                               int index = 0;\r
+                               while(index < table.getColumnCount()) {\r
+                                       if(table.getColumn(index) == column)\r
+                                               break;\r
+                                       index++;\r
+                               }\r
+                   for (int i = 1; i < items.length; i++) {\r
+                       String v1 = items[i].getText(index);\r
+                       if(v1.contains("*"))\r
+                               v1 = v1.substring(0, v1.indexOf("*"));\r
+                       Double value1;\r
+                       try {\r
+                               value1 = Double.parseDouble(v1);\r
+                       } catch(NumberFormatException ne) {\r
+                               continue;\r
+                       }\r
+                       for (int j = 0; j < i; j++){\r
+                               String v2 = items[j].getText(index);\r
+                               if(v2.contains("*"))\r
+                                       v2 = v2.substring(0, v2.indexOf("*"));\r
+                           Double value2;\r
+                               try {\r
+                                       value2 = Double.parseDouble(v2);\r
+                               } catch(NumberFormatException ne) {\r
+                                       continue;\r
+                               }\r
+                           int result = value1.compareTo(value2);\r
+                           if (dir == SWT.UP && result < 0 || dir == SWT.DOWN && result > 0) {\r
+                               int columns = table.getColumnCount();\r
+                               String[] values = new String[columns];\r
+                               for(int k = 0; k < columns; k++) {\r
+                                       values[k] = items[i].getText(k);\r
+                               }\r
+                               items[i].dispose();\r
+                               TableItem item = new TableItem(table, SWT.NONE, j);\r
+                               item.setText(values);\r
+                               items = table.getItems();\r
+                               break;\r
+                           }\r
+                       }\r
+                   }\r
+                   table.setSortColumn(column);\r
+                   table.setSortDirection(dir);\r
+               }\r
+           };\r
+\r
+\r
+               \r
+               String[] titles = titleList.toArray(new String[titleList.size()]);\r
+               \r
+               for (int i=0; i<titles.length; i++) {\r
+                       TableColumn column = new TableColumn (table, SWT.NONE);\r
+                       column.setText (titles [i]);\r
+                       column.addListener(SWT.Selection, sortListener);\r
+                       column.setMoveable(true);\r
+               }       \r
+               \r
+           table.setSortColumn(table.getColumn(0));\r
+           table.setSortDirection(SWT.UP);\r
+           \r
+               // add results\r
+               \r
+               for (int i=0; i<times.length; i++) {\r
+                       TableItem item = new TableItem (table, SWT.NONE);\r
+                       item.setText(0, String.valueOf(times[i]));\r
+                       for(int j=0; j<datasets.size(); j++) {\r
+                               String approximation = approximate(times[i], i, datasets.get(j));\r
+                               item.setText (j + 1 /* time is at column 0 */, approximation);\r
+                       }\r
+               }\r
+               \r
+               for (int i=0; i<titles.length; i++) {\r
+                       table.getColumn (i).pack ();\r
+               }       \r
+\r
+       }\r
+\r
+       \r
+       /**\r
+        * Approximate a value for a table cell. There might not be a value for some specific time step\r
+        * due to different result sets. Approximation uses linear interpolation to calculate an approximate\r
+        * value for the desired time step. \r
+        * \r
+        * @param time Time step that is displayed\r
+        * @param index Index of the displayed time on its dataset\r
+        * @param dataset The dataset that contains the values that are displayed\r
+        * @return The exact value of an approximate if an exat value is not found\r
+        */\r
+       private String approximate(Double time, int index, SysdynDataSet dataset) {\r
+               \r
+               // time out of datasets range\r
+               if(dataset.times.length == 0 || time > dataset.times[dataset.times.length - 1] ||\r
+                               time < dataset.times[0]) {\r
+                       return "---";\r
+               }\r
+               \r
+               // Make sure the index is within times array\r
+               if(index >= dataset.times.length)\r
+                       index = dataset.times.length - 1;\r
+\r
+               // times match, no approximation needed\r
+               double t;\r
+               for(int i = 0; i < dataset.times.length; i++) {\r
+                   t = dataset.times[i];\r
+                   if(t == time)\r
+                       return String.valueOf(dataset.values[i]);\r
+               }\r
+\r
+               // Search the position on datasets' timeline\r
+               int dir = table.getSortDirection();\r
+               while(dataset.times[index] > time) {\r
+                       index = dir == SWT.UP ? index - 1 : index + 1;\r
+               }\r
+               while(dataset.times[index] <= time)\r
+                       index = dir == SWT.UP ? index + 1 : index - 1;\r
+               \r
+               int a = dir == SWT.UP ? index - 1 : index;\r
+               int b = dir == SWT.UP ? index : index - 1;\r
+               \r
+               // Calculate and return approximation\r
+               return dataset.values[a] + \r
+               (dataset.values[b] - dataset.values[a]) * \r
+               (time - dataset.times[a]) /\r
+               (dataset.times[b] - dataset.times[a]) + "*"; \r
+       }\r
+\r
+       @Override\r
+       public void setFocus() {\r
+           \r
+       }\r
+\r
+       @Override\r
+       public void dispose() {\r
+               super.dispose();\r
+               getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(selectionListener);\r
+               disposed = true;\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/viewUtils/SysdynDatasetSelectionListener.java
new file mode 100644 (file)
index 0000000..688ba1f
--- /dev/null
@@ -0,0 +1,225 @@
+/*******************************************************************************\r
+ * Copyright (c) 2010 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.viewUtils;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.Set;\r
+\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchPart;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.procedure.adapter.DisposableListener;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.sysdyn.Functions;\r
+import org.simantics.sysdyn.JFreeChartResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.ui.trend.PinTrend;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
+\r
+/**\r
+ * Selection listener for listening datasets of the selected variables. Selections can come \r
+ * from both diagram and model browser. Listener provides the active datasets\r
+ * of the selected variable(s) or the JFreeChart of a selected chart definition. \r
+ * \r
+ * @author Teemu Lempinen\r
+ *\r
+ */\r
+public abstract class SysdynDatasetSelectionListener implements ISelectionListener {\r
+\r
+    /**\r
+     * Triggered after a variable is selected from diagram or model browser\r
+     * Subclasses implement.\r
+     * @param activeDatasets Active dataset(s) of the selected variable(s)\r
+     */\r
+    protected abstract void selectionChanged(Collection<SysdynDataSet> activeDatasets);\r
+\r
+    /**\r
+     * Triggered after a chart definition is selected from model browser\r
+     * Subclasses implement\r
+     * \r
+     * @param graph ReadGraph\r
+     * @param resource Chart definition resource\r
+     */\r
+    protected abstract void selectionChanged(ReadGraph graph, Resource resource);\r
+\r
+\r
+\r
+    public void dispose() {\r
+        if(listener != null)\r
+            listener.dispose();\r
+    }\r
+    \r
+    DisposableListener<ArrayList<SysdynDataSet>> listener;\r
+\r
+    @Override\r
+    public void selectionChanged(IWorkbenchPart part, final ISelection selection) {\r
+        // Empty selection or pinned trend -> Do nothing\r
+        if(selection.isEmpty() || Boolean.TRUE.equals(PinTrend.getState()))\r
+            return;\r
+\r
+        if(selection instanceof IStructuredSelection) {\r
+            Session session = SimanticsUI.peekSession();\r
+            if (session == null)\r
+                return;\r
+            \r
+            if(listener != null)\r
+                listener.dispose();\r
+            \r
+            listener = new DisposableListener<ArrayList<SysdynDataSet>>() {\r
+\r
+                @Override\r
+                public void execute(ArrayList<SysdynDataSet> vars) {\r
+                    if(vars != null)\r
+                        selectionChanged(vars);\r
+                }\r
+\r
+                @Override\r
+                public void exception(Throwable t) {\r
+                    t.printStackTrace();\r
+                }\r
+            };\r
+\r
+            try {\r
+                session.syncRequest(new Read<ArrayList<SysdynDataSet>>() {\r
+                    @Override\r
+                    public ArrayList<SysdynDataSet> perform(ReadGraph graph) throws DatabaseException {\r
+\r
+                        // Model browser provides variables\r
+                        Collection<Variable> vars = ISelectionUtils.filterSetSelection(selection, Variable.class);\r
+\r
+                        if(vars.isEmpty()) {\r
+                            // Selection did not contain variables\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
+                                // Selection is most probably in a diagram\r
+                                Resource runtime = runtimes.get(0);\r
+\r
+                                // Get variables for selected resources\r
+                                for(Resource resource : ress) {\r
+                                    Variable variable = getVariable(graph, resource, runtime);\r
+                                    if(variable != null)\r
+                                        vars.add(variable);\r
+                                }\r
+\r
+                                // If there is no vars and only one selection, it can be a chart\r
+                                if(vars.isEmpty() && ress.size() == 1) {\r
+                                    Resource r = ress.iterator().next();\r
+                                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                                    if(graph.isInstanceOf(r, jfree.ChartElement)) {\r
+                                        if(graph.hasStatement(r, jfree.ChartElement_component)) {\r
+                                            r = graph.getSingleObject(r, jfree.ChartElement_component);\r
+                                            selectionChanged(graph, r);\r
+                                            return null;\r
+                                        }\r
+                                    }\r
+                                }\r
+\r
+                            } else {\r
+                                // Selection is a jfreechart\r
+                                if(ress.size() == 1) {\r
+                                    Resource r = ress.iterator().next();\r
+                                    JFreeChartResource jfree = JFreeChartResource.getInstance(graph);\r
+                                    if(graph.isInstanceOf(r, jfree.Chart)) {\r
+                                        selectionChanged(graph, r);\r
+                                        return null;\r
+                                    }\r
+                                }\r
+                            }\r
+                        }\r
+\r
+                        // Update datasets and add result listeners to models\r
+                        return getDatasets(graph, vars);\r
+\r
+                    }\r
+                }, listener);\r
+            } catch (DatabaseException e) {\r
+                e.printStackTrace();   \r
+            }\r
+        }\r
+    }\r
+\r
+\r
+\r
+    /**\r
+     * Updates datasets for the selected variables\r
+     * @param graph ReadGraph\r
+     * @param variables Selected variables\r
+     * @throws DatabaseException\r
+     */\r
+    private ArrayList<SysdynDataSet> getDatasets(ReadGraph graph, Collection<Variable> variables) throws DatabaseException {\r
+\r
+        ArrayList<SysdynDataSet> datasets = new ArrayList<SysdynDataSet>();\r
+        for(Variable variable : variables) {\r
+            Variable v = graph.syncRequest(new PossibleActiveVariableFromVariable(variable));\r
+            if(v == null)\r
+                continue;\r
+            // Get all active datasets for the variable and add them to the result\r
+            Variable dsVariable = v.browsePossible(graph, "#" + Functions.ACTIVE_DATASETS + "#");\r
+            Object object = null;\r
+            if(dsVariable != null)\r
+                 object = dsVariable.getValue(graph);\r
+\r
+            if(object != null && object instanceof ArrayList<?>)\r
+                for(Object o : (ArrayList<?>)object) {\r
+                    if(o instanceof SysdynDataSet)\r
+                        datasets.add((SysdynDataSet)o);\r
+                }\r
+        }\r
+\r
+        return datasets;\r
+    }\r
+\r
+\r
+    /**\r
+     * Find a variable representing element\r
+     * \r
+     * @param g ReadGraph\r
+     * @param element Element resource\r
+     * @param runtime runtime resource\r
+     * @return Variable representing element\r
+     * @throws DatabaseException\r
+     */\r
+    private Variable getVariable(ReadGraph g, Resource element, Resource runtime) throws DatabaseException {\r
+        SysdynResource sr = SysdynResource.getInstance(g);\r
+        DiagramResource dr = DiagramResource.getInstance(g);\r
+        if(runtime == null) return null;\r
+        Resource resource = ModelingUtils.getPossibleElementCorrespondendence(g, element);\r
+        if(resource != null && g.isInstanceOf(resource, sr.Shadow)) resource = g.getPossibleObject(resource, sr.Shadow_original);\r
+        if(resource == null || !g.isInstanceOf(resource, sr.Variable)) return null;\r
+        String variableURI = g.getPossibleRelatedValue(runtime, dr.RuntimeDiagram_HasVariable);\r
+        if(variableURI != null) {\r
+            try {\r
+                Variable compositeVariable = Variables.getVariable(g, variableURI);\r
+                return compositeVariable.browsePossible(g, resource);\r
+            } catch (MissingVariableException e) {}\r
+        }\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/Preferences.java
new file mode 100644 (file)
index 0000000..f75c970
--- /dev/null
@@ -0,0 +1,55 @@
+package org.simantics.sysdyn.ui.wizards;\r
+\r
+import java.util.Deque;\r
+import java.util.Iterator;\r
+import java.util.LinkedList;\r
+import java.util.Set;\r
+import java.util.TreeSet;\r
+\r
+import org.eclipse.ui.IMemento;\r
+import org.simantics.utils.ui.workbench.StringMemento;\r
+\r
+public final class Preferences {\r
+\r
+    public static final String  RECENT_MODEL_IMPORT_LOCATIONS = "RECENT_MODEL_IMPORT_LOCATIONS";\r
+    public static final String  RECENT_MODEL_EXPORT_LOCATIONS = "RECENT_MODEL_EXPORT_LOCATIONS";\r
+    public static final String  MODEL_EXPORT_OVERWRITE = "MODEL_EXPORT_OVERWRITE";\r
+\r
+    private static final String TAG_PATH                = "path";\r
+    private static final String ATTR_NAME               = "name";\r
+\r
+    public static Deque<String> decodePaths(String recentPathsPref) {\r
+        Deque<String> result = new LinkedList<String>();\r
+        try {\r
+            StringMemento sm = new StringMemento(recentPathsPref);\r
+            for (IMemento m : sm.getChildren(TAG_PATH)) {\r
+                String name = m.getString(ATTR_NAME);\r
+                if (name != null && !name.isEmpty())\r
+                    result.add(name);\r
+            }\r
+        } catch (IllegalArgumentException e) {\r
+        }\r
+        return result;\r
+    }\r
+\r
+    public static String encodePaths(Deque<String> recentPaths) {\r
+        StringMemento sm = new StringMemento();\r
+        for (String path : recentPaths) {\r
+            IMemento m = sm.createChild(TAG_PATH);\r
+            m.putString(ATTR_NAME, path);\r
+        }\r
+        return sm.toString();\r
+    }\r
+\r
+    public static <T> void removeDuplicates(Iterable<String> iter) {\r
+        // Remove duplicates\r
+        Set<String> dups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);\r
+        for (Iterator<String> it = iter.iterator(); it.hasNext();) {\r
+            String path = it.next();\r
+            if (!dups.add(path)) {\r
+                it.remove();\r
+            }\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ExportWizardFunction.java
new file mode 100644 (file)
index 0000000..5b5667b
--- /dev/null
@@ -0,0 +1,53 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+\r
+public class ExportWizardFunction extends Wizard implements IImportWizard {\r
+       \r
+       private WizardFunctionsExportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       public Resource selection;\r
+\r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardFunction() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardFunction(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
\r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Export");\r
+        this.currentSelection = currentSelection;\r
+        selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class);\r
+    }\r
+    \r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardFunctionsExportPage(\r
+                               "wizardFunctionsExportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects(selection);\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeFunctionLabeler.java
new file mode 100644 (file)
index 0000000..37d85e0
--- /dev/null
@@ -0,0 +1,20 @@
+package org.simantics.sysdyn.ui.wizards.functions;\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.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+\r
+public class FunctionTreeFunctionLabeler extends LabelerContributor<FunctionLibraryNode<Resource>>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, FunctionLibraryNode<Resource> input)\r
+                       throws DatabaseException {\r
+               String name = NameUtils.getSafeName(graph, input.data);\r
+               return name;\r
+       }\r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeLibraries.java
new file mode 100644 (file)
index 0000000..f234424
--- /dev/null
@@ -0,0 +1,37 @@
+package org.simantics.sysdyn.ui.wizards.functions;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class FunctionTreeLibraries extends ViewpointContributor<ModelNode> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ModelNode model)\r
+    throws DatabaseException {\r
+       ArrayList<FunctionLibraryNode<Resource>> result = new ArrayList<FunctionLibraryNode<Resource>>();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+               for (Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))){\r
+                       result.add(new FunctionLibraryNode<Resource>(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/wizards/functions/FunctionTreeModelLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModelLabeler.java
new file mode 100644 (file)
index 0000000..1a2003a
--- /dev/null
@@ -0,0 +1,17 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class FunctionTreeModelLabeler extends LabelerContributorImpl<ModelNode>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, ModelNode input)\r
+                       throws DatabaseException {\r
+               return NameUtils.getSafeName(graph, input.data);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeModels.java
new file mode 100644 (file)
index 0000000..623f1a3
--- /dev/null
@@ -0,0 +1,43 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class FunctionTreeModels extends ViewpointContributorImpl<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+               \r
+\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.SysdynModel))) {\r
+                       result.add(new ModelNode(r));\r
+               }\r
+               Resource sharedlibrary = graph.getPossibleResource("http://SharedOntologies");\r
+               if (sharedlibrary != null)\r
+               result.add(new SharedFunctionsFolderNode(sharedlibrary));\r
+               \r
+               return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Function Library Import";\r
+       }\r
+       \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedFolderLabeler.java
new file mode 100644 (file)
index 0000000..17f5368
--- /dev/null
@@ -0,0 +1,15 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class FunctionTreeSharedFolderLabeler extends LabelerContributorImpl<SharedFunctionsFolderNode>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, SharedFunctionsFolderNode input)\r
+                       throws DatabaseException {\r
+               return "Shared Functions";\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraries.java
new file mode 100644 (file)
index 0000000..e9003a1
--- /dev/null
@@ -0,0 +1,35 @@
+package org.simantics.sysdyn.ui.wizards.functions;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+\r
+public class FunctionTreeSharedLibraries extends ViewpointContributor<SharedFunctionsFolderNode> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, SharedFunctionsFolderNode folder)\r
+    throws DatabaseException {\r
+       ArrayList<SharedFunctionLibraryNode> result = new ArrayList<SharedFunctionLibraryNode>();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Resource sharedlibrary = graph.getPossibleResource("http://SharedOntologies");\r
+               for (Resource r : graph.syncRequest(new ObjectsWithType(sharedlibrary, l0.ConsistsOf, sr.SharedFunctionOntology))){\r
+                       result.add(new SharedFunctionLibraryNode(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/wizards/functions/FunctionTreeSharedLibraryLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSharedLibraryLabeler.java
new file mode 100644 (file)
index 0000000..e054cf6
--- /dev/null
@@ -0,0 +1,17 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionLibraryNode;\r
+\r
+public class FunctionTreeSharedLibraryLabeler extends LabelerContributorImpl<SharedFunctionLibraryNode>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, SharedFunctionLibraryNode input)\r
+                       throws DatabaseException {\r
+               return NameUtils.getSafeName(graph, input.data);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/FunctionTreeSubLibraries.java
new file mode 100644 (file)
index 0000000..c88421a
--- /dev/null
@@ -0,0 +1,36 @@
+package org.simantics.sysdyn.ui.wizards.functions;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+\r
+public class FunctionTreeSubLibraries extends ViewpointContributor<FunctionLibraryNode<Resource>> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, FunctionLibraryNode<Resource> library)\r
+    throws DatabaseException {\r
+       ArrayList<FunctionLibraryNode<Resource>> result = new ArrayList<FunctionLibraryNode<Resource>>();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+        \r
+               for (Resource r : graph.syncRequest(new ObjectsWithType(library.data, l0.ConsistsOf, sr.SysdynModelicaFunctionLibrary))){\r
+                       result.add(new FunctionLibraryNode<Resource>(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/wizards/functions/ImportWizardFunction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/ImportWizardFunction.java
new file mode 100644 (file)
index 0000000..b51a322
--- /dev/null
@@ -0,0 +1,54 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+\r
+public class ImportWizardFunction extends Wizard implements IImportWizard {\r
+       \r
+       private WizardFunctionsImportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       public Resource selection;\r
+\r
+    /**\r
+     * Constructor for ImportWizardFunction.\r
+     */\r
+    public ImportWizardFunction() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ImportWizardFunction.\r
+     */\r
+    public ImportWizardFunction(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
\r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Import");\r
+        this.currentSelection = currentSelection;\r
+        selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class);\r
+    }\r
+    \r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardFunctionsImportPage(\r
+                               "wizardFunctionsImportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+               \r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/SharedFunctionsFolderNode.java
new file mode 100644 (file)
index 0000000..2658fb6
--- /dev/null
@@ -0,0 +1,60 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDropTargetNode;\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.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.FunctionLibraryNode;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class SharedFunctionsFolderNode extends FunctionLibraryNode<Resource> implements IDropTargetNode {\r
+\r
+    public SharedFunctionsFolderNode(Resource resource) {\r
+        super(resource);\r
+    }\r
+\r
+       @Override\r
+       public void delete() throws DeleteException {\r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               \r
+                               graph.deny(data, l0.PartOf);\r
+                               graph.deny(data, l0.IsLinkedTo_Inverse);\r
+\r
+                               // TODO: remove file\r
+                       }\r
+               });\r
+       }\r
+       \r
+       @Override\r
+       public void drop(Object data) {\r
+               final Resource[] resources = ResourceAdaptionUtils.toResources(data);\r
+               final Resource library = this.data;\r
+               if(resources.length > 0) {\r
+                       SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       for(Resource tobeMoved : resources) {\r
+                                               if(graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunction) ||\r
+                                                               graph.isInstanceOf(tobeMoved, sr.SysdynModelicaFunctionLibrary)) {\r
+                                                       graph.deny(tobeMoved, l0.PartOf);\r
+                                                       graph.claim(tobeMoved, l0.PartOf, library);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsExportPage.java
new file mode 100644 (file)
index 0000000..785df45
--- /dev/null
@@ -0,0 +1,366 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Files;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.TransferableGraphRequest2;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class WizardFunctionsExportPage extends WizardPage {\r
+       \r
+       // dialog store id constants\r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+       \r
+       //private IStructuredSelection currentSelection;\r
+       \r
+       GraphExplorerComposite functionLibraryExplorer;\r
+       \r
+       private boolean selectionMade = false;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardFunctionsExportPage() {\r
+               this("wizardFunctionsExportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardFunctionsExportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardFunctionsExportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               //this.currentSelection = currentSelection;\r
+               setPageComplete(false);\r
+               setTitle("Export Function Library");\r
+               setDescription("Choose the Function Library and the export location, then press Finish.");\r
+       }\r
+       \r
+       public void createControl(Composite parent) {\r
+               \r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);\r
+               createTree(workArea);\r
+               \r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+               \r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select the export location for Function Library:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+               \r
+               // function library location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+\r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               \r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();        \r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+               \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+               \r
+       }\r
+       \r
+       private void createTree(Composite workArea){\r
+               \r
+               //set label for tree\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Function Library to export:");\r
+\r
+               try {\r
+                       Resource input = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource model = SimanticsUI.getProject().get();\r
+                                       return model;\r
+                               }\r
+\r
+                       });\r
+\r
+                       functionLibraryExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                                       "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE);\r
+\r
+                       functionLibraryExplorer\r
+                       .setBrowseContexts(SysdynResource.URIs.FunctionTree);\r
+\r
+                       functionLibraryExplorer.finish();\r
+\r
+                       functionLibraryExplorer.setInput(null, input);\r
+\r
+                       GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                                       functionLibraryExplorer);\r
+                       \r
+                       ((Tree)functionLibraryExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() {\r
+                               \r
+                               @Override\r
+                               public void widgetSelected(SelectionEvent e) {\r
+                                       setMessage(null);\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                               @Override\r
+                               public void widgetDefaultSelected(SelectionEvent e) {\r
+                                       setMessage(null);\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                       });\r
+\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+\r
+       }\r
+    \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               \r
+               final Shell shell = filePathField.getShell();\r
+               \r
+               FileDialog dialog = new FileDialog(shell, SWT.SAVE);\r
+               \r
+               String[] ext = {"*.sysdynFunctions"};\r
+               dialog.setFilterExtensions(ext);\r
+               \r
+               dialog.setText("Export Function Library");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+               \r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }               \r
+\r
+       }\r
+       \r
+       //Get selection from the tree\r
+       @SuppressWarnings("unchecked")\r
+       public static <T> T getExplorerResource(GraphExplorerComposite explorer,\r
+                       Class<T> clazz) {\r
+               if(explorer == null)\r
+                       return null;\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return null;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement();\r
+               if (inc == null)\r
+                       return null;\r
+               final T resource = (T) inc.getAdapter(clazz);\r
+\r
+               return resource;\r
+       }\r
+       \r
+       public boolean createProjects(Resource selection) {\r
+               \r
+               final String selected = previouslyBrowsedFile;\r
+               if(selected == null) return false;\r
+               \r
+        final Resource functionLibrary = getExplorerResource(functionLibraryExplorer, Resource.class);\r
+        if(functionLibrary == null) return false;\r
+        \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
+                                       if (!graph.hasStatement(functionLibrary, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       String name = graph.syncRequest(new PossibleRelatedValue<String>(functionLibrary, l0.HasName, Bindings.STRING ));\r
+                                       return name;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               if(name == null) return false;\r
+       \r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               String name = graph.syncRequest(new PossibleRelatedValue<String>(functionLibrary, l0.HasName, Bindings.STRING ));\r
+                               ArrayList<Pair<Resource, String>> roots = new ArrayList<Pair<Resource, String>>();\r
+                               roots.add(Pair.make(functionLibrary, name));\r
+                               TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, functionLibrary));\r
+\r
+                               try {\r
+                                       Files.createFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class), tg);\r
+                               } catch (RuntimeBindingConstructionException e) {\r
+                                       e.printStackTrace();\r
+                               } catch (IOException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+\r
+                               \r
+                       }\r
+               });\r
+        \r
+        return true;\r
+       }\r
+       \r
+       void validatePage() {\r
+               \r
+               if (previouslyBrowsedFile.isEmpty() || selectionMade == false){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               \r
+               if (functionLibraryExplorer != null){\r
+                       final Resource selectedResource = getExplorerResource(functionLibraryExplorer, Resource.class);\r
+\r
+                       String root = null;\r
+                       try {\r
+                               root = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                                       @Override\r
+                                       public String perform(ReadGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               Resource model = graph.getPossibleObject(selectedResource, l0.PartOf);\r
+                                               String rootName = NameUtils.getSafeName(graph, model);\r
+\r
+                                               return rootName;\r
+                                       }\r
+\r
+                               });\r
+                               if (root != null && root.equalsIgnoreCase("Development Project")){\r
+                                       setPageComplete(false);\r
+                                       setMessage("Select Function Library folder under the Model or from the Shared Functions folder.");\r
+                                       return;\r
+                               }\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               \r
+               setPageComplete(true);\r
+               \r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/functions/WizardFunctionsImportPage.java
new file mode 100644 (file)
index 0000000..702a96c
--- /dev/null
@@ -0,0 +1,441 @@
+package org.simantics.sysdyn.ui.wizards.functions;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+public class WizardFunctionsImportPage extends WizardPage{\r
+\r
+       // dialog store id constants\r
+       private Text filePathField;\r
+\r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+\r
+       private Shell shell;\r
+\r
+       //private IStructuredSelection currentSelection;\r
+\r
+       private Resource selectedModel;\r
+\r
+       GraphExplorerComposite functionLibraryExplorer;\r
+       \r
+       private boolean selectionMade = false;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardFunctionsImportPage() {\r
+               this("wizardFunctionsImportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardFunctionsImportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+\r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardFunctionsImportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               setPageComplete(false);\r
+               //this.currentSelection = currentSelection;\r
+               setTitle("Import Function Library");\r
+               setDescription("Choose the Function Library file and the import location, then press Finish.");\r
+       }\r
+\r
+       public void createControl(Composite parent) {\r
+\r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);\r
+\r
+               createTree(workArea);\r
+               \r
+               \r
+       }\r
+\r
+       private void createProjectsRoot(Composite workArea) {\r
+\r
+               //set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Function Library source:");\r
+\r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+\r
+               // module location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+\r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               \r
+\r
+               filePathField.addModifyListener(new ModifyListener(){\r
+                       @Override\r
+                       public void modifyText(ModifyEvent e) {\r
+                               previouslyBrowsedFile = filePathField.getText();        \r
+                       }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+\r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+\r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+\r
+       }\r
+\r
+       private void createTree(Composite workArea){\r
+               \r
+               //set label for tree\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select import location:");\r
+\r
+               try {\r
+                       Resource input = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource model = SimanticsUI.getProject().get();\r
+                                       return model;\r
+                               }\r
+\r
+                       });\r
+\r
+                       functionLibraryExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                                       "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE);\r
+\r
+                       functionLibraryExplorer\r
+                       .setBrowseContexts(SysdynResource.URIs.FunctionTree);\r
+\r
+                       functionLibraryExplorer.finish();\r
+\r
+                       functionLibraryExplorer.setInput(null, input);\r
+\r
+                       GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                                       functionLibraryExplorer);\r
+                       \r
+                       ((Tree)functionLibraryExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() {\r
+                               \r
+                               @Override\r
+                               public void widgetSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                               @Override\r
+                               public void widgetDefaultSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                       });\r
+\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+\r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+\r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+\r
+               shell = filePathField.getShell();\r
+\r
+               FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
+\r
+               String[] ext = {"*.sysdynFunctions; *.tg", "*.*"};\r
+               dialog.setFilterExtensions(ext);\r
+\r
+               dialog.setText("Import Function Library");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+\r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+\r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }       \r
+       }\r
+\r
+       //Get selection from the tree\r
+       @SuppressWarnings("unchecked")\r
+       public static <T> T getExplorerResource(GraphExplorerComposite explorer,\r
+                       Class<T> clazz) {\r
+               \r
+               if(explorer == null)\r
+                       return null;\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return null;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement();\r
+               if (inc == null)\r
+                       return null;\r
+               final T resource = (T) inc.getAdapter(clazz);\r
+\r
+               return resource;\r
+       }\r
+\r
+       //Create project after finish is pressed.\r
+       public boolean createProjects() {\r
+               \r
+               selectedModel= getExplorerResource(functionLibraryExplorer, Resource.class);\r
+               if(selectedModel == null){\r
+                       setErrorMessage("Error when retrieving resource");\r
+                       return false;\r
+               }\r
+                       \r
+               String selected = previouslyBrowsedFile;\r
+               if(selected == null){\r
+                       setErrorMessage("No file selected");\r
+                       return false;\r
+               }\r
+               \r
+               IStatus status = ImportUtilsUI.importFunctionLibrary(selectedModel, selected, null);\r
+\r
+               /*\r
+               TransferableGraph1 tg = null;\r
+               try {\r
+                       tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class));\r
+               } catch (RuntimeBindingConstructionException e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               } catch (IOException e) {\r
+                       setErrorMessage("The imported file is not of type: Function Library");\r
+                       return false;\r
+               } \r
+               if(tg == null){\r
+                       setErrorMessage("The imported file is not of type: Function Library");\r
+                       return false;\r
+               }\r
+\r
+\r
+               try {\r
+                       Boolean hasSharedOntologies;\r
+                       hasSharedOntologies = SimanticsUI.getSession().syncRequest(new Read<Boolean>() {\r
+\r
+                               @Override\r
+                               public Boolean perform(ReadGraph graph) throws DatabaseException {\r
+                                       try {\r
+                                               graph.getResource("http://SharedOntologies");\r
+                                       } catch (ResourceNotFoundException e) {\r
+                                               return false;\r
+                                       }               \r
+                                       return true;\r
+                               }\r
+                       });\r
+\r
+                       if(!hasSharedOntologies) {\r
+                               SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               GraphUtils.create2(graph, l0.Library, \r
+                                                               l0.HasName, "SharedOntologies",\r
+                                                               l0.PartOf, graph.getResource("http:/"));\r
+                                       }\r
+                               });\r
+\r
+                       }\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               }\r
+\r
+\r
+               SysdynFunctionLibraryImportAdvisor ia = new SysdynFunctionLibraryImportAdvisor(selectedModel);\r
+               try {\r
+                       DefaultPasteHandler.defaultExecute(tg, selectedModel, ia);\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+               final Resource root = ia.getRoot();\r
+\r
+               try {\r
+                       SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       if(graph.isInstanceOf(root, SysdynResource.getInstance(graph).SharedFunctionOntology)) {\r
+                                               Resource library = graph.getResource("http://SharedOntologies");\r
+                                               if(!graph.hasStatement(library, l0.ConsistsOf, root)) {\r
+                                                       graph.claim(library, l0.ConsistsOf, root);\r
+                                               }\r
+\r
+                                               SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                               Resource model = selectedModel;\r
+                                               while(!graph.isInstanceOf(model, sr.SysdynModel) && graph.isInstanceOf(model, l0.Ontology))\r
+                                                       model = graph.getSingleObject(model, l0.PartOf);\r
+                                               if(graph.isInstanceOf(model, sr.SysdynModel)) {\r
+                                                       graph.claim(model, l0.IsLinkedTo, l0.IsLinkedTo_Inverse, root);\r
+                                               }\r
+\r
+                                       } else if(!graph.isInstanceOf(root, SysdynResource.getInstance(graph).SysdynModelicaFunctionLibrary)) {\r
+                                               Resource instanceOf = graph.getPossibleObject(root,l0.InstanceOf);\r
+                                               String type = "...";\r
+                                               if(instanceOf != null)\r
+                                                       type = NameUtils.getSafeName(graph, instanceOf);\r
+                                               else {\r
+                                                       Resource inheritedFrom = graph.getPossibleObject(root, l0.Inherits);\r
+                                                       if(inheritedFrom != null)\r
+                                                               type = NameUtils.getSafeName(graph, inheritedFrom);\r
+                                               } \r
+                                               graph.deny(root, l0.PartOf);\r
+                                               error = type;\r
+                                       }\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               if (!error.isEmpty()){\r
+                       setErrorMessage("The imported file is not of type: Function Library (" + error +")");\r
+                       error = "";\r
+                       return false;\r
+               }\r
+                */\r
+               if(status == null || !status.equals(Status.OK_STATUS)) {\r
+                   setErrorMessage(status.getMessage());\r
+                   return false;\r
+               }\r
+               return true;\r
+       }\r
+       /*\r
+\r
+       private class SysdynFunctionLibraryImportAdvisor extends DefaultPasteImportAdvisor {\r
+\r
+               public SysdynFunctionLibraryImportAdvisor(Resource library) {\r
+                       super(library);\r
+               }\r
+\r
+               @Override\r
+               public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {\r
+                       if(root.type.equals(SysdynResource.URIs.SharedFunctionOntology)) {\r
+                               try {\r
+                                       library = graph.getResource("http://SharedOntologies");\r
+                               } catch (ResourceNotFoundException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {\r
+                       Layer0 l0 = graph.getService(Layer0.class);\r
+                       this.root = graph.newResource();\r
+                       graph.claim(library, l0.ConsistsOf, l0.PartOf, this.root);\r
+                       String name = root.name;\r
+                       String newName = nameMappings.get(name);\r
+                       graph.addLiteral(this.root, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING);\r
+                       return this.root;\r
+\r
+               }\r
+\r
+       }\r
+       */\r
+       \r
+       void validatePage() {\r
+\r
+               if (previouslyBrowsedFile.isEmpty() || selectionMade == false){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               setErrorMessage(null);\r
+               setPageComplete(true);\r
+\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/ImportWizardMdl.java
new file mode 100644 (file)
index 0000000..9142284
--- /dev/null
@@ -0,0 +1,47 @@
+package org.simantics.sysdyn.ui.wizards.mdl;\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+\r
+public class ImportWizardMdl extends Wizard implements IImportWizard {\r
+       \r
+       private WizardMdlImportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardMdl() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardMdl(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
+\r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardMdlImportPage(\r
+                               "wizardMdlImportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+    \r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Import");\r
+        this.currentSelection = currentSelection;\r
+    }\r
+    \r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/mdl/WizardMdlImportPage.java
new file mode 100644 (file)
index 0000000..d4679f7
--- /dev/null
@@ -0,0 +1,213 @@
+package org.simantics.sysdyn.ui.wizards.mdl;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\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.modelImport.MdlParser;\r
+import org.simantics.sysdyn.modelImport.model.Model;\r
+import org.simantics.sysdyn.modelImport.model.WriteContext;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class WizardMdlImportPage extends WizardPage{\r
+       \r
+       // dialog store id constants\r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardMdlImportPage() {\r
+               this("wizardMdlImportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardMdlImportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardMdlImportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               setPageComplete(false);\r
+               setTitle("Import Vensim model");\r
+               setDescription("Choose the Vensim model file (.mdl), then press Finish.");\r
+       }\r
+\r
+       public void createControl(Composite parent) {\r
+       \r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);   \r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+\r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Vensim model source:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+\r
+               // model location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+               \r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();        \r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+               \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+               \r
+       }\r
+       \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               \r
+               final Shell shell = filePathField.getShell();\r
+\r
+               FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
+               String[] ext = {"*.mdl"};\r
+               dialog.setFilterExtensions(ext);\r
+               dialog.setText("Import Vensim model (.mdl)");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+               \r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }\r
+\r
+       }\r
+       \r
+       //Create project after finish is pressed.\r
+       public boolean createProjects() {\r
+               \r
+               final Resource project = SimanticsUI.getProject().get();\r
+               if(project == null) return false;\r
+\r
+               String selected = previouslyBrowsedFile;\r
+               if(selected == null) return false;\r
+               \r
+               File file = new File(selected);\r
+               \r
+               // TODO: is this wizard actually used anywhere?\r
+               final Model model;\r
+               \r
+               try {\r
+                       model = new MdlParser().parse(file);\r
+               }\r
+               catch (Exception e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               }\r
+               \r
+               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                       @Override\r
+                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                               model.write(graph, project, new WriteContext());\r
+                       }\r
+               });\r
+               \r
+               return true;\r
+               \r
+       }\r
+    void validatePage(){\r
+       \r
+               if (previouslyBrowsedFile.isEmpty()){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               \r
+               setPageComplete(true);\r
+    }\r
+}\r
+       
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynExportModel.java
new file mode 100644 (file)
index 0000000..593bec5
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+\r
+import org.simantics.db.common.NamedResource;\r
+\r
+public class SysdynExportModel {\r
+    \r
+    private Object              selection;\r
+    private File                exportLocation;\r
+    private String              description;\r
+    private boolean             overwrite;\r
+    private NamedResource       model;\r
+    private boolean             dependencies;\r
+    \r
+    public SysdynExportModel(Object selection, boolean overwrite) {\r
+        this.selection = selection;\r
+        this.description = "";\r
+        this.overwrite = overwrite;\r
+    }\r
+\r
+    /**\r
+     * @return the overwrite\r
+     */\r
+    public boolean getOverwrite() {\r
+        return overwrite;\r
+    }\r
+\r
+    /**\r
+     * @param overwrite the overwrite to set\r
+     */\r
+    public void setOverwrite(boolean overwrite) {\r
+        this.overwrite = overwrite;\r
+    }\r
+\r
+    /**\r
+     * @return the selection\r
+     */\r
+    public Object getSelection() {\r
+        return selection;\r
+    }\r
+\r
+    /**\r
+     * @param selection the selection to set\r
+     */\r
+    public void setSelection(Object selection) {\r
+        this.selection = selection;\r
+    }\r
+\r
+    /**\r
+     * @return the description\r
+     */\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    /**\r
+     * @param description the description to set\r
+     */\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+    /**\r
+     * @return the exportLocation\r
+     */\r
+    public File getExportLocation() {\r
+        return exportLocation;\r
+    }\r
+\r
+    /**\r
+     * @param exportLocation the exportLocation to set\r
+     */\r
+    public void setExportLocation(File exportLocation) {\r
+        this.exportLocation = exportLocation;\r
+    }\r
+\r
+    public void setModel(NamedResource model) {\r
+        this.model = model;\r
+    }\r
+    \r
+    public NamedResource getModel() {\r
+        return this.model;\r
+    }\r
+\r
+    /**\r
+     * @return the dependencies\r
+     */\r
+    public boolean getDependencies() {\r
+        return dependencies;\r
+    }\r
+\r
+    /**\r
+     * @param dependencies the dependencies to set\r
+     */\r
+    public void setDependencies(boolean dependencies) {\r
+        this.dependencies = dependencies;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynImportModel.java
new file mode 100644 (file)
index 0000000..b6e8ee9
--- /dev/null
@@ -0,0 +1,58 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.util.Deque;\r
+\r
+public class SysdynImportModel {\r
+\r
+    private Object          selection;\r
+    private Deque<String>   recentLocations;\r
+    private File            importLocation;\r
+\r
+    public SysdynImportModel(Deque<String> recentImportPaths) {\r
+        this.recentLocations = recentImportPaths;\r
+    }\r
+\r
+    /**\r
+     * @return the selection\r
+     */\r
+    public Object getSelection() {\r
+        return selection;\r
+    }\r
+\r
+    /**\r
+     * @param selection the selection to set\r
+     */\r
+    public void setSelection(Object selection) {\r
+        this.selection = selection;\r
+    }\r
+\r
+    /**\r
+     * @return the recentLocations\r
+     */\r
+    public Deque<String> getRecentLocations() {\r
+        return recentLocations;\r
+    }\r
+\r
+    /**\r
+     * @param recentLocations the recentLocations to set\r
+     */\r
+    public void setRecentLocations(Deque<String> recentLocations) {\r
+        this.recentLocations = recentLocations;\r
+    }\r
+\r
+    /**\r
+     * @return the importLocation\r
+     */\r
+    public File getImportLocation() {\r
+        return importLocation;\r
+    }\r
+\r
+    /**\r
+     * @param importLocation the importLocation to set\r
+     */\r
+    public void setImportLocation(File importLocation) {\r
+        this.importLocation = importLocation;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportPage.java
new file mode 100644 (file)
index 0000000..27b196d
--- /dev/null
@@ -0,0 +1,257 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\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.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.NamedResource;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.modelExport.ExportConstants;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+\r
+public class SysdynModelExportPage extends WizardPage {\r
+\r
+    private SysdynExportModel           exportModel;\r
+    private CCombo                      exportLocation;\r
+    private CCombo                      model;\r
+    //private Composite                   draft;\r
+    private Text                        description;\r
+    private Button                      overwrite;\r
+    private List<NamedResource>         models;\r
+    private Button                      dependencies;\r
+    private Button                      browseFileButton;\r
+    \r
+    protected SysdynModelExportPage(SysdynExportModel exportModel) {\r
+        super("Export Sysdyn Model", "Define Export location", null);\r
+        this.exportModel = exportModel;\r
+    }\r
+\r
+    @Override\r
+    public void createControl(Composite parent) {\r
+        Composite container = new Composite(parent, SWT.NONE);\r
+        GridLayout layout = new GridLayout();\r
+        layout.horizontalSpacing = 20;\r
+        layout.verticalSpacing = 10;\r
+        layout.numColumns = 3;\r
+        container.setLayout(layout);\r
+        \r
+//        draft = new Composite(container, SWT.NONE);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(draft);\r
+//        draft.setBackground(draft.getDisplay().getSystemColor(SWT.COLOR_RED));\r
+//        GridLayoutFactory.swtDefaults().spacing(5, 5).applyTo(draft);\r
+//        \r
+//        Composite draft2 = new Composite(draft, SWT.NONE);\r
+//        GridLayoutFactory.swtDefaults().applyTo(draft2);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(draft2);\r
+//        new Label(draft2, SWT.NONE).setText("The model contains unpublished dependencies. The model can only be saved with draft status.");\r
+//        \r
+        new Label(container, SWT.NONE).setText("Exported model:");\r
+        model = new CCombo(container, SWT.BORDER);\r
+        model.setEditable(false);\r
+        model.setText("");\r
+        model.setToolTipText("Selects the model to export a state from.");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(model);\r
+        model.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                \r
+                for (NamedResource nr : models) {\r
+                    if (model.getText().equals(nr.getName())) {\r
+                            exportModel.setModel(nr);\r
+                            break;\r
+                    }\r
+                }\r
+                browseFileButton.setFocus();\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        new Label(container, SWT.NONE).setText("&Target file:");\r
+        exportLocation = new CCombo(container, SWT.BORDER);\r
+        exportLocation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(exportLocation);\r
+        exportLocation.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        browseFileButton = new Button(container, SWT.PUSH);\r
+        browseFileButton.setText("Brows&e...");\r
+        browseFileButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
+        browseFileButton.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);\r
+                dialog.setText("Choose Export Target File");\r
+                String loc = exportLocation.getText();\r
+                //if (exportModel.model != null)\r
+                 //   dialog.setFileName(exportModel.model.get().getName());\r
+                dialog.setFilterPath(loc);\r
+                dialog.setFilterExtensions(new String[] { "*" + ExportConstants.MODEL_FILE_EXTENSION });\r
+                dialog.setFilterNames(new String[] { "Sysdyn Model (*" + ExportConstants.MODEL_FILE_EXTENSION + ")" });\r
+                dialog.setOverwrite(false);\r
+                String file = dialog.open();\r
+                if (file == null)\r
+                    return;\r
+                exportLocation.setText(file);\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        new Label(container, SWT.NONE).setText("Notes:");\r
+\r
+        description = new Text(container, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 150).grab(true, true).span(3, 1).applyTo(description);\r
+        description.addModifyListener(new ModifyListener() {\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                exportModel.setDescription(description.getText());\r
+            }\r
+        });\r
+        \r
+        Label horizRule = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule);\r
+\r
+        overwrite = new Button(container, SWT.CHECK);\r
+        overwrite.setText("&Overwrite existing files without warning");\r
+        overwrite.setSelection(exportModel.getOverwrite());\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(overwrite);\r
+        overwrite.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        dependencies = new Button(container, SWT.CHECK);\r
+        dependencies.setText("&Include Shared Libraries in exported file");\r
+        dependencies.setSelection(exportModel.getDependencies());\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(dependencies);\r
+        dependencies.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        \r
+        try {\r
+            initializeData();\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+        \r
+        setControl(container);\r
+        browseFileButton.setFocus();\r
+        validatePage();\r
+    }\r
+\r
+    private void initializeData() throws DatabaseException {\r
+        final Resource selection = ResourceAdaptionUtils.toSingleResource(exportModel.getSelection());\r
+\r
+        models = getModels();\r
+        Collections.sort(models);\r
+        int i = 0;\r
+        for (NamedResource namedResource : models) {\r
+            model.add(namedResource.getName());\r
+            if (selection != null && selection.equals(namedResource.getResource())) {\r
+                model.select(i);\r
+                exportModel.setModel(namedResource);\r
+            } else {\r
+                model.select(0);\r
+                for (NamedResource nr : models) {\r
+                    if (model.getItem(0).equals(nr.getName()))\r
+                        exportModel.setModel(nr);\r
+                }\r
+                \r
+            }\r
+            i++;\r
+        }\r
+    }\r
+\r
+    private List<NamedResource> getModels() throws DatabaseException {\r
+        return Simantics.getSession().sync(new UniqueRead<List<NamedResource>>() {\r
+\r
+            @Override\r
+            public List<NamedResource> perform(ReadGraph graph) throws DatabaseException {\r
+                Layer0 L0 = Layer0.getInstance(graph);\r
+                SysdynResource SYSDYN = SysdynResource.getInstance(graph);\r
+                ArrayList<NamedResource> models = new ArrayList<NamedResource>();\r
+                Resource currentProject = Simantics.getProjectResource();\r
+                Collection<Resource> consistsOfs = graph.getObjects(currentProject, L0.ConsistsOf);\r
+                for (Resource resource : consistsOfs) {\r
+                    if (graph.isInstanceOf(resource, SYSDYN.SysdynModel)) {\r
+                        String modelName = graph.getRelatedValue2(resource, L0.HasName, Bindings.STRING);\r
+                        models.add(new NamedResource(modelName, resource));\r
+                    }\r
+                }\r
+                return models;\r
+            }\r
+        });\r
+    }\r
+\r
+    protected void validatePage() {\r
+        if (model.getItemCount() == 0){\r
+            setErrorMessage("There are no exportable Sysdyn models in your workspace.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        String exportLoc = exportLocation.getText();\r
+        if (exportLoc.isEmpty()) {\r
+            setMessage("Select target file.");\r
+            setErrorMessage(null);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        if (!exportLoc.endsWith(ExportConstants.MODEL_FILE_EXTENSION)) {\r
+            setErrorMessage("Wrong file extension! Correct is " + ExportConstants.MODEL_FILE_EXTENSION);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File file = new File(exportLoc);\r
+        if (file.isDirectory()) {\r
+            setErrorMessage("The target must be a file, an existing directory was given.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File parent = file.getParentFile();\r
+        if (parent == null || !parent.isDirectory()) {\r
+            setErrorMessage("The target directory does not exist.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        \r
+        exportModel.setExportLocation(file);\r
+        exportModel.setOverwrite(overwrite.getSelection());\r
+        exportModel.setDependencies(dependencies.getSelection());\r
+        exportModel.setDescription(description.getText());\r
+        \r
+        setErrorMessage(null);\r
+        setMessage("Export selected model.");\r
+        setPageComplete(true);\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelExportWizard.java
new file mode 100644 (file)
index 0000000..baaea7f
--- /dev/null
@@ -0,0 +1,123 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.Deque;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.ui.IExportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.modeling.ui.utils.NoProjectPage;\r
+import org.simantics.sysdyn.modelExport.SysdynModelExporter;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.wizards.Preferences;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SysdynModelExportWizard extends Wizard implements IExportWizard {\r
+\r
+    private static final int MAX_RECENT_EXPORT_PATHS = 10;\r
+    \r
+    private SysdynExportModel   exportModel;\r
+    private Deque<String>       recentExportPaths;\r
+    private boolean             overwrite;\r
+    \r
+    public SysdynModelExportWizard() {\r
+        setWindowTitle("Export Sysdyn Model");\r
+        setNeedsProgressMonitor(true);\r
+    }\r
+\r
+    @Override\r
+    public void init(IWorkbench workbench, IStructuredSelection selection) {\r
+        readPreferences();\r
+        exportModel = new SysdynExportModel(selection.getFirstElement(), overwrite);\r
+    }\r
+    \r
+    @Override\r
+    public void addPages() {\r
+        super.addPages();\r
+        if (exportModel != null)\r
+            addPage(new SysdynModelExportPage(exportModel));\r
+        else\r
+            addPage(new NoProjectPage("Export Sysdyn Model"));\r
+    }\r
+\r
+    @Override\r
+    public boolean performFinish() {\r
+        try {\r
+            recentExportPaths.addFirst(exportModel.getExportLocation().getAbsolutePath());\r
+            Preferences.removeDuplicates(recentExportPaths);\r
+            if (recentExportPaths.size() > MAX_RECENT_EXPORT_PATHS)\r
+                recentExportPaths.pollLast();\r
+\r
+            writePreferences();\r
+        } catch (IOException e) {\r
+            ErrorLogger.defaultLogError("Failed to write preferences", e);\r
+        }\r
+\r
+        final File output = exportModel.getExportLocation();\r
+        if (output.exists()) {\r
+            if (!exportModel.getOverwrite()) {\r
+                boolean ok = MessageDialog.openConfirm(getShell(), "Overwrite", "A file by the name " + output.getAbsolutePath() + " already exists.\n\nDo you want to overwrite?");\r
+                if (!ok) {\r
+                    return false;\r
+                }\r
+            }\r
+            if (!output.delete()) {\r
+                MessageDialog.openError(getShell(), "Delete Problem", "Could not overwrite previously existing file " + output);\r
+                return false;\r
+            }\r
+        }\r
+        try {\r
+            getContainer().run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
+                    SysdynModelExporter.exportModel(monitor, exportModel.getModel().getResource(), exportModel.getExportLocation(), exportModel.getDescription(), exportModel.getDependencies());\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Throwable t = e.getTargetException();\r
+            WizardPage cp = (WizardPage) getContainer().getCurrentPage();\r
+            if (t instanceof IOException) {\r
+                ErrorLogger.defaultLogError("An I/O problem occurred while exporting the model. See exception for details.", t);\r
+                cp.setErrorMessage("An I/O problem occurred while exporting the model.\nMessage: " + t.getMessage());\r
+            } else {\r
+                ErrorLogger.defaultLogError("Unexpected exception while exporting the model. See exception for details.", t);\r
+                cp.setErrorMessage("Unexpected exception while exporting the model. See error log for details.\nMessage: " + t.getMessage());\r
+            }\r
+            return false;\r
+        } catch (InterruptedException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+            return false;\r
+        }\r
+\r
+        return true;\r
+    }\r
+\r
+    private void readPreferences() {\r
+        \r
+        IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        String recentPathsPref = store.getString(Preferences.RECENT_MODEL_EXPORT_LOCATIONS);\r
+        recentExportPaths = Preferences.decodePaths(recentPathsPref);\r
+        overwrite = store.getBoolean(Preferences.MODEL_EXPORT_OVERWRITE);\r
+    }\r
+    \r
+    private void writePreferences() throws IOException {\r
+        \r
+        IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        store.putValue(Preferences.RECENT_MODEL_EXPORT_LOCATIONS, Preferences.encodePaths(recentExportPaths));\r
+        store.setValue(Preferences.MODEL_EXPORT_OVERWRITE, exportModel.getOverwrite());\r
+        if (store.needsSaving())\r
+            store.save();\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportPage.java
new file mode 100644 (file)
index 0000000..3ab66cd
--- /dev/null
@@ -0,0 +1,219 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.concurrent.atomic.AtomicReference;\r
+\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\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.GridData;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.container.DataContainer;\r
+import org.simantics.databoard.container.DataContainers;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.modelExport.ExportConstants;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+public class SysdynModelImportPage extends WizardPage {\r
+\r
+    private SysdynImportModel       importModel;\r
+    private Text                    importTarget;\r
+    private CCombo                  importLocation;\r
+    private Label                   creation;\r
+    //private Label                   version;\r
+    private Text                    description;\r
+    private Text                    status;\r
+\r
+    protected SysdynModelImportPage(SysdynImportModel importModel) {\r
+        super("Import Sysdyn Model", "Define import location", null);\r
+        this.importModel = importModel;\r
+    }\r
+\r
+    @Override\r
+    public void createControl(Composite parent) {\r
+        Composite container = new Composite(parent, SWT.NONE);\r
+        GridLayoutFactory.swtDefaults().spacing(20, 10).numColumns(3).applyTo(container);\r
+\r
+//        draft = new Composite(container, SWT.NONE);\r
+//        draft.setBackground(draft.getDisplay().getSystemColor(SWT.COLOR_RED));\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(draft);\r
+//        GridLayoutFactory.swtDefaults().numColumns(0).margins(0, 0).applyTo(draft);\r
+//        \r
+//        Composite draft2 = new Composite(draft, SWT.NONE);\r
+//        GridLayoutFactory.swtDefaults().applyTo(draft2);\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(draft2);\r
+//        new Label(draft2, SWT.NONE).setText("This model draft was exported with unpublished dependencies.");\r
+        \r
+        new Label(container, SWT.NONE).setText("Import target:");\r
+        importTarget = new Text(container, SWT.BORDER);\r
+        importTarget.setEditable(false);\r
+        importTarget.setText("");\r
+        importTarget.setToolTipText("Shows the target of the import.");\r
+        importTarget.setEnabled(false);\r
+        GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(importTarget);\r
+\r
+        new Label(container, SWT.NONE).setText("&Model file:");\r
+        importLocation = new CCombo(container, SWT.BORDER);\r
+        importLocation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(importLocation);\r
+        importLocation.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+                validatePage();\r
+            }\r
+        });\r
+        Button browseFileButton = new Button(container, SWT.PUSH);\r
+        browseFileButton.setText("Br&owse...");\r
+        browseFileButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));\r
+        browseFileButton.addSelectionListener(new SelectionAdapter() {\r
+            @Override\r
+            public void widgetSelected(SelectionEvent e) {\r
+                FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);\r
+                dialog.setText("Choose Model to Import");\r
+                File lastFile = new File(importLocation.getText());\r
+                dialog.setFilterPath(lastFile.getParent());\r
+                dialog.setFilterExtensions(new String[] { "*.sysdyn" });\r
+                dialog.setFilterNames(new String[] { "Sysdyn Model (*.sysdyn)" });\r
+                String file = dialog.open();\r
+                if (file == null)\r
+                    return;\r
+                importLocation.setText(file);\r
+                //setDump(false, false);\r
+                validatePage();\r
+            }\r
+        });\r
+\r
+        Label horizRule = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule);\r
+\r
+        creation = new Label(container, SWT.NONE);\r
+        creation.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(creation);\r
+//        version = new Label(container, SWT.NONE);\r
+//        version.setText("");\r
+//        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(version);\r
+\r
+        Label notes = new Label(container, SWT.NONE);\r
+        notes.setText("Notes:");\r
+        GridDataFactory.fillDefaults().grab(false, false).span(3, 1).applyTo(notes);\r
+\r
+        description = new Text(container, SWT.MULTI | SWT.READ_ONLY | SWT.V_SCROLL | SWT.BORDER | SWT.FLAT);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 150).grab(true, true).span(3, 1).applyTo(description);\r
+\r
+        status = new Text(container, SWT.MULTI | SWT.READ_ONLY);\r
+        status.setText("");\r
+        GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(status);\r
+\r
+        Label horizRule2 = new Label(container, SWT.BORDER);\r
+        GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 0).grab(true, false).span(3, 1).applyTo(horizRule2);\r
+        \r
+        try {\r
+            initializeData();\r
+        } catch (DatabaseException e) {\r
+            ErrorLogger.defaultLogError(e);\r
+        }\r
+        \r
+        setControl(container);\r
+        validatePage();\r
+    }\r
+\r
+    private void initializeData() throws DatabaseException {\r
+        final AtomicReference<String> projectName = new AtomicReference<String>();\r
+\r
+        Simantics.getSession().syncRequest(new ReadRequest() {\r
+            @Override\r
+            public void run(ReadGraph graph) throws DatabaseException {\r
+                projectName.set( NameUtils.getSafeName(graph, Simantics.getProjectResource()) );\r
+            }\r
+        });\r
+\r
+        importTarget.setText(projectName.get());\r
+\r
+        for (String path : importModel.getRecentLocations()) {\r
+            importLocation.add(path);\r
+        }\r
+        if (importLocation.getItemCount() > 0)\r
+            importLocation.select(0);\r
+        \r
+    }\r
+\r
+    protected void validatePage() {\r
+        String importLoc = importLocation.getText();\r
+        if (importLoc.isEmpty()) {\r
+            setMessage("Select file to import.");\r
+            setErrorMessage(null);\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        File file = new File(importLoc);\r
+        if (!file.exists() || !file.isFile()) {\r
+            setErrorMessage("Selected file is invalid.");\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        \r
+        try {\r
+            importModel.setImportLocation(file);\r
+            \r
+            DataContainer container = DataContainers.readHeader(file);\r
+            \r
+            Variant dateVariant = container.metadata.get("date");\r
+            String dateText = dateVariant != null ? dateVariant.getValue().toString() : "Unknown date";\r
+            \r
+            Variant authorVariant = container.metadata.get("author");\r
+            String authorText = authorVariant != null ? authorVariant.getValue().toString() : "Unknown author";\r
+            \r
+            Variant descriptionVariant = container.metadata.get("description");\r
+            String descriptionText = descriptionVariant != null ? descriptionVariant.getValue().toString() : "";\r
+            \r
+            String creationText = "Created by " + authorText + " on " + dateText; \r
+            \r
+            creation.setText(creationText);\r
+            description.setText(descriptionText);\r
+            \r
+            \r
+            String statusText = "This model can be imported.";\r
+            if (container.version == ExportConstants.CURRENT_MODEL_EXPORT_VERSION) {\r
+//            } else if(container.version >= ExportConstants.SMALLEST_MIGRATED_MODEL_EXPORT_VERSION) {\r
+//                statusText = "This model can be migrated.";\r
+            } else {\r
+                status.setText("This model cannot be imported.");\r
+                setErrorMessage("This model cannot be imported");\r
+                setPageComplete(false);\r
+                return;\r
+            }\r
+            status.setText(statusText);\r
+            creation.getParent().layout();\r
+            \r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+            creation.setText("");\r
+//            version.setText("");\r
+            description.setText("");\r
+            status.setText("This model cannot be imported.");\r
+            setErrorMessage("Could not read header information from " + file.getAbsolutePath());\r
+            setPageComplete(false);\r
+            return;\r
+        }\r
+        setErrorMessage(null);\r
+        setMessage("Import " + file.getName() + "");\r
+        setPageComplete(true);\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/model/SysdynModelImportWizard.java
new file mode 100644 (file)
index 0000000..fad9cf9
--- /dev/null
@@ -0,0 +1,130 @@
+package org.simantics.sysdyn.ui.wizards.model;\r
+\r
+import java.io.IOException;\r
+import java.lang.reflect.InvocationTargetException;\r
+import java.util.Deque;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.OperationCanceledException;\r
+import org.eclipse.core.runtime.preferences.InstanceScope;\r
+import org.eclipse.jface.operation.IRunnableWithProgress;\r
+import org.eclipse.jface.preference.IPersistentPreferenceStore;\r
+import org.eclipse.jface.preference.IPreferenceStore;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.preferences.ScopedPreferenceStore;\r
+import org.simantics.Simantics;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.graph.db.MissingDependencyException;\r
+import org.simantics.modeling.ui.utils.NoProjectPage;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.sysdyn.ui.wizards.Preferences;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.ExceptionUtils;\r
+\r
+public class SysdynModelImportWizard extends Wizard implements IImportWizard {\r
+\r
+    private static final int MAX_RECENT_IMPORT_PATHS = 10;\r
+    \r
+    private SysdynImportModel importModel;\r
+\r
+    public SysdynModelImportWizard() {\r
+        setWindowTitle("Import Sysdyn Model");\r
+        setNeedsProgressMonitor(true);\r
+    }\r
+    \r
+    @Override\r
+    public void init(IWorkbench workbench, IStructuredSelection selection) {\r
+        readPreferences(selection);\r
+        \r
+\r
+    }\r
+    \r
+    @Override\r
+    public void addPages() {\r
+        super.addPages();\r
+        if (importModel != null)\r
+            addPage(new SysdynModelImportPage(importModel));\r
+        else\r
+            addPage(new NoProjectPage("Import Sysdyn Model"));\r
+    }\r
+\r
+    @Override\r
+    public boolean performFinish() {\r
+        try {\r
+            importModel.getRecentLocations().addFirst(importModel.getImportLocation().getAbsolutePath());\r
+            Preferences.removeDuplicates(importModel.getRecentLocations());\r
+            if (importModel.getRecentLocations().size() > MAX_RECENT_IMPORT_PATHS)\r
+                importModel.getRecentLocations().pollLast();\r
+\r
+            writePreferences();\r
+        } catch (IOException e) {\r
+            ErrorLogger.defaultLogError("Failed to write preferences", e);\r
+        }\r
+        \r
+        try {\r
+            getContainer().run(true, true, new IRunnableWithProgress() {\r
+                @Override\r
+                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {\r
+                    try {\r
+                        ImportUtilsUI.importModelFile(importModel.getImportLocation().getAbsolutePath(), monitor);\r
+                        //SysdynModelImporter.importModel(monitor, importModel.getImportLocation());\r
+                    } catch (Exception e) {\r
+                        throw new InvocationTargetException(e);\r
+                    } finally {\r
+                        monitor.done();\r
+                    }\r
+                }\r
+            });\r
+        } catch (InvocationTargetException e) {\r
+            Throwable t = e.getTargetException();\r
+            if (t instanceof OperationCanceledException)\r
+                return false;\r
+\r
+            WizardPage cp = (WizardPage) getContainer().getCurrentPage();\r
+            ErrorLogger.defaultLogError(t);\r
+            if (t instanceof IOException) {\r
+                cp.setErrorMessage("An I/O problem occurred while importing Sysdyn model.\n\nMessage: " + e.getMessage());\r
+            } else if (t instanceof MissingDependencyException) {\r
+                cp.setErrorMessage("The import target project is missing required dependencies from database.");\r
+                ExceptionUtils.logAndShowError(t.getMessage(), t);\r
+            } else {\r
+                cp.setErrorMessage("An unknown problem occurred while importing Sysdyn model.\n\nMessage: " + e.getMessage());\r
+            }\r
+            return false;\r
+        } catch (InterruptedException e) {\r
+            ExceptionUtils.logAndShowError(e);\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+    \r
+    private void readPreferences(IStructuredSelection selection) {\r
+        IPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+\r
+        String recentPathsPref = store.getString(Preferences.RECENT_MODEL_IMPORT_LOCATIONS);\r
+        Deque<String> recentImportPaths = Preferences.decodePaths(recentPathsPref);\r
+\r
+        ISessionContext ctx = Simantics.getSessionContext();\r
+        if (ctx == null)\r
+            return;\r
+//        IProject project = ctx.getHint(ProjectKeys.KEY_PROJECT);\r
+//        if (project == null)\r
+//            return;\r
+//        \r
+        importModel = new SysdynImportModel(recentImportPaths);\r
+        //importModel.project = project;\r
+        importModel.setSelection(selection.getFirstElement());\r
+    }\r
+\r
+    private void writePreferences() throws IOException {\r
+        IPersistentPreferenceStore store = new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID);\r
+        store.putValue(Preferences.RECENT_MODEL_IMPORT_LOCATIONS, Preferences.encodePaths(importModel.getRecentLocations()));\r
+        if (store.needsSaving())\r
+            store.save();\r
+    }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ExportWizardModel.java
new file mode 100644 (file)
index 0000000..5288762
--- /dev/null
@@ -0,0 +1,53 @@
+package org.simantics.sysdyn.ui.wizards.models;\r
+\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+@Deprecated\r
+public class ExportWizardModel extends Wizard implements IImportWizard {\r
+       \r
+       private WizardModelsExportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       public Resource selection;\r
+\r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardModel() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardModel(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
\r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Export");\r
+        this.currentSelection = currentSelection;\r
+        selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class);\r
+    }\r
+    \r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardModelsExportPage(\r
+                               "wizardModelsExportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/ImportWizardModel.java
new file mode 100644 (file)
index 0000000..c1a8726
--- /dev/null
@@ -0,0 +1,48 @@
+package org.simantics.sysdyn.ui.wizards.models;\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+\r
+@Deprecated\r
+public class ImportWizardModel extends Wizard implements IImportWizard {\r
+       \r
+       private WizardModelsImportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardModel() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardModel(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;      \r
+    }\r
+\r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardModelsImportPage(\r
+                               "wizardModelsImportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+    \r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Import");\r
+        this.currentSelection = currentSelection;\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsExportPage.java
new file mode 100644 (file)
index 0000000..ae1f0e8
--- /dev/null
@@ -0,0 +1,320 @@
+package org.simantics.sysdyn.ui.wizards.models;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Files;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.TransferableGraphRequest2;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class WizardModelsExportPage extends WizardPage {\r
+       \r
+       // dialog store id constants\r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+       \r
+       //private IStructuredSelection currentSelection;\r
+       \r
+       private Resource selectedModel;\r
+       \r
+       GraphExplorerComposite modelExplorer;\r
+       \r
+       private boolean selectionMade = false;\r
+       \r
+       \r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardModelsExportPage() {\r
+               this("wizardModelsExportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardModelsExportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardModelsExportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               //this.currentSelection = currentSelection;\r
+               setPageComplete(false);\r
+               setTitle("Export Model");\r
+               setDescription("Choose the Model and the export location, then press Finish.");\r
+       }\r
+       \r
+       public void createControl(Composite parent) {\r
+               \r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+               \r
+               createProjectsRoot(workArea);\r
+               createTree (workArea);\r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+               \r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select the export location for Model:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+               \r
+               // model location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+\r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               \r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();        \r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+\r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+               \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+               \r
+       }\r
+       \r
+       private void createTree(Composite workArea){\r
+               \r
+               //set label for tree\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Model to export:");\r
+\r
+               try {\r
+                       Resource input = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource model = SimanticsUI.getProject().get();\r
+                                       return model;\r
+                               }\r
+\r
+                       });\r
+\r
+                       modelExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                                       "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE);\r
+\r
+                       modelExplorer\r
+                       .setBrowseContexts(SysdynResource.URIs.ImportModuleTree);\r
+\r
+                       modelExplorer.finish();\r
+\r
+                       modelExplorer.setInput(null, input);\r
+\r
+                       GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                                       modelExplorer);\r
+                       \r
+                       ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() {\r
+                               \r
+                               @Override\r
+                               public void widgetSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                               @Override\r
+                               public void widgetDefaultSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                       });\r
+                       \r
+\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+       \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               final Shell shell = filePathField.getShell();\r
+               \r
+               FileDialog dialog = new FileDialog(shell, SWT.SAVE);\r
+               \r
+               String[] ext = {"*.sysdyn"};\r
+               dialog.setFilterExtensions(ext);\r
+               \r
+               dialog.setText("Export Model");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+               \r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }               \r
+\r
+       }\r
+       //Get selection from the tree\r
+       @SuppressWarnings("unchecked")\r
+       public static <T> T getExplorerResource(GraphExplorerComposite explorer,\r
+                       Class<T> clazz) {\r
+               \r
+               if(explorer == null)\r
+                       return null;\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return null;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement();\r
+               if (inc == null)\r
+                       return null;\r
+               final T resource = (T) inc.getAdapter(clazz);\r
+\r
+               return resource;\r
+       }\r
+       \r
+       public boolean createProjects() {\r
+               \r
+               final String selected = previouslyBrowsedFile;\r
+               if(selected == null) return false;\r
+               \r
+               selectedModel= getExplorerResource(modelExplorer, Resource.class);\r
+               if(selectedModel == null)\r
+                       return false;\r
+        \r
+        // FIXME: Model browser doesn't change its selection even if the selected object is removed,\r
+        // so you can try to export a removed model \r
+               \r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               String name = graph.syncRequest(new PossibleRelatedValue<String>(selectedModel, l0.HasName, Bindings.STRING ));\r
+                               ArrayList<Pair<Resource, String>> roots = new ArrayList<Pair<Resource, String>>();\r
+                               roots.add(Pair.make(selectedModel, name));\r
+                               TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, selectedModel));\r
+\r
+                               try {\r
+                                       Files.createFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class), tg);\r
+                               } catch (RuntimeBindingConstructionException e) {\r
+                                       e.printStackTrace();\r
+                               } catch (IOException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                               \r
+                       }\r
+               });\r
+\r
+               return true;\r
+       }\r
+       \r
+       void validatePage() {\r
+               \r
+               if (previouslyBrowsedFile.isEmpty() || selectionMade == false){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               \r
+               setPageComplete(true);\r
+               \r
+       }\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/models/WizardModelsImportPage.java
new file mode 100644 (file)
index 0000000..a4c69b9
--- /dev/null
@@ -0,0 +1,456 @@
+package org.simantics.sysdyn.ui.wizards.models;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.sysdyn.ui.Activator;\r
+import org.simantics.sysdyn.ui.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class WizardModelsImportPage extends WizardPage{\r
+       \r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+\r
+       private Shell shell;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardModelsImportPage() {\r
+               this("wizardModelsImportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardModelsImportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardModelsImportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               //this.initialPath = initialPath;\r
+               //this.currentSelection = currentSelection;\r
+               setPageComplete(false);\r
+               setTitle("Import Model");\r
+               setDescription("Choose the Model file, then press Finish.");\r
+       }\r
+\r
+       \r
+       public void createControl(Composite parent) {\r
+\r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);\r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+\r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Model source:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+\r
+               // model location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+               \r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();\r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+                       \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               setErrorMessage(null);\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });     \r
+       }\r
+\r
+       \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               \r
+               shell = filePathField.getShell();\r
+               \r
+               FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
+               \r
+               String[] ext = {"*.sysdyn; *.tg", "*.*"};\r
+               dialog.setFilterExtensions(ext);\r
+               \r
+               dialog.setText("Import Model");\r
+\r
+               String path = Activator.getDefault().getPreferenceStore().getString(ImportUtilsUI.IMPORTMODELTPATH);\r
+               if(path.isEmpty() || !(new File(path).exists()))\r
+                       path = Platform.getLocation().toOSString();\r
+               dialog.setFilterPath(path);\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+       }\r
+\r
+       //Create project after finish is pressed.\r
+       public boolean createProjects() {\r
+               \r
+               Resource project = SimanticsUI.getProject().get();\r
+               if(project == null){\r
+                       setErrorMessage("Error when retrieving resource");\r
+                       return false;\r
+               }\r
+               \r
+               final String selected = previouslyBrowsedFile;\r
+               if(selected == null){\r
+                       setErrorMessage("No file selected");\r
+                       return false;\r
+               }\r
+\r
+               try {\r
+                       IStatus status = ImportUtilsUI.importModelFile(selected, null);\r
+                       if(status == null || !status.equals(Status.OK_STATUS)) {\r
+                           setErrorMessage(status.getMessage());\r
+                           return false;\r
+                       }\r
+                       return true;\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               }\r
+               \r
+        /*\r
+               TransferableGraph1 tg = null;\r
+               try {\r
+                       tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class));\r
+               } catch (RuntimeBindingConstructionException e) {\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {       \r
+                       try {\r
+                               OldTransferableGraph1 otg = (OldTransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(OldTransferableGraph1.class));\r
+                               tg = new TransferableGraph1(otg.resourceCount, otg.identities, otg.statements, otg.values);\r
+                       } catch (RuntimeBindingConstructionException e1) {\r
+                               e1.printStackTrace();\r
+                       } catch (IOException e1) {\r
+                               setErrorMessage("The imported file is not of type: System Dynamics Model");\r
+                               return false;\r
+                       }\r
+               }\r
+               if(tg == null){ \r
+                       setErrorMessage("The imported file is not of type: System Dynamics Model");\r
+                       return false;\r
+               }\r
+               \r
+               try {\r
+                       \r
+                       DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(project);\r
+                       DefaultPasteHandler.defaultExecute(tg, SimanticsUI.getProject().get(), ia);\r
+                       \r
+                       // Check that imported resource was actually a model \r
+                       //and fix changes made to old ontology versions\r
+                       final Resource root = ia.getRoot();\r
+                       SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       \r
+                                       if(!graph.isInstanceOf(root, SysdynResource.getInstance(graph).SysdynModel)) {\r
+                                               Resource instanceOf = graph.getPossibleObject(root, Layer0.getInstance(graph).InstanceOf);\r
+                                               String type = "...";\r
+                                               if(instanceOf != null)\r
+                                                       type = NameUtils.getSafeName(graph, instanceOf);\r
+                                               else {\r
+                                                       Resource inheritedFrom = graph.getPossibleObject(root, Layer0.getInstance(graph).Inherits);\r
+                                                       if(inheritedFrom != null)\r
+                                                               type = NameUtils.getSafeName(graph, inheritedFrom);\r
+                                               }\r
+                                               graph.deny(root, Layer0.getInstance(graph).PartOf);\r
+                                               error = type;\r
+                                       } else {\r
+                                               updateOldConfigurationToBaseRealization(graph, root);\r
+                                               addDefaultOntologyLinks(graph, root);\r
+                                               addURIsToDiagrams(graph, root);\r
+                                               addSpreadSheetBook(graph, root);\r
+                                       }\r
+                               }\r
+                       });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+    \r
+               if (!error.isEmpty()){\r
+                       setErrorMessage("The imported file is not of type: System Dynamics Model (" + error +")");\r
+                       error = "";\r
+                       return false;\r
+               }\r
+               */\r
+//             if(status == null || !status.equals(Status.OK_STATUS)) {\r
+//                 setErrorMessage(status.getMessage());\r
+//                 return false;\r
+//             }\r
+//             return true;            \r
+       }\r
+       \r
+       /**\r
+        * In old versions base realization was separate. Newer versions use configuration as base realization. \r
+        * @param graph WriteGraph\r
+        * @param model Imported model\r
+        */\r
+       /*\r
+       private static void updateOldConfigurationToBaseRealization(WriteGraph graph, Resource model) {\r
+               Layer0X L0X = Layer0X.getInstance(graph);\r
+               try {\r
+                       Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
+                       if(configuration != null && !graph.hasStatement(configuration, L0X.IsBaseRealizationOf, model))\r
+                               graph.claim(configuration, L0X.IsBaseRealizationOf, model);\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+       }\r
+       */\r
+       \r
+       /**\r
+        * Links should be exported and imported automatically. If it has failed, the \r
+        * default ontology links sysdyn and layer0 are added.\r
+        * \r
+        * @param graph WriteGraph\r
+        * @param model Imported model\r
+        */\r
+        /*\r
+       private static void addDefaultOntologyLinks(WriteGraph graph, Resource model) {\r
+               try {\r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                       // The links should be exported and imported automatically\r
+                       Resource sysdyn = graph.getResource("http://www.simantics.org/Sysdyn-1.1");\r
+                       Resource layer0 = graph.getResource("http://www.simantics.org/Layer0-1.1");\r
+                       if(!graph.hasStatement(model, l0.IsLinkedTo, sysdyn))\r
+                               graph.claim(model, l0.IsLinkedTo, sysdyn);\r
+                       if(!graph.hasStatement(model, l0.IsLinkedTo, layer0))\r
+                               graph.claim(model, l0.IsLinkedTo, layer0);\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+               \r
+       private static void addURIsToDiagrams(WriteGraph graph, Resource model) {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SimulationResource simu = SimulationResource.getInstance(graph);\r
+               ModelingResources mr = ModelingResources.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+               try {\r
+                       HashSet<Resource> configurations = new HashSet<Resource>();\r
+               \r
+                       Resource configuration = graph.getPossibleObject(model, simu.HasConfiguration);\r
+                       if(configuration != null) \r
+                               configurations.add(configuration);\r
+                       \r
+                       for(Resource r : graph.getObjects(model, l0.ConsistsOf)) {\r
+                               if(graph.isInheritedFrom(r, sr.Module)) {\r
+                                       Resource moduleConfiguration = graph.getPossibleObject(r, sr2.IsDefinedBy);\r
+                                       if(moduleConfiguration != null)\r
+                                               configurations.add(moduleConfiguration);\r
+                               }\r
+                       }\r
+                       \r
+                       for(Resource conf : configurations) {\r
+                               Resource configurationDiagram = graph.getPossibleObject(conf, mr.CompositeToDiagram);\r
+                               if(configurationDiagram != null && !graph.hasStatement(configurationDiagram, l0.PartOf)) {\r
+                                       GraphUtils.create2(graph, l0.Library, \r
+                                                       l0.HasName, "__CONTAINER__",\r
+                                                       l0.PartOf, conf,\r
+                                                       l0.ConsistsOf, configurationDiagram);\r
+                               }\r
+                       }\r
+                       \r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+*/     \r
+       \r
+       /**\r
+        * Add a missing spreadsheet book to the model\r
+        * \r
+        * @param graph\r
+        * @param model\r
+        */\r
+       /*\r
+       private static void addSpreadSheetBook(WriteGraph graph, Resource model) {\r
+           try {\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SpreadsheetResource ssr = SpreadsheetResource.getInstance(graph);\r
+               SimulationResource simu = SimulationResource.getInstance(graph);\r
+               Resource conf = graph.getPossibleObject(model, simu.HasConfiguration);\r
+               if(conf != null && graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, ssr.Book)).isEmpty()) {\r
+                   Resource book = graph.newResource();\r
+                   graph.claim(book, l0.InstanceOf, null, ssr.Book);\r
+                   graph.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING);\r
+                   graph.claim(conf, l0.ConsistsOf, l0.PartOf, book);\r
+\r
+                   createSheet(graph, book, "Sheet1", new String[] { }, new int[] { 50 });\r
+               }\r
+           } catch (DatabaseException e) {\r
+               e.printStackTrace();\r
+           }\r
+       }\r
+       */\r
+       /**\r
+        * Create a sheet (Copied from SysdynProject)\r
+        * \r
+        * @param graph\r
+        * @param book\r
+        * @param name\r
+        * @param colNames\r
+        * @param colWidths\r
+        * @return\r
+        * @throws DatabaseException\r
+        */\r
+       /*\r
+    private static Resource createSheet(WriteGraph graph, Resource book, String name, String[] colNames, int[] colWidths) throws DatabaseException {\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Layer0X L0X = Layer0X.getInstance(graph);\r
+        SpreadsheetResource sr = SpreadsheetResource.getInstance(graph);\r
+\r
+        Resource result = graph.newResource();\r
+        graph.claim(result, L0.InstanceOf, null, sr.Spreadsheet);\r
+\r
+        if(name == null) {\r
+            name = NameUtils.findFreshEscapedName(graph, "Sheet", book, sr.HasSheet);\r
+        }\r
+        graph.claimLiteral(result, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
+        graph.claim(book, L0.ConsistsOf, L0.PartOf, result);\r
+\r
+        {\r
+            Resource newCell = graph.newResource();\r
+            graph.claim(newCell, L0.InstanceOf, null, sr.Dimensions);\r
+            graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Dimensions", Bindings.STRING);\r
+            graph.addLiteral(newCell, sr.Dimensions_fitColumns, sr.Dimensions_fitColumns_Inverse, L0.Boolean, false, Bindings.BOOLEAN);\r
+            graph.addLiteral(newCell, sr.Dimensions_fitRows, sr.Dimensions_fitRows_Inverse, L0.Boolean, false, Bindings.BOOLEAN);\r
+            graph.addLiteral(newCell, sr.Dimensions_columnCount, sr.Dimensions_columnCount_Inverse, L0.Integer, 128, Bindings.INTEGER);\r
+            graph.addLiteral(newCell, sr.Dimensions_rowCount, sr.Dimensions_rowCount_Inverse, L0.Integer, 256, Bindings.INTEGER);\r
+            graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
+        }\r
+\r
+        {\r
+            Resource newCell = graph.newResource();\r
+            graph.claim(newCell, L0.InstanceOf, null, sr.Dimensions);\r
+            graph.claimLiteral(newCell, L0.HasName, L0.NameOf, L0.String, "Headers", Bindings.STRING);\r
+            graph.addLiteral(newCell, sr.Headers_columnLabels, sr.Headers_columnLabels_Inverse, L0.StringArray, colNames, Bindings.STRING_ARRAY);\r
+            graph.addLiteral(newCell, sr.Headers_columnWidths, sr.Headers_columnWidths_Inverse, L0.IntegerArray, colWidths, Bindings.INT_ARRAY);\r
+            graph.claim(result, L0.ConsistsOf, L0.PartOf, newCell);\r
+        }\r
+\r
+        {\r
+            \r
+            double[] doubles = new double[10*2];\r
+            for(int i=0;i<10*2;i++) doubles[i] = i;\r
+            \r
+            Resource newCell = graph.newResource();\r
+            graph.claim(newCell, L0.InstanceOf, null, sr.DoubleArrayCell);\r
+            graph.addLiteral(newCell, sr.DoubleArrayCell_HasWidth, sr.DoubleArrayCell_HasWidth_Inverse, L0.Integer, 10, Bindings.INTEGER);\r
+            graph.addLiteral(newCell, sr.HasLocation, sr.HasLocation_Inverse, L0.String, "B2", Bindings.STRING);\r
+            graph.addLiteral(newCell, sr.DoubleArrayCell_HasDoubleArray, sr.DoubleArrayCell_HasDoubleArray_Inverse, L0.DoubleArray, doubles, Bindings.DOUBLE_ARRAY);\r
+            graph.claim(result, L0X.HasChildVariables, L0X.HasChildVariables_Inverse, newCell);\r
+            \r
+        }\r
+        \r
+        return result;\r
+\r
+    }\r
+    */\r
+    void validatePage(){\r
+       \r
+               if (previouslyBrowsedFile.isEmpty()){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               setErrorMessage(null);\r
+               setPageComplete(true);\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ExportWizardModule.java
new file mode 100644 (file)
index 0000000..a808443
--- /dev/null
@@ -0,0 +1,54 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+\r
+public class ExportWizardModule extends Wizard implements IImportWizard {\r
+       \r
+       private WizardModulesExportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       public Resource selection;\r
+\r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardModule() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ExportWizardModule(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
\r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Export");\r
+        this.currentSelection = currentSelection;\r
+        selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class);\r
+    }\r
+    \r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardModulesExportPage(\r
+                               "wizardModulesExportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+               \r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ImportWizardModule.java
new file mode 100644 (file)
index 0000000..a389366
--- /dev/null
@@ -0,0 +1,54 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.ui.IImportWizard;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.simantics.db.Resource;\r
+import org.simantics.utils.ui.AdaptionUtils;\r
+\r
+\r
+public class ImportWizardModule extends Wizard implements IImportWizard {\r
+       \r
+       private WizardModulesImportPage mainPage;\r
+       private IStructuredSelection currentSelection = null;\r
+       private String initialPath = null;\r
+       public Resource selection;\r
+\r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardModule() {\r
+       this(null);\r
+    }\r
+    \r
+    /**\r
+     * Constructor for ExternalProjectImportWizard.\r
+     */\r
+    public ImportWizardModule(String initialPath)\r
+    {\r
+        super();\r
+        this.initialPath = initialPath;\r
+    }\r
\r
+    public void init(IWorkbench workbench, IStructuredSelection currentSelection) {\r
+        setWindowTitle("Import");\r
+        this.currentSelection = currentSelection;\r
+        selection = (Resource)AdaptionUtils.adaptToSingle(currentSelection, org.simantics.db.Resource.class);\r
+    }\r
+    \r
+    public void addPages() {\r
+        super.addPages();\r
+               mainPage = new WizardModulesImportPage(\r
+                               "wizardModulesImportPage", initialPath, currentSelection); //$NON-NLS-1$\r
+        addPage(mainPage);\r
+    }\r
+\r
+       @Override\r
+       public boolean performFinish() {\r
+               return mainPage.createProjects();\r
+               \r
+       }\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleComponentTypeNode.java
new file mode 100644 (file)
index 0000000..7b50181
--- /dev/null
@@ -0,0 +1,161 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.common.node.DeleteException;\r
+import org.simantics.browsing.ui.common.node.IDeletableNode;\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.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.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.db.layer0.adapter.PasteHandler;\r
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class ModuleComponentTypeNode extends AbstractNode<Resource> implements IDeletableNode, IModifiableNode {\r
+\r
+       \r
+       Listener<String> configurationNameSynchronizer;\r
+       private boolean disposed = false;\r
+       private Resource configuration;\r
+       \r
+    public ModuleComponentTypeNode(Resource resource) {\r
+        super(resource);\r
+\r
+        SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+                       configuration = graph.getPossibleObject(data, sr2.IsDefinedBy);                         \r
+                       }\r
+               });\r
+        \r
+        // Not the best solution for name sync\r
+        configurationNameSynchronizer = new Listener<String>() {\r
+\r
+               @Override\r
+                       public void execute(final String result) {\r
+                               SimanticsUI.getSession().asyncRequest(new WriteRequest() {\r
+                                       \r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               if(configuration != null)\r
+                                                       graph.claimLiteral(configuration, Layer0.getInstance(graph).HasLabel, result);\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 disposed;\r
+                       }\r
+               };\r
+               \r
+        SimanticsUI.getSession().asyncRequest(new Read<String>() {\r
+\r
+                       @Override\r
+                       public String perform(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               return graph.getRelatedValue(data, l0.HasName);\r
+                       }\r
+               \r
+        }, configurationNameSynchronizer);\r
+        \r
+    }\r
+\r
+    @Override\r
+    public Modifier getModifier(String columnId) {\r
+        Modifier modifier = null;\r
+        try {\r
+            modifier = SimanticsUI.getSession().syncRequest(new Read<Modifier>() {\r
+\r
+                @Override\r
+                public Modifier perform(ReadGraph graph) throws ManyObjectsForFunctionalRelationException, ServiceException {\r
+                    ModelingResources mr = ModelingResources.getInstance(graph);\r
+                    Layer0 l0 = Layer0.getInstance(graph);\r
+                    Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+\r
+                    LabelModifier modifier = new LabelModifier(SimanticsUI.getSession(), type, l0.HasName) {\r
+                        @Override\r
+                        public String isValid(String label) {\r
+                            if (label.isEmpty())\r
+                                return "Empty name not allowed";\r
+                            return null;\r
+                        }\r
+                    };\r
+\r
+\r
+                    return modifier;\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        return modifier;\r
+    }\r
+\r
+    @Override\r
+    public void delete() throws DeleteException {\r
+       disposed = true;\r
+        try {\r
+            SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException {\r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                    StructuralResource2 st = StructuralResource2.getInstance(graph);\r
+                    ModelingResources mr = ModelingResources.getInstance(graph);\r
+\r
+                    Resource type =  graph.getPossibleObject(data, mr.SymbolToComponentType);\r
+                    Resource model = graph.getSingleObject(type, l0.PartOf);\r
+                    Resource modelConfiguration = graph.getSingleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
+                    if (!graph.syncRequest(new ObjectsWithType(modelConfiguration, l0.ConsistsOf, type)).isEmpty()) {\r
+                        System.out.println("The module is used at the model configuration");\r
+                        return;\r
+                    }\r
+                    Collection<Resource> moduleTypes = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, st.ComponentType));\r
+                    for(Resource r : moduleTypes) {\r
+                        Resource configuration = graph.getSingleObject(r, st.IsDefinedBy);\r
+                        if(!graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, type)).isEmpty()) {\r
+                            System.out.println("The module is used at another module: " + graph.getRelatedValue(r, l0.HasName));\r
+                            return;\r
+                        }\r
+                    }\r
+                    graph.deny(model, l0.ConsistsOf, type);\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+    \r
+    @SuppressWarnings("rawtypes")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if(PasteHandler.class == adapter && configuration != null) \r
+            return new DefaultPasteHandler(configuration);\r
+        return super.getAdapter(adapter);\r
+    }\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModels.java
new file mode 100644 (file)
index 0000000..272a2af
--- /dev/null
@@ -0,0 +1,40 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.simantics.browsing.ui.common.node.AbstractNode;\r
+import org.simantics.browsing.ui.graph.impl.contributor.viewpoint.ViewpointContributorImpl;\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.layer0.Layer0;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class ModuleTreeModels extends ViewpointContributorImpl<Resource> {\r
+\r
+       @Override\r
+       public Collection<?> getContribution(ReadGraph graph, Resource input)\r
+                       throws DatabaseException {\r
+               \r
+\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               ArrayList<AbstractNode<Resource>> result = new ArrayList<AbstractNode<Resource>>();\r
+               for(Resource r : graph.syncRequest(new ObjectsWithType(input, l0.ConsistsOf, sr.SysdynModel))) {\r
+                       result.add(new ModelNode(r));\r
+               }\r
+               \r
+               return result;\r
+       }\r
+\r
+       @Override\r
+       public String getViewpointId() {\r
+               return "Module Import";\r
+       }\r
+       \r
+\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModules.java
new file mode 100644 (file)
index 0000000..76f76f8
--- /dev/null
@@ -0,0 +1,35 @@
+package org.simantics.sysdyn.ui.wizards.modules;\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.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.ui.browser.nodes.ModelNode;\r
+\r
+public class ModuleTreeModules extends ViewpointContributor<ModelNode> {\r
+\r
+    @Override\r
+    public Collection<?> getContribution(ReadGraph graph, ModelNode model)\r
+    throws DatabaseException {\r
+       ArrayList<ModuleComponentTypeNode> result = new ArrayList<ModuleComponentTypeNode>();\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+               for (Resource r : graph.syncRequest(new ObjectsWithType(model.data, l0.ConsistsOf, sr2.ComponentType))){\r
+                       result.add(new ModuleComponentTypeNode(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/wizards/modules/ModuleTreeModulesLabeler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/ModuleTreeModulesLabeler.java
new file mode 100644 (file)
index 0000000..0aa030a
--- /dev/null
@@ -0,0 +1,16 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+import org.simantics.browsing.ui.graph.impl.contributor.labeler.LabelerContributorImpl;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+\r
+public class ModuleTreeModulesLabeler extends LabelerContributorImpl<ModuleComponentTypeNode>{\r
+\r
+       @Override\r
+       public String getLabel(ReadGraph graph, ModuleComponentTypeNode input)\r
+                       throws DatabaseException {\r
+               return NameUtils.getSafeName(graph, input.data);\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesExportPage.java
new file mode 100644 (file)
index 0000000..3625dd9
--- /dev/null
@@ -0,0 +1,475 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Files;\r
+import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.TransferableGraphRequest2;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class WizardModulesExportPage extends WizardPage {\r
+       \r
+       // dialog store id constants\r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+       \r
+       private Resource selectedModule;\r
+       \r
+       GraphExplorerComposite modelExplorer;\r
+\r
+       private boolean selectionMade = false;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardModulesExportPage() {\r
+               this("wizardModulesExportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardModulesExportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardModulesExportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               //this.currentSelection = currentSelection;\r
+               setPageComplete(false);\r
+               setTitle("Export Module");\r
+               setDescription("Choose the Module and the export location, then press Finish.");\r
+       }\r
+       \r
+       public void createControl(Composite parent) {\r
+               \r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);\r
+               createTree(workArea);\r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+               \r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select the export location for Module:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+\r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+               \r
+               // module location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+\r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               \r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();        \r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+               \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+               \r
+       }\r
+\r
+       private void createTree(Composite workArea){\r
+               \r
+               //set label for tree\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Module to export:");\r
+\r
+               try {\r
+                       Resource input = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource model = SimanticsUI.getProject().get();\r
+                                       return model;\r
+                               }\r
+\r
+                       });\r
+\r
+                       modelExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                                       "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE);\r
+\r
+                       modelExplorer\r
+                       .setBrowseContexts(SysdynResource.URIs.ExportModuleTree);\r
+\r
+                       modelExplorer.finish();\r
+                       \r
+                       modelExplorer.setInput(null, input);\r
+\r
+                       GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                                       modelExplorer);\r
+                       \r
+                       ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() {\r
+                               \r
+                               @Override\r
+                               public void widgetSelected(SelectionEvent e) {\r
+                                       setMessage(null);\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                               @Override\r
+                               public void widgetDefaultSelected(SelectionEvent e) {\r
+                                       setMessage(null);\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                       });\r
+\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+    \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               \r
+               final Shell shell = filePathField.getShell();\r
+               \r
+               FileDialog dialog = new FileDialog(shell, SWT.SAVE);\r
+               \r
+               String[] ext = {"*.sysdynModule"};\r
+               dialog.setFilterExtensions(ext);\r
+               \r
+               dialog.setText("Export Module");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+               \r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }               \r
+\r
+       }\r
+       \r
+       //Get selection from the tree\r
+       @SuppressWarnings("unchecked")\r
+       public static <T> T getExplorerResource(GraphExplorerComposite explorer,\r
+                       Class<T> clazz) {\r
+               \r
+               if(explorer == null)\r
+                       return null;\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return null;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement();\r
+               if (inc == null)\r
+                       return null;\r
+               final T resource = (T) inc.getAdapter(clazz);\r
+\r
+               return resource;\r
+       }\r
+       \r
+       //Create export file when finish is pressed\r
+       public boolean createProjects() {\r
+               \r
+               final String selected = previouslyBrowsedFile;\r
+               if(selected == null) return false;\r
+\r
+               selectedModule= getExplorerResource(modelExplorer, Resource.class);\r
+               if(selectedModule == null)\r
+                       return false;\r
+               \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
+                                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+                                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                                       Layer0 l0 = Layer0.getInstance(graph);\r
+                                       \r
+                                       Resource component = selectedModule;\r
+                                       if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
+                                               return null;\r
+                                       \r
+                                       Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                                       if (configuration == null)\r
+                                               return null;\r
+                                       \r
+                                       ArrayList<String> dependencies = null;\r
+                                       for(Resource r : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Module))) {\r
+                                               if(dependencies == null)\r
+                                                       dependencies = new ArrayList<String>();\r
+                                               String name = NameUtils.getSafeName(graph, r);\r
+                                               String instanceOf = NameUtils.getSafeName(graph, graph.getSingleObject(r, l0.InstanceOf));\r
+                                               dependencies.add(name + " : " + instanceOf);\r
+                                       }\r
+                                       if(dependencies != null && !dependencies.isEmpty())\r
+                                               throw new ContainsDependenciesException(dependencies);\r
+                                       \r
+                                       String name = graph.getPossibleRelatedValue(component, l0.HasName, Bindings.STRING);\r
+                                       return name;\r
+                                       \r
+                               }\r
+                               \r
+                       });\r
+               } \r
+               catch (DatabaseException e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               if(name == null) return false;\r
+               \r
+               SimanticsUI.getSession().asyncRequest(new ReadRequest() {\r
+                       \r
+                       @Override\r
+                       public void run(ReadGraph graph) throws DatabaseException {\r
+                               Layer0 l0 = Layer0.getInstance(graph);\r
+                               \r
+                               final Resource component = selectedModule;\r
+                               //final Resource component = graph.getPossibleObject(modulesymbol, mr.SymbolToComponentType);\r
+                               if (component == null || !graph.hasStatement(component, Layer0.getInstance(graph).PartOf))\r
+                                       return;\r
+                               String name = graph.syncRequest(new PossibleRelatedValue<String>(component, l0.HasName, Bindings.STRING ));\r
+                               final ArrayList<Pair<Resource, String>> roots = new ArrayList<Pair<Resource, String>>();\r
+                               roots.add(Pair.make(component, name));\r
+\r
+                               graph.asyncRequest(new WriteRequest() {\r
+\r
+                                       @Override\r
+                                       public void perform(WriteGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+                                               ModelingResources mr = ModelingResources.getInstance(graph);\r
+                                               final Resource modulesymbol = graph.getPossibleObject(component, mr.ComponentTypeToSymbol);\r
+                                               Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                                               if (!graph.hasStatement(configuration, l0.PartOf, component)&& \r
+                                                               !graph.hasStatement(modulesymbol, l0.PartOf, component)) {\r
+                                                       // Make sure that configuration and symbol are included.\r
+                                                       // In old versions, they were attached to model, not to module.\r
+                                                       Resource previousPartof = graph.getSingleObject(configuration, l0.PartOf);\r
+\r
+                                                       graph.deny(configuration, l0.PartOf);\r
+                                                       graph.deny(modulesymbol, l0.PartOf);\r
+                                                       graph.claim(configuration, l0.PartOf, l0.ConsistsOf, component);\r
+                                                       graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, component);\r
+\r
+                                                       export(graph, selected, roots, component);\r
+\r
+                                                       graph.deny(configuration, l0.PartOf);\r
+                                                       graph.deny(modulesymbol, l0.PartOf);\r
+                                                       graph.claim(configuration, l0.PartOf, l0.ConsistsOf, previousPartof);\r
+                                                       graph.claim(modulesymbol, l0.PartOf, l0.ConsistsOf, previousPartof);\r
+                                               } else {\r
+                                                       // Normal export\r
+                                                       export(graph, selected, roots, component);\r
+                                               }\r
+                                       }\r
+                               });\r
+\r
+                       }\r
+               });\r
+\r
+               return true;\r
+       }\r
+       \r
+       private void export(WriteGraph graph, String path, ArrayList<Pair<Resource, String>> roots, Resource component) {\r
+               \r
+               // FIXME: Enumeration replacement handling like this is not suitable.\r
+               try {\r
+                       Layer0 l0 = Layer0.getInstance(graph);\r
+                       SysdynResource sr = SysdynResource.getInstance(graph);\r
+                       StructuralResource2 sr2 = StructuralResource2.getInstance(graph);\r
+\r
+                       Resource configuration = graph.getPossibleObject(component, sr2.IsDefinedBy);\r
+                       ArrayList<Pair<Resource, Resource>> replacements = new ArrayList<Pair<Resource, Resource>>();\r
+\r
+                       for(Resource enumeration : graph.syncRequest(new ObjectsWithType(configuration, l0.ConsistsOf, sr.Enumeration))) {\r
+                               if(graph.hasStatement(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
+                                       for(Resource replacement : graph.getObjects(enumeration, sr.Redeclaration_replacedEnumeration_Inverse)) {\r
+                                               replacements.add(new Pair<Resource, Resource>(enumeration, replacement));\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
+                       for(Pair<Resource,Resource> replacement : replacements)\r
+                               graph.deny(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
+                       \r
+                       TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, component));\r
+                       Files.createFile(new File(path), Bindings.getBindingUnchecked(TransferableGraph1.class), tg);\r
+                       \r
+                       for(Pair<Resource,Resource> replacement : replacements)\r
+                               graph.claim(replacement.first, sr.Redeclaration_replacedEnumeration_Inverse, replacement.second);\r
+\r
+               } catch (RuntimeBindingConstructionException e) {\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+       \r
+       class ContainsDependenciesException extends DatabaseException {\r
+               private static final long serialVersionUID = -1533706136673146020L;\r
+               \r
+               private Collection<String> dependencies;\r
+               \r
+               ContainsDependenciesException(Collection<String> dependencies) {\r
+                       this.dependencies = dependencies;\r
+               }\r
+               \r
+               public Collection<String> getDependencies() {\r
+                       return this.dependencies;\r
+               }\r
+               \r
+       }\r
+       \r
+       void validatePage() {\r
+               \r
+               if (previouslyBrowsedFile.isEmpty() || selectionMade == false){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               \r
+               if (modelExplorer != null){\r
+                       final Resource selectedResource = getExplorerResource(modelExplorer, Resource.class);\r
+\r
+                       String root = null;\r
+                       try {\r
+                               root = SimanticsUI.getSession().syncRequest(new Read<String>() {\r
+\r
+                                       @Override\r
+                                       public String perform(ReadGraph graph) throws DatabaseException {\r
+                                               Layer0 l0 = Layer0.getInstance(graph);\r
+                                               Resource model = graph.getPossibleObject(selectedResource, l0.PartOf);\r
+                                               String rootName = NameUtils.getSafeName(graph, model);\r
+\r
+                                               return rootName;\r
+                                       }\r
+\r
+                               });\r
+                               if (root != null && root.equalsIgnoreCase("Development Project")){\r
+                                       setPageComplete(false);\r
+                                       setMessage("Select Module under the Model.");\r
+                                       return;\r
+                               }\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+               }\r
+               \r
+               setPageComplete(true);\r
+               \r
+       }\r
+        \r
+\r
+\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/wizards/modules/WizardModulesImportPage.java
new file mode 100644 (file)
index 0000000..415d02c
--- /dev/null
@@ -0,0 +1,365 @@
+package org.simantics.sysdyn.ui.wizards.modules;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.PixelConverter;\r
+import org.eclipse.jface.viewers.ISelection;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.jface.viewers.IStructuredSelection;\r
+import org.eclipse.jface.wizard.WizardPage;\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.events.SelectionListener;\r
+import org.eclipse.swt.layout.GridData;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Button;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.FileDialog;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite;\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.utils.imports.ImportUtilsUI;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.ArrayMap;\r
+\r
+\r
+public class WizardModulesImportPage extends WizardPage{\r
+       \r
+       public static String IMPORTMODULETPATH = "IMPORT_MODULE_PATH";\r
+       \r
+       // dialog store id constants\r
+       \r
+       private Text filePathField;\r
+       \r
+       // Keep track of the archive that we browsed to last time\r
+       // the wizard was invoked.\r
+       private static String previouslyBrowsedFile = "";\r
+\r
+       private Button browseDirectoriesButton;\r
+\r
+       private Shell shell;\r
+       \r
+       //private IStructuredSelection currentSelection;\r
+       \r
+       private Resource selectedModel;\r
+       \r
+       GraphExplorerComposite modelExplorer;\r
+       \r
+       private boolean selectionMade = false;\r
+       \r
+       /**\r
+        * Creates a new project creation wizard page.\r
+        * \r
+        */\r
+       public WizardModulesImportPage() {\r
+               this("wizardModulesImportPage", null, null); //$NON-NLS-1$\r
+       }\r
+\r
+       /**\r
+        * Create a new instance of the receiver.\r
+        * \r
+        * @param pageName\r
+        */\r
+       public WizardModulesImportPage(String pageName) {\r
+               this(pageName,null, null);\r
+       }\r
+                       \r
+       /**\r
+        * More (many more) parameters.\r
+        * \r
+        * @param pageName\r
+        * @param initialPath\r
+        * @param currentSelection\r
+        * @since 3.5\r
+        */\r
+       public WizardModulesImportPage(String pageName,String initialPath,\r
+                       IStructuredSelection currentSelection) {\r
+               super(pageName);\r
+               setPageComplete(false);\r
+               //this.currentSelection = currentSelection;\r
+               setTitle("Import Module");\r
+               setDescription("Choose the Module file and the import location, then press Finish.");\r
+       }\r
+       \r
+       public void createControl(Composite parent) {\r
+       \r
+               initializeDialogUnits(parent);\r
+\r
+               Composite workArea = new Composite(parent, SWT.NONE);\r
+               setControl(workArea);\r
+\r
+               workArea.setLayout(new GridLayout());\r
+               workArea.setLayoutData(new GridData(GridData.FILL_BOTH\r
+                               | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL));\r
+\r
+               createProjectsRoot(workArea);\r
+               \r
+               createTree(workArea);\r
+       }\r
+       \r
+       private void createProjectsRoot(Composite workArea) {\r
+               \r
+               // set label for field\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select Module source:");\r
+               \r
+               Composite projectGroup = new Composite(workArea, SWT.NONE);\r
+               GridLayout layout = new GridLayout();\r
+               layout.numColumns = 2;\r
+               layout.makeColumnsEqualWidth = false;\r
+               layout.marginWidth = 0;\r
+               \r
+               projectGroup.setLayout(layout);\r
+               projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));\r
+               \r
+               // module location entry field\r
+               this.filePathField = new Text(projectGroup, SWT.BORDER);\r
+\r
+               GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false);\r
+               directoryPathData.widthHint = new PixelConverter(filePathField).convertWidthInCharsToPixels(25);\r
+               filePathField.setLayoutData(directoryPathData);\r
+               \r
+               filePathField.addModifyListener(new ModifyListener(){\r
+            @Override\r
+            public void modifyText(ModifyEvent e) {\r
+               previouslyBrowsedFile = filePathField.getText();        \r
+            }\r
+               });\r
+               if (previouslyBrowsedFile != null){\r
+                       filePathField.setText(previouslyBrowsedFile);\r
+                       validatePage();\r
+               }\r
+               \r
+               // browse button\r
+               browseDirectoriesButton = new Button(projectGroup, SWT.PUSH);\r
+               browseDirectoriesButton.setText("Browse");\r
+               setButtonLayoutData(browseDirectoriesButton);\r
+               \r
+               browseDirectoriesButton.addSelectionListener(new SelectionAdapter() {\r
+                       /*\r
+                        * (non-Javadoc)\r
+                        * \r
+                        * @see org.eclipse.swt.events.SelectionAdapter#widgetS\r
+                        * elected(org.eclipse.swt.events.SelectionEvent)\r
+                        */\r
+                       public void widgetSelected(SelectionEvent e) {\r
+                               handleLocationDirectoryButtonPressed();\r
+                       }\r
+               });\r
+               \r
+       }\r
+\r
+       private void createTree(Composite workArea){\r
+               \r
+               //set label for tree\r
+               Label title = new Label(workArea, SWT.NONE);\r
+               title.setText("Select import location:");\r
+\r
+               try {\r
+                       Resource input = SimanticsUI.getSession().syncRequest(new Read<Resource>() {\r
+\r
+                               @Override\r
+                               public Resource perform(ReadGraph graph)\r
+                                               throws DatabaseException {\r
+                                       Resource model = SimanticsUI.getProject().get();\r
+                                       return model;\r
+                               }\r
+\r
+                       });\r
+\r
+                       modelExplorer = new GraphExplorerComposite(ArrayMap.keys(\r
+                                       "displaySelectors", "displayFilter").values(false, false), null, workArea, SWT.BORDER | SWT.SINGLE);\r
+\r
+                       modelExplorer\r
+                       .setBrowseContexts(SysdynResource.URIs.ImportModuleTree);\r
+\r
+                       modelExplorer.finish();\r
+\r
+                       modelExplorer.setInput(null, input);\r
+                       \r
+                       GridDataFactory.fillDefaults().grab(true, true).applyTo(\r
+                                       modelExplorer);\r
+                       \r
+                       ((Tree)modelExplorer.getExplorer().getControl()).addSelectionListener(new SelectionListener() {\r
+                               \r
+                               @Override\r
+                               public void widgetSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                               @Override\r
+                               public void widgetDefaultSelected(SelectionEvent e) {\r
+                                       selectionMade = true;\r
+                                       validatePage();\r
+                               }\r
+                       });\r
+                       \r
+\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+\r
+       }\r
+       \r
+       //Set filePathField active\r
+       public void setVisible(boolean visible) {\r
+               super.setVisible(visible);\r
+               this.filePathField.setFocus();\r
+       }\r
+       \r
+       //Open dialog for choosing the file\r
+       protected void handleLocationDirectoryButtonPressed() {\r
+               \r
+               shell = filePathField.getShell();\r
+               \r
+               FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
+               \r
+               String[] ext = {"*.sysdynModule; *.tg", "*.*"};\r
+               dialog.setFilterExtensions(ext);\r
+               \r
+               dialog.setText("Import Module");\r
+\r
+               String dirName = filePathField.getText().trim();\r
+               \r
+               File path = new File(dirName);\r
+               if (path.exists()) {\r
+                       dialog.setFilterPath(new Path(dirName).toOSString());   \r
+               }\r
+               \r
+               String selectedFile = dialog.open();\r
+               if (selectedFile != null) {\r
+                       filePathField.setText(selectedFile);\r
+                       validatePage();\r
+               }               \r
+       }\r
+       \r
+       //Get selection from the tree\r
+       @SuppressWarnings("unchecked")\r
+       public static <T> T getExplorerResource(GraphExplorerComposite explorer,\r
+                       Class<T> clazz) {\r
+               \r
+               if(explorer == null)\r
+                       return null;\r
+               ISelection selection = ((ISelectionProvider) explorer\r
+                               .getAdapter(ISelectionProvider.class)).getSelection();\r
+               if (selection == null)\r
+                       return null;\r
+               IStructuredSelection iss = (IStructuredSelection) selection;\r
+               AdaptableHintContext inc = (AdaptableHintContext) iss.getFirstElement();\r
+               if (inc == null)\r
+                       return null;\r
+               final T resource = (T) inc.getAdapter(clazz);\r
+\r
+               return resource;\r
+       }\r
+       \r
+       //Create project after finish is pressed.\r
+       public boolean createProjects() {\r
+               \r
+               String selected = previouslyBrowsedFile;\r
+               if(selected == null){ \r
+                       setErrorMessage("Error when retrieving resource");\r
+                       return false;\r
+               }\r
+               \r
+               selectedModel= getExplorerResource(modelExplorer, Resource.class);\r
+               if(selectedModel == null){\r
+                       setErrorMessage("No file selected");\r
+                       return false;\r
+               }\r
+               \r
+               IStatus status = ImportUtilsUI.importModuleFile(selectedModel, selected, null);\r
+               \r
+               /*\r
+               TransferableGraph1 tg = null;\r
+               try {\r
+                       tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class));\r
+               } catch (RuntimeBindingConstructionException e) {\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       setErrorMessage("The imported file is not of type: Module Type");\r
+                       return false;\r
+               }\r
+               if(tg == null){\r
+                       setErrorMessage("The imported file is not of type: Module Type");\r
+                       return false;\r
+               }\r
+\r
+               \r
+               DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(selectedModel);\r
+               try {\r
+                       DefaultPasteHandler.defaultExecute(tg, selectedModel, ia);\r
+               } catch (MissingDependencyException e) {\r
+                       e.printStackTrace();\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+               final Resource root = ia.getRoot();\r
+               \r
+               try {\r
+                       SimanticsUI.getSession().syncRequest(new WriteRequest() {\r
+                               \r
+                               @Override\r
+                               public void perform(WriteGraph graph) throws DatabaseException {\r
+                                       if(!graph.isInheritedFrom(root, SysdynResource.getInstance(graph).Module)) {\r
+                                               Resource instanceOf = graph.getPossibleObject(root, Layer0.getInstance(graph).InstanceOf);\r
+                                               String type = "...";\r
+                                               if(instanceOf != null)\r
+                                                       type = NameUtils.getSafeName(graph, instanceOf);\r
+                                               else {\r
+                                                       Resource inheritedFrom = graph.getPossibleObject(root, Layer0.getInstance(graph).Inherits);\r
+                                                       if(inheritedFrom != null)\r
+                                                               type = NameUtils.getSafeName(graph, inheritedFrom);\r
+                                               }\r
+                                               graph.deny(root, Layer0.getInstance(graph).PartOf);\r
+                                               error = type;\r
+                                       }\r
+                               }\r
+                               });\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               \r
+               if (!error.isEmpty()){\r
+                       setErrorMessage("The imported file is not of type: Module Type (" + error +")");\r
+                       error = "";\r
+                       return false;\r
+               }\r
+               */\r
+               if(status == null || !status.equals(Status.OK_STATUS)) {\r
+                   setErrorMessage(status.getMessage());\r
+                   return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+       \r
+       void validatePage() {\r
+               \r
+               if (previouslyBrowsedFile.isEmpty() || selectionMade == false){\r
+                       setPageComplete(false);\r
+                       return;\r
+               }\r
+               \r
+               setErrorMessage(null);\r
+               setPageComplete(true);\r
+               \r
+       }\r
+       \r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn.ui/sysdyn.product b/org.simantics.sysdyn.ui/sysdyn.product
new file mode 100644 (file)
index 0000000..cfa3680
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?pde version="3.5"?>\r
+\r
+<product name="Simantics System Dynamic Tool" uid="org.simantics.sysdyn.product.Sysdyn" id="org.simantics.sysdyn.ui.product" application="org.simantics.workbench.application" version="1.8.1" useFeatures="true" includeLaunchers="true">\r
+\r
+   <aboutInfo>\r
+      <image path="/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png"/>\r
+      <text>\r
+         %about.text\r
+      </text>\r
+   </aboutInfo>\r
+\r
+   <configIni use="default">\r
+   </configIni>\r
+\r
+   <launcherArgs>\r
+      <programArgs>-fixerrors
+--launcher.XXMaxPermSize 192m
+-data @noDefault</programArgs>\r
+      <vmArgs>-ea  -Xmx768M -XX:MaxPermSize=192m -Xshare:off -Dorg.simantics.undo.enabled=true</vmArgs>\r
+      <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac>\r
+      <vmArgsWin>-Dorg.osgi.framework.os.name=win32</vmArgsWin>\r
+   </launcherArgs>\r
+\r
+   <windowImages i16="/org.simantics.sysdyn.ui/icons/simantics_sysdyn16.png" i32="/org.simantics.sysdyn.ui/icons/simantics_sysdyn32.png" i48="/org.simantics.sysdyn.ui/icons/simantics_sysdyn48.png" i64="/org.simantics.sysdyn.ui/icons/simantics_sysdyn64.png" i128="/org.simantics.sysdyn.ui/icons/simantics_sysdyn128.png"/>\r
+\r
+   <splash\r
+      location="org.simantics.sysdyn.ui" />\r
+   <launcher name="Simantics-Sysdyn">\r
+      <solaris/>\r
+      <win useIco="false">\r
+         <bmp/>\r
+      </win>\r
+   </launcher>\r
+\r
+   <vm>\r
+      <windows include="true">org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7</windows>\r
+   </vm>\r
+\r
+   <license>\r
+        <url>http://www.eclipse.org/legal/epl-v10.html</url>\r
+        <text>\r
+   Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+&quot;Contribution&quot; means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+i) changes to the Program, and
+ii) additions to the Program;
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+&quot;Contributor&quot; means any person or entity that distributes the Program.
+
+&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
+
+&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+b) its license agreement:
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+b) a copy of this Agreement must be included with each copy of the Program.
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.\r
+         </text>\r
+   </license>\r
+\r
+   <plugins>\r
+   </plugins>\r
+\r
+   <features>\r
+      <feature id="org.simantics.sysdyn" version="1.8.0.qualifier"/>\r
+      <feature id="fi.semantum.simupedia" version="1.0.0.qualifier"/>\r
+   </features>\r
+\r
+\r
+</product>\r