]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
50aab8c6c52d53b4333729fb5c9b7f4b70690193
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.elements2.profiles;\r
13 \r
14 import java.awt.geom.AffineTransform;\r
15 import java.awt.geom.Rectangle2D;\r
16 import java.util.Collections;\r
17 import java.util.List;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.common.request.PossibleTypedParent;\r
23 import org.simantics.db.common.utils.ListUtils;\r
24 import org.simantics.db.exception.DatabaseException;\r
25 import org.simantics.db.layer0.variable.Variable;\r
26 import org.simantics.diagram.profile.StyleBase;\r
27 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
28 import org.simantics.issues.common.ErrorIssues;\r
29 import org.simantics.issues.common.FatalIssues;\r
30 import org.simantics.issues.common.WarningIssues;\r
31 import org.simantics.issues.ontology.IssueResource;\r
32 import org.simantics.layer0.Layer0;\r
33 import org.simantics.modeling.ModelingResources;\r
34 import org.simantics.scenegraph.INode;\r
35 import org.simantics.scenegraph.g2d.nodes.SVGNode;\r
36 import org.simantics.scenegraph.profile.EvaluationContext;\r
37 import org.simantics.scenegraph.profile.common.ProfileVariables;\r
38 import org.simantics.scenegraph.utils.NodeUtil;\r
39 import org.simantics.simulation.ontology.SimulationResource;\r
40 import org.simantics.sysdyn.ui.Activator;\r
41 import org.simantics.utils.datastructures.map.Tuple;\r
42 \r
43 /**\r
44  * Issue Decorations. Display an issue icon on \r
45  * a diagram element depending on the type of the issue\r
46  * .\r
47  * @author Teemu Lempinen\r
48  *\r
49  */\r
50 public class IssueDecorationStyle extends StyleBase<IssueResult> {\r
51 \r
52     private static final String DECORATION_NODE_NAME = "issueDecorations";\r
53 \r
54     @Override\r
55     public IssueResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
56         Layer0 L0 = Layer0.getInstance(graph);\r
57         ModelingResources MOD = ModelingResources.getInstance(graph);\r
58         \r
59         // Find a component for the element \r
60         Resource component = graph.getPossibleObject(element, MOD.ElementToComponent);\r
61         if (component == null)\r
62             return null;\r
63 \r
64         // Get the current transform of the element to be able to move the decoration with the element\r
65         AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element);\r
66 \r
67         // Find the model of the component\r
68         Resource model = graph.syncRequest(new PossibleTypedParent(component, SimulationResource.getInstance(graph).Model));\r
69         if (model == null)\r
70             return null;\r
71 \r
72         // Project\r
73         Resource project = graph.getPossibleObject(model, L0.PartOf);\r
74         if (project == null)\r
75             return null;\r
76 \r
77         IssueResult result = null;\r
78         \r
79         /*\r
80          * Search for issues. Start from fatal and move to\r
81          * less important issues. This way the most important \r
82          * issue will be displayed.\r
83          * \r
84          * The issue is returned immediately after it is found.\r
85          */\r
86         \r
87         Set<Variable> fatals = graph.syncRequest(new FatalIssues(project, true));\r
88         result = getIssue(graph, IssueResult.Severity.FATAL, fatals, component, transform);\r
89         if(result != null) return result;\r
90         \r
91         Set<Variable> errors = graph.syncRequest(new ErrorIssues(project, true));\r
92         result = getIssue(graph, IssueResult.Severity.ERROR, errors, component, transform);\r
93         if(result != null) return result;\r
94 \r
95         Set<Variable> warnings = graph.syncRequest(new WarningIssues(project, true));\r
96         result = getIssue(graph, IssueResult.Severity.WARNING, warnings, component, transform);\r
97         if(result != null) return result;\r
98 \r
99         // No issue was found\r
100         return null;\r
101     }\r
102     \r
103     /**\r
104      * See if a set of issue variables concern this component\r
105      * \r
106      * @param graph ReadGraph\r
107      * @param severity IssueResult.Severity of the issue\r
108      * @param issues Collection of issues of type severity\r
109      * @param component The component that is evaluated for issues\r
110      * @param transform AffineTransform of the diagram element\r
111      * @return IssueResult containing the severity and transform of the issue or null if no issue concerned component\r
112      * @throws DatabaseException\r
113      */\r
114     private IssueResult getIssue(ReadGraph graph, IssueResult.Severity severity, Set<Variable> issues, Resource component, AffineTransform transform) throws DatabaseException {\r
115         IssueResource ISSUE = IssueResource.getInstance(graph);\r
116         Resource list, issueResource;\r
117         for(Variable issue : issues) {\r
118             issueResource = issue.getRepresents(graph);\r
119             list = graph.getPossibleObject(issueResource, ISSUE.Issue_HasContexts);\r
120             List<Resource> contexts = ListUtils.toList(graph, list);\r
121             if(!contexts.isEmpty()) {\r
122                 if(ListUtils.toList(graph, list).get(0).equals(component)) {\r
123                     return new IssueResult(severity, transform);\r
124                 }\r
125             }\r
126         }\r
127         return null;\r
128     }\r
129 \r
130     @Override\r
131     public void applyStyleForNode(EvaluationContext observer, INode node, IssueResult result) {\r
132         \r
133         // If result == null, remove possible issue decoration\r
134         if (result == null) {\r
135             ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME);\r
136             return;\r
137         }\r
138 \r
139         // Create issue decoration node\r
140         SVGNode svgNode = ProfileVariables.claimChild(node, "", DECORATION_NODE_NAME, SVGNode.class, observer);\r
141 \r
142         // Move the decoration to the upper right corner of the element\r
143         Rectangle2D bounds = NodeUtil.getLocalBounds(node, Collections.<INode>singleton(svgNode));\r
144         double tx = bounds.getMaxX();\r
145         double ty = bounds.getY();\r
146         svgNode.setZIndex( Integer.MAX_VALUE );\r
147         svgNode.setTransform( AffineTransform.getTranslateInstance(tx-1, ty-1)); \r
148         svgNode.getTransform().scale(0.5, 0.5);\r
149         \r
150 \r
151         // Apply the corresponding svg graphics to the node\r
152         IssueResult.Severity sev = result.getSeverity();\r
153         if (IssueResult.Severity.FATAL.equals(sev))\r
154             svgNode.setData(Activator.FATAL_SVG_TEXT);\r
155         else if (IssueResult.Severity.ERROR.equals(sev))\r
156             svgNode.setData(Activator.ERROR_SVG_TEXT);\r
157         else if (IssueResult.Severity.WARNING.equals(sev))\r
158             svgNode.setData(Activator.WARNING_SVG_TEXT);\r
159     }\r
160 \r
161     @Override\r
162     protected void cleanupStyleForNode(INode node) {\r
163         ProfileVariables.denyChild(node, "", DECORATION_NODE_NAME);\r
164     }\r
165 \r
166 }\r
167 \r
168 /**\r
169  * This is needed to keep the issue decoration up-to-date when its parent\r
170  * element moves.\r
171  */\r
172 class IssueResult extends Tuple {\r
173     \r
174     public enum Severity{FATAL, ERROR, WARNING};\r
175     \r
176     public IssueResult(Severity severity, AffineTransform transform) {\r
177         super(severity, transform);\r
178     }\r
179     public Severity getSeverity() {\r
180         return (Severity) getField(0);\r
181     }\r
182 }\r