]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerSelectionProvider.java
42c489e24d4b866d310507cf7d1d00d4cc1508cf
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / DiagramViewerSelectionProvider.java
1 package org.simantics.modeling.ui.diagramEditor;\r
2 \r
3 import java.util.ArrayList;\r
4 \r
5 import org.eclipse.jface.viewers.ISelection;\r
6 import org.eclipse.jface.viewers.StructuredSelection;\r
7 import org.eclipse.ui.IWorkbenchPartSite;\r
8 import org.simantics.Simantics;\r
9 import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
10 import org.simantics.db.ReadGraph;\r
11 import org.simantics.db.Resource;\r
12 import org.simantics.db.common.request.ResourceRead;\r
13 import org.simantics.db.common.request.ResourceRead2;\r
14 import org.simantics.db.common.utils.RequestUtil;\r
15 import org.simantics.db.exception.DatabaseException;\r
16 import org.simantics.db.layer0.SelectionHints;\r
17 import org.simantics.db.layer0.request.PossibleModel;\r
18 import org.simantics.db.layer0.variable.Variable;\r
19 import org.simantics.db.layer0.variable.Variables;\r
20 import org.simantics.diagram.Logger;\r
21 import org.simantics.diagram.flag.FlagUtil;\r
22 import org.simantics.diagram.stubs.DiagramResource;\r
23 import org.simantics.diagram.ui.DiagramModelHints;\r
24 import org.simantics.diagram.ui.WorkbenchSelectionProvider;\r
25 import org.simantics.g2d.diagram.IDiagram;\r
26 import org.simantics.g2d.element.ElementHints;\r
27 import org.simantics.g2d.element.ElementUtils;\r
28 import org.simantics.g2d.element.IElement;\r
29 import org.simantics.layer0.Layer0;\r
30 import org.simantics.modeling.ModelingResources;\r
31 import org.simantics.ui.SimanticsUI;\r
32 import org.simantics.ui.selection.AnyResource;\r
33 import org.simantics.ui.selection.AnyVariable;\r
34 import org.simantics.ui.selection.WorkbenchSelectionContentType;\r
35 import org.simantics.utils.DataContainer;\r
36 import org.simantics.utils.threads.IThreadWorkQueue;\r
37 import org.simantics.utils.ui.ErrorLogger;\r
38 \r
39 /**\r
40  * @author Antti Villberg\r
41  */\r
42 public class DiagramViewerSelectionProvider extends WorkbenchSelectionProvider {\r
43 \r
44     protected static class SelectionElement extends AdaptableHintContext {\r
45 \r
46         final public Resource runtime;\r
47         final public Resource element;\r
48 \r
49         public SelectionElement(Key[] keys, Resource runtime, Resource element) {\r
50             super(keys);\r
51             this.runtime = runtime;\r
52             this.element = element;\r
53         }\r
54 \r
55         @SuppressWarnings("unchecked")\r
56         @Override\r
57         public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {\r
58                 if(contentType instanceof AnyResource) return (T)element;\r
59                 else if(contentType instanceof AnyVariable) {\r
60                 AnyVariable type = (AnyVariable)contentType;\r
61                 try {\r
62                     return (T) type.processor.sync(new ResourceRead2<Variable>(runtime, element) {\r
63                         @Override\r
64                         public Variable perform(ReadGraph graph) throws DatabaseException {\r
65 \r
66                             DiagramResource DIA = DiagramResource.getInstance(graph);\r
67                             ModelingResources MOD = ModelingResources.getInstance(graph);\r
68 \r
69                             String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasVariable);\r
70                             if (uri == null)\r
71                                 return null;\r
72 \r
73                             Variable var = Variables.getPossibleVariable(graph, uri);\r
74                             if (var == null)\r
75                                 return null;\r
76 \r
77                             Resource config = graph.getPossibleObject(resource2, MOD.ElementToComponent);\r
78                             if (config == null) {\r
79                                 // Apros #9646: if resource2 is the diagram\r
80                                 // itself, return the diagram composite variable\r
81                                 // since it is generally more useful than the\r
82                                 // variable to the diagram.\r
83                                 Resource composite = graph.getPossibleObject(resource2, MOD.DiagramToComposite);\r
84                                 if (composite != null && composite.equals(var.getPossibleRepresents(graph))) {\r
85                                     //return Variables.getPossibleVariable(graph, resource2);\r
86                                     return var;\r
87                                 }\r
88                                 \r
89                                 if(graph.isInstanceOf(resource2, DIA.Flag)) {\r
90                                         Layer0 L0 = Layer0.getInstance(graph);\r
91                                         Variable signal = FlagUtil.getPossibleFlagSignal(graph, var, resource2, L0.Entity);\r
92                                         if(signal != null)\r
93                                                 return signal;\r
94                                 }\r
95 \r
96                                 return null;\r
97                                 \r
98                             }\r
99 \r
100                             return var.browsePossible(graph, config);\r
101 \r
102                         }\r
103                     });\r
104                 } catch (DatabaseException e) {\r
105                     Logger.defaultLogError(e);\r
106                 }\r
107             } \r
108             return null;\r
109         }\r
110 \r
111     }\r
112 \r
113     protected DataContainer<IDiagram> sourceDiagram;\r
114 \r
115     public DiagramViewerSelectionProvider(IThreadWorkQueue queue, IWorkbenchPartSite site, DataContainer<IDiagram> sourceDiagram) {\r
116         super(queue, site);\r
117         assert(sourceDiagram != null);\r
118         this.sourceDiagram = sourceDiagram;\r
119     }\r
120 \r
121         @Override\r
122         protected ISelection constructAdaptableSelection(Iterable<?> selection) {\r
123                 ArrayList<Object> objects = new ArrayList<Object>();\r
124                 IDiagram diagram = sourceDiagram.get();\r
125                 if (diagram != null) {\r
126                         Resource runtime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
127                         Resource dr = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
128                         for (Object o : selection) {\r
129                                 Resource resource = getSelectionResource(o);\r
130                                 if (resource != null) {\r
131                                         objects.add( constructSelectionElement(runtime, resource) );\r
132                                 } else {\r
133                                         System.out.println("  unrecognized selection: " + o.getClass() + ": " + o);\r
134                                 }\r
135                         }\r
136                         if (objects.isEmpty() && runtime != null && dr != null) {\r
137                                 objects.add( constructSelectionElement(runtime, dr) );\r
138                         }\r
139                 }\r
140                 return new StructuredSelection(objects);\r
141         }\r
142 \r
143         protected Resource getSelectionResource(Object o) {\r
144                 if (o instanceof IElement) {\r
145                         IElement e = (IElement) o;\r
146                         Object object = e.getHint(ElementHints.KEY_OBJECT);\r
147                         if (object instanceof Resource)\r
148                                 return (Resource) object;\r
149                         object = ElementUtils.adaptElement(e, Resource.class);\r
150                         if (object != null)\r
151                                 return (Resource) object;\r
152                 }\r
153                 return null;\r
154         }\r
155 \r
156         /**\r
157          * @param runtime\r
158          * @param object\r
159          * @return\r
160          */\r
161         protected static SelectionElement constructSelectionElement(Resource runtime, Resource object) {\r
162                 SelectionElement context = new SelectionElement(SelectionHints.STD_KEYS, runtime, object);\r
163                 context.setHint(SelectionHints.KEY_MAIN, object);\r
164                 if (runtime != null) {\r
165                         context.setHint(SelectionHints.KEY_VARIABLE_RESOURCE, runtime);\r
166                         try {\r
167                                 Resource model = RequestUtil.trySyncRequest(\r
168                                                 Simantics.getSession(),\r
169                                                 SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,\r
170                                                 SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,\r
171                                                 null,\r
172                                                 new ModelOfRuntime(runtime));\r
173                                 if (model != null)\r
174                                         context.setHint(SelectionHints.KEY_MODEL, model);\r
175                         } catch (DatabaseException | InterruptedException ex) {\r
176                                 ErrorLogger.defaultLogError(ex);\r
177                         }\r
178                 }\r
179                 return context;\r
180         }\r
181 \r
182         private static class ModelOfRuntime extends ResourceRead<Resource> {\r
183                 public ModelOfRuntime(Resource runtime) {\r
184                         super(runtime);\r
185                 }\r
186 \r
187                 @Override\r
188                 public Resource perform(ReadGraph graph) throws DatabaseException {\r
189                         DiagramResource DIA = DiagramResource.getInstance(graph);\r
190                         String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasModelURI);\r
191                         if (uri != null) {\r
192                                 Resource resource = graph.getPossibleResource(uri);\r
193                                 if(resource != null) return resource;\r
194                         }\r
195                         Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration);\r
196                         if (diagram == null)\r
197                                 return null;\r
198                         return graph.syncRequest(new PossibleModel(diagram));\r
199                 }\r
200         }\r
201 \r
202 }