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