]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Issues-view menu improvements & Variable-based issue context resolution 78/278/3
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Thu, 19 Jan 2017 23:06:09 +0000 (01:06 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Fri, 20 Jan 2017 10:28:02 +0000 (12:28 +0200)
This adds a new [Resource] valued property for Issue instances that is
by default defined to just read the old Issue.HasContexts L0.List
property. The property allows for more specific domains to override the
issue context resource calculations.

To support this calculation a noteworthy change needed to be made to
org.simantics.db.layer0.function.All.getStandardChildDomainPropertyVariable.
It now performs a new final fallback step that resembles how the
standard procedural variables work. If the parent variable has a solver
variable node defined, it will use NodeManager.getClassifications as an
attempt to read the type Resource of the variable. If this is
successful, the asserted properties of the type are searched to find a
property matching name of the the requested property. To support this a
new request was added: UnescapedAssertedPropertyMapOfResource. This
request is also used to optimize the implementation of
All.standardGetValue[12].

These changes also add a Help action for Issues view context menu that
looks for the "contextHelpId" String property from the Variable
describing the issue.

refs #6948

Change-Id: I9655ea3647851fa04fb2420686cb13dd0c6719b6

16 files changed:
bundles/org.simantics.db.layer0/META-INF/MANIFEST.MF
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/UnescapedAssertedPropertyMapOfResource.java [new file with mode: 0644]
bundles/org.simantics.issues.common/src/org/simantics/issues/common/All.java
bundles/org.simantics.issues.ontology/graph.tg
bundles/org.simantics.issues.ontology/graph/Issue.pgraph
bundles/org.simantics.issues.ontology/src/org/simantics/issues/ontology/IssueResource.java
bundles/org.simantics.issues.ui.ontology/graph.tg
bundles/org.simantics.issues.ui.ontology/graph/IssueUI.pgraph
bundles/org.simantics.issues.ui.ontology/src/org/simantics/issues/ui/ontology/IssueUIResource.java
bundles/org.simantics.issues.ui/adapters.xml
bundles/org.simantics.issues.ui/plugin.xml
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/IssueView2.java
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/Help.java [new file with mode: 0644]
bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/MenuActions.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/OpenDiagramFromIssue.java

index d6a2b6365594cd6a140b7c3f2a28d470e758a891..7bf579b69a781020a290006076f6f3598cf8daa4 100644 (file)
@@ -32,7 +32,8 @@ Require-Bundle: gnu.trove3;bundle-version="3.0.3",
  org.simantics.issues.ontology;bundle-version="1.2.0",
  org.simantics.simulator.variable;bundle-version="1.0.0",
  org.simantics.scl.osgi;bundle-version="1.0.4",
- org.simantics.scl.compiler;bundle-version="0.4.0"
+ org.simantics.scl.compiler;bundle-version="0.4.0",
+ org.slf4j.api
 Export-Package: org.simantics.db.layer0,
  org.simantics.db.layer0.adapter,
  org.simantics.db.layer0.adapter.impl,
index 1c9331069ff13f28a56013cb42eaaa514bcd7f20..6a144165247732a36e1d47aa08240c5fbf9c0f86 100644 (file)
@@ -27,10 +27,10 @@ import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.issue.StandardIssue;
 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied2;
+import org.simantics.db.common.primitiverequest.PossibleResource;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.request.IsEnumeratedValue;
-import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
 import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.Functions;
@@ -47,6 +47,7 @@ import org.simantics.db.layer0.exception.VariableException;
 import org.simantics.db.layer0.request.PossibleURI;
 import org.simantics.db.layer0.request.PropertyInfo;
 import org.simantics.db.layer0.request.PropertyInfoRequest;
+import org.simantics.db.layer0.request.UnescapedAssertedPropertyMapOfResource;
 import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource;
 import org.simantics.db.layer0.scl.CompileResourceValueRequest;
 import org.simantics.db.layer0.scl.CompileValueRequest;
@@ -56,6 +57,7 @@ import org.simantics.db.layer0.variable.AbstractVariable;
 import org.simantics.db.layer0.variable.ChildVariableMapRequest;
 import org.simantics.db.layer0.variable.ExternalSetValue;
 import org.simantics.db.layer0.variable.PropertyVariableMapRequest;
+import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
 import org.simantics.db.layer0.variable.StandardComposedProperty;
 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
@@ -118,10 +120,20 @@ public class All {
                        
             if (variable.isAsserted()) {
                                if (variable.parentResource != null) {
-                           Layer0 L0 = Layer0.getInstance(graph);
-                                       for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {
-                                               if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {
-                                                       return graph.getRelatedValue2(assertion, L0.HasObject, variable);
+                                       Map<String, Pair<PropertyInfo, Resource>> assertions = graph.syncRequest(
+                                                       new UnescapedAssertedPropertyMapOfResource(variable.parentResource),
+                                                       TransientCacheAsyncListener.instance());
+
+                                       // NOTE: This optimization assumes the property
+                                       // variable's representation is the asserted object.
+                                       Resource object = variable.getPossibleRepresents(graph);
+                                       if (object != null) {
+                                               return graph.getValue2(object, variable);
+                                       } else {
+                                               for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
+                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                               return graph.getValue2(assertion.second, variable);
+                                                       }
                                                }
                                        }
                                }
@@ -156,13 +168,12 @@ public class All {
                
        try {
                        
-               Layer0 L0 = Layer0.getInstance(graph);
-               
                if(variable.property.hasEnumerationRange) {
                Resource object = variable.getRepresents(graph);
                if(graph.sync(new IsEnumeratedValue(object))) {
+                       Layer0 L0 = Layer0.getInstance(graph);
                        if(graph.isInstanceOf(object, L0.Literal)) {
-                               return graph.getValue(object);
+                               return graph.getValue(object, binding);
                        } else {
                                return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);
                        }
@@ -171,11 +182,22 @@ public class All {
                        
                if (variable.isAsserted()) {
                        if (variable.parentResource != null) {
-                               for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {
-                                       if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {
-                                               return graph.getRelatedValue2(assertion, L0.HasObject, context);
-                                       }
-                               }
+                                       Map<String, Pair<PropertyInfo, Resource>> assertions = graph.syncRequest(
+                                                       new UnescapedAssertedPropertyMapOfResource(variable.parentResource),
+                                                       TransientCacheAsyncListener.instance());
+
+                                       // NOTE: This optimization assumes the property
+                                       // variable's representation is the asserted object.
+                                       Resource object = variable.getPossibleRepresents(graph);
+                                       if (object != null) {
+                                               return graph.getValue2(object, variable, binding);
+                                       } else {
+                                               for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
+                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                               return graph.getValue2(assertion.second, variable, binding);
+                                                       }
+                                               }
+                                       }
                        }
                }
                        
@@ -450,6 +472,33 @@ public class All {
             // Fallback: try to ask property resource uri from NodeManager
             return createStandardGraphPropertyVariable(graph, variable, propertyNode);
         }
+        // Final fallback: check types corresponding to
+        // node classification(s) and look for asserted
+        // properties from the URIs specified.
+        if (variable.node != null) {
+            try {
+                @SuppressWarnings("unchecked")
+                Set<String> classifications = variable.node.support.manager.getClassifications(variable.node.node);
+                if (!classifications.isEmpty()) {
+                    for (String uri : classifications) {
+                        Resource type = graph.syncRequest(
+                                new PossibleResource(uri),
+                                TransientCacheAsyncListener.instance());
+                        if (type == null)
+                            continue;
+                        Map<String, Pair<PropertyInfo, Resource>> pm = graph.syncRequest(
+                                new UnescapedAssertedPropertyMapOfResource(type),
+                                TransientCacheAsyncListener.instance());
+                        Pair<PropertyInfo, Resource> pi = pm.get(name);
+                        if (pi != null) {
+                            return new StandardAssertedGraphPropertyVariable(graph, context, null, type, pi.first.predicate, pi.second);
+                        }
+                    }
+                }
+            } catch(NodeManagerException e) {
+                throw new DatabaseException(e);
+            }
+        }
         return null;
     }
 
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/UnescapedAssertedPropertyMapOfResource.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/request/UnescapedAssertedPropertyMapOfResource.java
new file mode 100644 (file)
index 0000000..6341363
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.layer0.request;
+
+ import gnu.trove.map.hash.THashMap;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.27.0
+ */
+public class UnescapedAssertedPropertyMapOfResource extends ResourceRead<Map<String, Pair<PropertyInfo, Resource>>> {
+
+       private static final Logger LOGGER = LoggerFactory.getLogger(UnescapedAssertedPropertyMapOfResource.class);
+
+       public UnescapedAssertedPropertyMapOfResource(Resource resource) {
+               super(resource);
+       }
+
+       @Override
+       public Map<String,Pair<PropertyInfo, Resource>> perform(ReadGraph graph) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               Collection<Statement> assertions = graph.getAssertedStatements(resource, L0.HasProperty); 
+               THashMap<String, Pair<PropertyInfo, Resource>> result = new THashMap<>(assertions.size());
+               for (Statement stm : assertions) {
+                       PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(stm.getPredicate()), TransientCacheAsyncListener.<PropertyInfo>instance());
+                       if (info != null && info.isHasProperty) {
+                               String name = info.name;
+                               // Use putIfAbsent because we want to prefer the results that are first,
+                               // i.e. the ones deeper in the type inheritance chain.
+                               if (result.putIfAbsent(name, Pair.make(info, stm.getObject())) != null) {
+                                       if (LOGGER.isDebugEnabled()) {
+                                               LOGGER.debug(this + ": The database resource $" + resource.getResourceId()
+                                                               + " asserts the multiple properties with the same name " + name + " (resource=$"
+                                                               + info.predicate.getResourceId() + ").");
+                                       }
+                               }
+                       }
+               }
+               return result;
+       }
+
+}
index 6ff625c0bb4ffc9f9535340da6f640181f5af8b4..9173101eee8d77e57f218791d551ac9d2e5f6ff5 100644 (file)
@@ -76,5 +76,10 @@ public class All {
                return IssueUtils.pathString(uri, modelURI.length()+1);
        }
     }
-     
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> [Resource]")
+    public static List<Resource> standardIssueContexts(ReadGraph graph, Resource converter, Variable property) throws DatabaseException {
+        return IssueUtils.getContextsForProperty(graph, property);
+    }
+
 }
index d0ad31bf4c0463847af4658c7484b4f053f0fcaf..7ed3dc9244b9666e3f4ee14fddb9d004c6178f4a 100644 (file)
Binary files a/bundles/org.simantics.issues.ontology/graph.tg and b/bundles/org.simantics.issues.ontology/graph.tg differ
index 3d428ed595088b49d085a52e55ab8837e8d5f0fd..47a8160b55dd44b718033bfd5667a60486831247 100644 (file)
@@ -33,6 +33,7 @@ ISSUE.Issue <T L0.Entity
       L0.InverseOf ISSUE.Issue.HasContext.Inverse <R L0.IsRelatedTo
     >-- ISSUE.Issue.HasSeverity --> ISSUE.Severity <R L0.DependsOn : L0.FunctionalRelation
     >-- ISSUE.Issue.HasContexts --> L0.List <R L0.DependsOn
+    >-- ISSUE.Issue.contexts ==> "[Resource]" <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.severity ==> "String" <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.resource ==> "String" <R L0.HasProperty : L0.FunctionalRelation
     >-- ISSUE.Issue.path ==> "String" <R L0.HasProperty : L0.FunctionalRelation
@@ -49,6 +50,9 @@ ISSUE.Issue <T L0.Entity
     @L0.assert ISSUE.Issue.path 
       ISSUE.Functions.standardIssuePath : L0.Function
         L0.HasValueType "String"
+    @L0.assert ISSUE.Issue.contexts
+      ISSUE.Functions.standardIssueContexts : L0.Function
+        L0.HasValueType "[Resource]"
 
 ISSUE.UserIssue
     L0.HasDescription "A tag for marking issues as manually added, i.e. so called user issues."
index 0bb8fd55f46c977de1af7f5f1fc3c735c14d4611..7c51fd64faf6e24519f45560bc7994cf64609c0c 100644 (file)
@@ -17,6 +17,7 @@ public class IssueResource {
     public final Resource Functions;
     public final Resource Functions_defaultDescription;
     public final Resource Functions_dependencyBaseRealizationFunction;
+    public final Resource Functions_standardIssueContexts;
     public final Resource Functions_standardIssuePath;
     public final Resource Functions_standardIssueResource;
     public final Resource Functions_standardIssueSeverity;
@@ -37,6 +38,8 @@ public class IssueResource {
     public final Resource Issue_HasContexts_Inverse;
     public final Resource Issue_HasSeverity;
     public final Resource Issue_HasSeverity_Inverse;
+    public final Resource Issue_contexts;
+    public final Resource Issue_contexts_Inverse;
     public final Resource Issue_creationTime;
     public final Resource Issue_creationTime_Inverse;
     public final Resource Issue_path;
@@ -83,6 +86,7 @@ public class IssueResource {
         public static final String Functions = "http://www.simantics.org/Issue-1.2/Functions";
         public static final String Functions_defaultDescription = "http://www.simantics.org/Issue-1.2/Functions/defaultDescription";
         public static final String Functions_dependencyBaseRealizationFunction = "http://www.simantics.org/Issue-1.2/Functions/dependencyBaseRealizationFunction";
+        public static final String Functions_standardIssueContexts = "http://www.simantics.org/Issue-1.2/Functions/standardIssueContexts";
         public static final String Functions_standardIssuePath = "http://www.simantics.org/Issue-1.2/Functions/standardIssuePath";
         public static final String Functions_standardIssueResource = "http://www.simantics.org/Issue-1.2/Functions/standardIssueResource";
         public static final String Functions_standardIssueSeverity = "http://www.simantics.org/Issue-1.2/Functions/standardIssueSeverity";
@@ -103,6 +107,8 @@ public class IssueResource {
         public static final String Issue_HasContexts_Inverse = "http://www.simantics.org/Issue-1.2/Issue/HasContexts/Inverse";
         public static final String Issue_HasSeverity = "http://www.simantics.org/Issue-1.2/Issue/HasSeverity";
         public static final String Issue_HasSeverity_Inverse = "http://www.simantics.org/Issue-1.2/Issue/HasSeverity/Inverse";
+        public static final String Issue_contexts = "http://www.simantics.org/Issue-1.2/Issue/contexts";
+        public static final String Issue_contexts_Inverse = "http://www.simantics.org/Issue-1.2/Issue/contexts/Inverse";
         public static final String Issue_creationTime = "http://www.simantics.org/Issue-1.2/Issue/creationTime";
         public static final String Issue_creationTime_Inverse = "http://www.simantics.org/Issue-1.2/Issue/creationTime/Inverse";
         public static final String Issue_path = "http://www.simantics.org/Issue-1.2/Issue/path";
@@ -159,6 +165,7 @@ public class IssueResource {
         Functions = getResourceOrNull(graph, URIs.Functions);
         Functions_defaultDescription = getResourceOrNull(graph, URIs.Functions_defaultDescription);
         Functions_dependencyBaseRealizationFunction = getResourceOrNull(graph, URIs.Functions_dependencyBaseRealizationFunction);
+        Functions_standardIssueContexts = getResourceOrNull(graph, URIs.Functions_standardIssueContexts);
         Functions_standardIssuePath = getResourceOrNull(graph, URIs.Functions_standardIssuePath);
         Functions_standardIssueResource = getResourceOrNull(graph, URIs.Functions_standardIssueResource);
         Functions_standardIssueSeverity = getResourceOrNull(graph, URIs.Functions_standardIssueSeverity);
@@ -179,6 +186,8 @@ public class IssueResource {
         Issue_HasContexts_Inverse = getResourceOrNull(graph, URIs.Issue_HasContexts_Inverse);
         Issue_HasSeverity = getResourceOrNull(graph, URIs.Issue_HasSeverity);
         Issue_HasSeverity_Inverse = getResourceOrNull(graph, URIs.Issue_HasSeverity_Inverse);
+        Issue_contexts = getResourceOrNull(graph, URIs.Issue_contexts);
+        Issue_contexts_Inverse = getResourceOrNull(graph, URIs.Issue_contexts_Inverse);
         Issue_creationTime = getResourceOrNull(graph, URIs.Issue_creationTime);
         Issue_creationTime_Inverse = getResourceOrNull(graph, URIs.Issue_creationTime_Inverse);
         Issue_path = getResourceOrNull(graph, URIs.Issue_path);
index fc1fd6498348e1fc77a615a673e8e1fdb2a8b79f..07c00e83007dd66ccff344ca3d9b9d90e7408c09 100644 (file)
Binary files a/bundles/org.simantics.issues.ui.ontology/graph.tg and b/bundles/org.simantics.issues.ui.ontology/graph.tg differ
index abc2da18bc877746ef74cbac9ab166ef5411e779..281bec912b3b2e8295d299f76fde093401f5f36d 100644 (file)
@@ -14,7 +14,7 @@ UI = <http://www.simantics.org/IssueUI-1.1> : L0.Ontology
     L0.HasResourceClass "org.simantics.issues.ui.ontology.IssueUIResource"
 
 //--------------------------------------------------------------------------
-// Functions
+// Libraries
 UI.Functions : L0.Library
 
 
@@ -43,6 +43,7 @@ ACTIONS.SeverityActionCategory : VP.ActionCategory
 ACTIONS.SetSeverityAction <T ACT.Action
     >-- ACTIONS.SetSeverityAction.HasSeverity --> ISSUE.Severity <R L0.DependsOn : L0.FunctionalRelation
 
+ACTIONS.Help : ACT.Action
 
 //--------------------------------------------------------------------------
 // Issue Browse context
@@ -194,7 +195,8 @@ IAC = UI.ActionContext : VP.BrowseContext
         ACTIONS.Hide : ACT.Action
     @VP.actionContribution "Unhide" IBC.Issue SILK.shading VP.EditActionCategory 
         ACTIONS.Unhide : ACT.Action
-
+    @VP.actionContribution "Help" IBC.Issue SILK.help VP.EditActionCategory ACTIONS.Help
+    @VP.actionContribution "Help" IBC.DynamicIssueHierarchyNode SILK.help VP.EditActionCategory ACTIONS.Help
 
 //--------------------------------------------------------------------------
 // Batch Issue Source Browse context
index 95eadd6a977f4f40d3914b43bd85748160bdfcee..6db48d7e81005e3dbf099926da6d42857dbd9f99 100644 (file)
@@ -12,6 +12,7 @@ public class IssueUIResource {
     
     public final Resource ActionContext;
     public final Resource Actions;
+    public final Resource Actions_Help;
     public final Resource Actions_Hide;
     public final Resource Actions_Resolve;
     public final Resource Actions_SetSeverityAction;
@@ -70,6 +71,7 @@ public class IssueUIResource {
     public static class URIs {
         public static final String ActionContext = "http://www.simantics.org/IssueUI-1.1/ActionContext";
         public static final String Actions = "http://www.simantics.org/IssueUI-1.1/Actions";
+        public static final String Actions_Help = "http://www.simantics.org/IssueUI-1.1/Actions/Help";
         public static final String Actions_Hide = "http://www.simantics.org/IssueUI-1.1/Actions/Hide";
         public static final String Actions_Resolve = "http://www.simantics.org/IssueUI-1.1/Actions/Resolve";
         public static final String Actions_SetSeverityAction = "http://www.simantics.org/IssueUI-1.1/Actions/SetSeverityAction";
@@ -138,6 +140,7 @@ public class IssueUIResource {
     public IssueUIResource(ReadGraph graph) {
         ActionContext = getResourceOrNull(graph, URIs.ActionContext);
         Actions = getResourceOrNull(graph, URIs.Actions);
+        Actions_Help = getResourceOrNull(graph, URIs.Actions_Help);
         Actions_Hide = getResourceOrNull(graph, URIs.Actions_Hide);
         Actions_Resolve = getResourceOrNull(graph, URIs.Actions_Resolve);
         Actions_SetSeverityAction = getResourceOrNull(graph, URIs.Actions_SetSeverityAction);
index 0754b4acd2b61b36a3da2ee118baed04d5860340..c1254f1800dc9b2ea9318c9b81481a018d93a1f6 100644 (file)
@@ -77,7 +77,9 @@
                        class="org.simantics.issues.ui.handler.Hide"/>
                <resource uri="http://www.simantics.org/IssueUI-0.0/Actions/Unhide"
                        class="org.simantics.issues.ui.handler.Unhide"/>
-               
+
+               <resource uri="http://www.simantics.org/IssueUI-0.0/Actions/Help"
+                       class="org.simantics.issues.ui.handler.Help" />
        </target>
 
 
index e67d2e12bdc8e5f669a403dc06ca84a944861346..584bd41ae80e429e42c656f6f714148e48bc9df6 100644 (file)
             id="org.simantics.issues.category"
             name="Issues">
       </category>
-      <!--
-      <view
-            category="org.simantics.issues.category"
-            class="org.simantics.issues.ui.IssueView"
-            icon="platform:/plugin/com.famfamfam.silk/icons/error.png"
-            id="org.simantics.issues.ui.issueview"
-            name="Issues">
-      </view>
-      -->
       <view
             category="org.simantics.issues.category"
             class="org.simantics.issues.ui.IssueView2"
index b683f246455ac13e5a52a29f7b555a25407421c6..162eeff87d5913862e9ff2fa7d5a799c3831dccf 100644 (file)
  *******************************************************************************/
 package org.simantics.issues.ui;
 
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.ui.IWorkbenchPart;
 import org.simantics.Simantics;
+import org.simantics.browsing.ui.GraphExplorer;
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.request.ResourceRead;
@@ -23,6 +27,7 @@ import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.issues.ui.ontology.IssueUIResource;
 import org.simantics.modeling.ModelingResources;
 import org.simantics.ui.workbench.IPropertyPage;
+import org.simantics.utils.ui.SWTUtils;
 import org.simantics.views.swt.ModelledView;
 
 /**
@@ -101,4 +106,29 @@ public class IssueView2 extends ModelledView {
         return null;
     }
 
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    @Override
+    public <T> T getAdapter(Class<T> adapter) {
+        if (GraphExplorer.class == adapter)
+            return (T) tryGetExplorer(container);
+        if (BrowseContext.class == adapter)
+            return (T) tryGetBrowseContext(container);
+        return super.getAdapter(adapter);
+    }
+
+    private BrowseContext tryGetBrowseContext(Control control) {
+        return SWTUtils.tryGetObject(control, c -> {
+            return c instanceof IAdaptable
+                    ? (BrowseContext) ((IAdaptable) c).getAdapter(BrowseContext.class)
+                            : null;
+        });
+    }
+
+    private GraphExplorer tryGetExplorer(Control control) {
+        return SWTUtils.tryGetObject(control, c -> {
+            return c.isDisposed() ? null
+                    : (GraphExplorer) c.getData(GraphExplorer.KEY_GRAPH_EXPLORER);
+        });
+    }
+
 }
diff --git a/bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/Help.java b/bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/handler/Help.java
new file mode 100644 (file)
index 0000000..ebdb5a4
--- /dev/null
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.issues.ui.handler;
+
+import org.eclipse.ui.PlatformUI;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.request.TernaryRead;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.db.layer0.variable.Variable;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.27.0
+ */
+public class Help implements ActionFactory {
+
+       @Override
+       public Runnable create(Object target) {
+               if (target instanceof Variable) {
+                       return () -> {
+                               try {
+                                       String id = Simantics.sync(new PossibleVariablePropertyValue<String>((Variable) target, "contextualHelpId", Bindings.STRING));
+                                       if (id == null) {
+                                               PlatformUI.getWorkbench().getHelpSystem().displayDynamicHelp();
+                                               return;
+                                       }
+                                       PlatformUI.getWorkbench().getHelpSystem().displayHelp(id);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
+                               }
+                       };
+               }
+
+               return null;
+       }
+
+       static class PossibleVariablePropertyValue<T> extends TernaryRead<Variable, String, Binding, T> {
+
+               public PossibleVariablePropertyValue(Variable variable, String property, Binding binding) {
+                       super(variable, property, binding);
+               }
+
+               @Override
+               public T perform(ReadGraph graph) throws DatabaseException {
+                       return parameter.getPossiblePropertyValue(graph, parameter2, parameter3);
+               }
+
+       }
+
+}
index 0323597316ac12170031157a20460d2c2401e341..b607eb7e1b065602aa0c0250599ad940b67445a4 100644 (file)
@@ -39,7 +39,6 @@ import org.simantics.issues.common.IssueUtils;
 import org.simantics.issues.ontology.IssueResource;
 import org.simantics.issues.ui.internal.Activator;
 import org.simantics.ui.contribution.DynamicMenuContribution;
-import org.simantics.utils.datastructures.Callback;
 import org.simantics.utils.ui.ErrorLogger;
 import org.simantics.utils.ui.ISelectionUtils;
 
@@ -181,12 +180,9 @@ public class MenuActions extends DynamicMenuContribution {
                         graph.deny(issue, ISSUE.Issue_HasSeverity);
                 }
             }
-        }, new Callback<DatabaseException>() {
-            @Override
-            public void run(DatabaseException e) {
-                if (e != null)
-                    ErrorLogger.defaultLogError(e);
-            }
+        }, e -> {
+            if (e != null)
+                ErrorLogger.defaultLogError(e);
         });
     }
 
index 8595d737440320c24e43816ed400ba622a159143..6af1ff84b95cee9abd1f6324680f29ccf3339889 100644 (file)
@@ -27,10 +27,8 @@ import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingResources;
 import org.simantics.modeling.ui.Activator;
-import org.simantics.structural.stubs.StructuralResource2;
 import org.simantics.ui.SimanticsUI;
 import org.simantics.ui.workbench.editor.AbstractResourceEditorAdapter;
-import org.simantics.utils.datastructures.Pair;
 
 /**
  * @author Tuukka Lehtonen