From: Tuukka Lehtonen Date: Mon, 29 Aug 2016 09:17:11 +0000 (+0300) Subject: Several Wiki documentation view improvements. X-Git-Tag: v1.25.0~148 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=089832880807e21e696b5f321a81fa93473c07a9;p=simantics%2Fplatform.git Several Wiki documentation view improvements. * Pin Selection toggle button added to Documentation view toolbar * Added support for linking to internal documents within the Simantics database in wiki documentation: [[Media:root://Documents/Document.pdf|This is the anchor text for the created link]] ** DocumentDialect will transform links like this into external links that look like this: [http://simantics-internal/http://Projects/Development%20Project/Project/Documents/Document.pdf This is the anchor text for the created link] ** Obviously external browsers and viewers do not understand these links but when these links are clicked in the Workbench Documentation view, the Browser component location changes are intercepted by the function returned by org.simantics.document.ui.function.All.locationChanging and the workbench's default action is performed for the database resource/variable that the URI in the link resolves to in the Simantics database. * DiagramViewerSelectionProvider.SelectionElement will now return a the variable of the diagram composite when element selection is the diagram resource itself. This helps the Documentation view show the wiki page of the diagram composite when nothing is selected on the diagram editor. * Fixed a couple of typos from org.simantics.scl.reflection.internal.registry.Namespace * org.simantics.views.ontology now supports defining SWT RowLayout/RowData for modelled composites. This is used in the Documentation view to flow all the action buttons above the text editor to separate rows even when the view is not wide enough to fit all buttons on a single row. refs #6449 --- diff --git a/bundles/org.simantics.document.ui.ontology/graph.tg b/bundles/org.simantics.document.ui.ontology/graph.tg index 0501da805..a32cf12e7 100644 Binary files a/bundles/org.simantics.document.ui.ontology/graph.tg and b/bundles/org.simantics.document.ui.ontology/graph.tg differ diff --git a/bundles/org.simantics.document.ui.ontology/graph/DocumentUI.pgraph b/bundles/org.simantics.document.ui.ontology/graph/DocumentUI.pgraph index 914bdca44..cb7cd6498 100644 --- a/bundles/org.simantics.document.ui.ontology/graph/DocumentUI.pgraph +++ b/bundles/org.simantics.document.ui.ontology/graph/DocumentUI.pgraph @@ -38,8 +38,12 @@ UI.WikitextContribution.View : VIEWS.Composite SG.Node.children _ : L0.List @L0.list _ : VIEWS.Composite - VIEWS.Composite.layout _ : VIEWS.GridLayout - VIEWS.GridLayout.columnCount 19 + VIEWS.Composite.layout _ : VIEWS.RowLayout + //VIEWS.RowLayout.type VIEWS.Control.Style.Constant.Horizontal + //VIEWS.RowLayout.spacing 0 + //VIEWS.RowLayout.justify true + //VIEWS.RowLayout.pack true + //VIEWS.RowLayout.wrap true VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData VIEWS.GridLayout.GridData.horizontalGrab true SG.Node.children _ : L0.List @@ -49,135 +53,102 @@ UI.WikitextContribution.View : VIEWS.Composite VIEWS.Button.tooltip "Makes selection bold or inserts some bold text at cursor" VIEWS.Button.modifier UI.Functions.boldModifier : L0.Function VIEWS.Button.image SILK.text_bold - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Makes selection italic or inserts some italic text at cursor" VIEWS.Button.modifier UI.Functions.italicModifier : L0.Function VIEWS.Button.image SILK.text_italic - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Makes selection strikethrough or inserts some strikethrough text at cursor" VIEWS.Button.modifier UI.Functions.strikethroughModifier : L0.Function VIEWS.Button.image SILK.text_strikethrough - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Makes selection underlined or inserts some underlined text at cursor" VIEWS.Button.modifier UI.Functions.underlineModifier : L0.Function VIEWS.Button.image SILK.text_underline - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a horizontal ruler at cursor" VIEWS.Button.modifier UI.Functions.horizontalRulerModifier : L0.Function VIEWS.Button.image SILK.text_horizontalrule - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Indents text" VIEWS.Button.modifier UI.Functions.indentModifier : L0.Function VIEWS.Button.image SILK.text_indent - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Modifies selection font or inserts text with font settings" VIEWS.Button.modifier UI.Functions.fontModifier : L0.Function VIEWS.Button.image SILK.font - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts an image" VIEWS.Button.modifier UI.Functions.imageModifier : L0.Function VIEWS.Button.image SILK.image - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData + _ : VIEWS.Button + VIEWS.Button.tooltip "Inserts an internal model-specific document link" + VIEWS.Button.modifier UI.Functions.internalLinkModifier : L0.Function + VIEWS.Button.image SILK.database_link + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData + _ : VIEWS.Button + VIEWS.Button.tooltip "Inserts an external website link" + VIEWS.Button.modifier UI.Functions.linkModifier : L0.Function + VIEWS.Button.image SILK.world_link + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a 1st level header" VIEWS.Button.modifier UI.Functions.header1Modifier : L0.Function VIEWS.Button.image SILK.text_heading_1 - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a 2nd level header" VIEWS.Button.modifier UI.Functions.header2Modifier : L0.Function VIEWS.Button.image SILK.text_heading_2 - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a 3rd level header" VIEWS.Button.modifier UI.Functions.header3Modifier : L0.Function VIEWS.Button.image SILK.text_heading_3 - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a 4th level header" VIEWS.Button.modifier UI.Functions.header4Modifier : L0.Function VIEWS.Button.image SILK.text_heading_4 - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a numbered list" VIEWS.Button.modifier UI.Functions.numberedListModifier : L0.Function VIEWS.Button.image SILK.text_list_numbers - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a bullet list" VIEWS.Button.modifier UI.Functions.bulletListModifier : L0.Function VIEWS.Button.image SILK.text_list_bullets - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.tooltip "Inserts a table" VIEWS.Button.modifier UI.Functions.tableModifier : L0.Function VIEWS.Button.image SILK.table - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING - _ : VIEWS.Button - VIEWS.Button.tooltip "Inserts an external website link" - VIEWS.Button.modifier UI.Functions.linkModifier : L0.Function - VIEWS.Button.image SILK.link - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.text "&Styles" VIEWS.Button.tooltip "Edits document styles" VIEWS.Button.modifier UI.Functions.styleModifier : L0.Function - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.text "&Apply changes" VIEWS.Button.tooltip "Applies any changes in the wiki markup into the document" VIEWS.Button.modifier UI.Functions.wikitextModifier : L0.Function - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData _ : VIEWS.Button VIEWS.Button.text "Delete document" VIEWS.Button.tooltip "Deletes the document" VIEWS.Button.modifier UI.Functions.onDeleteDocumentButton : L0.Function - VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData - VIEWS.GridLayout.GridData.horizontalAlignment VIEWS.GridLayout.GridData.BEGINNING - VIEWS.GridLayout.GridData.verticalAlignment VIEWS.GridLayout.GridData.BEGINNING + VIEWS.Control.layoutData _ : VIEWS.RowLayout.RowData UI.WikitextContribution.View.TextContainer : VIEWS.Composite VIEWS.Control.layoutData _ : VIEWS.GridLayout.GridData @@ -242,6 +213,8 @@ UI.Sash : VIEWS.SashForm VIEWS.GridLayout.GridData.verticalGrab true VIEWS.Browser.variable DOC.Functions.documentationRootVariable VIEWS.Browser.document DOC.Functions.documentationText + VIEWS.Browser.locationChanging UI.Functions.locationChanging : L0.Function + L0.HasValueType "a -> Boolean" UI.WikitextContribution.View UI.NoDocument : VIEWS.Composite diff --git a/bundles/org.simantics.document.ui.ontology/src/org/simantics/document/ui/DocumentUIResource.java b/bundles/org.simantics.document.ui.ontology/src/org/simantics/document/ui/DocumentUIResource.java index 7c5b0f455..82375ae2a 100644 --- a/bundles/org.simantics.document.ui.ontology/src/org/simantics/document/ui/DocumentUIResource.java +++ b/bundles/org.simantics.document.ui.ontology/src/org/simantics/document/ui/DocumentUIResource.java @@ -34,9 +34,11 @@ public class DocumentUIResource { public final Resource Functions_horizontalRulerModifier; public final Resource Functions_imageModifier; public final Resource Functions_indentModifier; + public final Resource Functions_internalLinkModifier; public final Resource Functions_isWikitext; public final Resource Functions_italicModifier; public final Resource Functions_linkModifier; + public final Resource Functions_locationChanging; public final Resource Functions_noDocumentText; public final Resource Functions_numberedListModifier; public final Resource Functions_onCreateDocumentButton; @@ -83,9 +85,11 @@ public class DocumentUIResource { public static final String Functions_horizontalRulerModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/horizontalRulerModifier"; public static final String Functions_imageModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/imageModifier"; public static final String Functions_indentModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/indentModifier"; + public static final String Functions_internalLinkModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/internalLinkModifier"; public static final String Functions_isWikitext = "http://www.simantics.org/DocumentUI-1.1/Functions/isWikitext"; public static final String Functions_italicModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/italicModifier"; public static final String Functions_linkModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/linkModifier"; + public static final String Functions_locationChanging = "http://www.simantics.org/DocumentUI-1.1/Functions/locationChanging"; public static final String Functions_noDocumentText = "http://www.simantics.org/DocumentUI-1.1/Functions/noDocumentText"; public static final String Functions_numberedListModifier = "http://www.simantics.org/DocumentUI-1.1/Functions/numberedListModifier"; public static final String Functions_onCreateDocumentButton = "http://www.simantics.org/DocumentUI-1.1/Functions/onCreateDocumentButton"; @@ -142,9 +146,11 @@ public class DocumentUIResource { Functions_horizontalRulerModifier = getResourceOrNull(graph, URIs.Functions_horizontalRulerModifier); Functions_imageModifier = getResourceOrNull(graph, URIs.Functions_imageModifier); Functions_indentModifier = getResourceOrNull(graph, URIs.Functions_indentModifier); + Functions_internalLinkModifier = getResourceOrNull(graph, URIs.Functions_internalLinkModifier); Functions_isWikitext = getResourceOrNull(graph, URIs.Functions_isWikitext); Functions_italicModifier = getResourceOrNull(graph, URIs.Functions_italicModifier); Functions_linkModifier = getResourceOrNull(graph, URIs.Functions_linkModifier); + Functions_locationChanging = getResourceOrNull(graph, URIs.Functions_locationChanging); Functions_noDocumentText = getResourceOrNull(graph, URIs.Functions_noDocumentText); Functions_numberedListModifier = getResourceOrNull(graph, URIs.Functions_numberedListModifier); Functions_onCreateDocumentButton = getResourceOrNull(graph, URIs.Functions_onCreateDocumentButton); diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/DocumentView.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/DocumentView.java index ccbfbd508..025b88b08 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/DocumentView.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/DocumentView.java @@ -11,7 +11,12 @@ *******************************************************************************/ package org.simantics.document.ui; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchPart; import org.simantics.ui.workbench.IPropertyPage; +import org.simantics.utils.ui.BundleUtils; import org.simantics.views.swt.ModelledView; /** @@ -19,6 +24,8 @@ import org.simantics.views.swt.ModelledView; */ public class DocumentView extends ModelledView { + private boolean pinSelection = false; + @Override protected String configurationURI() { return DocumentUIResource.URIs.View; @@ -29,4 +36,32 @@ public class DocumentView extends ModelledView { return null; } + @Override + protected void inputChanged(IWorkbenchPart provider, Object input) { + if (pinSelection) + return; + super.inputChanged(provider, input); + } + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + getViewSite().getActionBars().getToolBarManager().add(new PinSelection()); + } + + private class PinSelection extends Action { + public PinSelection() { + super("Pin Selection", IAction.AS_CHECK_BOX); + setImageDescriptor( + BundleUtils.getImageDescriptorFromPlugin( + "org.eclipse.ui", + "icons/full/etool16/pin_editor.png")); + } + + @Override + public void run() { + pinSelection = isChecked(); + } + } + } diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java index 20b8d3d0e..e5f8b4392 100644 --- a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/function/All.java @@ -13,8 +13,11 @@ 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; @@ -30,19 +33,26 @@ 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; @@ -50,9 +60,12 @@ 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; @@ -546,7 +559,7 @@ public class All { @Override void perform(String before, String selected, String after, Point selection) { - textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + selected + after); + textReference.setValue(before + "[[Image:root://Library/image.png|100px]]" + "\r\n" + selected + after); } @@ -683,6 +696,18 @@ public class All { } + @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 { @@ -691,8 +716,8 @@ public class All { @Override void perform(String before, String selected, String after, Point selection) { - textReference.setValue(before + "\r\n" + - "[http://www.simantics.org External Website Link]\r\n" + selected + after); + textReference.setValue(before + + "[http://www.simantics.org External Website Link]\r\n" + selected + after); } @@ -815,5 +840,51 @@ public class All { return true; } - + + private static class ResolveURI extends UnaryRead { + 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 PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE = new Function1() { + @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 locationChanging(ReadGraph graph, Resource variable, Variable context) throws DatabaseException { + return PERFORM_DEFAULT_ACTION_FOR_URI_RESOURCE; + } + } diff --git a/bundles/org.simantics.document/src/org/simantics/document/DocumentDialect.java b/bundles/org.simantics.document/src/org/simantics/document/DocumentDialect.java index 9fc8e98a7..7cb6bbee0 100644 --- a/bundles/org.simantics.document/src/org/simantics/document/DocumentDialect.java +++ b/bundles/org.simantics.document/src/org/simantics/document/DocumentDialect.java @@ -11,9 +11,10 @@ *******************************************************************************/ package org.simantics.document; -import java.io.File; import java.io.IOException; import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.regex.Matcher; @@ -26,78 +27,109 @@ import org.simantics.db.Resource; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.exception.DatabaseException; import org.simantics.image2.ontology.ImageResource; -import org.simantics.utils.FileUtils; - public class DocumentDialect { - - final Pattern imagePattern = Pattern.compile("\\[\\[Image(?::([^\\]]+))?\\]\\]"); final static public DocumentDialect INSTANCE = new DocumentDialect(); - public String transform(ReadGraph graph, Resource res, String options) { - + public static final String SIMANTICS_INTERNAL_URI_PREFIX = "http://simantics-internal/"; + + private static final String HTTP = "http://"; + private static final String ROOT = "root:/"; + private static final String IMAGE = "image"; + private static final String MEDIA = "media"; + + final Pattern imageOrMediaPattern = Pattern.compile("\\[\\[([Ii]mage|[Mm]edia)(?::([^\\]]+))?\\]\\]"); + + private static String digest(byte[] bytes) throws NoSuchAlgorithmException { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(bytes); + BigInteger number = new BigInteger(1, md.digest()); + return number.toString(16); + } + + private static String imageExtension(ReadGraph graph, Resource image) throws DatabaseException { + ImageResource IMAGE = ImageResource.getInstance(graph); + if (graph.isInstanceOf(image, IMAGE.PngImage)) + return ".png"; + else if (graph.isInstanceOf(image, IMAGE.JpegImage)) + return ".jpg"; + return null; + } + + public String transform(ReadGraph graph, Resource res, String type, String options) { try { - String[] parts = options.split("\\|"); - if(parts.length > 0) { - + if (parts.length > 0) { String uri = parts[0]; + Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(res)); - if(indexRoot == null) return null; + if (indexRoot == null) return null; String rootURI = graph.getURI(indexRoot); - uri = uri.replace("root:/", rootURI); - // (Apros #12268) For easier image linking, allow users to - // write white space as ' ' in the wiki-style image links. + + uri = uri.replace(ROOT, rootURI); + + // (Apros #12268) For more user-friendly linking, allow users to + // write white space as ' ' in the wiki-style image links instead + // of having to write %20. uri = uri.replace(" ", "%20"); - Resource image = graph.getPossibleResource(uri); - if(image == null) return null; - byte[] bytes = graph.getValue(image, Bindings.BYTE_ARRAY); - MessageDigest md; - md = MessageDigest.getInstance("MD5"); - md.update(bytes); - BigInteger number = new BigInteger(1, md.digest()); - String digest = number.toString(16); - File dir = Simantics.getTemporaryDirectory("documentImages"); - dir.mkdirs(); - - ImageResource IMAGE = ImageResource.getInstance(graph); - - String extension; - if(graph.isInstanceOf(image, IMAGE.PngImage)) extension = ".png"; - else if(graph.isInstanceOf(image, IMAGE.JpegImage)) extension = ".jpg"; - else return null; - - File f = new File(dir, digest + extension); - if(!f.exists()) - FileUtils.writeFile(f, bytes); - StringBuilder sb = new StringBuilder(); - sb.append("[[File: " + f.toURI()); - for(int i=1;i-- Views.Browser.document ==> "String" -- Views.Browser.variable ==> "Variable" -- Views.Browser.locationChanging ==> "a -> Boolean" -- Views.WikiBrowser.document ==> "String" -- Views.RowLayout.type ==> "Integer" -- Views.RowLayout.spacing ==> "Integer" -- Views.RowLayout.center ==> "Boolean" -- Views.RowLayout.fill ==> "Boolean" -- Views.RowLayout.justify ==> "Boolean" -- Views.RowLayout.pack ==> "Boolean" -- Views.RowLayout.wrap ==> "Boolean" -- Views.RowLayout.extendedMargins ==> "a" -- Views.RowLayout.RowData.width ==> "Integer" -- Views.RowLayout.RowData.height ==> "Integer" extends SWTParentNode implements LoaderNode { @@ -36,7 +36,7 @@ abstract public class SingleSWTViewNode extends SWTParentNode private Map genericProperties = new HashMap(); public Function2 propertyCallback; - public GridDataBean layoutData; + public LayoutDataBean layoutData; public int style; public String text; public RGB.Integer background; @@ -292,8 +292,8 @@ abstract public class SingleSWTViewNode extends SWTParentNode final public void synchronizeStyle(int style) { } - final public void synchronizeLayoutData(GridDataBean layoutData) { - if(layoutData != null) control.setLayoutData(SWTViewUtils.toGridData(layoutData)); + final public void synchronizeLayoutData(LayoutDataBean layoutData) { + if(layoutData != null) control.setLayoutData(SWTViewUtils.toLayoutData(layoutData)); } } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTBrowser.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTBrowser.java index 6df6bdaad..5c4d21269 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTBrowser.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTBrowser.java @@ -3,8 +3,11 @@ package org.simantics.views.swt.client.impl; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.browser.Browser; +import org.eclipse.swt.browser.LocationEvent; +import org.eclipse.swt.browser.LocationListener; import org.eclipse.swt.widgets.Composite; import org.simantics.db.layer0.variable.Variable; +import org.simantics.scl.runtime.function.Function1; import org.simantics.utils.datastructures.map.Tuple; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -12,10 +15,11 @@ public class SWTBrowser extends SingleSWTViewNode { private static final long serialVersionUID = -2704760050046054447L; - public String document; - public Variable variable; + public String document; + public Variable variable; + public Function1 locationChanging; - private Tuple lastAppliedParametrization; + private Tuple lastAppliedParametrization; @Override public void reset() { @@ -32,6 +36,18 @@ public class SWTBrowser extends SingleSWTViewNode { control = new Browser(parent, style); GridDataFactory.fillDefaults().grab(true, true).applyTo(control); + control.addLocationListener(new LocationListener() { + @Override + public void changing(LocationEvent event) { + Function1 lc = locationChanging; + if (lc != null) + lc.apply(event); + } + @Override + public void changed(LocationEvent event) { + } + }); + setProperties(); } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTComposite.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTComposite.java index 5fe825a96..a67d0abf9 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTComposite.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTComposite.java @@ -1,7 +1,7 @@ package org.simantics.views.swt.client.impl; import org.eclipse.swt.widgets.Composite; -import org.simantics.views.ViewUtils.GridLayoutBean; +import org.simantics.views.ViewUtils.LayoutBean; import org.simantics.views.swt.client.base.SWTViewUtils; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -9,7 +9,7 @@ public class SWTComposite extends SingleSWTViewNode { private static final long serialVersionUID = 7932335224632082902L; - public GridLayoutBean layout; + public LayoutBean layout; @Override public void createControls(org.eclipse.swt.widgets.Composite parent) { @@ -22,7 +22,7 @@ public class SWTComposite extends SingleSWTViewNode { } - final public void synchronizeLayout(GridLayoutBean layout) { + final public void synchronizeLayout(LayoutBean layout) { if(layout != null) control.setLayout(SWTViewUtils.toLayout(layout)); } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTExplorer.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTExplorer.java index f448ebde4..3c0ce5a1f 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTExplorer.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTExplorer.java @@ -23,7 +23,7 @@ import org.simantics.browsing.ui.swt.widgets.ModelBrowser; import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupportImpl; import org.simantics.scl.runtime.function.Function1; import org.simantics.views.ViewUtils.ColumnBean; -import org.simantics.views.ViewUtils.GridLayoutBean; +import org.simantics.views.ViewUtils.LayoutBean; import org.simantics.views.swt.client.base.SWTViewUtils; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -31,7 +31,7 @@ public class SWTExplorer extends SingleSWTViewNode { private static final long serialVersionUID = 7932335224632082902L; - public GridLayoutBean layout; + public LayoutBean layout; public String browseContext; public String contextMenuId; public String uiContext; @@ -189,7 +189,7 @@ public class SWTExplorer extends SingleSWTViewNode { } } - final public void synchronizeLayout(GridLayoutBean layout) { + final public void synchronizeLayout(LayoutBean layout) { } } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTSashForm.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTSashForm.java index 5bc8b2366..af79bdc8d 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTSashForm.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTSashForm.java @@ -3,7 +3,7 @@ package org.simantics.views.swt.client.impl; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Sash; -import org.simantics.views.ViewUtils.GridLayoutBean; +import org.simantics.views.ViewUtils.LayoutBean; import org.simantics.views.swt.client.base.SWTViewUtils; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -11,7 +11,7 @@ public class SWTSashForm extends SingleSWTViewNode { private static final long serialVersionUID = 7932335224632082902L; - public GridLayoutBean layout; + public LayoutBean layout; public int[] weights; public Integer orientation; @@ -26,7 +26,7 @@ public class SWTSashForm extends SingleSWTViewNode { } - final public void synchronizeLayout(GridLayoutBean layout) { + final public void synchronizeLayout(LayoutBean layout) { if(layout != null) control.setLayout(SWTViewUtils.toLayout(layout)); } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTScrolledComposite.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTScrolledComposite.java index 421315f89..1bf86ca12 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTScrolledComposite.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTScrolledComposite.java @@ -13,7 +13,7 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; -import org.simantics.views.ViewUtils.GridLayoutBean; +import org.simantics.views.ViewUtils.LayoutBean; import org.simantics.views.swt.client.base.SWTViewUtils; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -23,7 +23,7 @@ public class SWTScrolledComposite extends SingleSWTViewNode { private static final long serialVersionUID = 7932335224632082902L; - public GridLayoutBean layout; + public LayoutBean layout; private int minSize = 100; @@ -124,7 +124,7 @@ public class SWTScrolledComposite extends SingleSWTViewNode { } - final public void synchronizeLayout(GridLayoutBean layout) { + final public void synchronizeLayout(LayoutBean layout) { if(layout != null) control.setLayout(SWTViewUtils.toLayout(layout)); } diff --git a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTTabFolder.java b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTTabFolder.java index b8aebe537..629f28285 100644 --- a/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTTabFolder.java +++ b/bundles/org.simantics.views.swt.client/src/org/simantics/views/swt/client/impl/SWTTabFolder.java @@ -14,7 +14,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.simantics.browsing.ui.swt.widgets.GraphExplorerComposite; import org.simantics.utils.ui.jface.BasePostSelectionProvider; -import org.simantics.views.ViewUtils.GridLayoutBean; +import org.simantics.views.ViewUtils.LayoutBean; import org.simantics.views.swt.client.base.ISWTViewNode; import org.simantics.views.swt.client.base.SingleSWTViewNode; @@ -24,7 +24,7 @@ public class SWTTabFolder extends SingleSWTViewNode { public List childNames; - public GridLayoutBean layout; + public LayoutBean layout; final BasePostSelectionProvider selectionProvider = new BasePostSelectionProvider(); @@ -119,7 +119,7 @@ public class SWTTabFolder extends SingleSWTViewNode { } - final public void synchronizeLayout(GridLayoutBean layout) { + final public void synchronizeLayout(LayoutBean layout) { } } diff --git a/bundles/org.simantics.views/src/org/simantics/views/All.java b/bundles/org.simantics.views/src/org/simantics/views/All.java index 941213f9c..6d26bb7f8 100644 --- a/bundles/org.simantics.views/src/org/simantics/views/All.java +++ b/bundles/org.simantics.views/src/org/simantics/views/All.java @@ -104,12 +104,22 @@ public class All { @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") public static Object gridData(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { - return ViewUtils.getGridData(graph, converter); + return ViewUtils.getGridData(graph, converter); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") public static Object gridLayout(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { - return ViewUtils.getLayout(graph, converter); + return ViewUtils.getLayout(graph, converter); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") + public static Object rowData(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { + return ViewUtils.getRowData(graph, converter); + } + + @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") + public static Object rowLayout(ReadGraph graph, Resource converter, Variable context) throws DatabaseException { + return ViewUtils.getRowLayout(graph, converter); } @SCLValue(type = "ReadGraph -> Resource -> Variable -> a") diff --git a/bundles/org.simantics.views/src/org/simantics/views/ViewUtils.java b/bundles/org.simantics.views/src/org/simantics/views/ViewUtils.java index f22e5ad83..749c2856e 100644 --- a/bundles/org.simantics.views/src/org/simantics/views/ViewUtils.java +++ b/bundles/org.simantics.views/src/org/simantics/views/ViewUtils.java @@ -32,20 +32,35 @@ public class ViewUtils { } public static final Binding EXTENDED_MARGINS_BINDING = Bindings.getBindingUnchecked(ExtendedMargins.class); - - public static class GridLayoutBean extends Bean { - - public int numColumns; - public int horizontalSpacing; - public int verticalSpacing; + + public static class LayoutBean extends Bean { public int marginLeft; public int marginRight; public int marginTop; public int marginBottom; + } + + public static class GridLayoutBean extends LayoutBean { + + public int numColumns; + public int horizontalSpacing; + public int verticalSpacing; } - - public static class GridDataBean extends Bean { + + public static class RowLayoutBean extends LayoutBean { + public int type; + public int spacing; + public boolean center; + public boolean fill; + public boolean justify; + public boolean pack; + public boolean wrap; + } + + public static class LayoutDataBean extends Bean {} + + public static class GridDataBean extends LayoutDataBean { public int horizontalSpan; public boolean grabExcessHorizontalSpace; @@ -56,7 +71,12 @@ public class ViewUtils { public int heightHint; } - + + public static class RowDataBean extends LayoutDataBean { + public int width; + public int height; + } + public static class ColumnBean extends Bean { public String key; @@ -128,6 +148,50 @@ public class ViewUtils { } + public static RowLayoutBean getRowLayout(RequestProcessor processor, Resource configuration) throws DatabaseException { + return processor.sync(new ResourceRead(configuration) { + @Override + public RowLayoutBean perform(ReadGraph graph) throws DatabaseException { + ViewsResources VIEW = ViewsResources.getInstance(graph); + Integer type = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_type, Bindings.INTEGER); + Integer spacing = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_spacing, Bindings.INTEGER); + Boolean center = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_center, Bindings.BOOLEAN); + Boolean fill = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_fill, Bindings.BOOLEAN); + Boolean justify = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_justify, Bindings.BOOLEAN); + Boolean pack = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_pack, Bindings.BOOLEAN); + Boolean wrap = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_wrap, Bindings.BOOLEAN); + ExtendedMargins extendedMargins = graph.getPossibleRelatedValue(resource, VIEW.RowLayout_extendedMargins, EXTENDED_MARGINS_BINDING); + + RowLayoutBean layout = new RowLayoutBean(); + layout.type = type; + layout.spacing = spacing; + layout.center = center; + layout.fill = fill; + layout.justify = justify; + layout.pack = pack; + layout.wrap = wrap; + layout.marginLeft = extendedMargins.left; + layout.marginRight = extendedMargins.right; + layout.marginTop = extendedMargins.top; + layout.marginBottom = extendedMargins.bottom; + return layout; + } + }); + } + + public static RowDataBean getRowData(RequestProcessor processor, Resource configuration) throws DatabaseException { + return processor.sync(new ResourceRead(configuration) { + @Override + public RowDataBean perform(ReadGraph graph) throws DatabaseException { + ViewsResources VIEW = ViewsResources.getInstance(graph); + RowDataBean data = new RowDataBean(); + data.width = graph.getPossibleRelatedValue(resource, VIEW.GridLayout_GridData_preferredWidth, Bindings.INTEGER); + data.height = graph.getPossibleRelatedValue(resource, VIEW.GridLayout_GridData_preferredHeight, Bindings.INTEGER); + return data; + } + }); + } + public static int getStyle(RequestProcessor processor, Resource configuration) throws DatabaseException { return processor.sync(new ResourceRead(configuration) { @@ -188,6 +252,7 @@ public class ViewUtils { Simantics.getSession().async(new TernaryRead (configuration, context, relationURI) { + @SuppressWarnings("unchecked") @Override public T perform(ReadGraph graph) throws DatabaseException { Object value = graph.getRelatedValue2(parameter, graph.getResource(parameter3), parameter2);