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