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.ReadRequest;
25 import org.simantics.db.common.request.UnaryAsyncRead;
26 import org.simantics.db.common.utils.NameUtils;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.procedure.AsyncProcedure;
29 import org.simantics.diagram.elements.SVGImage;
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.scenegraph.g2d.nodes.SVGNode;
50 import org.simantics.utils.Development;
51 import org.simantics.utils.datastructures.cache.IFactory;
52 import org.simantics.utils.datastructures.cache.ProvisionException;
53 import org.simantics.utils.ui.ErrorLogger;
56 * An {@link ElementFactory} for DIA.SVGElement instances.
59 * Loads element layers, transform and SVG document.
61 * @author Tuukka Lehtonen
63 public class SVGElementClassFactory extends ElementFactoryAdapter {
65 public static final ElementFactory INSTANCE = new SVGElementClassFactory();
67 private static final StaticSymbolImpl STATIC_SYMBOL = new StaticSymbolImpl(DefaultImages.SVG.get());
69 static class ClassRequest extends UnaryAsyncRead<Resource, ElementClass> {
71 public ClassRequest(Resource elementType) {
76 public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
77 createClass(graph, parameter, procedure);
83 public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram,
84 final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
86 graph.asyncRequest(new ClassRequest(elementType), new TransientCacheAsyncListener<ElementClass>() {
89 public void exception(AsyncReadGraph graph, Throwable t) {
90 procedure.exception(graph, t);
94 public void execute(AsyncReadGraph graph, ElementClass result) {
95 procedure.execute(graph, result);
102 static void createClass(AsyncReadGraph graph, final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
103 String id = "SVGElement: " + elementType.getResourceId();
104 procedure.execute(graph, ElementClass.compile(
106 new StaticObjectAdapter(elementType),
107 DefaultTransform.INSTANCE,
108 StaticSymbolImageInitializer.INSTANCE,
110 ImageElementHandler.INSTANCE,
111 SimpleElementLayers.INSTANCE)
116 public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> procedure) {
117 e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);
119 final GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 3);
121 loadSVG(graph, diagram, element, e, guard);
122 ElementFactoryUtil.loadLayersForElement(graph, diagram, e, element, guard);
123 ElementFactoryUtil.readTransform(graph, element, e, guard);
126 private void loadSVG(AsyncReadGraph graph, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> guard) {
127 G2DResource G2D = graph.getService(G2DResource.class);
129 graph.forPossibleRelatedValue(element, G2D.HasSVGDocument, Bindings.STRING, new AsyncProcedure<String>() {
131 public void exception(AsyncReadGraph graph, Throwable throwable) {
132 guard.exception(graph, throwable);
136 public void execute(AsyncReadGraph graph, final String svgDocument) {
137 if (svgDocument != null) {
139 if(Development.DEVELOPMENT) {
140 Rectangle2D bounds = SVGNode.getRealBounds(svgDocument);
141 if(bounds != null && bounds.isEmpty()) {
142 Simantics.async(new ReadRequest() {
144 public void run(ReadGraph graph) throws DatabaseException {
145 System.err.println("Graphics for element " + NameUtils.getSafeName(graph, element) + " are empty.");
151 Point referenceSize = diagram.getHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE);
152 IFactory<Image> img = SVGImage.createFactoryFromString(String.valueOf(element.getResourceId()), svgDocument, referenceSize);
154 img = ProviderUtils.rasterize(img);
155 e.setHint(ElementHints.KEY_IMAGE, img.get());
156 guard.execute(graph, e);
157 } catch (ProvisionException ex) {
158 ErrorLogger.defaultLogError(ex);
159 e.setHint(ElementHints.KEY_IMAGE, DefaultImages.SVG.get());
160 guard.execute(graph, e);
163 e.setHint(ElementHints.KEY_IMAGE, DefaultImages.UNKNOWN.get());
164 guard.execute(graph, e);