]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/SVGElementClassFactory.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / SVGElementClassFactory.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in 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.diagram.adapter;\r
13 \r
14 import java.awt.Point;\r
15 import java.awt.geom.Rectangle2D;\r
16 \r
17 import org.simantics.Simantics;\r
18 import org.simantics.databoard.Bindings;\r
19 import org.simantics.db.AsyncReadGraph;\r
20 import org.simantics.db.ReadGraph;\r
21 import org.simantics.db.Resource;\r
22 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
23 import org.simantics.db.common.procedure.guarded.GuardedAsyncProcedureWrapper;\r
24 import org.simantics.db.common.request.BinaryAsyncRead;\r
25 import org.simantics.db.common.request.ReadRequest;\r
26 import org.simantics.db.common.request.UnaryAsyncRead;\r
27 import org.simantics.db.common.utils.NameUtils;\r
28 import org.simantics.db.exception.DatabaseException;\r
29 import org.simantics.db.procedure.AsyncProcedure;\r
30 import org.simantics.diagram.stubs.G2DResource;\r
31 import org.simantics.diagram.synchronization.SynchronizationHints;\r
32 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;\r
33 import org.simantics.g2d.canvas.ICanvasContext;\r
34 import org.simantics.g2d.diagram.DiagramHints;\r
35 import org.simantics.g2d.diagram.IDiagram;\r
36 import org.simantics.g2d.element.ElementClass;\r
37 import org.simantics.g2d.element.ElementHints;\r
38 import org.simantics.g2d.element.IElement;\r
39 import org.simantics.g2d.element.handler.impl.DefaultTransform;\r
40 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;\r
41 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
42 import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;\r
43 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;\r
44 import org.simantics.g2d.element.handler.impl.TextImpl;\r
45 import org.simantics.g2d.elementclass.ImageClass.ImageElementHandler;\r
46 import org.simantics.g2d.image.DefaultImages;\r
47 import org.simantics.g2d.image.Image;\r
48 import org.simantics.g2d.image.ProviderUtils;\r
49 import org.simantics.g2d.svg.SVGImage;\r
50 import org.simantics.scenegraph.g2d.nodes.SVGNode;\r
51 import org.simantics.utils.Development;\r
52 import org.simantics.utils.datastructures.cache.IFactory;\r
53 import org.simantics.utils.datastructures.cache.ProvisionException;\r
54 import org.simantics.utils.ui.ErrorLogger;\r
55 \r
56 /**\r
57  * An {@link ElementFactory} for DIA.SVGElement instances.\r
58  * \r
59  * <p>\r
60  * Loads element layers, transform and SVG document.\r
61  * \r
62  * @author Tuukka Lehtonen\r
63  */\r
64 public class SVGElementClassFactory extends ElementFactoryAdapter {\r
65 \r
66     public static final ElementFactory INSTANCE = new SVGElementClassFactory();\r
67 \r
68     private static final StaticSymbolImpl STATIC_SYMBOL = new StaticSymbolImpl(DefaultImages.SVG.get());\r
69 \r
70     static class ClassRequest extends UnaryAsyncRead<Resource, ElementClass> {\r
71 \r
72         public ClassRequest(Resource elementType) {\r
73             super(elementType);\r
74         }\r
75 \r
76         @Override\r
77         public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {\r
78             createClass(graph, parameter, procedure);\r
79         }\r
80 \r
81     }\r
82 \r
83     @Override\r
84     public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram,\r
85             final Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
86 \r
87         graph.asyncRequest(new ClassRequest(elementType), new TransientCacheAsyncListener<ElementClass>() {\r
88 \r
89             @Override\r
90             public void exception(AsyncReadGraph graph, Throwable t) {\r
91                 procedure.exception(graph, t);\r
92             }\r
93 \r
94             @Override\r
95             public void execute(AsyncReadGraph graph, ElementClass result) {\r
96                 procedure.execute(graph, result);\r
97             }\r
98 \r
99         });\r
100 \r
101     }\r
102 \r
103     static void createClass(AsyncReadGraph graph, final Resource elementType, final AsyncProcedure<ElementClass> procedure) {\r
104         String id = "SVGElement: " + elementType.getResourceId();\r
105         procedure.execute(graph, ElementClass.compile(\r
106                 TextImpl.INSTANCE,\r
107                 new StaticObjectAdapter(elementType),\r
108                 DefaultTransform.INSTANCE,\r
109                 StaticSymbolImageInitializer.INSTANCE,\r
110                 STATIC_SYMBOL,\r
111                 ImageElementHandler.INSTANCE,\r
112                 SimpleElementLayers.INSTANCE)\r
113                 .setId(id));\r
114     }\r
115 \r
116     @Override\r
117     public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> procedure) {\r
118         e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);\r
119 \r
120         final GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 3);\r
121 \r
122         loadSVG(graph, diagram, element, e, guard);\r
123         ElementFactoryUtil.loadLayersForElement(graph, diagram, e, element, guard);\r
124         ElementFactoryUtil.readTransform(graph, element, e, guard);\r
125     }\r
126 \r
127     private void loadSVG(AsyncReadGraph graph, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> guard) {\r
128         G2DResource G2D = graph.getService(G2DResource.class);\r
129 \r
130         graph.forPossibleRelatedValue(element, G2D.HasSVGDocument, Bindings.STRING, new AsyncProcedure<String>() {\r
131             @Override\r
132             public void exception(AsyncReadGraph graph, Throwable throwable) {\r
133                 guard.exception(graph, throwable);\r
134             }\r
135 \r
136             @Override\r
137             public void execute(AsyncReadGraph graph, final String svgDocument) {\r
138                 if (svgDocument != null) {\r
139 \r
140                     if(Development.DEVELOPMENT) {\r
141                         Rectangle2D bounds = SVGNode.getRealBounds(svgDocument);\r
142                         if(bounds != null && bounds.isEmpty()) {\r
143                             Simantics.async(new ReadRequest() {\r
144                                 @Override \r
145                                 public void run(ReadGraph graph) throws DatabaseException {\r
146                                     System.err.println("Graphics for element " + NameUtils.getSafeName(graph, element) + " are empty.");\r
147                                 }\r
148                             });\r
149                         }\r
150                     }\r
151 \r
152                     Point referenceSize = diagram.getHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE);\r
153                     IFactory<Image> img = SVGImage.createFactoryFromString(String.valueOf(element.getResourceId()), svgDocument, referenceSize);\r
154                     try {\r
155                         img = ProviderUtils.rasterize(img);\r
156                         e.setHint(ElementHints.KEY_IMAGE, img.get());\r
157                         guard.execute(graph, e);\r
158                     } catch (ProvisionException ex) {\r
159                         ErrorLogger.defaultLogError(ex);\r
160                         e.setHint(ElementHints.KEY_IMAGE, DefaultImages.SVG.get());\r
161                         guard.execute(graph, e);\r
162                     }\r
163                 } else {\r
164                     e.setHint(ElementHints.KEY_IMAGE, DefaultImages.UNKNOWN.get());\r
165                     guard.execute(graph, e);\r
166                 }\r
167             }\r
168         });\r
169     }\r
170 \r
171 }