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