1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.diagram.adapter;
14 import java.awt.Point;
15 import java.awt.geom.Rectangle2D;
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;
57 * An {@link ElementFactory} for DIA.SVGElement instances.
60 * Loads element layers, transform and SVG document.
62 * @author Tuukka Lehtonen
64 public class SVGElementClassFactory extends ElementFactoryAdapter {
66 public static final ElementFactory INSTANCE = new SVGElementClassFactory();
68 private static final StaticSymbolImpl STATIC_SYMBOL = new StaticSymbolImpl(DefaultImages.SVG.get());
70 static class ClassRequest extends UnaryAsyncRead<Resource, ElementClass> {
72 public ClassRequest(Resource elementType) {
77 public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
78 createClass(graph, parameter, procedure);
84 public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram,
85 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
87 graph.asyncRequest(new ClassRequest(elementType), new TransientCacheAsyncListener<ElementClass>() {
90 public void exception(AsyncReadGraph graph, Throwable t) {
91 procedure.exception(graph, t);
95 public void execute(AsyncReadGraph graph, ElementClass result) {
96 procedure.execute(graph, result);
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(
107 new StaticObjectAdapter(elementType),
108 DefaultTransform.INSTANCE,
109 StaticSymbolImageInitializer.INSTANCE,
111 ImageElementHandler.INSTANCE,
112 SimpleElementLayers.INSTANCE)
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);
120 final GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 3);
122 loadSVG(graph, diagram, element, e, guard);
123 ElementFactoryUtil.loadLayersForElement(graph, diagram, e, element, guard);
124 ElementFactoryUtil.readTransform(graph, element, e, guard);
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);
130 graph.forPossibleRelatedValue(element, G2D.HasSVGDocument, Bindings.STRING, new AsyncProcedure<String>() {
132 public void exception(AsyncReadGraph graph, Throwable throwable) {
133 guard.exception(graph, throwable);
137 public void execute(AsyncReadGraph graph, final String svgDocument) {
138 if (svgDocument != null) {
140 if(Development.DEVELOPMENT) {
141 Rectangle2D bounds = SVGNode.getRealBounds(svgDocument);
142 if(bounds != null && bounds.isEmpty()) {
143 Simantics.async(new ReadRequest() {
145 public void run(ReadGraph graph) throws DatabaseException {
146 System.err.println("Graphics for element " + NameUtils.getSafeName(graph, element) + " are empty.");
152 Point referenceSize = diagram.getHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE);
153 IFactory<Image> img = SVGImage.createFactoryFromString(String.valueOf(element.getResourceId()), svgDocument, referenceSize);
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);
164 e.setHint(ElementHints.KEY_IMAGE, DefaultImages.UNKNOWN.get());
165 guard.execute(graph, e);