]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
1fb36162a2c5dd822dbacfcca4d94fd03f6afa94
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2010, 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.properties;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collection;\r
16 import java.util.Collections;\r
17 import java.util.List;\r
18 \r
19 import org.eclipse.jface.viewers.ISelection;\r
20 import org.simantics.browsing.ui.NodeContext;\r
21 import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
22 import org.simantics.browsing.ui.model.nodetypes.SpecialNodeType;\r
23 import org.simantics.db.ReadGraph;\r
24 import org.simantics.db.Resource;\r
25 import org.simantics.db.common.request.ObjectsWithType;\r
26 import org.simantics.db.common.utils.ListUtils;\r
27 import org.simantics.db.common.utils.NameUtils;\r
28 import org.simantics.db.exception.DatabaseException;\r
29 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
30 import org.simantics.db.exception.ServiceException;\r
31 import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable;\r
32 import org.simantics.db.layer0.variable.Variable;\r
33 import org.simantics.diagram.stubs.DiagramResource;\r
34 import org.simantics.jfreechart.ChartSelectionTabContributor;\r
35 import org.simantics.jfreechart.chart.properties.xyline.XYLineGeneralPropertiesTab;\r
36 import org.simantics.layer0.Layer0;\r
37 import org.simantics.modeling.ModelingResources;\r
38 import org.simantics.modeling.ui.property.svg.SVGElementComposite;\r
39 import org.simantics.selectionview.ComparableTabContributor;\r
40 import org.simantics.selectionview.SelectionProcessor;\r
41 import org.simantics.simulation.ontology.SimulationResource;\r
42 import org.simantics.sysdyn.JFreeChartResource;\r
43 import org.simantics.sysdyn.SysdynResource;\r
44 import org.simantics.sysdyn.ui.browser.nodes.SharedFunctionsFolder;\r
45 import org.simantics.sysdyn.ui.trend.SensitivityChartAxisAndVariablesTab;\r
46 import org.simantics.ui.selection.AnyVariable;\r
47 import org.simantics.ui.selection.WorkbenchSelectionElement;\r
48 import org.simantics.utils.ui.AdaptionUtils;\r
49 import org.simantics.utils.ui.ISelectionUtils;\r
50 \r
51 /**\r
52  * SelectionProcessor for processing selections for property view in system dynamics\r
53  * \r
54  * @author Teemu Lempinen\r
55  * @author Tuomas Miettinen\r
56  *\r
57  */\r
58 public class ResourceSelectionProcessor implements SelectionProcessor<Object, ReadGraph>  {\r
59 \r
60     private SpecialNodeType sharedFunctionsTestNode;\r
61 \r
62     @Override\r
63     public Collection<?> process(Object selection, ReadGraph backend) {\r
64         List<ComparableTabContributor> tabs = new ArrayList<ComparableTabContributor>();\r
65         SysdynResource sr = SysdynResource.getInstance(backend);\r
66         DiagramResource dr = DiagramResource.getInstance(backend);\r
67         ModelingResources mr = ModelingResources.getInstance(backend);\r
68         SimulationResource simu = SimulationResource.getInstance(backend);\r
69 //        JFreeChartResource jfree = JFreeChartResource.getInstance(backend);\r
70 \r
71         // Test nodes\r
72         if(sharedFunctionsTestNode == null)\r
73             sharedFunctionsTestNode = new SpecialNodeType(sr.ModelingBrowseContext_SharedFunctionsFolder, Resource.class);\r
74 \r
75         try {\r
76             // Many elements \r
77             if (selection instanceof ArrayList<?> && ((ArrayList<?>) selection).size() > 1) {\r
78                 List<Resource> variables = new ArrayList<Resource>();\r
79                 List<Resource> dependencies = new ArrayList<Resource>();\r
80                 List<Resource> flows = new ArrayList<Resource>();\r
81                 Resource model = null;\r
82                 for(Object o : (ArrayList<?>)selection) {\r
83                     Resource r = AdaptionUtils.adaptToSingle(o, Resource.class);\r
84                     if (r == null)\r
85                         continue;\r
86                     Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
87                     if (component != null) {\r
88                         r = component;\r
89                     } else {\r
90                         // Try connection\r
91                         Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
92                         if(connection != null)\r
93                             r = connection;\r
94                     }\r
95                     \r
96                     if(r != null) {\r
97                         if(model == null)\r
98                             model = backend.getPossibleObject(r, Layer0.getInstance(backend).PartOf);\r
99                         if(model != null && model.equals( backend.getSingleObject(r, Layer0.getInstance(backend).PartOf))) {\r
100                                 if (backend.isInstanceOf(r, sr.Variable)) {\r
101                                         variables.add(r);\r
102                                 } else if (backend.isInstanceOf(r, sr.Dependency)) {\r
103                                         Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
104                                         dependencies.add(diaConnection);\r
105                                 } else if (backend.isInstanceOf(r, sr.Flow)) {\r
106                                         Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
107                                         flows.add(diaConnection);\r
108                                 }\r
109                         }\r
110                     }\r
111                 }\r
112                 \r
113                 if (!variables.isEmpty())\r
114                         // Do we have at least one variable\r
115                         tabs.add(new ComparableTabContributor(\r
116                                 new ArrayIndexesTab(),\r
117                                 1,\r
118                                 variables,\r
119                                 "Indexes"));\r
120                 else if (!dependencies.isEmpty()) {\r
121                     // Dependencies only\r
122                         tabs.add(new ComparableTabContributor(\r
123                             new ArrayDependencyTab(),\r
124                             1,\r
125                             dependencies,\r
126                             "Dependency Properties"));\r
127                 }\r
128                 else if (!flows.isEmpty()) {\r
129                     // Flows only\r
130                         tabs.add(new ComparableTabContributor(\r
131                             new ArrayFlowTab(),\r
132                             1,\r
133                             flows,\r
134                             "Flow Properties"));\r
135                 }\r
136                 return tabs;\r
137             }\r
138 \r
139             // Single element\r
140             Variable var = null; \r
141             WorkbenchSelectionElement wse = ISelectionUtils.filterSingleSelection(selection, WorkbenchSelectionElement.class);\r
142             if(wse != null) {\r
143                 var = wse.getContent(new AnyVariable(backend));\r
144                 if(var == null) {\r
145                     var = AdaptionUtils.adaptToSingle(selection, Variable.class);\r
146                     if(var != null) {\r
147                         Variable possibleActiveVariable = backend.syncRequest(new PossibleActiveVariableFromVariable(var));\r
148                         if(possibleActiveVariable != null)\r
149                             var = possibleActiveVariable;\r
150                     }\r
151                 }\r
152             }\r
153 \r
154             Resource r = AdaptionUtils.adaptToSingle(selection, Resource.class);\r
155             if(r == null) {\r
156                 // Selection is not directly a resource, try if it is a variable \r
157                 var = AdaptionUtils.adaptToSingle(selection, Variable.class);\r
158                 if(var != null)\r
159                     r = var.getRepresents(backend);\r
160             }\r
161             \r
162             if(r == null) {\r
163                 // SharedFunctionsFolder has properties but no adapted resource\r
164                 SharedFunctionsFolder sff = AdaptionUtils.adaptToSingle(selection, SharedFunctionsFolder.class);\r
165                 if (sff != null) {\r
166                     return Collections.singleton(new ComparableTabContributor(\r
167                             new SharedFunctionLibrariesTab(),\r
168                             2,\r
169                             sff.data,\r
170                             "Shared Functions"));\r
171                 }\r
172 \r
173                 return Collections.emptyList();\r
174             }\r
175 \r
176             NodeContext nc = AdaptionUtils.adaptToSingle(selection, NodeContext.class);\r
177             if(nc != null) {\r
178                 NodeType type = nc.getConstant(NodeType.TYPE);\r
179                 if(type != null && type.equals(sharedFunctionsTestNode)) {\r
180                     return Collections.singleton(new ComparableTabContributor(\r
181                             new SharedFunctionLibrariesTab(),\r
182                             2,\r
183                             r,\r
184                             "Shared Functions"));\r
185                 }\r
186             }\r
187 \r
188             // SVG elements in symbol editor\r
189             if (backend.isInstanceOf(r, dr.SVGElement))\r
190                 return Collections.singleton(SVGElementComposite.make(r, 1, "SVG"));\r
191 \r
192             // if r == diagram element, change it to component\r
193             if (backend.isInstanceOf(r, dr.Element)) {\r
194                 Resource component = backend.getPossibleObject(r, mr.ElementToComponent);\r
195                 if (component != null) {\r
196                     r = component;\r
197                 } else {\r
198                     Resource connection = backend.getPossibleObject(r, mr.DiagramConnectionToConnection);\r
199                     if(connection != null)\r
200                         r = connection;\r
201                 }\r
202             }\r
203             \r
204             \r
205             // Check that var has found the correct variable\r
206             if(r != null && var != null) {\r
207                 if(!r.equals(var.getRepresents(backend)))\r
208                     // Var found the wrong variable. This may happen with ModuleType editors\r
209                     var = null;\r
210             }\r
211             \r
212             \r
213             // If shadow variable, display properties of the original variable\r
214             if(backend.isInstanceOf(r, sr.Shadow)) {\r
215                 Resource original = backend.getPossibleObject(r, sr.Shadow_original);\r
216                 if(original != null && var != null) {\r
217                     r = original;\r
218                     Variable parent = var.getParent(backend);\r
219                     var = parent.getPossibleChild(backend, NameUtils.getSafeName(backend, r));\r
220                 }\r
221             }\r
222 \r
223             // If loop\r
224             if(backend.isInstanceOf(r, sr.Loop)) {\r
225                 return Collections.singleton(\r
226                                 (new ComparableTabContributor(\r
227                                 new LoopTab(),\r
228                                 1,\r
229                                 r,\r
230                                 "Loop")));\r
231             }\r
232 \r
233             // Independent variable\r
234             if (backend.isInstanceOf(r, sr.IndependentVariable)) {\r
235                 Resource activeExpression = backend.getPossibleObject(r, sr.IndependentVariable_activeExpression);\r
236                 Resource expression = null;\r
237                 if(activeExpression != null)\r
238                     // if variable has active expression, display it\r
239                     expression = activeExpression;\r
240                 else if (backend.hasStatement(r, sr.Variable_expressionList)){\r
241                     // else display the first expression of the variable\r
242                     Resource expressions = backend.getPossibleObject(r, sr.Variable_expressionList);\r
243                     List<Resource> expressionList = ListUtils.toList(backend, expressions);\r
244                     if(expressionList.isEmpty()) {\r
245                         System.err.println("expressionList is empty for " + r);\r
246                         return Collections.emptyList();\r
247                     }\r
248                     expression = expressionList.get(0);\r
249                 }\r
250                 tabs.add(new ComparableTabContributor(\r
251                         new EquationTab(),\r
252                         3,\r
253                         var != null ? var : r,\r
254                         "Equation"));\r
255                 if(expression != null && backend.isInstanceOf(expression, sr.WithLookupExpression)) {\r
256                     // WithLookupExpression has its own extra tab for visual configuration\r
257                     tabs.add(new ComparableTabContributor(\r
258                             new LookupTableTab(),\r
259                             2,\r
260                             expression,\r
261                             "Lookup Table"));\r
262                 }\r
263 \r
264                 tabs.add(new ComparableTabContributor(\r
265                         new ArrayIndexesTab(),\r
266                         1,\r
267                         r,\r
268                         "Indexes"));\r
269 \r
270                 tabs.add(new ComparableTabContributor(\r
271                         new VariableInformationTab(),\r
272                         0,\r
273                         r,\r
274                         "Additional Information"));\r
275                 return tabs;\r
276             }\r
277 \r
278             // Input variable\r
279             if (backend.isInstanceOf(r, sr.Input)) {\r
280                 tabs.add(new ComparableTabContributor(\r
281                         new InputVariableTab(),\r
282                         2,\r
283                         r,\r
284                         "Input"));\r
285 \r
286                 tabs.add(new ComparableTabContributor(\r
287                         new ArrayIndexesTab(),\r
288                         1,\r
289                         r,\r
290                         "Indexes"));\r
291 \r
292                 tabs.add(new ComparableTabContributor(\r
293                         new VariableInformationTab(),\r
294                         0,\r
295                         r,\r
296                         "Additional Information"));\r
297                 return tabs;\r
298             }\r
299 \r
300             // Enumeration\r
301             if (backend.isInstanceOf(r, sr.Enumeration)) {\r
302                 Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
303                 if(s == null)\r
304                     s = r;\r
305                 // give either variable or the actual resource\r
306                 return Collections.singleton(new ComparableTabContributor(\r
307                         new EnumerationTab(),\r
308                         2,\r
309                         s,\r
310                         "Enumeration"));\r
311             }\r
312 \r
313             // Configuration and model. They both show the properties of the configuration\r
314             if ( backend.isInstanceOf(r, sr.Configuration) || backend.isInstanceOf(r, sr.SysdynModel)) {\r
315                 if(!backend.isInstanceOf(r, sr.SysdynModel))\r
316                     r = backend.getPossibleObject(r, SimulationResource.getInstance(backend).IsConfigurationOf);\r
317                 if (r != null)\r
318                     return Collections.singleton(\r
319                             new ComparableTabContributor(\r
320                                     new ConfigurationTab(),\r
321                                     0,\r
322                                     r,\r
323                                     "Model Properties"));\r
324             }\r
325 \r
326             // Module\r
327             if (backend.isInstanceOf(r, sr.Module)){\r
328                 tabs.add(new ComparableTabContributor(\r
329                         new ModuleTab(),\r
330                         10,\r
331                         r,\r
332                         "Module Properties"));\r
333                 tabs.add(new ComparableTabContributor(\r
334                         new ModuleParameterTab(),\r
335                         9,\r
336                         r,\r
337                         "Parameters"));\r
338                 tabs.add(new ComparableTabContributor(\r
339                         new ModuleInputTab(),\r
340                         2,\r
341                         r,\r
342                         "Inputs"));\r
343                 tabs.add(new ComparableTabContributor(\r
344                         new ModuleOutputTab(),\r
345                         1,\r
346                         r,\r
347                         "Outputs"));\r
348                 return tabs;\r
349             }\r
350 \r
351             // Playback experiment\r
352             if (backend.isInstanceOf(r, sr.PlaybackExperiment))\r
353                 return Collections.singleton(\r
354                         new ComparableTabContributor(\r
355                                 new PlaybackExperimentTab(),\r
356                                 0,\r
357                                 r,\r
358                                 "Experiment Properties"));\r
359 \r
360          // Game experiment\r
361             if (backend.isInstanceOf(r, sr.GameExperiment))\r
362                 return Collections.singleton(\r
363                         new ComparableTabContributor(\r
364                                 new GameExperimentTab(),\r
365                                 0,\r
366                                 r,\r
367                                 "Experiment Properties"));\r
368 \r
369          // Sensitivity analysis experiment\r
370             if (backend.isInstanceOf(r, sr.SensitivityAnalysisExperiment))\r
371                 return Collections.singleton(\r
372                         new ComparableTabContributor(\r
373                                 new SensitivityAnalysisExperimentTab(),\r
374                                 0,\r
375                                 r,\r
376                                 "Experiment Properties"));\r
377 \r
378          // Default experiment\r
379             if (backend.isInstanceOf(r, simu.Experiment))\r
380                 return Collections.singleton(\r
381                         new ComparableTabContributor(\r
382                                 new ExperimentTab(),\r
383                                 0,\r
384                                 r,\r
385                                 "Experiment Properties"));\r
386 \r
387             // History data\r
388             if (backend.isInstanceOf(r, sr.HistoryDataset))\r
389                 return Collections.singleton(\r
390                         new ComparableTabContributor(\r
391                                 new HistoryDataTab(),\r
392                                 0,\r
393                                 r,\r
394                                 "History Data Properties"));\r
395 \r
396             // Saved simulation result\r
397             if (backend.isInstanceOf(r, sr.Result))\r
398                 return Collections.singleton(\r
399                         new ComparableTabContributor(\r
400                                 new ResultTab(),\r
401                                 0,\r
402                                 r,\r
403                                 "Result Properties"));\r
404 \r
405             // Dependency\r
406             if (backend.isInstanceOf(r, sr.Dependency))\r
407                 if (backend.hasStatement(r, sr.Dependency_refersTo)) {\r
408                     Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
409                     return Collections.singleton(\r
410                             new ComparableTabContributor(\r
411                                     new DependencyTab(),\r
412                                     0,\r
413                                     diaConnection,\r
414                                     "Reference Properties"));\r
415                 } else {\r
416                     Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
417                     return Collections.singleton(\r
418                             new ComparableTabContributor(\r
419                                     new DependencyTab(),\r
420                                     0,\r
421                                     diaConnection,\r
422                                     "Dependency Properties"));\r
423                 }\r
424 \r
425             // Flow\r
426             if (backend.isInstanceOf(r, sr.Flow)) {\r
427                 Resource diaConnection = backend.getPossibleObject(r, ModelingResources.getInstance(backend).ConnectionToDiagramConnection);\r
428                 return Collections.singleton(\r
429                         new ComparableTabContributor(\r
430                                         new FlowTab(),\r
431                                         0,\r
432                                         diaConnection,\r
433                                         "Flow Properties"));\r
434             }\r
435 \r
436             // Module symbol. Modules in modules-folder are actually symbol resources\r
437             if (backend.isInheritedFrom(r, sr.ModuleSymbol)) {\r
438                 // Find the component resource\r
439                 r =  backend.getPossibleObject(r, mr.SymbolToComponentType);\r
440                 if(r != null)\r
441                     return Collections.singleton(\r
442                             new ComparableTabContributor(\r
443                                     new ModuleTypeTab(),\r
444                                     0,\r
445                                     r,\r
446                                     "Module Type Properties"));\r
447             }\r
448 \r
449             // Function\r
450             if (backend.isInstanceOf(r, sr.SysdynModelicaFunction)) {\r
451                 tabs.add(new ComparableTabContributor(\r
452                         new FunctionTab(),\r
453                         2,\r
454                         r,\r
455                         "Function"));\r
456                 tabs.add(new ComparableTabContributor(\r
457                         new ExternalFilesTab(),\r
458                         1,\r
459                         r,\r
460                         "External files"));\r
461                 return tabs;\r
462             }\r
463 \r
464             // Function library\r
465             if (backend.isInstanceOf(r, sr.SysdynModelicaFunctionLibrary)) {\r
466                 Object s = AdaptionUtils.adaptToSingle(selection, ISelection.class);\r
467                 if(s == null)\r
468                     s = r;\r
469                 // give either variable or the actual resource\r
470                 return Collections.singleton(new ComparableTabContributor(\r
471                         new FunctionLibraryTab(),\r
472                         2,\r
473                         s,\r
474                         "Function library"));\r
475             }\r
476             \r
477             // Try sensitivity chart before other charts\r
478             if (contributeSensitivityChart(backend, r, tabs)) {\r
479                 return tabs;\r
480             }\r
481             \r
482             // Try normal charts\r
483             if (ChartSelectionTabContributor.contibuteTabs(backend, r, tabs)) {\r
484                 return tabs;\r
485             }\r
486 \r
487             // Default experiment\r
488             if (backend.isInstanceOf(r, sr.AdditionalSymbols_MultilineText))\r
489                 return Collections.singleton(\r
490                         new ComparableTabContributor(\r
491                                 new CommentTab(),\r
492                                 0,\r
493                                 r,\r
494                                 "Comment"));\r
495 \r
496         } catch (ServiceException e) {\r
497             e.printStackTrace();\r
498         } catch (ManyObjectsForFunctionalRelationException e) {\r
499             e.printStackTrace();\r
500         } catch (DatabaseException e) {\r
501             e.printStackTrace();\r
502         }\r
503         return Collections.emptyList();\r
504     }\r
505     \r
506     public static boolean contributeSensitivityChart(ReadGraph backend, Resource r, List<ComparableTabContributor> tabs) throws DatabaseException {\r
507         JFreeChartResource jfree = JFreeChartResource.getInstance(backend);\r
508         if(backend.isInstanceOf(r, jfree.ChartElement)) {\r
509             if(backend.hasStatement(r, jfree.ChartElement_component))\r
510                 r = backend.getSingleObject(r, jfree.ChartElement_component);\r
511         }\r
512 \r
513         if (backend.isInstanceOf(r, jfree.Chart)) {\r
514 \r
515             Collection<Resource> plots = backend.syncRequest(new ObjectsWithType(r, Layer0.getInstance(backend).ConsistsOf, jfree.Plot));\r
516             if(!plots.isEmpty()) {\r
517                 Resource plot = plots.iterator().next();\r
518 \r
519                 if(backend.isInstanceOf(plot, SysdynResource.getInstance(backend).Charts_SensitivityPlot)) {\r
520                     tabs.add(new ComparableTabContributor(\r
521                             new XYLineGeneralPropertiesTab(),\r
522                             10,\r
523                             r,\r
524                             "General"));\r
525                     tabs.add(new ComparableTabContributor(\r
526                             new SensitivityChartAxisAndVariablesTab(),\r
527                             9,\r
528                             r,\r
529                             "Axis and Variables"));\r
530                     return true;\r
531                 }\r
532             }\r
533         }\r
534         return false;\r
535     }\r
536 }\r