Sync git svn branch with SVN repository r33406.
[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                             Layer0 L0 = Layer0.getInstance(graph);\r
69 \r
70                             String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasVariable);\r
71                             if (uri == null)\r
72                                 return null;\r
73 \r
74                             Variable var = Variables.getPossibleVariable(graph, uri);\r
75                             if (var == null)\r
76                                 return null;\r
77 \r
78                             Resource config = graph.getPossibleObject(resource2, MOD.ElementToComponent);\r
79                             if (config == null) {\r
80                                 if (graph.isInstanceOf(resource2, DIA.Connection)) {\r
81                                     Variable v = FlagUtil.getPossibleConnectionSignal(graph, var, resource2, L0.Entity);\r
82                                     if (v != null)\r
83                                         return v;\r
84                                 }\r
85                                 // Apros #9646: if resource2 is the diagram\r
86                                 // itself, return the diagram composite variable\r
87                                 // since it is generally more useful than the\r
88                                 // variable to the diagram.\r
89                                 Resource composite = graph.getPossibleObject(resource2, MOD.DiagramToComposite);\r
90                                 if (composite != null && composite.equals(var.getPossibleRepresents(graph))) {\r
91                                     //return Variables.getPossibleVariable(graph, resource2);\r
92                                     return var;\r
93                                 }\r
94                                 \r
95                                 if(graph.isInstanceOf(resource2, DIA.Flag)) {\r
96                                         Variable signal = FlagUtil.getPossibleFlagSignal(graph, var, resource2, L0.Entity);\r
97                                         if(signal != null)\r
98                                                 return signal;\r
99                                 }\r
100 \r
101                                 return null;\r
102                                 \r
103                             }\r
104 \r
105                             return var.browsePossible(graph, config);\r
106 \r
107                         }\r
108                     });\r
109                 } catch (DatabaseException e) {\r
110                     Logger.defaultLogError(e);\r
111                 }\r
112             } \r
113             return null;\r
114         }\r
115 \r
116     }\r
117 \r
118     protected DataContainer<IDiagram> sourceDiagram;\r
119 \r
120     public DiagramViewerSelectionProvider(IThreadWorkQueue queue, IWorkbenchPartSite site, DataContainer<IDiagram> sourceDiagram) {\r
121         super(queue, site);\r
122         assert(sourceDiagram != null);\r
123         this.sourceDiagram = sourceDiagram;\r
124     }\r
125 \r
126         @Override\r
127         protected ISelection constructAdaptableSelection(Iterable<?> selection) {\r
128                 ArrayList<Object> objects = new ArrayList<Object>();\r
129                 IDiagram diagram = sourceDiagram.get();\r
130                 if (diagram != null) {\r
131                         Resource runtime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
132                         Resource dr = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RESOURCE);\r
133                         for (Object o : selection) {\r
134                                 Resource resource = getSelectionResource(o);\r
135                                 if (resource != null) {\r
136                                         objects.add( constructSelectionElement(runtime, resource) );\r
137                                 } else {\r
138                                         System.out.println("  unrecognized selection: " + o.getClass() + ": " + o);\r
139                                 }\r
140                         }\r
141                         if (objects.isEmpty() && runtime != null && dr != null) {\r
142                                 objects.add( constructSelectionElement(runtime, dr) );\r
143                         }\r
144                 }\r
145                 return new StructuredSelection(objects);\r
146         }\r
147 \r
148         protected Resource getSelectionResource(Object o) {\r
149                 if (o instanceof IElement) {\r
150                         IElement e = (IElement) o;\r
151                         Object object = e.getHint(ElementHints.KEY_OBJECT);\r
152                         if (object instanceof Resource)\r
153                                 return (Resource) object;\r
154                         object = ElementUtils.adaptElement(e, Resource.class);\r
155                         if (object != null)\r
156                                 return (Resource) object;\r
157                 }\r
158                 return null;\r
159         }\r
160 \r
161         /**\r
162          * @param runtime\r
163          * @param object\r
164          * @return\r
165          */\r
166         protected static SelectionElement constructSelectionElement(Resource runtime, Resource object) {\r
167                 SelectionElement context = new SelectionElement(SelectionHints.STD_KEYS, runtime, object);\r
168                 context.setHint(SelectionHints.KEY_MAIN, object);\r
169                 if (runtime != null) {\r
170                         context.setHint(SelectionHints.KEY_VARIABLE_RESOURCE, runtime);\r
171                         try {\r
172                                 Resource model = RequestUtil.trySyncRequest(\r
173                                                 Simantics.getSession(),\r
174                                                 SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,\r
175                                                 SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,\r
176                                                 null,\r
177                                                 new ModelOfRuntime(runtime));\r
178                                 if (model != null)\r
179                                         context.setHint(SelectionHints.KEY_MODEL, model);\r
180                         } catch (DatabaseException | InterruptedException ex) {\r
181                                 ErrorLogger.defaultLogError(ex);\r
182                         }\r
183                 }\r
184                 return context;\r
185         }\r
186 \r
187         private static class ModelOfRuntime extends ResourceRead<Resource> {\r
188                 public ModelOfRuntime(Resource runtime) {\r
189                         super(runtime);\r
190                 }\r
191 \r
192                 @Override\r
193                 public Resource perform(ReadGraph graph) throws DatabaseException {\r
194                         DiagramResource DIA = DiagramResource.getInstance(graph);\r
195                         String uri = graph.getPossibleRelatedValue(resource, DIA.RuntimeDiagram_HasModelURI);\r
196                         if (uri != null) {\r
197                                 Resource resource = graph.getPossibleResource(uri);\r
198                                 if(resource != null) return resource;\r
199                         }\r
200                         Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration);\r
201                         if (diagram == null)\r
202                                 return null;\r
203                         return graph.syncRequest(new PossibleModel(diagram));\r
204                 }\r
205         }\r
206 \r
207 }