]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.ui/src/org/simantics/document/ui/contribution/DocumentTabContribution.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.document.ui / src / org / simantics / document / ui / contribution / DocumentTabContribution.java
1 package org.simantics.document.ui.contribution;\r
2 \r
3 import java.util.Collection;\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.swt.SWT;\r
9 import org.eclipse.swt.dnd.DND;\r
10 import org.eclipse.swt.dnd.DropTarget;\r
11 import org.eclipse.swt.dnd.DropTargetAdapter;\r
12 import org.eclipse.swt.dnd.DropTargetEvent;\r
13 import org.eclipse.swt.dnd.TextTransfer;\r
14 import org.eclipse.swt.dnd.Transfer;\r
15 import org.eclipse.swt.events.SelectionAdapter;\r
16 import org.eclipse.swt.events.SelectionEvent;\r
17 import org.eclipse.swt.widgets.Button;\r
18 import org.eclipse.swt.widgets.Composite;\r
19 import org.eclipse.swt.widgets.Display;\r
20 import org.eclipse.swt.widgets.Label;\r
21 import org.eclipse.swt.widgets.Text;\r
22 import org.eclipse.ui.IWorkbenchSite;\r
23 import org.simantics.Simantics;\r
24 import org.simantics.browsing.ui.swt.widgets.StringPropertyFactory;\r
25 import org.simantics.browsing.ui.swt.widgets.StringPropertyModifier;\r
26 import org.simantics.browsing.ui.swt.widgets.TrackedText;\r
27 import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
28 import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
29 import org.simantics.db.AsyncReadGraph;\r
30 import org.simantics.db.ReadGraph;\r
31 import org.simantics.db.Resource;\r
32 import org.simantics.db.WriteGraph;\r
33 import org.simantics.db.common.NamedResource;\r
34 import org.simantics.db.common.ResourceArray;\r
35 import org.simantics.db.common.procedure.adapter.AsyncListenerAdapter;\r
36 import org.simantics.db.common.request.ReadRequest;\r
37 import org.simantics.db.common.request.WriteRequest;\r
38 import org.simantics.db.exception.DatabaseException;\r
39 import org.simantics.db.management.ISessionContext;\r
40 import org.simantics.db.request.Read;\r
41 import org.simantics.db.service.SerialisationSupport;\r
42 import org.simantics.document.DocumentResource;\r
43 import org.simantics.document.ui.graphfile.DocumentVersionUtils;\r
44 import org.simantics.layer0.Layer0;\r
45 import org.simantics.selectionview.AbstractResourceTabContribution;\r
46 import org.simantics.selectionview.ComparableTabContributor;\r
47 import org.simantics.selectionview.PropertyTabContributorImpl;\r
48 import org.simantics.ui.dnd.LocalObjectTransfer;\r
49 import org.simantics.ui.dnd.ResourceReferenceTransfer;\r
50 import org.simantics.ui.dnd.ResourceTransferUtils;\r
51 import org.simantics.ui.utils.ResourceAdaptionUtils;\r
52 import org.simantics.ui.workbench.editor.EditorAdapter;\r
53 import org.simantics.ui.workbench.editor.EditorRegistry;\r
54 import org.simantics.utils.ui.AdaptionUtils;\r
55 import org.simantics.utils.ui.ErrorLogger;\r
56 import org.simantics.utils.ui.ExceptionUtils;\r
57 \r
58 /**\r
59  * PropertyTab for documents.\r
60  * \r
61  * \r
62  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
63  *\r
64  */\r
65 public class DocumentTabContribution extends AbstractResourceTabContribution{\r
66         \r
67         \r
68         public DocumentTabContribution(ReadGraph graph, Resource r) throws DatabaseException{\r
69                 super(graph,r);\r
70         }\r
71         \r
72         @Override\r
73         public void getContributors(ReadGraph graph, Resource resource,\r
74                         Integer priority, String label,\r
75                         Collection<ComparableTabContributor> result)\r
76                         throws DatabaseException {\r
77                 DocumentResource doc = DocumentResource.getInstance(graph);\r
78                 if (!graph.isInstanceOf(resource, doc.Document))\r
79                         return;\r
80                 result.add(new ComparableTabContributor(new DocumentPropertyTabContributor(), 1, resource, "Document"));\r
81         }\r
82         \r
83         private class DocumentPropertyTabContributor extends PropertyTabContributorImpl {\r
84                 \r
85                 @Override\r
86                 public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, final WidgetSupport support) {\r
87                         \r
88                         Composite composite = new Composite(body, SWT.NONE);\r
89                         GridDataFactory.fillDefaults().grab(true, true).applyTo(composite);\r
90                         GridLayoutFactory.fillDefaults().margins(3,3).spacing(1, 1).numColumns(4).applyTo(composite);\r
91 \r
92                         Label label = new Label(composite, SWT.NONE);\r
93                         label.setText("Name");\r
94 \r
95                         TrackedText name = new TrackedText(composite, support, SWT.BORDER);\r
96                         name.setTextFactory(new StringPropertyFactory(Layer0.URIs.HasName));\r
97                         name.addModifyListener(new StringPropertyModifier(context, Layer0.URIs.HasName));\r
98                         NameInputValidator validator = new NameInputValidator();\r
99                         name.setInputValidator(validator);\r
100                         support.register(validator);\r
101                         \r
102                         Button showButton = new Button(composite, SWT.PUSH);\r
103                         showButton.setText("Show");\r
104                         showButton.addSelectionListener(new SelectionAdapter() {\r
105                                 @Override\r
106                                 public void widgetSelected(SelectionEvent e) {\r
107                                         openResource(AdaptionUtils.adaptToSingle(support.getInput(),Resource.class));\r
108                                 }\r
109                         });\r
110                         DocumentResource doc;\r
111                         try {\r
112                                 doc = DocumentResource.getInstance(context.getSession());\r
113                                 new DocumentRevisionWidget(composite, support, doc.HasOlderVersion, "Old");\r
114                                 new DocumentRevisionWidget(composite, support, doc.HasNewerVersion, "New");\r
115                         } catch (DatabaseException e1) {\r
116                                 ExceptionUtils.logAndShowError("Cannot create documen version UI", e1);\r
117                         }\r
118                         \r
119 \r
120                         GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(name.getWidget());\r
121                         GridDataFactory.fillDefaults().span(2, 1).applyTo(showButton);\r
122                 }\r
123                 \r
124                 @Override\r
125                 public Read<String> getPartNameReadRequest(final ISelection forSelection) {\r
126                         \r
127                         return new Read<String>() {\r
128                                 @Override\r
129                                 public String perform(ReadGraph graph) throws DatabaseException {\r
130                                         Resource res = AdaptionUtils.adaptToSingle(forSelection, Resource.class);\r
131                                         if (res == null)\r
132                                                 return "N/A";\r
133                                         Layer0 l0 = Layer0.getInstance(graph);\r
134                                         return graph.getPossibleRelatedValue(res, l0.HasName);\r
135                                 }\r
136                         };\r
137                 }\r
138         }\r
139         \r
140         private static void openResource(final Resource resource) {\r
141                 Simantics.getSession().asyncRequest(new ReadRequest() {\r
142                         \r
143                         @Override\r
144                         public void run(ReadGraph graph) throws DatabaseException {\r
145                                 openResource(graph, resource);  \r
146                         }\r
147                 });\r
148         }\r
149         \r
150         private static void openResource(ReadGraph graph, final Resource resource) throws DatabaseException{\r
151                 EditorAdapter[] adapters = EditorRegistry.getInstance().getAdaptersFor(graph, resource);\r
152                 if (adapters.length == 0)\r
153                         return;\r
154                 EditorAdapter highPri = null;\r
155                 int pri = Integer.MIN_VALUE;\r
156                 for (EditorAdapter a : adapters) {\r
157                         int p = a.getPriority();\r
158                         if (highPri == null || p > pri) {\r
159                                 highPri = a;\r
160                                 pri = p;\r
161                         } \r
162                 }\r
163                 final EditorAdapter adapter = highPri;\r
164                 \r
165                 Display.getDefault().asyncExec(new Runnable() {\r
166                         \r
167                         @Override\r
168                         public void run() {\r
169                                 try {\r
170                                         adapter.openEditor(resource);\r
171                                 } catch (Exception e) {\r
172                                         ExceptionUtils.logAndShowError("Cannot open editor", e);\r
173                                 }\r
174                         }\r
175                 });\r
176         }\r
177         \r
178         private static class DocumentRevisionWidget implements Widget {\r
179                 ISessionContext context;\r
180                 \r
181                 Resource document;\r
182                 Resource revisionRel;\r
183                 NamedResource revisionDoc;\r
184                 \r
185                 Button showButton;\r
186                 Button removeButton;\r
187                 Text text;\r
188                 \r
189                 public DocumentRevisionWidget(Composite parent, WidgetSupport support, Resource rel, String name) {\r
190                         support.register(this);\r
191                         this.revisionRel = rel;\r
192                         \r
193                         Label label = new Label(parent, SWT.NONE);\r
194                         label.setText(name);\r
195                         text = new Text(parent, SWT.SINGLE|SWT.BORDER|SWT.READ_ONLY);\r
196                         showButton = new Button(parent, SWT.PUSH);\r
197                         showButton.setText("Show");\r
198                         showButton.addSelectionListener(new SelectionAdapter() {\r
199                                 @Override\r
200                                 public void widgetSelected(SelectionEvent e) {\r
201                                         if (revisionDoc != null)\r
202                                                 openResource(revisionDoc.getResource());\r
203                                 }\r
204                         });\r
205                         removeButton = new Button(parent, SWT.PUSH);\r
206                         removeButton.setText("Unset");\r
207                         removeButton.addSelectionListener(new SelectionAdapter() {\r
208                                 @Override\r
209                                 public void widgetSelected(SelectionEvent e) {\r
210                                         if (revisionDoc == null)\r
211                                                 return;\r
212                                         try {\r
213                                                 context.getSession().syncRequest(new WriteRequest() {\r
214                                                         \r
215                                                         @Override\r
216                                                         public void perform(WriteGraph graph) throws DatabaseException {\r
217                                                                 DocumentVersionUtils.unsetVersion(graph, document, revisionDoc.getResource(), revisionRel);\r
218                                                         }\r
219                                                 });\r
220                                                 revisionDoc = null;\r
221                                         } catch (DatabaseException e1) {\r
222                                                 ExceptionUtils.logAndShowError("Cannot remove document revision", e1);\r
223                                         }\r
224                                         updateUI();\r
225                                 }\r
226                         });\r
227                         \r
228                         DropTarget dropTarget = new DropTarget(text, DND.DROP_COPY|DND.DROP_LINK);\r
229                         dropTarget.setTransfer(new Transfer[] { TextTransfer.getInstance(),ResourceReferenceTransfer.getInstance(), LocalObjectTransfer.getTransfer() });\r
230                         dropTarget.addDropListener(new DropTargetAdapter() {\r
231                                 \r
232                                 @Override\r
233                                 public void dragEnter(DropTargetEvent event) {\r
234                                         // drop data is null, so we cannot to validate drop.\r
235                                         event.detail = DND.DROP_LINK;\r
236                                 }\r
237                                 \r
238                                 @Override\r
239                                 public void drop(DropTargetEvent event) {\r
240                                         ResourceArray[] data = parseEventData(event);\r
241                                         if (data.length != 1)\r
242                                                 return;\r
243                                         if (data[0].resources ==null || data[0].resources.length != 1)\r
244                                                 return;\r
245                                         setRevisionDoc(data[0].resources[0]);\r
246                                 }\r
247                                 \r
248                                 private ResourceArray[] parseEventData(DropTargetEvent event) {\r
249                         if (event.data instanceof String) {\r
250                             try {\r
251                                 SerialisationSupport support = context.getSession().getService(SerialisationSupport.class);\r
252                                 return ResourceTransferUtils.readStringTransferable(support, (String) event.data).toResourceArrayArray();\r
253                             } catch (IllegalArgumentException e) {\r
254                                 ErrorLogger.defaultLogError(e);\r
255                             } catch (DatabaseException e) {\r
256                                 ErrorLogger.defaultLogError(e);\r
257                             }\r
258                         }\r
259                         ResourceArray[] ret = ResourceAdaptionUtils.toResourceArrays(event.data);\r
260                         if (ret.length > 0)\r
261                             return ret;\r
262                         return null;\r
263                     }\r
264                         });\r
265                         \r
266                         GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(text);\r
267                         \r
268                 }\r
269                 \r
270                 @Override\r
271                 public void setInput(ISessionContext context, Object input) {\r
272                         this.context = context;\r
273                         document = AdaptionUtils.adaptToSingle(input, Resource.class);\r
274                         \r
275                         context.getSession().asyncRequest(new Read<NamedResource>() {\r
276                                 @Override\r
277                                 public NamedResource perform(ReadGraph graph)\r
278                                                 throws DatabaseException {\r
279                                         Layer0 l0 = Layer0.getInstance(graph);\r
280                                         Resource revisionDoc = graph.getPossibleObject(document, revisionRel);\r
281                                         if (revisionDoc == null)\r
282                                                 return null;\r
283                                         return new NamedResource((String)graph.getRelatedValue(revisionDoc, l0.HasName), revisionDoc);\r
284                                 }\r
285                         },new AsyncListenerAdapter<NamedResource>(){\r
286                                 @Override\r
287                                 public void execute(AsyncReadGraph graph,final NamedResource result) {\r
288                                         Display.getDefault().asyncExec(new Runnable() {\r
289                                                 \r
290                                                 @Override\r
291                                                 public void run() {\r
292                                                         revisionDoc = result;\r
293                                                         updateUI();\r
294                                                 }\r
295                                         });\r
296                                 }\r
297                                 \r
298                                 @Override\r
299                                 public void exception(AsyncReadGraph graph, Throwable t) {\r
300                                         ExceptionUtils.logAndShowError("Cannot show document revision", t);\r
301                                 }\r
302                                 \r
303                                 @Override\r
304                                 public boolean isDisposed() {\r
305                                         return showButton.isDisposed();\r
306                                 }\r
307                         });\r
308                         \r
309                         \r
310                         updateUI();\r
311                 }\r
312                 \r
313                 private void updateUI() {\r
314                         if (showButton.isDisposed())\r
315                                 return;\r
316                         showButton.setEnabled(revisionDoc != null);\r
317                         removeButton.setEnabled(revisionDoc != null);\r
318                         if (revisionDoc != null)\r
319                                 text.setText(revisionDoc.getName());\r
320                         else\r
321                                 text.setText("");\r
322                 }\r
323                 \r
324                 private void setRevisionDoc(final Resource toSet) {\r
325                         context.getSession().asyncRequest(new WriteRequest() {\r
326                                 \r
327                                 @Override\r
328                                 public void perform(WriteGraph graph) throws DatabaseException {\r
329                                         DocumentVersionUtils.setVersion(graph, document, toSet, revisionRel);\r
330                                 }\r
331                         });\r
332                 }\r
333                 \r
334         }\r
335 \r
336 \r
337 }\r