]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.selectionview/src/org/simantics/selectionview/ModelledTabContributor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.selectionview / src / org / simantics / selectionview / ModelledTabContributor.java
1 package org.simantics.selectionview;\r
2 \r
3 import java.util.function.Consumer;\r
4 \r
5 import org.eclipse.jface.layout.GridDataFactory;\r
6 import org.eclipse.jface.layout.GridLayoutFactory;\r
7 import org.eclipse.jface.viewers.ISelection;\r
8 import org.eclipse.jface.viewers.ISelectionProvider;\r
9 import org.eclipse.jface.viewers.StructuredSelection;\r
10 import org.eclipse.swt.SWT;\r
11 import org.eclipse.swt.widgets.Composite;\r
12 import org.eclipse.swt.widgets.Control;\r
13 import org.eclipse.swt.widgets.Event;\r
14 import org.eclipse.swt.widgets.Listener;\r
15 import org.eclipse.ui.IWorkbenchSite;\r
16 import org.simantics.Simantics;\r
17 import org.simantics.browsing.ui.common.ErrorLogger;\r
18 import org.simantics.browsing.ui.common.views.IFilterArea;\r
19 import org.simantics.browsing.ui.common.views.IFilterAreaProvider;\r
20 import org.simantics.browsing.ui.swt.PartNameListener;\r
21 import org.simantics.databoard.Bindings;\r
22 import org.simantics.db.AsyncReadGraph;\r
23 import org.simantics.db.ReadGraph;\r
24 import org.simantics.db.Resource;\r
25 import org.simantics.db.VirtualGraph;\r
26 import org.simantics.db.WriteGraph;\r
27 import org.simantics.db.common.procedure.adapter.DisposableAsyncListener;\r
28 import org.simantics.db.common.procedure.adapter.ListenerSupport;\r
29 import org.simantics.db.common.request.UniqueRead;\r
30 import org.simantics.db.common.request.WriteRequest;\r
31 import org.simantics.db.common.request.WriteResultRequest;\r
32 import org.simantics.db.common.utils.Logger;\r
33 import org.simantics.db.common.utils.NameUtils;\r
34 import org.simantics.db.exception.DatabaseException;\r
35 import org.simantics.db.exception.ServiceNotFoundException;\r
36 import org.simantics.db.layer0.variable.Variable;\r
37 import org.simantics.db.management.ISessionContext;\r
38 import org.simantics.db.request.Read;\r
39 import org.simantics.layer0.Layer0;\r
40 import org.simantics.scenegraph.ontology.ScenegraphResources;\r
41 import org.simantics.utils.datastructures.Pair;\r
42 import org.simantics.utils.ui.ISelectionUtils;\r
43 import org.simantics.utils.ui.jface.ActiveSelectionProvider;\r
44 \r
45 abstract public class ModelledTabContributor implements PropertyTabContributor, ListenerSupport {\r
46 \r
47         static class InputRead extends UniqueRead<Pair<Variable, Resource>> {\r
48                 \r
49                 private Object input;\r
50                 \r
51                 InputRead(Object input) {\r
52                         this.input = input;\r
53                 }\r
54 \r
55                 @Override\r
56                 public Pair<Variable, Resource> perform(ReadGraph graph) throws DatabaseException {\r
57 \r
58                         Variable resultVariable = null;\r
59                         Resource resultResource = null;\r
60 \r
61                         if(input instanceof ISelection) {\r
62                                 Variable var = ISelectionUtils.filterSingleSelection((ISelection)input, Variable.class);\r
63                                 if(var != null) resultVariable = var;\r
64                                 Resource res = ISelectionUtils.filterSingleSelection((ISelection)input, Resource.class);\r
65                                 if(res != null) resultResource = res;\r
66                         } else if (input instanceof Resource) {\r
67                                 resultResource = (Resource)input;\r
68                         }\r
69 \r
70                         return Pair.make(resultVariable, resultResource);\r
71 \r
72                 }\r
73 \r
74         };\r
75         \r
76         static class InputListener extends DisposableAsyncListener<Pair<Variable, Resource>> {\r
77         \r
78         final Resource runtime;\r
79         \r
80         public InputListener(Resource runtime) {\r
81                 this.runtime = runtime;\r
82         }\r
83 \r
84                 @Override\r
85                 public void execute(AsyncReadGraph graph, final Pair<Variable, Resource> result) {\r
86                         \r
87                         Simantics.getSession().async(new WriteRequest(Simantics.getSession().getService(VirtualGraph.class)) {\r
88 \r
89                                 @Override\r
90                                 public void perform(WriteGraph graph) throws DatabaseException {\r
91 \r
92                                         ScenegraphResources SG = ScenegraphResources.getInstance(graph);\r
93                                         \r
94                                         if(result.first != null) {\r
95                                                 String uri = result.first.getURI(graph);\r
96                                                 graph.claimLiteral(runtime, SG.Runtime_HasVariable, uri, Bindings.STRING);\r
97                                         }\r
98 \r
99                                         if(result.second != null) {\r
100                         graph.deny(runtime, SG.Runtime_HasResource);\r
101                         graph.claim(runtime, SG.Runtime_HasResource, result.second);\r
102                     }\r
103                                         \r
104                                 }\r
105                                 \r
106                         });                             \r
107                         \r
108                 }\r
109 \r
110                 @Override\r
111                 public void exception(AsyncReadGraph graph, Throwable throwable) {\r
112                         Logger.defaultLogError(throwable);\r
113                 }\r
114                 \r
115     }\r
116         \r
117     protected Resource runtime;\r
118         \r
119     // For ListenerSupport (supporting DB request listeners)\r
120     protected boolean    disposed = false;\r
121     protected ISelection input    = StructuredSelection.EMPTY;\r
122     \r
123     protected ISelectionProvider selectionProvider = new ActiveSelectionProvider();\r
124 \r
125     abstract public void createControls(Composite body, IWorkbenchSite site);\r
126 \r
127     public IFilterArea getFilterArea() {\r
128         return null;\r
129     }\r
130 \r
131     public void requestFocus() {\r
132     }\r
133 \r
134     public ISelectionProvider getSelectionProvider() {\r
135         return selectionProvider; \r
136     }\r
137 \r
138     public Read<String> getPartNameReadRequest(final ISelection forSelection) {\r
139         return new UniqueRead<String>() {\r
140 \r
141                 private String forResource(ReadGraph graph, Resource resource) throws DatabaseException {\r
142                         Layer0 L0 = Layer0.getInstance(graph);\r
143                         String name = NameUtils.getSafeName(graph, resource);\r
144                         Resource type = graph.getPossibleType(resource, L0.Entity);\r
145                         if(type != null) {\r
146                                 name += " : " + NameUtils.getSafeName(graph, type);\r
147                         }\r
148                         return name;\r
149                 }\r
150                  \r
151                         @Override\r
152                         public String perform(ReadGraph graph) throws DatabaseException {\r
153                                 Resource resource = ISelectionUtils.filterSingleSelection(forSelection, Resource.class);\r
154                                 if(resource != null) return forResource(graph, resource);\r
155                                 Variable variable = ISelectionUtils.filterSingleSelection(forSelection, Variable.class);\r
156                                 if(variable != null) {\r
157                                         Resource represents = variable.getPossibleRepresents(graph);\r
158                                         if(represents != null) return forResource(graph, represents);\r
159                                 }\r
160                                 return "Selection";\r
161                         }\r
162                 \r
163         };\r
164     }\r
165 \r
166     public void updatePartName(ISelection forSelection, Consumer<String> updateCallback) {\r
167         Read<String> read = getPartNameReadRequest(forSelection);\r
168         if (read == null) {\r
169             updateCallback.accept("Selection");\r
170         } else {\r
171             Simantics.getSession().asyncRequest(read, new PartNameListener(updateCallback, this));\r
172         }\r
173     }\r
174 \r
175     public void updatePartName(Consumer<String> updateCallback) {\r
176         updatePartName(input, updateCallback);\r
177     }\r
178 \r
179     protected void dispose() {\r
180         this.disposed = true;\r
181     }\r
182 \r
183     @Override\r
184     public void exception(Throwable t) {\r
185         ErrorLogger.defaultLogError("PropertyTabContributorImpl received unexpected exception.", t);\r
186     }\r
187 \r
188     @Override\r
189     public boolean isDisposed() {\r
190         return disposed;\r
191     }\r
192 \r
193     public Control createControl(Composite parent, final IWorkbenchSite site) {\r
194 \r
195         class TabComposite extends Composite {\r
196             public TabComposite(Composite parent) {\r
197                 super(parent, 0);\r
198 \r
199                 GridLayoutFactory.fillDefaults().applyTo(parent);\r
200                 GridDataFactory.fillDefaults().span(1, 1).grab(true, true).applyTo(this);\r
201 \r
202                 Composite body = this;\r
203                 GridLayoutFactory.fillDefaults().spacing(0, 0).equalWidth(false).numColumns(1).applyTo(body);\r
204 \r
205                 try {\r
206                         ModelledTabContributor.this.createControls(body, site);\r
207                 } catch (Throwable t) {\r
208                     ErrorLogger.defaultLogError(t);\r
209                 }\r
210             }\r
211         }\r
212 \r
213         final TabComposite tc = new TabComposite(parent);\r
214         tc.addListener(SWT.Dispose, new Listener() {\r
215             public void handleEvent(Event e) {\r
216                 ModelledTabContributor.this.dispose();\r
217             }\r
218         });\r
219         \r
220         return tc;\r
221         \r
222     }\r
223 \r
224     @Override\r
225     public IPropertyTab create(Composite parent, IWorkbenchSite site, ISessionContext context, Object input) {\r
226         IPropertyTab tab = new Tab(site, parent);\r
227         tab.createControl((Composite) tab.getControl(), context);\r
228         return tab;\r
229     }\r
230 \r
231     class Tab extends Composite implements IPropertyTab2, IFilterAreaProvider {\r
232 \r
233         final IWorkbenchSite    site;\r
234 \r
235         private InputListener listener;\r
236         \r
237         public Tab(IWorkbenchSite site, Composite parent) {\r
238                 \r
239             super(parent, SWT.NONE);\r
240             this.site = site;\r
241             \r
242                 try {\r
243                         runtime = Simantics.getSession().sync(new WriteResultRequest<Resource>(Simantics.getSession().getService(VirtualGraph.class)) {\r
244                             @Override\r
245                             public Resource perform(WriteGraph graph) throws DatabaseException {\r
246                                 Layer0 L0 = Layer0.getInstance(graph);\r
247                                 ScenegraphResources SG = ScenegraphResources.getInstance(graph);\r
248                                 Resource runtime = graph.newResource();\r
249                                                 graph.claim(runtime, L0.InstanceOf, null, SG.Runtime);\r
250                                                 return runtime;\r
251                             }\r
252                         });\r
253                 } catch (ServiceNotFoundException e) {\r
254                         Logger.defaultLogError(e);\r
255                 } catch (DatabaseException e) {\r
256                         Logger.defaultLogError(e);\r
257                 }\r
258             \r
259         }\r
260 \r
261         @Override\r
262         public void createControl(Composite parent, ISessionContext context) {\r
263                 Control c = ModelledTabContributor.this.createControl(parent, site);\r
264             c.addListener(SWT.Dispose, new Listener() {\r
265                 public void handleEvent(Event e) {\r
266                         if(listener != null) {\r
267                                 listener.dispose();\r
268                                 listener = null;\r
269                         }\r
270                 }\r
271             });\r
272         }\r
273 \r
274         @Override\r
275         public Control getControl() {\r
276             return this;\r
277         }\r
278 \r
279         @Override\r
280         public boolean isDisposed() {\r
281             return super.isDisposed();\r
282         }\r
283 \r
284         @Override\r
285         public void requestFocus() {\r
286                 ModelledTabContributor.this.requestFocus();\r
287         }\r
288 \r
289         @Override\r
290         public void setInput(ISessionContext context, ISelection selection, boolean force) {\r
291                 \r
292                 ModelledTabContributor.this.input = selection;\r
293 \r
294                         if(listener != null) listener.dispose();\r
295                         \r
296                         listener = new InputListener(runtime);\r
297                         \r
298                         try {\r
299                                 Simantics.getSession().syncRequest(new InputRead(ModelledTabContributor.this.input), listener);\r
300                         } catch (DatabaseException e) {\r
301                                 Logger.defaultLogError(e);\r
302                         }\r
303             \r
304         }\r
305 \r
306         @Override\r
307         public ISelectionProvider getSelectionProvider() {\r
308             return ModelledTabContributor.this.getSelectionProvider();\r
309         }\r
310 \r
311         @Override\r
312         public IFilterArea getFilterArea() {\r
313             return ModelledTabContributor.this.getFilterArea();\r
314         }\r
315 \r
316         @Override\r
317         public void updatePartName(Consumer<String> updateCallback) {\r
318                 ModelledTabContributor.this.updatePartName(input, updateCallback);\r
319         }\r
320 \r
321     }\r
322         \r
323 }\r