]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.document.ui / src / org / simantics / document / ui / function / All.java
index e5f8b439238c9b1709a2f4d13e6d3df38527e831..76b5abe95c48559e3a384506b4ad5e3b2582e2a6 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.document.ui.function;\r
-\r
-import java.util.TreeMap;\r
-\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.Status;\r
-import org.eclipse.jface.viewers.ISelectionProvider;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.eclipse.swt.browser.LocationEvent;\r
-import org.eclipse.swt.graphics.FontData;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.graphics.RGB;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.FontDialog;\r
-import org.eclipse.swt.widgets.TreeItem;\r
-import org.eclipse.ui.PartInitException;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.simantics.Simantics;\r
-import org.simantics.browsing.ui.BuiltinKeys;\r
-import org.simantics.browsing.ui.NodeContext;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.common.utils.RequestUtil;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.adapter.Instances;\r
-import org.simantics.db.layer0.request.PossibleModel;\r
-import org.simantics.db.layer0.request.PossibleResource;\r
-import org.simantics.db.layer0.util.RemoverUtil;\r
-import org.simantics.db.layer0.variable.RVI;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.document.DocumentDialect;\r
-import org.simantics.document.DocumentResource;\r
-import org.simantics.document.DocumentUtils;\r
-import org.simantics.document.ui.Activator;\r
-import org.simantics.document.ui.CSSEditor;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.scenegraph.INode;\r
-import org.simantics.scenegraph.loader.ScenegraphLoaderProcess;\r
-import org.simantics.scenegraph.loader.ScenegraphLoaderUtils;\r
-import org.simantics.scenegraph.loader.ScenegraphLoaderUtils.ScenegraphPropertyReference;\r
-import org.simantics.scl.reflection.annotations.SCLValue;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.scl.runtime.function.FunctionImpl1;\r
-import org.simantics.scl.runtime.function.FunctionImpl3;\r
-import org.simantics.ui.SimanticsUI;\r
-import org.simantics.ui.workbench.ResourceEditorInput2;\r
-import org.simantics.ui.workbench.action.DefaultActions;\r
-import org.simantics.utils.threads.SWTThread;\r
-import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
-\r
-\r
-public class All {\r
-\r
-       private static boolean createDocument(WriteGraph graph, Resource resource, Resource model) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               DocumentResource DOC = DocumentResource.getInstance(graph);\r
-\r
-               if(graph.hasStatement(resource, DOC.HasDocumentation)) return true;\r
-               \r
-               Instances query = graph.adapt(DOC.DocumentTypeBinding, Instances.class);\r
-               \r
-               TreeMap<Double, Resource> bindings = new TreeMap<Double, Resource>();\r
-               for(Resource binding : query.find(graph, model)) {\r
-                       double priority = graph.getRelatedValue2(binding, DOC.DocumentTypeBinding_priority, Bindings.DOUBLE);\r
-                       Resource type = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasType);\r
-                       if(graph.isInstanceOf(resource, type)) {\r
-                               bindings.put(priority, binding);\r
-                       }\r
-               }\r
-               \r
-               if(bindings.isEmpty()) return false;\r
-               \r
-               Resource binding = bindings.lastEntry().getValue();\r
-                               \r
-               Resource documentType = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasDocumentType);\r
-               Resource document = graph.newResource();\r
-               graph.claim(document, L0.InstanceOf, null, DOC.ScenegraphDocument);\r
-               graph.claimLiteral(document, L0.HasName, "Documentation");\r
-               graph.claim(resource, DOC.HasDocumentation, document);\r
-               graph.claim(document, L0.PartOf, resource);\r
-\r
-               Resource scenegraph = graph.newResource();\r
-               graph.claim(scenegraph, L0.InstanceOf, null, documentType);\r
-               graph.claimLiteral(scenegraph, L0.HasName, "Scenegraph");\r
-               graph.claim(scenegraph, L0.PartOf, document);\r
-               graph.claim(document, DOC.ScenegraphDocument_scenegraph, scenegraph);\r
-\r
-               return true;\r
-               \r
-       }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object onCreateDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new FunctionImpl1<Object, Object>() {\r
-\r
-                       @Override\r
-                       public Object apply(Object _o) {\r
-                               \r
-                               Simantics.async(new ReadRequest() {\r
-\r
-                                       @Override\r
-                                       public void run(ReadGraph graph) throws DatabaseException {\r
-                                               \r
-                                       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);\r
-                                       if(selection == null) return;\r
-                                       \r
-                                               final Resource input = selection.getRepresents(graph);\r
-                                       if(input == null) return;\r
-                                               \r
-                                       graph.async(new WriteRequest() {\r
-\r
-                                                       @Override\r
-                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                               \r
-                                                               Resource model = graph.sync(new PossibleModel(input));\r
-                                                               if(model == null) return;\r
-                                                               createDocument(graph, input, model);\r
-                                                               \r
-                                                       }\r
-                                               \r
-                                       });\r
-                                       \r
-                                       }\r
-                                       \r
-                               });\r
-                               \r
-                               return true;\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object onDeleteDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new FunctionImpl1<Object, Object>() {\r
-\r
-                       @Override\r
-                       public Object apply(Object _o) {\r
-                               \r
-                               Simantics.async(new ReadRequest() {\r
-\r
-                                       @Override\r
-                                       public void run(ReadGraph graph) throws DatabaseException {\r
-                                               \r
-                                       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);\r
-                                       if(selection == null) return;\r
-                                       \r
-                                               final Resource input = selection.getRepresents(graph);\r
-                                       if(input == null) return;\r
-                                       \r
-                                               DocumentResource DOC = DocumentResource.getInstance(graph);\r
-                                               if(!graph.hasStatement(input, DOC.HasDocumentation)) return;\r
-                                               \r
-                                       graph.async(new WriteRequest() {\r
-\r
-                                                       @Override\r
-                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                               \r
-                                                               DocumentResource DOC = DocumentResource.getInstance(graph);\r
-                                                               Resource document = graph.getPossibleObject(input, DOC.HasDocumentation);\r
-                                                               if(document == null) return;\r
-                                                               \r
-                                                               RemoverUtil.remove(graph, document);\r
-                                                               \r
-                                                       }\r
-                                               \r
-                                       });\r
-                                       \r
-                                       }\r
-                                       \r
-                               });\r
-                               \r
-                               return true;\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
-    public static Object editorLoaded(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-       \r
-       return new FunctionImpl3<WriteGraph, Variable, Variable, Boolean>() {\r
-\r
-                       @Override\r
-                       public Boolean apply(WriteGraph graph, Variable editor, Variable input) {\r
-\r
-//                             try {\r
-//                                     return createDocument(graph, input);\r
-//                             } catch (DatabaseException e) {\r
-//                                     Logger.defaultLogError(e);\r
-//                             }\r
-\r
-                               return true;\r
-                               \r
-                       }\r
-               \r
-       };\r
-       \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")\r
-    public static Boolean hasDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-       \r
-               DocumentResource DOC = DocumentResource.getInstance(graph);\r
-               \r
-       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);\r
-       if(selection == null) return false;\r
-       \r
-               Resource input = selection.getRepresents(graph);\r
-       if(input == null) return null;\r
-       \r
-               return graph.hasStatement(input, DOC.HasDocumentation);\r
-       \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
-    public static Object viewInputChanged(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-       \r
-       return new FunctionImpl1<Variable, Boolean>() {\r
-\r
-                       @Override\r
-                       public Boolean apply(final Variable viewVariable) {\r
-                               return true;\r
-                       }\r
-               \r
-       };\r
-       \r
-    }\r
-    \r
-       \r
-    @SCLValue(type = "ReadGraph -> Variable -> Boolean")\r
-    public static Boolean isWikitext(ReadGraph graph, Variable context) throws DatabaseException {\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       DocumentResource DOC = DocumentResource.getInstance(graph);\r
-       Resource p = context.getPossiblePredicateResource(graph);\r
-       if (p == null)\r
-           return Boolean.FALSE;\r
-       Resource range = graph.getPossibleObject(p, L0.HasRange);\r
-       return DOC.WikiDocument_WikiText.equals(range);\r
-    }\r
-    \r
-    private static Variable getDefaultSelection(ReadGraph graph, Variable context) throws DatabaseException {\r
-       \r
-               DocumentResource DOC = DocumentResource.getInstance(graph);\r
-       Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);\r
-       \r
-       Resource represents = sel.getRepresents(graph);\r
-       Resource doc = graph.getSingleObject(represents, DOC.HasDocument);\r
-       Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);\r
-       \r
-       Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);\r
-               INode root = runtime.adapt(graph, INode.class);\r
-\r
-       Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);\r
-       if(result != null) {\r
-               Variable userDoc = result.getPossibleProperty(graph, "UserDocumentation");\r
-               if(userDoc != null) return userDoc;\r
-       }\r
-       \r
-       return null;\r
-       \r
-    }\r
-    \r
-    private static Variable resolveEditSelection(ReadGraph graph, Variable context, String path) throws DatabaseException {\r
-       \r
-               final ScenegraphPropertyReference<Variable> selectionReference = \r
-                               ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, path);\r
-               \r
-               Variable editSelection = selectionReference.getExternalValue(graph);\r
-               if(editSelection == null) editSelection = getDefaultSelection(graph, context);\r
-               \r
-               return editSelection;\r
-       \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
-    public static Object wikitextModifier(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-       \r
-               final ScenegraphPropertyReference<String> textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");\r
-       \r
-       return new FunctionImpl1<Object, Object>() {\r
-\r
-                       @Override\r
-                       public Object apply(final Object event) {\r
-           \r
-                               final String value = textReference.getValue();\r
-\r
-                               try {\r
-                                       Simantics.getSession().sync(new WriteRequest() {\r
-\r
-                                               @Override\r
-                                               public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                       \r
-                                                       Variable selection = resolveEditSelection(graph, context, "..../Scroll/Browser#edited");\r
-                                                       if (selection != null)\r
-                                                           selection.setValue(graph, (String)value, Bindings.STRING);\r
-                                                       else {\r
-                                                               System.err.println("no selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);\r
-                                                       }\r
-                                               }\r
-                                               \r
-                                       });\r
-                               } catch (DatabaseException e) {\r
-                                       e.printStackTrace();\r
-                               }\r
-                               return null;\r
-                       }\r
-               \r
-       };\r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
-    public static String wikitext(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
-       Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);\r
-       return selection.getValue(graph);\r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
-    public static String selectedDocumentPart(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
-\r
-               Variable selection = resolveEditSelection(graph, context, ".../Scroll/Browser#edited");\r
-               if(selection == null) return null;\r
-\r
-       return selection.getValue(graph);\r
-       \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object documentStructureSelected(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
-       \r
-       return new FunctionImpl1<Object, Boolean>() {\r
-               \r
-           @Override\r
-           public Boolean apply(Object _event) {\r
-               \r
-               Event event = (Event)_event;\r
-               \r
-               final TreeItem item = (TreeItem)event.item;\r
-               NodeContext context = (NodeContext)item.getData();\r
-               final Variable entry = (Variable)context.getConstant(BuiltinKeys.INPUT);\r
-               \r
-               ISelectionProvider provider = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();\r
-               provider.setSelection(new StructuredSelection(entry));\r
-               \r
-               return null;\r
-               \r
-           }\r
-               \r
-       };\r
-        \r
-    }\r
-\r
-    abstract static class WikiButtonModifier extends FunctionImpl1<Object, Object> {\r
-\r
-               final ScenegraphPropertyReference<String> textReference;\r
-               final ScenegraphPropertyReference<Point> selectionReference;\r
-\r
-       public WikiButtonModifier(ReadGraph graph, Variable context) throws DatabaseException {\r
-               textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");\r
-               selectionReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#selection");\r
-       }\r
-       \r
-       abstract void perform(String before, String selected, String after, Point selection);\r
-       \r
-           @Override\r
-           public Object apply(Object _event) {\r
-               String text = textReference.getValue();\r
-               Point selection = selectionReference.getValue(); \r
-               String before = text.substring(0, selection.x);\r
-               String selected = text.substring(selection.x, selection.y);\r
-               String after = text.substring(selection.y);\r
-               perform(before, selected, after, selection);\r
-               return null;\r
-           }\r
-\r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object boldModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               if(selected.isEmpty()) {\r
-                                       textReference.setValue(before + "'''bold text'''" + after);\r
-                               } else {\r
-                                       textReference.setValue(before + "'''" + selected + "'''" + after);      \r
-                               }\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object italicModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               if(selected.isEmpty()) {\r
-                                       textReference.setValue(before + "''italic text''" + after);\r
-                               } else {\r
-                                       textReference.setValue(before + "''" + selected + "''" + after);        \r
-                               }\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object strikethroughModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               if(selected.isEmpty()) {\r
-                                       textReference.setValue(before + "<span style=\"text-decoration:line-through;\">strikethrough text</span>" + after);\r
-                               } else {\r
-                                       textReference.setValue(before + "<span style=\"text-decoration:line-through;\">" + selected + "</span>" + after);       \r
-                               }\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object underlineModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               if(selected.isEmpty()) {\r
-                                       textReference.setValue(before + "<span style=\"text-decoration:underline;\">strikethrough text</span>" + after);\r
-                               } else {\r
-                                       textReference.setValue(before + "<span style=\"text-decoration:underline;\">" + selected + "</span>" + after);  \r
-                               }\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object horizontalRulerModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n<hr/>\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object indentModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + ":" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object fontModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-               private String hex2(int value) {\r
-                       String result = Integer.toHexString(value);\r
-                       if(result.length() == 1) result = "0" + result;\r
-                       return result;\r
-               }\r
-               \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               FontDialog dialog = new FontDialog(Display.getCurrent().getActiveShell()); \r
-                               FontData data = dialog.open();\r
-                               if(data == null) return;\r
-\r
-                               String family = data.getName();\r
-                               int size = data.getHeight();\r
-                               \r
-                               RGB rgb = dialog.getRGB();\r
-                               String hex = hex2(rgb.red) + hex2(rgb.green) + hex2(rgb.blue);\r
-\r
-                               if(selected.isEmpty()) {\r
-                                       textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >formatted text</font>" + selected + after);\r
-                               } else {\r
-                                       textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >" + selected + "</font>" + after);\r
-                               }\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object imageModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-               \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + "\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object header1Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n= Header 1 =\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object header2Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n== Header 2 ==\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object header3Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n=== Header 3 ===\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object header4Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n==== Header 4 ====\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object numberedListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n" +\r
-                                               "# Item1\r\n" + \r
-                                               "# Item2\r\n" + \r
-                                               "## Item2.1\r\n" + \r
-                                               "# Item3\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object bulletListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n" +\r
-                                               "* Item1\r\n" + \r
-                                               "* Item2\r\n" + \r
-                                               "** Item2.1\r\n" + \r
-                                               "* Item3\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object tableModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before + "\r\n" +\r
-                                               "{| border=\"1\"\r\n" + \r
-                                               "! header\r\n" +\r
-                                               "! header2 \r\n" +\r
-                                               "|-\r\n" +\r
-                                               "| cell || cell2\r\n" + \r
-                                               "|-\r\n" +\r
-                                               "| cell3\r\n" + \r
-                                               "| cell4\r\n" + \r
-                                               "|}\r\n"  + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object internalLinkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-        return new WikiButtonModifier(graph, context) {\r
-            @Override\r
-            void perform(String before, String selected, String after, Point selection) {\r
-                textReference.setValue(before +\r
-                        "[[Media:root://Documents/Document.pdf|Link to a file within the model]]\r\n" + selected + after);\r
-                \r
-            }\r
-        };\r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object linkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               textReference.setValue(before +\r
-                                               "[http://www.simantics.org External Website Link]\r\n" + selected + after);\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Object styleModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-\r
-       return new WikiButtonModifier(graph, context) {\r
-                       \r
-                       @Override\r
-                       void perform(String before, String selected, String after, Point selection) {\r
-\r
-                               Simantics.getSession().asyncRequest(new ReadRequest() {\r
-\r
-                                       @Override\r
-                                       public void run(ReadGraph graph) throws DatabaseException {\r
-\r
-                                       Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);\r
-                                       Resource root = sel.getIndexRoot(graph);\r
-                                       String editorId = CSSEditor.EDITOR_ID;\r
-                               RVI rvi = null;\r
-\r
-                               PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
-                                       \r
-                                   @Override\r
-                                   public void run() {\r
-\r
-                                                   try {\r
-                                                                       WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));\r
-                                                               } catch (PartInitException e) {\r
-                                                                       Logger.defaultLogError(e);\r
-                                                               }\r
-                                       \r
-                                   }\r
-                                   \r
-                               });\r
-\r
-                                       }\r
-                                       \r
-                               });\r
-                               \r
-                       }\r
-                       \r
-               };\r
-        \r
-    }\r
-    \r
-    \r
-//    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
-//    public static Object navigate(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {\r
-//     \r
-//     return new FunctionImpl1<String, Boolean>() {\r
-//\r
-//                     @Override\r
-//                     public Boolean apply(final String path) {\r
-//                             \r
-//                             Simantics.getSession().asyncRequest(new ReadRequest() {\r
-//\r
-//                                     @Override\r
-//                                     public void run(ReadGraph graph) throws DatabaseException {\r
-//                                             \r
-//                                             DocumentResource DOC = DocumentResource.getInstance(graph);\r
-//                                     Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);\r
-//                                     \r
-//                                     Resource represents = sel.getRepresents(graph);\r
-//                                     Resource doc = graph.getSingleObject(represents, DOC.HasDocument);\r
-//                                     Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);\r
-//                                     \r
-//                                     Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);\r
-//                                             INode root = runtime.adapt(graph, INode.class);\r
-//                                     \r
-//                                     Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);\r
-//                                     Variable location = result.browse(graph, path);\r
-//                                             \r
-//                                             ScenegraphPropertyReference<Variable> editReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".#edited");\r
-//                                             editReference.setValue(location);\r
-//                                             \r
-//                                     }\r
-//                                     \r
-//                             });\r
-//                             \r
-//                             return null;\r
-//                             \r
-//                     }\r
-//             \r
-//     };\r
-//     \r
-//    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")\r
-    public static String noDocumentText(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-               \r
-       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);\r
-       if(selection == null) return "<no input>";\r
-       \r
-               Resource input = selection.getRepresents(graph);\r
-       if(input == null) return "<no input>";\r
-       \r
-       String path = DocumentUtils.indexRootPath(graph, selection);\r
-       if(!path.isEmpty()) {\r
-               return "for " + path + selection.getName(graph);\r
-       }\r
-       \r
-               return "for " + NameUtils.getSafeLabel(graph, input);\r
-       \r
-    }\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")\r
-    public static Boolean canCreateDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {\r
-               \r
-       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);\r
-       if(selection == null) return false;\r
-       \r
-               Resource input = selection.getRepresents(graph);\r
-       if(input == null) return false;\r
-       \r
-       return true;\r
-       \r
-    }\r
-\r
-    private static class ResolveURI extends UnaryRead<String, Object> {\r
-        public ResolveURI(String uri) {\r
-            super(uri);\r
-        }\r
-        @Override\r
-        public Object perform(ReadGraph graph) throws DatabaseException {\r
-            Object result = graph.syncRequest(new PossibleResource(parameter));\r
-            if (result == null)\r
-                result = Variables.getPossibleVariable(graph, parameter);\r
-            return result;\r
-        }\r
-    }\r
-\r
-    private static final Function1<Object, Boolean> PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE = new Function1<Object, Boolean>() {\r
-        @Override\r
-        public Boolean apply(Object p0) {\r
-            LocationEvent le = (LocationEvent) p0;\r
-            if (le.location.startsWith(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX)) {\r
-                // This is not a valid URL anyway so deny relocation.\r
-                le.doit = false;\r
-\r
-                // Try to execute default action for the resource or variable\r
-                // that the URI represents.\r
-                String uri = le.location.substring(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX.length());\r
-                try {\r
-                    Session s = Simantics.getSession();\r
-                    Object input = RequestUtil.trySyncRequest(s,\r
-                            SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,\r
-                            SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,\r
-                            new ResolveURI(uri));\r
-                    if (input != null) {\r
-                        DefaultActions.asyncPerformDefaultAction(s, input, false, false, false);\r
-                    }\r
-                } catch (DatabaseException | InterruptedException e) {\r
-                    Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to resolve URI to a database resource or variable: " + uri, e));\r
-                }\r
-            }\r
-            return true;\r
-        }\r
-    };\r
-\r
-    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")\r
-    public static Function1<Object, Boolean> locationChanging(ReadGraph graph, Resource variable, Variable context) throws DatabaseException {\r
-        return PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE;\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.document.ui.function;
+
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FontDialog;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.simantics.Simantics;
+import org.simantics.browsing.ui.BuiltinKeys;
+import org.simantics.browsing.ui.NodeContext;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.common.utils.RequestUtil;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.request.PossibleModel;
+import org.simantics.db.layer0.request.PossibleResource;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.document.DocumentDialect;
+import org.simantics.document.DocumentResource;
+import org.simantics.document.DocumentUtils;
+import org.simantics.document.ui.Activator;
+import org.simantics.document.ui.CSSEditor;
+import org.simantics.layer0.Layer0;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.loader.ScenegraphLoaderProcess;
+import org.simantics.scenegraph.loader.ScenegraphLoaderUtils;
+import org.simantics.scenegraph.loader.ScenegraphLoaderUtils.ScenegraphPropertyReference;
+import org.simantics.scl.reflection.annotations.SCLValue;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.function.FunctionImpl3;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.ui.workbench.ResourceEditorInput2;
+import org.simantics.ui.workbench.action.DefaultActions;
+import org.simantics.utils.threads.SWTThread;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+
+public class All {
+
+       private static boolean createDocument(WriteGraph graph, Resource resource, Resource model) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               DocumentResource DOC = DocumentResource.getInstance(graph);
+
+               if(graph.hasStatement(resource, DOC.HasDocumentation)) return true;
+               
+               Instances query = graph.adapt(DOC.DocumentTypeBinding, Instances.class);
+               
+               TreeMap<Double, Resource> bindings = new TreeMap<Double, Resource>();
+               for(Resource binding : query.find(graph, model)) {
+                       double priority = graph.getRelatedValue2(binding, DOC.DocumentTypeBinding_priority, Bindings.DOUBLE);
+                       Resource type = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasType);
+                       if(graph.isInstanceOf(resource, type)) {
+                               bindings.put(priority, binding);
+                       }
+               }
+               
+               if(bindings.isEmpty()) return false;
+               
+               Resource binding = bindings.lastEntry().getValue();
+                               
+               Resource documentType = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasDocumentType);
+               Resource document = graph.newResource();
+               graph.claim(document, L0.InstanceOf, null, DOC.ScenegraphDocument);
+               graph.claimLiteral(document, L0.HasName, "Documentation");
+               graph.claim(resource, DOC.HasDocumentation, document);
+               graph.claim(document, L0.PartOf, resource);
+
+               Resource scenegraph = graph.newResource();
+               graph.claim(scenegraph, L0.InstanceOf, null, documentType);
+               graph.claimLiteral(scenegraph, L0.HasName, "Scenegraph");
+               graph.claim(scenegraph, L0.PartOf, document);
+               graph.claim(document, DOC.ScenegraphDocument_scenegraph, scenegraph);
+
+               return true;
+               
+       }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object onCreateDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new FunctionImpl1<Object, Object>() {
+
+                       @Override
+                       public Object apply(Object _o) {
+                               
+                               Simantics.async(new ReadRequest() {
+
+                                       @Override
+                                       public void run(ReadGraph graph) throws DatabaseException {
+                                               
+                                       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
+                                       if(selection == null) return;
+                                       
+                                               final Resource input = selection.getRepresents(graph);
+                                       if(input == null) return;
+                                               
+                                       graph.async(new WriteRequest() {
+
+                                                       @Override
+                                                       public void perform(WriteGraph graph) throws DatabaseException {
+                                                               
+                                                               Resource model = graph.sync(new PossibleModel(input));
+                                                               if(model == null) return;
+                                                               createDocument(graph, input, model);
+                                                               
+                                                       }
+                                               
+                                       });
+                                       
+                                       }
+                                       
+                               });
+                               
+                               return true;
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object onDeleteDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new FunctionImpl1<Object, Object>() {
+
+                       @Override
+                       public Object apply(Object _o) {
+                               
+                               Simantics.async(new ReadRequest() {
+
+                                       @Override
+                                       public void run(ReadGraph graph) throws DatabaseException {
+                                               
+                                       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
+                                       if(selection == null) return;
+                                       
+                                               final Resource input = selection.getRepresents(graph);
+                                       if(input == null) return;
+                                       
+                                               DocumentResource DOC = DocumentResource.getInstance(graph);
+                                               if(!graph.hasStatement(input, DOC.HasDocumentation)) return;
+                                               
+                                       graph.async(new WriteRequest() {
+
+                                                       @Override
+                                                       public void perform(WriteGraph graph) throws DatabaseException {
+                                                               
+                                                               DocumentResource DOC = DocumentResource.getInstance(graph);
+                                                               Resource document = graph.getPossibleObject(input, DOC.HasDocumentation);
+                                                               if(document == null) return;
+                                                               
+                                                               RemoverUtil.remove(graph, document);
+                                                               
+                                                       }
+                                               
+                                       });
+                                       
+                                       }
+                                       
+                               });
+                               
+                               return true;
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+    public static Object editorLoaded(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+       
+       return new FunctionImpl3<WriteGraph, Variable, Variable, Boolean>() {
+
+                       @Override
+                       public Boolean apply(WriteGraph graph, Variable editor, Variable input) {
+
+//                             try {
+//                                     return createDocument(graph, input);
+//                             } catch (DatabaseException e) {
+//                                     Logger.defaultLogError(e);
+//                             }
+
+                               return true;
+                               
+                       }
+               
+       };
+       
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
+    public static Boolean hasDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+       
+               DocumentResource DOC = DocumentResource.getInstance(graph);
+               
+       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
+       if(selection == null) return false;
+       
+               Resource input = selection.getRepresents(graph);
+       if(input == null) return null;
+       
+               return graph.hasStatement(input, DOC.HasDocumentation);
+       
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+    public static Object viewInputChanged(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+       
+       return new FunctionImpl1<Variable, Boolean>() {
+
+                       @Override
+                       public Boolean apply(final Variable viewVariable) {
+                               return true;
+                       }
+               
+       };
+       
+    }
+    
+       
+    @SCLValue(type = "ReadGraph -> Variable -> Boolean")
+    public static Boolean isWikitext(ReadGraph graph, Variable context) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(graph);
+       DocumentResource DOC = DocumentResource.getInstance(graph);
+       Resource p = context.getPossiblePredicateResource(graph);
+       if (p == null)
+           return Boolean.FALSE;
+       Resource range = graph.getPossibleObject(p, L0.HasRange);
+       return DOC.WikiDocument_WikiText.equals(range);
+    }
+    
+    private static Variable getDefaultSelection(ReadGraph graph, Variable context) throws DatabaseException {
+       
+               DocumentResource DOC = DocumentResource.getInstance(graph);
+       Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
+       
+       Resource represents = sel.getRepresents(graph);
+       Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
+       Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
+       
+       Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
+               INode root = runtime.adapt(graph, INode.class);
+
+       Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
+       if(result != null) {
+               Variable userDoc = result.getPossibleProperty(graph, "UserDocumentation");
+               if(userDoc != null) return userDoc;
+       }
+       
+       return null;
+       
+    }
+    
+    private static Variable resolveEditSelection(ReadGraph graph, Variable context, String path) throws DatabaseException {
+       
+               final ScenegraphPropertyReference<Variable> selectionReference = 
+                               ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, path);
+               
+               Variable editSelection = selectionReference.getExternalValue(graph);
+               if(editSelection == null) editSelection = getDefaultSelection(graph, context);
+               
+               return editSelection;
+       
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+    public static Object wikitextModifier(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+       
+               final ScenegraphPropertyReference<String> textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
+       
+       return new FunctionImpl1<Object, Object>() {
+
+                       @Override
+                       public Object apply(final Object event) {
+           
+                               final String value = textReference.getValue();
+
+                               try {
+                                       Simantics.getSession().sync(new WriteRequest() {
+
+                                               @Override
+                                               public void perform(WriteGraph graph) throws DatabaseException {
+                                                       
+                                                       Variable selection = resolveEditSelection(graph, context, "..../Scroll/Browser#edited");
+                                                       if (selection != null)
+                                                           selection.setValue(graph, (String)value, Bindings.STRING);
+                                                       else {
+                                                               System.err.println("no selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);
+                                                       }
+                                               }
+                                               
+                                       });
+                               } catch (DatabaseException e) {
+                                       e.printStackTrace();
+                               }
+                               return null;
+                       }
+               
+       };
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
+    public static String wikitext(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
+       Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
+       return selection.getValue(graph);
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
+    public static String selectedDocumentPart(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
+
+               Variable selection = resolveEditSelection(graph, context, ".../Scroll/Browser#edited");
+               if(selection == null) return null;
+
+       return selection.getValue(graph);
+       
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object documentStructureSelected(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
+       
+       return new FunctionImpl1<Object, Boolean>() {
+               
+           @Override
+           public Boolean apply(Object _event) {
+               
+               Event event = (Event)_event;
+               
+               final TreeItem item = (TreeItem)event.item;
+               NodeContext context = (NodeContext)item.getData();
+               final Variable entry = (Variable)context.getConstant(BuiltinKeys.INPUT);
+               
+               ISelectionProvider provider = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();
+               provider.setSelection(new StructuredSelection(entry));
+               
+               return null;
+               
+           }
+               
+       };
+        
+    }
+
+    abstract static class WikiButtonModifier extends FunctionImpl1<Object, Object> {
+
+               final ScenegraphPropertyReference<String> textReference;
+               final ScenegraphPropertyReference<Point> selectionReference;
+
+       public WikiButtonModifier(ReadGraph graph, Variable context) throws DatabaseException {
+               textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
+               selectionReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#selection");
+       }
+       
+       abstract void perform(String before, String selected, String after, Point selection);
+       
+           @Override
+           public Object apply(Object _event) {
+               String text = textReference.getValue();
+               Point selection = selectionReference.getValue(); 
+               String before = text.substring(0, selection.x);
+               String selected = text.substring(selection.x, selection.y);
+               String after = text.substring(selection.y);
+               perform(before, selected, after, selection);
+               return null;
+           }
+
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object boldModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               if(selected.isEmpty()) {
+                                       textReference.setValue(before + "'''bold text'''" + after);
+                               } else {
+                                       textReference.setValue(before + "'''" + selected + "'''" + after);      
+                               }
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object italicModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               if(selected.isEmpty()) {
+                                       textReference.setValue(before + "''italic text''" + after);
+                               } else {
+                                       textReference.setValue(before + "''" + selected + "''" + after);        
+                               }
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object strikethroughModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               if(selected.isEmpty()) {
+                                       textReference.setValue(before + "<span style=\"text-decoration:line-through;\">strikethrough text</span>" + after);
+                               } else {
+                                       textReference.setValue(before + "<span style=\"text-decoration:line-through;\">" + selected + "</span>" + after);       
+                               }
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object underlineModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               if(selected.isEmpty()) {
+                                       textReference.setValue(before + "<span style=\"text-decoration:underline;\">strikethrough text</span>" + after);
+                               } else {
+                                       textReference.setValue(before + "<span style=\"text-decoration:underline;\">" + selected + "</span>" + after);  
+                               }
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object horizontalRulerModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n<hr/>\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object indentModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + ":" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object fontModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+               private String hex2(int value) {
+                       String result = Integer.toHexString(value);
+                       if(result.length() == 1) result = "0" + result;
+                       return result;
+               }
+               
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               FontDialog dialog = new FontDialog(Display.getCurrent().getActiveShell()); 
+                               FontData data = dialog.open();
+                               if(data == null) return;
+
+                               String family = data.getName();
+                               int size = data.getHeight();
+                               
+                               RGB rgb = dialog.getRGB();
+                               String hex = hex2(rgb.red) + hex2(rgb.green) + hex2(rgb.blue);
+
+                               if(selected.isEmpty()) {
+                                       textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >formatted text</font>" + selected + after);
+                               } else {
+                                       textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >" + selected + "</font>" + after);
+                               }
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object imageModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+               
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + "\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object header1Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n= Header 1 =\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object header2Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n== Header 2 ==\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object header3Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n=== Header 3 ===\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object header4Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n==== Header 4 ====\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object numberedListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n" +
+                                               "# Item1\r\n" + 
+                                               "# Item2\r\n" + 
+                                               "## Item2.1\r\n" + 
+                                               "# Item3\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object bulletListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n" +
+                                               "* Item1\r\n" + 
+                                               "* Item2\r\n" + 
+                                               "** Item2.1\r\n" + 
+                                               "* Item3\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object tableModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before + "\r\n" +
+                                               "{| border=\"1\"\r\n" + 
+                                               "! header\r\n" +
+                                               "! header2 \r\n" +
+                                               "|-\r\n" +
+                                               "| cell || cell2\r\n" + 
+                                               "|-\r\n" +
+                                               "| cell3\r\n" + 
+                                               "| cell4\r\n" + 
+                                               "|}\r\n"  + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object internalLinkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+        return new WikiButtonModifier(graph, context) {
+            @Override
+            void perform(String before, String selected, String after, Point selection) {
+                textReference.setValue(before +
+                        "[[Media:root://Documents/Document.pdf|Link to a file within the model]]\r\n" + selected + after);
+                
+            }
+        };
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object linkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               textReference.setValue(before +
+                                               "[http://www.simantics.org External Website Link]\r\n" + selected + after);
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Object styleModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+
+       return new WikiButtonModifier(graph, context) {
+                       
+                       @Override
+                       void perform(String before, String selected, String after, Point selection) {
+
+                               Simantics.getSession().asyncRequest(new ReadRequest() {
+
+                                       @Override
+                                       public void run(ReadGraph graph) throws DatabaseException {
+
+                                       Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
+                                       Resource root = sel.getIndexRoot(graph);
+                                       String editorId = CSSEditor.EDITOR_ID;
+                               RVI rvi = null;
+
+                               PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+                                       
+                                   @Override
+                                   public void run() {
+
+                                                   try {
+                                                                       WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));
+                                                               } catch (PartInitException e) {
+                                                                       Logger.defaultLogError(e);
+                                                               }
+                                       
+                                   }
+                                   
+                               });
+
+                                       }
+                                       
+                               });
+                               
+                       }
+                       
+               };
+        
+    }
+    
+    
+//    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+//    public static Object navigate(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+//     
+//     return new FunctionImpl1<String, Boolean>() {
+//
+//                     @Override
+//                     public Boolean apply(final String path) {
+//                             
+//                             Simantics.getSession().asyncRequest(new ReadRequest() {
+//
+//                                     @Override
+//                                     public void run(ReadGraph graph) throws DatabaseException {
+//                                             
+//                                             DocumentResource DOC = DocumentResource.getInstance(graph);
+//                                     Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
+//                                     
+//                                     Resource represents = sel.getRepresents(graph);
+//                                     Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
+//                                     Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
+//                                     
+//                                     Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
+//                                             INode root = runtime.adapt(graph, INode.class);
+//                                     
+//                                     Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
+//                                     Variable location = result.browse(graph, path);
+//                                             
+//                                             ScenegraphPropertyReference<Variable> editReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".#edited");
+//                                             editReference.setValue(location);
+//                                             
+//                                     }
+//                                     
+//                             });
+//                             
+//                             return null;
+//                             
+//                     }
+//             
+//     };
+//     
+//    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
+    public static String noDocumentText(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+               
+       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
+       if(selection == null) return "<no input>";
+       
+               Resource input = selection.getRepresents(graph);
+       if(input == null) return "<no input>";
+       
+       String path = DocumentUtils.indexRootPath(graph, selection);
+       if(!path.isEmpty()) {
+               return "for " + path + selection.getName(graph);
+       }
+       
+               return "for " + NameUtils.getSafeLabel(graph, input);
+       
+    }
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
+    public static Boolean canCreateDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
+               
+       Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
+       if(selection == null) return false;
+       
+               Resource input = selection.getRepresents(graph);
+       if(input == null) return false;
+       
+       return true;
+       
+    }
+
+    private static class ResolveURI extends UnaryRead<String, Object> {
+        public ResolveURI(String uri) {
+            super(uri);
+        }
+        @Override
+        public Object perform(ReadGraph graph) throws DatabaseException {
+            Object result = graph.syncRequest(new PossibleResource(parameter));
+            if (result == null)
+                result = Variables.getPossibleVariable(graph, parameter);
+            return result;
+        }
+    }
+
+    private static final Function1<Object, Boolean> PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE = new Function1<Object, Boolean>() {
+        @Override
+        public Boolean apply(Object p0) {
+            LocationEvent le = (LocationEvent) p0;
+            if (le.location.startsWith(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX)) {
+                // This is not a valid URL anyway so deny relocation.
+                le.doit = false;
+
+                // Try to execute default action for the resource or variable
+                // that the URI represents.
+                String uri = le.location.substring(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX.length());
+                try {
+                    Session s = Simantics.getSession();
+                    Object input = RequestUtil.trySyncRequest(s,
+                            SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
+                            SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,
+                            new ResolveURI(uri));
+                    if (input != null) {
+                        DefaultActions.asyncPerformDefaultAction(s, input, false, false, false);
+                    }
+                } catch (DatabaseException | InterruptedException e) {
+                    Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to resolve URI to a database resource or variable: " + uri, e));
+                }
+            }
+            return true;
+        }
+    };
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+    public static Function1<Object, Boolean> locationChanging(ReadGraph graph, Resource variable, Variable context) throws DatabaseException {
+        return PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE;
+    }
+
+}