]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java
76b5abe95c48559e3a384506b4ad5e3b2582e2a6
[simantics/platform.git] / bundles / org.simantics.document.ui / src / org / simantics / document / ui / function / All.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.document.ui.function;
13
14 import java.util.TreeMap;
15
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.Status;
18 import org.eclipse.jface.viewers.ISelectionProvider;
19 import org.eclipse.jface.viewers.StructuredSelection;
20 import org.eclipse.swt.browser.LocationEvent;
21 import org.eclipse.swt.graphics.FontData;
22 import org.eclipse.swt.graphics.Point;
23 import org.eclipse.swt.graphics.RGB;
24 import org.eclipse.swt.widgets.Display;
25 import org.eclipse.swt.widgets.Event;
26 import org.eclipse.swt.widgets.FontDialog;
27 import org.eclipse.swt.widgets.TreeItem;
28 import org.eclipse.ui.PartInitException;
29 import org.eclipse.ui.PlatformUI;
30 import org.simantics.Simantics;
31 import org.simantics.browsing.ui.BuiltinKeys;
32 import org.simantics.browsing.ui.NodeContext;
33 import org.simantics.databoard.Bindings;
34 import org.simantics.db.ReadGraph;
35 import org.simantics.db.Resource;
36 import org.simantics.db.Session;
37 import org.simantics.db.WriteGraph;
38 import org.simantics.db.common.request.ReadRequest;
39 import org.simantics.db.common.request.UnaryRead;
40 import org.simantics.db.common.request.WriteRequest;
41 import org.simantics.db.common.utils.Logger;
42 import org.simantics.db.common.utils.NameUtils;
43 import org.simantics.db.common.utils.RequestUtil;
44 import org.simantics.db.exception.DatabaseException;
45 import org.simantics.db.layer0.adapter.Instances;
46 import org.simantics.db.layer0.request.PossibleModel;
47 import org.simantics.db.layer0.request.PossibleResource;
48 import org.simantics.db.layer0.util.RemoverUtil;
49 import org.simantics.db.layer0.variable.RVI;
50 import org.simantics.db.layer0.variable.Variable;
51 import org.simantics.db.layer0.variable.Variables;
52 import org.simantics.document.DocumentDialect;
53 import org.simantics.document.DocumentResource;
54 import org.simantics.document.DocumentUtils;
55 import org.simantics.document.ui.Activator;
56 import org.simantics.document.ui.CSSEditor;
57 import org.simantics.layer0.Layer0;
58 import org.simantics.scenegraph.INode;
59 import org.simantics.scenegraph.loader.ScenegraphLoaderProcess;
60 import org.simantics.scenegraph.loader.ScenegraphLoaderUtils;
61 import org.simantics.scenegraph.loader.ScenegraphLoaderUtils.ScenegraphPropertyReference;
62 import org.simantics.scl.reflection.annotations.SCLValue;
63 import org.simantics.scl.runtime.function.Function1;
64 import org.simantics.scl.runtime.function.FunctionImpl1;
65 import org.simantics.scl.runtime.function.FunctionImpl3;
66 import org.simantics.ui.SimanticsUI;
67 import org.simantics.ui.workbench.ResourceEditorInput2;
68 import org.simantics.ui.workbench.action.DefaultActions;
69 import org.simantics.utils.threads.SWTThread;
70 import org.simantics.utils.ui.workbench.WorkbenchUtils;
71
72
73 public class All {
74
75         private static boolean createDocument(WriteGraph graph, Resource resource, Resource model) throws DatabaseException {
76
77                 Layer0 L0 = Layer0.getInstance(graph);
78                 DocumentResource DOC = DocumentResource.getInstance(graph);
79
80                 if(graph.hasStatement(resource, DOC.HasDocumentation)) return true;
81                 
82                 Instances query = graph.adapt(DOC.DocumentTypeBinding, Instances.class);
83                 
84                 TreeMap<Double, Resource> bindings = new TreeMap<Double, Resource>();
85                 for(Resource binding : query.find(graph, model)) {
86                         double priority = graph.getRelatedValue2(binding, DOC.DocumentTypeBinding_priority, Bindings.DOUBLE);
87                         Resource type = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasType);
88                         if(graph.isInstanceOf(resource, type)) {
89                                 bindings.put(priority, binding);
90                         }
91                 }
92                 
93                 if(bindings.isEmpty()) return false;
94                 
95                 Resource binding = bindings.lastEntry().getValue();
96                                 
97                 Resource documentType = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasDocumentType);
98                 Resource document = graph.newResource();
99                 graph.claim(document, L0.InstanceOf, null, DOC.ScenegraphDocument);
100                 graph.claimLiteral(document, L0.HasName, "Documentation");
101                 graph.claim(resource, DOC.HasDocumentation, document);
102                 graph.claim(document, L0.PartOf, resource);
103
104                 Resource scenegraph = graph.newResource();
105                 graph.claim(scenegraph, L0.InstanceOf, null, documentType);
106                 graph.claimLiteral(scenegraph, L0.HasName, "Scenegraph");
107                 graph.claim(scenegraph, L0.PartOf, document);
108                 graph.claim(document, DOC.ScenegraphDocument_scenegraph, scenegraph);
109
110                 return true;
111                 
112         }
113
114     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
115     public static Object onCreateDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
116
117         return new FunctionImpl1<Object, Object>() {
118
119                         @Override
120                         public Object apply(Object _o) {
121                                 
122                                 Simantics.async(new ReadRequest() {
123
124                                         @Override
125                                         public void run(ReadGraph graph) throws DatabaseException {
126                                                 
127                                         Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
128                                         if(selection == null) return;
129                                         
130                                                 final Resource input = selection.getRepresents(graph);
131                                         if(input == null) return;
132                                                 
133                                         graph.async(new WriteRequest() {
134
135                                                         @Override
136                                                         public void perform(WriteGraph graph) throws DatabaseException {
137                                                                 
138                                                                 Resource model = graph.sync(new PossibleModel(input));
139                                                                 if(model == null) return;
140                                                                 createDocument(graph, input, model);
141                                                                 
142                                                         }
143                                                 
144                                         });
145                                         
146                                         }
147                                         
148                                 });
149                                 
150                                 return true;
151                                 
152                         }
153                         
154                 };
155         
156     }
157
158     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
159     public static Object onDeleteDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
160
161         return new FunctionImpl1<Object, Object>() {
162
163                         @Override
164                         public Object apply(Object _o) {
165                                 
166                                 Simantics.async(new ReadRequest() {
167
168                                         @Override
169                                         public void run(ReadGraph graph) throws DatabaseException {
170                                                 
171                                         Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
172                                         if(selection == null) return;
173                                         
174                                                 final Resource input = selection.getRepresents(graph);
175                                         if(input == null) return;
176                                         
177                                                 DocumentResource DOC = DocumentResource.getInstance(graph);
178                                                 if(!graph.hasStatement(input, DOC.HasDocumentation)) return;
179                                                 
180                                         graph.async(new WriteRequest() {
181
182                                                         @Override
183                                                         public void perform(WriteGraph graph) throws DatabaseException {
184                                                                 
185                                                                 DocumentResource DOC = DocumentResource.getInstance(graph);
186                                                                 Resource document = graph.getPossibleObject(input, DOC.HasDocumentation);
187                                                                 if(document == null) return;
188                                                                 
189                                                                 RemoverUtil.remove(graph, document);
190                                                                 
191                                                         }
192                                                 
193                                         });
194                                         
195                                         }
196                                         
197                                 });
198                                 
199                                 return true;
200                                 
201                         }
202                         
203                 };
204         
205     }
206     
207     @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
208     public static Object editorLoaded(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
209         
210         return new FunctionImpl3<WriteGraph, Variable, Variable, Boolean>() {
211
212                         @Override
213                         public Boolean apply(WriteGraph graph, Variable editor, Variable input) {
214
215 //                              try {
216 //                                      return createDocument(graph, input);
217 //                              } catch (DatabaseException e) {
218 //                                      Logger.defaultLogError(e);
219 //                              }
220
221                                 return true;
222                                 
223                         }
224                 
225         };
226         
227     }
228
229     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
230     public static Boolean hasDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
231         
232                 DocumentResource DOC = DocumentResource.getInstance(graph);
233                 
234         Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
235         if(selection == null) return false;
236         
237                 Resource input = selection.getRepresents(graph);
238         if(input == null) return null;
239         
240                 return graph.hasStatement(input, DOC.HasDocumentation);
241         
242     }
243
244     @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
245     public static Object viewInputChanged(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
246         
247         return new FunctionImpl1<Variable, Boolean>() {
248
249                         @Override
250                         public Boolean apply(final Variable viewVariable) {
251                                 return true;
252                         }
253                 
254         };
255         
256     }
257     
258         
259     @SCLValue(type = "ReadGraph -> Variable -> Boolean")
260     public static Boolean isWikitext(ReadGraph graph, Variable context) throws DatabaseException {
261         Layer0 L0 = Layer0.getInstance(graph);
262         DocumentResource DOC = DocumentResource.getInstance(graph);
263         Resource p = context.getPossiblePredicateResource(graph);
264         if (p == null)
265             return Boolean.FALSE;
266         Resource range = graph.getPossibleObject(p, L0.HasRange);
267         return DOC.WikiDocument_WikiText.equals(range);
268     }
269     
270     private static Variable getDefaultSelection(ReadGraph graph, Variable context) throws DatabaseException {
271         
272                 DocumentResource DOC = DocumentResource.getInstance(graph);
273         Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
274         
275         Resource represents = sel.getRepresents(graph);
276         Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
277         Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
278         
279         Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
280                 INode root = runtime.adapt(graph, INode.class);
281
282         Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
283         if(result != null) {
284                 Variable userDoc = result.getPossibleProperty(graph, "UserDocumentation");
285                 if(userDoc != null) return userDoc;
286         }
287         
288         return null;
289         
290     }
291     
292     private static Variable resolveEditSelection(ReadGraph graph, Variable context, String path) throws DatabaseException {
293         
294                 final ScenegraphPropertyReference<Variable> selectionReference = 
295                                 ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, path);
296                 
297                 Variable editSelection = selectionReference.getExternalValue(graph);
298                 if(editSelection == null) editSelection = getDefaultSelection(graph, context);
299                 
300                 return editSelection;
301         
302     }
303
304     @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
305     public static Object wikitextModifier(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
306         
307                 final ScenegraphPropertyReference<String> textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
308         
309         return new FunctionImpl1<Object, Object>() {
310
311                         @Override
312                         public Object apply(final Object event) {
313             
314                                 final String value = textReference.getValue();
315
316                                 try {
317                                         Simantics.getSession().sync(new WriteRequest() {
318
319                                                 @Override
320                                                 public void perform(WriteGraph graph) throws DatabaseException {
321                                                         
322                                                         Variable selection = resolveEditSelection(graph, context, "..../Scroll/Browser#edited");
323                                                         if (selection != null)
324                                                             selection.setValue(graph, (String)value, Bindings.STRING);
325                                                         else {
326                                                                 System.err.println("no selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);
327                                                         }
328                                                 }
329                                                 
330                                         });
331                                 } catch (DatabaseException e) {
332                                         e.printStackTrace();
333                                 }
334                                 return null;
335                         }
336                 
337         };
338     }
339     
340     @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
341     public static String wikitext(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
342         Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
343         return selection.getValue(graph);
344     }
345
346     @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
347     public static String selectedDocumentPart(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
348
349                 Variable selection = resolveEditSelection(graph, context, ".../Scroll/Browser#edited");
350                 if(selection == null) return null;
351
352         return selection.getValue(graph);
353         
354     }
355     
356     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
357     public static Object documentStructureSelected(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
358         
359         return new FunctionImpl1<Object, Boolean>() {
360                 
361             @Override
362             public Boolean apply(Object _event) {
363                 
364                 Event event = (Event)_event;
365                 
366                 final TreeItem item = (TreeItem)event.item;
367                 NodeContext context = (NodeContext)item.getData();
368                 final Variable entry = (Variable)context.getConstant(BuiltinKeys.INPUT);
369                 
370                 ISelectionProvider provider = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();
371                 provider.setSelection(new StructuredSelection(entry));
372                 
373                 return null;
374                 
375             }
376                 
377         };
378         
379     }
380
381     abstract static class WikiButtonModifier extends FunctionImpl1<Object, Object> {
382
383                 final ScenegraphPropertyReference<String> textReference;
384                 final ScenegraphPropertyReference<Point> selectionReference;
385
386         public WikiButtonModifier(ReadGraph graph, Variable context) throws DatabaseException {
387                 textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
388                 selectionReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#selection");
389         }
390         
391         abstract void perform(String before, String selected, String after, Point selection);
392         
393             @Override
394             public Object apply(Object _event) {
395                 String text = textReference.getValue();
396                 Point selection = selectionReference.getValue(); 
397                 String before = text.substring(0, selection.x);
398                 String selected = text.substring(selection.x, selection.y);
399                 String after = text.substring(selection.y);
400                 perform(before, selected, after, selection);
401                 return null;
402             }
403
404     }
405     
406     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
407     public static Object boldModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
408
409         return new WikiButtonModifier(graph, context) {
410                         
411                         @Override
412                         void perform(String before, String selected, String after, Point selection) {
413
414                                 if(selected.isEmpty()) {
415                                         textReference.setValue(before + "'''bold text'''" + after);
416                                 } else {
417                                         textReference.setValue(before + "'''" + selected + "'''" + after);      
418                                 }
419                                 
420                         }
421                         
422                 };
423         
424     }
425
426     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
427     public static Object italicModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
428
429         return new WikiButtonModifier(graph, context) {
430                         
431                         @Override
432                         void perform(String before, String selected, String after, Point selection) {
433
434                                 if(selected.isEmpty()) {
435                                         textReference.setValue(before + "''italic text''" + after);
436                                 } else {
437                                         textReference.setValue(before + "''" + selected + "''" + after);        
438                                 }
439                                 
440                         }
441                         
442                 };
443         
444     }
445     
446     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
447     public static Object strikethroughModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
448
449         return new WikiButtonModifier(graph, context) {
450                         
451                         @Override
452                         void perform(String before, String selected, String after, Point selection) {
453
454                                 if(selected.isEmpty()) {
455                                         textReference.setValue(before + "<span style=\"text-decoration:line-through;\">strikethrough text</span>" + after);
456                                 } else {
457                                         textReference.setValue(before + "<span style=\"text-decoration:line-through;\">" + selected + "</span>" + after);       
458                                 }
459                                 
460                         }
461                         
462                 };
463         
464     }
465
466     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
467     public static Object underlineModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
468
469         return new WikiButtonModifier(graph, context) {
470                         
471                         @Override
472                         void perform(String before, String selected, String after, Point selection) {
473
474                                 if(selected.isEmpty()) {
475                                         textReference.setValue(before + "<span style=\"text-decoration:underline;\">strikethrough text</span>" + after);
476                                 } else {
477                                         textReference.setValue(before + "<span style=\"text-decoration:underline;\">" + selected + "</span>" + after);  
478                                 }
479                                 
480                         }
481                         
482                 };
483         
484     }
485
486     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
487     public static Object horizontalRulerModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
488
489         return new WikiButtonModifier(graph, context) {
490                         
491                         @Override
492                         void perform(String before, String selected, String after, Point selection) {
493
494                                 textReference.setValue(before + "\r\n<hr/>\r\n" + selected + after);
495                                 
496                         }
497                         
498                 };
499         
500     }
501     
502     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
503     public static Object indentModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
504
505         return new WikiButtonModifier(graph, context) {
506                         
507                         @Override
508                         void perform(String before, String selected, String after, Point selection) {
509
510                                 textReference.setValue(before + ":" + selected + after);
511                                 
512                         }
513                         
514                 };
515         
516     }
517
518     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
519     public static Object fontModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
520
521         return new WikiButtonModifier(graph, context) {
522                         
523                 private String hex2(int value) {
524                         String result = Integer.toHexString(value);
525                         if(result.length() == 1) result = "0" + result;
526                         return result;
527                 }
528                 
529                         @Override
530                         void perform(String before, String selected, String after, Point selection) {
531
532                                 FontDialog dialog = new FontDialog(Display.getCurrent().getActiveShell()); 
533                                 FontData data = dialog.open();
534                                 if(data == null) return;
535
536                                 String family = data.getName();
537                                 int size = data.getHeight();
538                                 
539                                 RGB rgb = dialog.getRGB();
540                                 String hex = hex2(rgb.red) + hex2(rgb.green) + hex2(rgb.blue);
541
542                                 if(selected.isEmpty()) {
543                                         textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >formatted text</font>" + selected + after);
544                                 } else {
545                                         textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >" + selected + "</font>" + after);
546                                 }
547                                 
548                         }
549                         
550                 };
551         
552     }
553
554     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
555     public static Object imageModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
556
557         return new WikiButtonModifier(graph, context) {
558                 
559                         @Override
560                         void perform(String before, String selected, String after, Point selection) {
561
562                                 textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + "\r\n" + selected + after);
563                                 
564                         }
565                         
566                 };
567         
568     }
569     
570     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
571     public static Object header1Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
572
573         return new WikiButtonModifier(graph, context) {
574                         
575                         @Override
576                         void perform(String before, String selected, String after, Point selection) {
577
578                                 textReference.setValue(before + "\r\n= Header 1 =\r\n" + selected + after);
579                                 
580                         }
581                         
582                 };
583         
584     }
585
586     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
587     public static Object header2Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
588
589         return new WikiButtonModifier(graph, context) {
590                         
591                         @Override
592                         void perform(String before, String selected, String after, Point selection) {
593
594                                 textReference.setValue(before + "\r\n== Header 2 ==\r\n" + selected + after);
595                                 
596                         }
597                         
598                 };
599         
600     }
601
602     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
603     public static Object header3Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
604
605         return new WikiButtonModifier(graph, context) {
606                         
607                         @Override
608                         void perform(String before, String selected, String after, Point selection) {
609
610                                 textReference.setValue(before + "\r\n=== Header 3 ===\r\n" + selected + after);
611                                 
612                         }
613                         
614                 };
615         
616     }
617     
618     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
619     public static Object header4Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
620
621         return new WikiButtonModifier(graph, context) {
622                         
623                         @Override
624                         void perform(String before, String selected, String after, Point selection) {
625
626                                 textReference.setValue(before + "\r\n==== Header 4 ====\r\n" + selected + after);
627                                 
628                         }
629                         
630                 };
631         
632     }
633     
634     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
635     public static Object numberedListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
636
637         return new WikiButtonModifier(graph, context) {
638                         
639                         @Override
640                         void perform(String before, String selected, String after, Point selection) {
641
642                                 textReference.setValue(before + "\r\n" +
643                                                 "# Item1\r\n" + 
644                                                 "# Item2\r\n" + 
645                                                 "## Item2.1\r\n" + 
646                                                 "# Item3\r\n" + selected + after);
647                                 
648                         }
649                         
650                 };
651         
652     }
653
654     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
655     public static Object bulletListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
656
657         return new WikiButtonModifier(graph, context) {
658                         
659                         @Override
660                         void perform(String before, String selected, String after, Point selection) {
661
662                                 textReference.setValue(before + "\r\n" +
663                                                 "* Item1\r\n" + 
664                                                 "* Item2\r\n" + 
665                                                 "** Item2.1\r\n" + 
666                                                 "* Item3\r\n" + selected + after);
667                                 
668                         }
669                         
670                 };
671         
672     }
673     
674     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
675     public static Object tableModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
676
677         return new WikiButtonModifier(graph, context) {
678                         
679                         @Override
680                         void perform(String before, String selected, String after, Point selection) {
681
682                                 textReference.setValue(before + "\r\n" +
683                                                 "{| border=\"1\"\r\n" + 
684                                                 "! header\r\n" +
685                                                 "! header2 \r\n" +
686                                                 "|-\r\n" +
687                                                 "| cell || cell2\r\n" + 
688                                                 "|-\r\n" +
689                                                 "| cell3\r\n" + 
690                                                 "| cell4\r\n" + 
691                                                 "|}\r\n"  + selected + after);
692                                 
693                         }
694                         
695                 };
696         
697     }
698
699     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
700     public static Object internalLinkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
701         return new WikiButtonModifier(graph, context) {
702             @Override
703             void perform(String before, String selected, String after, Point selection) {
704                 textReference.setValue(before +
705                         "[[Media:root://Documents/Document.pdf|Link to a file within the model]]\r\n" + selected + after);
706                 
707             }
708         };
709     }
710     
711     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
712     public static Object linkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
713
714         return new WikiButtonModifier(graph, context) {
715                         
716                         @Override
717                         void perform(String before, String selected, String after, Point selection) {
718
719                                 textReference.setValue(before +
720                                                 "[http://www.simantics.org External Website Link]\r\n" + selected + after);
721                                 
722                         }
723                         
724                 };
725         
726     }
727     
728     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
729     public static Object styleModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
730
731         return new WikiButtonModifier(graph, context) {
732                         
733                         @Override
734                         void perform(String before, String selected, String after, Point selection) {
735
736                                 Simantics.getSession().asyncRequest(new ReadRequest() {
737
738                                         @Override
739                                         public void run(ReadGraph graph) throws DatabaseException {
740
741                                         Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
742                                         Resource root = sel.getIndexRoot(graph);
743                                         String editorId = CSSEditor.EDITOR_ID;
744                                 RVI rvi = null;
745
746                                 PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
747                                         
748                                     @Override
749                                     public void run() {
750
751                                                     try {
752                                                                         WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));
753                                                                 } catch (PartInitException e) {
754                                                                         Logger.defaultLogError(e);
755                                                                 }
756                                         
757                                     }
758                                     
759                                 });
760
761                                         }
762                                         
763                                 });
764                                 
765                         }
766                         
767                 };
768         
769     }
770     
771     
772 //    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
773 //    public static Object navigate(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
774 //      
775 //      return new FunctionImpl1<String, Boolean>() {
776 //
777 //                      @Override
778 //                      public Boolean apply(final String path) {
779 //                              
780 //                              Simantics.getSession().asyncRequest(new ReadRequest() {
781 //
782 //                                      @Override
783 //                                      public void run(ReadGraph graph) throws DatabaseException {
784 //                                              
785 //                                              DocumentResource DOC = DocumentResource.getInstance(graph);
786 //                                      Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
787 //                                      
788 //                                      Resource represents = sel.getRepresents(graph);
789 //                                      Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
790 //                                      Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
791 //                                      
792 //                                      Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
793 //                                              INode root = runtime.adapt(graph, INode.class);
794 //                                      
795 //                                      Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
796 //                                      Variable location = result.browse(graph, path);
797 //                                              
798 //                                              ScenegraphPropertyReference<Variable> editReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".#edited");
799 //                                              editReference.setValue(location);
800 //                                              
801 //                                      }
802 //                                      
803 //                              });
804 //                              
805 //                              return null;
806 //                              
807 //                      }
808 //              
809 //      };
810 //      
811 //    }
812
813     @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
814     public static String noDocumentText(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
815                 
816         Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
817         if(selection == null) return "<no input>";
818         
819                 Resource input = selection.getRepresents(graph);
820         if(input == null) return "<no input>";
821         
822         String path = DocumentUtils.indexRootPath(graph, selection);
823         if(!path.isEmpty()) {
824                 return "for " + path + selection.getName(graph);
825         }
826         
827                 return "for " + NameUtils.getSafeLabel(graph, input);
828         
829     }
830
831     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
832     public static Boolean canCreateDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
833                 
834         Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
835         if(selection == null) return false;
836         
837                 Resource input = selection.getRepresents(graph);
838         if(input == null) return false;
839         
840         return true;
841         
842     }
843
844     private static class ResolveURI extends UnaryRead<String, Object> {
845         public ResolveURI(String uri) {
846             super(uri);
847         }
848         @Override
849         public Object perform(ReadGraph graph) throws DatabaseException {
850             Object result = graph.syncRequest(new PossibleResource(parameter));
851             if (result == null)
852                 result = Variables.getPossibleVariable(graph, parameter);
853             return result;
854         }
855     }
856
857     private static final Function1<Object, Boolean> PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE = new Function1<Object, Boolean>() {
858         @Override
859         public Boolean apply(Object p0) {
860             LocationEvent le = (LocationEvent) p0;
861             if (le.location.startsWith(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX)) {
862                 // This is not a valid URL anyway so deny relocation.
863                 le.doit = false;
864
865                 // Try to execute default action for the resource or variable
866                 // that the URI represents.
867                 String uri = le.location.substring(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX.length());
868                 try {
869                     Session s = Simantics.getSession();
870                     Object input = RequestUtil.trySyncRequest(s,
871                             SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
872                             SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,
873                             new ResolveURI(uri));
874                     if (input != null) {
875                         DefaultActions.asyncPerformDefaultAction(s, input, false, false, false);
876                     }
877                 } catch (DatabaseException | InterruptedException e) {
878                     Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to resolve URI to a database resource or variable: " + uri, e));
879                 }
880             }
881             return true;
882         }
883     };
884
885     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
886     public static Function1<Object, Boolean> locationChanging(ReadGraph graph, Resource variable, Variable context) throws DatabaseException {
887         return PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE;
888     }
889
890 }