]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java
3fbfa2304a062f67983ad8a62199057fe360acb7
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / SCLScenegraph.java
1 package org.simantics.modeling;
2
3 import java.awt.Dimension;
4 import java.awt.RenderingHints.Key;
5 import java.awt.geom.Rectangle2D;
6 import java.io.ByteArrayOutputStream;
7 import java.io.IOException;
8 import java.io.OutputStreamWriter;
9 import java.io.UnsupportedEncodingException;
10 import java.io.Writer;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.List;
14 import java.util.Set;
15 import java.util.UUID;
16
17 import org.apache.batik.dom.GenericDOMImplementation;
18 import org.apache.batik.svggen.SVGGraphics2D;
19 import org.simantics.db.Resource;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.diagram.elements.DiagramNodeUtil;
22 import org.simantics.diagram.elements.TextGridNode;
23 import org.simantics.diagram.elements.TextNode;
24 import org.simantics.g2d.canvas.ICanvasContext;
25 import org.simantics.g2d.diagram.DiagramHints;
26 import org.simantics.g2d.diagram.IDiagram;
27 import org.simantics.g2d.diagram.handler.DataElementMap;
28 import org.simantics.g2d.diagram.participant.Selection;
29 import org.simantics.g2d.element.IElement;
30 import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider;
31 import org.simantics.g2d.utils.CanvasUtils;
32 import org.simantics.scenegraph.ParentNode;
33 import org.simantics.scenegraph.g2d.G2DHints;
34 import org.simantics.scenegraph.g2d.G2DParentNode;
35 import org.simantics.scenegraph.g2d.G2DSceneGraph;
36 import org.simantics.scenegraph.g2d.events.command.Commands;
37 import org.simantics.scenegraph.g2d.nodes.BackgroundNode;
38 import org.simantics.scenegraph.g2d.nodes.BoundsNode;
39 import org.simantics.scenegraph.g2d.nodes.ConnectionNode;
40 import org.simantics.scenegraph.g2d.nodes.DataNode;
41 import org.simantics.scenegraph.g2d.nodes.DecorationSVGNode;
42 import org.simantics.scenegraph.g2d.nodes.NavigationNode;
43 import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
44 import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
45 import org.simantics.scenegraph.utils.NodeUtil;
46 import org.simantics.trend.impl.ItemNode;
47 import org.simantics.utils.threads.ThreadUtils;
48 import org.w3c.dom.DOMImplementation;
49 import org.w3c.dom.Document;
50 import org.w3c.dom.Element;
51
52 public class SCLScenegraph {
53         
54         public static ICanvasSceneGraphProvider getICanvasSceneGraphProvider(Resource model, Resource diagram, String diagramRVI) throws DatabaseException, InterruptedException {
55                 ICanvasSceneGraphProvider provider = DiagramNodeUtil.loadSceneGraphProvider(model, diagram, diagramRVI);
56                 return provider;
57         }
58         
59         public static void disposeSceneGraphProvider(ICanvasSceneGraphProvider provider) {
60                 provider.dispose();
61         }
62         
63         //public static Resource getDiagramRuntime(Resource ) 
64         
65         
66 //      public static String getNodeTransform(ICanvasContext ctx, String name) throws DatabaseException, InterruptedException {
67 //              return getNodeTransform(ctx, name);
68 //      }
69         
70         public static String getNodeTransform(ICanvasContext ctx, String name) {
71                 
72                 Set<TextNode> texts = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
73                 for (TextNode text : texts) {
74                         String nodeName = NodeUtil.getNodeName(text);
75                         if (nodeName.equals(name)) {
76                                 String transform = text.getTransform().toString();
77                                 return transform;
78                         }
79                 }
80                 return "No node found";
81         }
82         
83         public static String getNodeText(ICanvasContext ctx, String name) {
84                 
85                 Set<TextNode> texts = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
86                 for (TextNode text : texts) {
87                         String nodeName = NodeUtil.getNodeName(text);
88                         if (nodeName.equals(name)) {
89                                 String texti = text.getText();
90                                 return texti;
91                         }
92                 }
93                 return "No node found";
94         }
95         
96         public static String getNodeCount(ICanvasContext ctx) {
97                 G2DSceneGraph g2 = ctx.getSceneGraph();
98                 int amount = NodeUtil.countTreeNodes(g2);
99                 return "Node count: " + amount;
100         }
101         
102     public static String getAllNodes (ICanvasContext ctx) {
103         
104         Set<G2DSceneGraph> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), G2DSceneGraph.class);
105         int amount = g2.size() +1;
106         return "All nodes: " + amount;
107     }
108     
109     public static String getBoundsNodes (ICanvasContext ctx) {
110         
111         Set<BoundsNode> bn = NodeUtil.collectNodes(ctx.getSceneGraph(), BoundsNode.class);
112         int amount = bn.size();
113         return "BoundsNodes: " + amount;
114     }
115     
116     public static String getBackgroundNodes (ICanvasContext ctx) {
117         
118         Set<BackgroundNode> bg = NodeUtil.collectNodes(ctx.getSceneGraph(), BackgroundNode.class);
119         int amount = bg.size();
120         return "BackgroundNodes: " + amount;
121     }
122     
123     public static String getDataNodes (ICanvasContext ctx) {
124         
125         Set<DataNode> dn = NodeUtil.collectNodes(ctx.getSceneGraph(), DataNode.class);
126         int amount = dn.size();
127         return "DataNodes: " + amount;
128     }
129     
130     public static String getNavigationNodes (ICanvasContext ctx) {
131         
132         Set<NavigationNode> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), NavigationNode.class);
133         int amount = g2.size();
134         return "NavigationNodes: " + amount;
135     }
136     
137     public static String getParentNodes (ICanvasContext ctx) {
138         
139         Set<G2DParentNode> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), G2DParentNode.class);
140         int amount = g2.size();
141         return "ParentNodes: " + amount;
142     }
143     
144     public static String getDecorationNodes (ICanvasContext ctx) {
145         
146         Set<DecorationSVGNode> deco = NodeUtil.collectNodes(ctx.getSceneGraph(), DecorationSVGNode.class);
147         int amount = deco.size();
148         return "DecorationNodes: " + amount;
149     }
150     
151     public static String getSingleElementNodes (ICanvasContext ctx) {
152         
153         Set<SingleElementNode> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), SingleElementNode.class);
154         int amount = g2.size();
155         return "SingleElementNodes: " + amount;
156     }
157     
158     public static String getConnectionNodes (ICanvasContext ctx) {
159         
160         Set<ConnectionNode> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), ConnectionNode.class);
161         int amount = g2.size();
162         return "ConnectionNodes: " + amount;
163     }
164     
165     public static String getTextNodes (ICanvasContext ctx) {
166         
167         Set<TextNode> tn = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
168         Set<TextGridNode> tgn = NodeUtil.collectNodes(ctx.getSceneGraph(), TextGridNode.class);
169         int amount = tn.size() + tgn.size();
170         return "TextNodes: " + amount;
171     }
172     
173     public static String getItemNodes (ICanvasContext ctx) {
174         
175         Set<ItemNode> item = NodeUtil.collectNodes(ctx.getSceneGraph(), ItemNode.class);
176         int amount = item.size();
177         return "ItemNodes: " + amount;
178     }
179   
180     public static String editNodeText (ICanvasContext ctx, String module, String previous_value, String new_value) {
181                 
182         Set<TextNode> textGridNodes = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
183         for (TextNode modulenode : textGridNodes) {
184                 if (module.equals(modulenode.getText())) {
185                         //System.out.println("Module what we were looking for: " + module);
186                         //System.out.println("Modulenode: " + modulenode.getText());
187                         
188                         ParentNode<?> parentnode = modulenode.getParent();
189                         //System.out.println("Parentnode: " + parentnode);
190                         
191                         Collection<TextNode> textnodes = (Collection<TextNode>) parentnode.getNodes();
192                         for (TextNode valuenode : textnodes) {
193                                 if (previous_value.equals(valuenode.getText())) {
194                                         //System.out.println("Value what we were looking for: " + previous_value);
195                                         //System.out.println("Valuenode: " + valuenode.getText());
196                                         
197                                         //valuenode.setEditMode(true);
198                                         valuenode.activateEdit(0, null, ctx);
199                                         valuenode.setText(new_value);
200                                         valuenode.fireTextEditingEnded();
201                                         
202                                         //System.out.println("valuenode modified: " + valuenode);
203                                         return "Modified module " + module + " with value " + new_value;
204                                 }
205                         }
206                         return "Not found module : " + module;
207                 }
208         }
209         return "No nodes in scenegraph!";
210     }
211
212     public static String sceneGraphTest (ICanvasContext ctx, String module, String value) {
213         
214         boolean module_founded = false;
215         boolean value_founded = false;
216         
217         Set<G2DSceneGraph> g2 = NodeUtil.collectNodes(ctx.getSceneGraph(), G2DSceneGraph.class);
218         System.out.println("Total amount of nodes: " + g2.size() + 1);
219         
220         Set<TextGridNode> grid = NodeUtil.collectNodes(ctx.getSceneGraph(), TextGridNode.class);
221         Integer textGridNodeAmount = grid.size();
222         System.out.println("Amount of TextGridNodes " + textGridNodeAmount);
223         
224         Set<TextNode> texts = NodeUtil.collectNodes(ctx.getSceneGraph(), TextNode.class);
225         Integer textNodeAmount = grid.size();
226         System.out.println("Amount of TextNodes " + textNodeAmount);
227
228         for (TextNode node : texts) {
229             if (module.equals(node.getText())) {
230                 module_founded = true;
231                 System.out.println("Correct module " + module + " founded.");
232             }
233             if (value.equals(node.getText())) {
234                 value_founded = true;
235                 System.out.println("Correct value " + value + " founded.");
236             }
237         }
238         
239         if (value_founded == true && module_founded == true) {
240                 return "Found both correct module " + module + " and value " + value;
241         }
242         if (value_founded == false && module_founded == true) {
243                 return "Found only correct module " + module + " but not value " + value;
244         }
245         if (value_founded == true && module_founded == false) {
246                 return "Found only correct value " + value + " but not module " + module;
247         }
248         else {
249                 return "Didn't found either module " + module + " or value " + value;
250         }
251     }
252     
253      public static boolean copyPaste (final ICanvasContext source_ctx, final ICanvasContext target_ctx, List<Resource> modules) throws DatabaseException {
254         
255         IDiagram idiagram = source_ctx.getDefaultHintContext().getHint(DiagramHints.KEY_DIAGRAM);
256
257                 DataElementMap dem = idiagram.getDiagramClass().getAtMostOneItemOfClass(DataElementMap.class);
258                 if (dem != null) {
259                         final Collection<IElement> newSelection = new ArrayList<IElement>();
260                         for (Resource module : modules) {
261                                 IElement element = dem.getElement(idiagram, module);
262                                 if (element != null) {
263                                         newSelection.add(element);
264                                 } else {
265                                         throw new DatabaseException("Could not find IElement for " + element);
266                                 }
267                         }
268                         
269                         ThreadUtils.syncExec(source_ctx.getThreadAccess(), new Runnable() {
270                     @Override
271                     public void run() {
272                         if (source_ctx.isDisposed())
273                             return;
274                         Selection selection = source_ctx.getAtMostOneItemOfClass(Selection.class);
275                         if (selection != null) {
276                             // This prevents workbench selection from being left over.
277                             // Also prevents scene graph crap from being left on the screen.
278                             selection.setSelection(0, newSelection);
279                         }
280                                 CanvasUtils.sendCommand(source_ctx, Commands.COPY);
281                                 CanvasUtils.sendCommand(target_ctx, Commands.PASTE);
282                     }
283                 });
284                         
285                 //}
286                 
287                 while(source_ctx.getEventQueue().size() > 0) {
288                         try {
289                                 Thread.sleep(10);
290                         } catch (InterruptedException e) {
291                                 throw new DatabaseException(e);
292                         }
293                 }
294
295                 ThreadUtils.syncExec(source_ctx.getThreadAccess(), new Runnable() {
296             @Override
297             public void run() {
298             }
299         });             
300                                 
301                 }
302                 return true;
303     }
304      
305    
306      
307      
308      static class Generator extends SVGGraphics2D {
309          
310          int elemLevel = 0;
311          String newElementId = null;
312          ArrayList<Element> elements = new ArrayList<Element>();
313
314          public static final String svgNS = "http://www.w3.org/2000/svg";
315          
316                 public Generator(Document document) {
317                         super(document);
318                 }
319                 
320                 @Override
321                 public Element getRoot() {
322                         Element root = super.getRoot();
323                         for(Element e : elements) {
324                                 root.appendChild(e);
325                         }
326                         return root;
327                 }
328                 
329                 @Override
330                 public void setRenderingHint(Key arg0, Object arg1) {
331                         if(G2DHints.KEY_BEGIN_ELEMENT == arg0) {
332                                 elemLevel++;
333                         }
334                         if(G2DHints.KEY_ELEMENT_ID == arg0) {
335                                 if(arg1 != null)
336                                         newElementId = arg1.toString();
337                                 else
338                                         newElementId = UUID.randomUUID().toString();
339                         }
340                         if(G2DHints.KEY_END_ELEMENT == arg0) {
341                                 elemLevel--;
342                                 if(elemLevel == 0) {
343                                         Element group = getDOMFactory().createElementNS(SVG_NAMESPACE_URI, SVG_G_TAG);
344                                         group.setAttributeNS(null, "id", newElementId);
345                                         group.setAttributeNS(null, "class", arg1.toString());
346                                         getRoot(group);
347                                         elements.add(group);
348                                 }
349                         }
350                         super.setRenderingHint(arg0, arg1);
351                 }
352          
353      }
354      
355      public static String renderSVG(ICanvasContext ctx) {
356
357          // Get a DOMImplementation.
358          DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
359
360          // Create an instance of org.w3c.dom.Document.
361          String svgNS = "http://www.w3.org/2000/svg";
362          Document document = domImpl.createDocument(svgNS, "svg", null);
363          
364          // Create an instance of the SVG Generator.
365          SVGGraphics2D svgGenerator = new Generator(document);
366
367          try {
368                  
369              G2DSceneGraph sg = ctx.getSceneGraph();
370              G2DParentNode root = (G2DParentNode) sg.getRootNode();
371              
372              // rtree is the actual content of the diagram
373              RTreeNode rtree = NodeUtil.getNearestChildByClass(root, RTreeNode.class);
374              Rectangle2D rtreeBounds = NodeUtil.getLocalBounds(rtree);
375              
376              // nav is a node that has zooming functionalities
377              NavigationNode nav = NodeUtil.getNearestChildByClass(root, NavigationNode.class);
378              nav.setZoomEnabled(true);
379              
380              // fit view with the contents of rtreeBounds
381              nav.zoomTo(rtreeBounds);
382              
383              // get the bounds of the content
384              Rectangle2D content = NodeUtil.getLocalBounds(nav);
385              
386              // translate svgGenerator to the x and y coordinates of current content
387              svgGenerator.translate(-1 * content.getX(), -1 * content.getY());
388
389              Rectangle2D destination = new Rectangle2D.Double(0,0,1000,1000);
390              double sx = destination.getWidth() / content.getWidth();
391              double sy = destination.getHeight() / content.getHeight();
392              double scale = sx < sy ? sx : sy;
393              
394              svgGenerator.scale(scale, scale);
395              
396              // Set svgCanvasSize to the given size parameters
397              svgGenerator.setSVGCanvasSize(new Dimension((int)(scale * content.getWidth()), (int)(scale * content.getHeight())));
398              svgGenerator.setClip(content);
399              
400              sg.render(svgGenerator);
401              
402          } finally {
403          }
404
405          String result = "";
406
407          // Finally, stream out SVG to the standard output using
408          // UTF-8 encoding.
409          boolean useCSS = true; // we want to use CSS style attributes
410          try {
411              ByteArrayOutputStream os = new ByteArrayOutputStream();
412              Writer out = new OutputStreamWriter(os, "UTF-8");
413              svgGenerator.stream(out, useCSS);
414              os.flush();
415              os.close();
416              result = new String(os.toByteArray());//Base64.encode(os.toByteArray());
417          } catch (UnsupportedEncodingException e) {
418              e.printStackTrace();
419          } catch (IOException e) {
420              e.printStackTrace();
421          }
422          
423          return result;
424          
425      }
426
427
428 }