1 /*******************************************************************************
2 * Copyright (c) 2012, 2017 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 * Semantum Oy - (#7066) introducing logger & refactoring
12 *******************************************************************************/
13 package org.simantics.document.ui.function;
15 import java.util.TreeMap;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.jface.viewers.ISelectionProvider;
20 import org.eclipse.jface.viewers.StructuredSelection;
21 import org.eclipse.swt.browser.LocationEvent;
22 import org.eclipse.swt.graphics.FontData;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.graphics.RGB;
25 import org.eclipse.swt.widgets.Display;
26 import org.eclipse.swt.widgets.Event;
27 import org.eclipse.swt.widgets.FontDialog;
28 import org.eclipse.swt.widgets.TreeItem;
29 import org.eclipse.ui.PartInitException;
30 import org.eclipse.ui.PlatformUI;
31 import org.simantics.Simantics;
32 import org.simantics.browsing.ui.BuiltinKeys;
33 import org.simantics.browsing.ui.NodeContext;
34 import org.simantics.databoard.Bindings;
35 import org.simantics.db.ReadGraph;
36 import org.simantics.db.Resource;
37 import org.simantics.db.Session;
38 import org.simantics.db.WriteGraph;
39 import org.simantics.db.common.request.ReadRequest;
40 import org.simantics.db.common.request.UnaryRead;
41 import org.simantics.db.common.request.WriteRequest;
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 import org.slf4j.Logger;
72 import org.slf4j.LoggerFactory;
77 private static final Logger LOGGER = LoggerFactory.getLogger(All.class);
79 private static boolean createDocument(WriteGraph graph, Resource resource, Resource model) throws DatabaseException {
81 Layer0 L0 = Layer0.getInstance(graph);
82 DocumentResource DOC = DocumentResource.getInstance(graph);
84 if(graph.hasStatement(resource, DOC.HasDocumentation)) return true;
86 Instances query = graph.adapt(DOC.DocumentTypeBinding, Instances.class);
88 TreeMap<Double, Resource> bindings = new TreeMap<Double, Resource>();
89 for(Resource binding : query.find(graph, model)) {
90 double priority = graph.getRelatedValue2(binding, DOC.DocumentTypeBinding_priority, Bindings.DOUBLE);
91 Resource type = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasType);
92 if(graph.isInstanceOf(resource, type)) {
93 bindings.put(priority, binding);
97 if(bindings.isEmpty()) return false;
99 Resource binding = bindings.lastEntry().getValue();
101 Resource documentType = graph.getSingleObject(binding, DOC.DocumentTypeBinding_HasDocumentType);
102 Resource document = graph.newResource();
103 graph.claim(document, L0.InstanceOf, null, DOC.ScenegraphDocument);
104 graph.claimLiteral(document, L0.HasName, "Documentation");
105 graph.claim(resource, DOC.HasDocumentation, document);
106 graph.claim(document, L0.PartOf, resource);
108 Resource scenegraph = graph.newResource();
109 graph.claim(scenegraph, L0.InstanceOf, null, documentType);
110 graph.claimLiteral(scenegraph, L0.HasName, "Scenegraph");
111 graph.claim(scenegraph, L0.PartOf, document);
112 graph.claim(document, DOC.ScenegraphDocument_scenegraph, scenegraph);
118 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
119 public static Object onCreateDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
121 return new FunctionImpl1<Object, Object>() {
124 public Object apply(Object _o) {
126 Simantics.async(new ReadRequest() {
129 public void run(ReadGraph graph) throws DatabaseException {
131 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
132 if(selection == null) return;
134 final Resource input = selection.getRepresents(graph);
135 if(input == null) return;
137 graph.async(new WriteRequest() {
140 public void perform(WriteGraph graph) throws DatabaseException {
142 Resource model = graph.sync(new PossibleModel(input));
143 if(model == null) return;
144 createDocument(graph, input, model);
162 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
163 public static Object onDeleteDocumentButton(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
165 return new FunctionImpl1<Object, Object>() {
168 public Object apply(Object _o) {
170 Simantics.async(new ReadRequest() {
173 public void run(ReadGraph graph) throws DatabaseException {
175 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
176 if(selection == null) return;
178 final Resource input = selection.getRepresents(graph);
179 if(input == null) return;
181 DocumentResource DOC = DocumentResource.getInstance(graph);
182 if(!graph.hasStatement(input, DOC.HasDocumentation)) return;
184 graph.async(new WriteRequest() {
187 public void perform(WriteGraph graph) throws DatabaseException {
189 DocumentResource DOC = DocumentResource.getInstance(graph);
190 Resource document = graph.getPossibleObject(input, DOC.HasDocumentation);
191 if(document == null) return;
193 RemoverUtil.remove(graph, document);
194 graph.markUndoPoint();
212 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
213 public static Object editorLoaded(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
215 return new FunctionImpl3<WriteGraph, Variable, Variable, Boolean>() {
218 public Boolean apply(WriteGraph graph, Variable editor, Variable input) {
221 // return createDocument(graph, input);
222 // } catch (DatabaseException e) {
223 // Logger.defaultLogError(e);
234 @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
235 public static Boolean hasDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
237 DocumentResource DOC = DocumentResource.getInstance(graph);
239 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
240 if(selection == null) return false;
242 Resource input = selection.getRepresents(graph);
243 if(input == null) return null;
245 return graph.hasStatement(input, DOC.HasDocumentation);
249 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
250 public static Object viewInputChanged(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
252 return new FunctionImpl1<Variable, Boolean>() {
255 public Boolean apply(final Variable viewVariable) {
264 @SCLValue(type = "ReadGraph -> Variable -> Boolean")
265 public static Boolean isWikitext(ReadGraph graph, Variable context) throws DatabaseException {
266 Layer0 L0 = Layer0.getInstance(graph);
267 DocumentResource DOC = DocumentResource.getInstance(graph);
268 Resource p = context.getPossiblePredicateResource(graph);
270 return Boolean.FALSE;
271 Resource range = graph.getPossibleObject(p, L0.HasRange);
272 return DOC.WikiDocument_WikiText.equals(range);
275 private static Variable getDefaultSelection(ReadGraph graph, Variable context) throws DatabaseException {
277 DocumentResource DOC = DocumentResource.getInstance(graph);
278 Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
280 Resource represents = sel.getRepresents(graph);
281 Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
282 Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
284 Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
285 INode root = runtime.adapt(graph, INode.class);
287 Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
289 Variable userDoc = result.getPossibleProperty(graph, "UserDocumentation");
290 if(userDoc != null) return userDoc;
297 private static Variable resolveEditSelection(ReadGraph graph, Variable context, String path) throws DatabaseException {
299 final ScenegraphPropertyReference<Variable> selectionReference =
300 ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, path);
302 Variable editSelection = selectionReference.getExternalValue(graph);
303 if(editSelection == null) editSelection = getDefaultSelection(graph, context);
305 return editSelection;
309 @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
310 public static Object wikitextModifier(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
312 final ScenegraphPropertyReference<String> textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
314 return new FunctionImpl1<Object, Object>() {
317 public Object apply(final Object event) {
319 final String value = textReference.getValue();
322 Simantics.getSession().sync(new WriteRequest() {
325 public void perform(WriteGraph graph) throws DatabaseException {
326 Variable selection = resolveEditSelection(graph, context, "..../Scroll/Browser#edited");
327 if (selection != null) {
328 selection.setValue(graph, (String)value, Bindings.STRING);
329 graph.markUndoPoint();
331 LOGGER.error("No selection for resource : " + resource + ", Variable context : " + context + ", value : " + value);
336 } catch (DatabaseException e) {
345 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
346 public static String wikitext(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
347 Variable selection = ScenegraphLoaderUtils.getVariableSelection(graph, context);
348 return selection.getValue(graph);
351 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
352 public static String selectedDocumentPart(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
354 Variable selection = resolveEditSelection(graph, context, ".../Scroll/Browser#edited");
355 if(selection == null) return null;
357 return selection.getValue(graph);
361 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
362 public static Object documentStructureSelected(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {
364 return new FunctionImpl1<Object, Boolean>() {
367 public Boolean apply(Object _event) {
369 Event event = (Event)_event;
371 final TreeItem item = (TreeItem)event.item;
372 NodeContext context = (NodeContext)item.getData();
373 final Variable entry = (Variable)context.getConstant(BuiltinKeys.INPUT);
375 ISelectionProvider provider = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();
376 provider.setSelection(new StructuredSelection(entry));
386 abstract static class WikiButtonModifier extends FunctionImpl1<Object, Object> {
388 final ScenegraphPropertyReference<String> textReference;
389 final ScenegraphPropertyReference<Point> selectionReference;
391 public WikiButtonModifier(ReadGraph graph, Variable context) throws DatabaseException {
392 textReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#text");
393 selectionReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".../TextContainer/Text#selection");
396 abstract void perform(String before, String selected, String after, Point selection);
399 public Object apply(Object _event) {
400 String text = textReference.getValue();
401 Point selection = selectionReference.getValue();
402 String before = text.substring(0, selection.x);
403 String selected = text.substring(selection.x, selection.y);
404 String after = text.substring(selection.y);
405 perform(before, selected, after, selection);
411 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
412 public static Object boldModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
414 return new WikiButtonModifier(graph, context) {
417 void perform(String before, String selected, String after, Point selection) {
419 if(selected.isEmpty()) {
420 textReference.setValue(before + "'''bold text'''" + after);
422 textReference.setValue(before + "'''" + selected + "'''" + after);
431 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
432 public static Object italicModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
434 return new WikiButtonModifier(graph, context) {
437 void perform(String before, String selected, String after, Point selection) {
439 if(selected.isEmpty()) {
440 textReference.setValue(before + "''italic text''" + after);
442 textReference.setValue(before + "''" + selected + "''" + after);
451 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
452 public static Object strikethroughModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
454 return new WikiButtonModifier(graph, context) {
457 void perform(String before, String selected, String after, Point selection) {
459 if(selected.isEmpty()) {
460 textReference.setValue(before + "<span style=\"text-decoration:line-through;\">strikethrough text</span>" + after);
462 textReference.setValue(before + "<span style=\"text-decoration:line-through;\">" + selected + "</span>" + after);
471 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
472 public static Object underlineModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
474 return new WikiButtonModifier(graph, context) {
477 void perform(String before, String selected, String after, Point selection) {
479 if(selected.isEmpty()) {
480 textReference.setValue(before + "<span style=\"text-decoration:underline;\">strikethrough text</span>" + after);
482 textReference.setValue(before + "<span style=\"text-decoration:underline;\">" + selected + "</span>" + after);
491 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
492 public static Object horizontalRulerModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
494 return new WikiButtonModifier(graph, context) {
497 void perform(String before, String selected, String after, Point selection) {
499 textReference.setValue(before + "\r\n<hr/>\r\n" + selected + after);
507 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
508 public static Object indentModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
510 return new WikiButtonModifier(graph, context) {
513 void perform(String before, String selected, String after, Point selection) {
515 textReference.setValue(before + ":" + selected + after);
523 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
524 public static Object fontModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
526 return new WikiButtonModifier(graph, context) {
528 private String hex2(int value) {
529 String result = Integer.toHexString(value);
530 if(result.length() == 1) result = "0" + result;
535 void perform(String before, String selected, String after, Point selection) {
537 FontDialog dialog = new FontDialog(Display.getCurrent().getActiveShell());
538 FontData data = dialog.open();
539 if(data == null) return;
541 String family = data.getName();
542 int size = data.getHeight();
544 RGB rgb = dialog.getRGB();
545 String hex = hex2(rgb.red) + hex2(rgb.green) + hex2(rgb.blue);
547 if(selected.isEmpty()) {
548 textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >formatted text</font>" + selected + after);
550 textReference.setValue(before + "<font style=\"font-size:" + size + ";color: #" + hex + ";font-family:" + family + ";\" >" + selected + "</font>" + after);
559 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
560 public static Object imageModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
562 return new WikiButtonModifier(graph, context) {
565 void perform(String before, String selected, String after, Point selection) {
567 textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + "\r\n" + selected + after);
575 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
576 public static Object header1Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
578 return new WikiButtonModifier(graph, context) {
581 void perform(String before, String selected, String after, Point selection) {
583 textReference.setValue(before + "\r\n= Header 1 =\r\n" + selected + after);
591 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
592 public static Object header2Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
594 return new WikiButtonModifier(graph, context) {
597 void perform(String before, String selected, String after, Point selection) {
599 textReference.setValue(before + "\r\n== Header 2 ==\r\n" + selected + after);
607 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
608 public static Object header3Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
610 return new WikiButtonModifier(graph, context) {
613 void perform(String before, String selected, String after, Point selection) {
615 textReference.setValue(before + "\r\n=== Header 3 ===\r\n" + selected + after);
623 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
624 public static Object header4Modifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
626 return new WikiButtonModifier(graph, context) {
629 void perform(String before, String selected, String after, Point selection) {
631 textReference.setValue(before + "\r\n==== Header 4 ====\r\n" + selected + after);
639 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
640 public static Object numberedListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
642 return new WikiButtonModifier(graph, context) {
645 void perform(String before, String selected, String after, Point selection) {
647 textReference.setValue(before + "\r\n" +
651 "# Item3\r\n" + selected + after);
659 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
660 public static Object bulletListModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
662 return new WikiButtonModifier(graph, context) {
665 void perform(String before, String selected, String after, Point selection) {
667 textReference.setValue(before + "\r\n" +
671 "* Item3\r\n" + selected + after);
679 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
680 public static Object tableModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
682 return new WikiButtonModifier(graph, context) {
685 void perform(String before, String selected, String after, Point selection) {
687 textReference.setValue(before + "\r\n" +
688 "{| border=\"1\"\r\n" +
692 "| cell || cell2\r\n" +
696 "|}\r\n" + selected + after);
704 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
705 public static Object internalLinkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
706 return new WikiButtonModifier(graph, context) {
708 void perform(String before, String selected, String after, Point selection) {
709 textReference.setValue(before +
710 "[[Media:root://Documents/Document.pdf|Link to a file within the model]]\r\n" + selected + after);
716 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
717 public static Object linkModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
719 return new WikiButtonModifier(graph, context) {
722 void perform(String before, String selected, String after, Point selection) {
724 textReference.setValue(before +
725 "[http://www.simantics.org External Website Link]\r\n" + selected + after);
733 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
734 public static Object styleModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
736 return new WikiButtonModifier(graph, context) {
739 void perform(String before, String selected, String after, Point selection) {
741 Simantics.getSession().asyncRequest(new ReadRequest() {
744 public void run(ReadGraph graph) throws DatabaseException {
746 Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
747 Resource root = sel.getIndexRoot(graph);
748 String editorId = CSSEditor.EDITOR_ID;
751 PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
753 WorkbenchUtils.openEditor(editorId, new ResourceEditorInput2(editorId, root, root, rvi));
754 } catch (PartInitException e) {
755 LOGGER.error("Failed to open CSS editor for root " + root, e);
770 // @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
771 // public static Object navigate(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
773 // return new FunctionImpl1<String, Boolean>() {
776 // public Boolean apply(final String path) {
778 // Simantics.getSession().asyncRequest(new ReadRequest() {
781 // public void run(ReadGraph graph) throws DatabaseException {
783 // DocumentResource DOC = DocumentResource.getInstance(graph);
784 // Variable sel = ScenegraphLoaderUtils.getVariableSelection(graph, context);
786 // Resource represents = sel.getRepresents(graph);
787 // Resource doc = graph.getSingleObject(represents, DOC.HasDocument);
788 // Resource scenegraph = graph.getSingleObject(doc, DOC.ScenegraphDocument_scenegraph);
790 // Variable runtime = ScenegraphLoaderUtils.getRuntimeVariable(graph, context);
791 // INode root = runtime.adapt(graph, INode.class);
793 // Variable result = ScenegraphLoaderProcess.getVariable(graph, null, scenegraph, ScenegraphLoaderUtils.getRuntime(graph, context), root);
794 // Variable location = result.browse(graph, path);
796 // ScenegraphPropertyReference<Variable> editReference = ScenegraphLoaderUtils.getRelativePropertyReference(SWTThread.getThreadAccess(), graph, context, ".#edited");
797 // editReference.setValue(location);
811 @SCLValue(type = "ReadGraph -> Resource -> Variable -> String")
812 public static String noDocumentText(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
814 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
815 if(selection == null) return "<no input>";
817 Resource input = selection.getRepresents(graph);
818 if(input == null) return "<no input>";
820 String path = DocumentUtils.indexRootPath(graph, selection);
821 if(!path.isEmpty()) {
822 return "for " + path + selection.getName(graph);
825 return "for " + NameUtils.getSafeLabel(graph, input);
829 @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")
830 public static Boolean canCreateDocument(ReadGraph graph, final Resource resource, final Variable context) throws DatabaseException {
832 Variable selection = ScenegraphLoaderUtils.getPossibleVariableSelection(graph, context);
833 if(selection == null) return false;
835 Resource input = selection.getRepresents(graph);
836 if(input == null) return false;
842 private static class ResolveURI extends UnaryRead<String, Object> {
843 public ResolveURI(String uri) {
847 public Object perform(ReadGraph graph) throws DatabaseException {
848 Object result = graph.syncRequest(new PossibleResource(parameter));
850 result = Variables.getPossibleVariable(graph, parameter);
855 private static final Function1<Object, Boolean> PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE = new Function1<Object, Boolean>() {
857 public Boolean apply(Object p0) {
858 LocationEvent le = (LocationEvent) p0;
859 if (le.location.startsWith(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX)) {
860 // This is not a valid URL anyway so deny relocation.
863 // Try to execute default action for the resource or variable
864 // that the URI represents.
865 String uri = le.location.substring(DocumentDialect.SIMANTICS_INTERNAL_URI_PREFIX.length());
867 Session s = Simantics.getSession();
868 Object input = RequestUtil.trySyncRequest(s,
869 SimanticsUI.UI_THREAD_REQUEST_START_TIMEOUT,
870 SimanticsUI.UI_THREAD_REQUEST_EXECUTION_TIMEOUT,
871 new ResolveURI(uri));
873 DefaultActions.asyncPerformDefaultAction(s, input, false, false, false);
875 } catch (DatabaseException | InterruptedException e) {
876 Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to resolve URI to a database resource or variable: " + uri, e));
883 @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
884 public static Function1<Object, Boolean> locationChanging(ReadGraph graph, Resource variable, Variable context) throws DatabaseException {
885 return PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE;