]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/symbolEditor/PopulateTerminalDropParticipant.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / symbolEditor / PopulateTerminalDropParticipant.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/symbolEditor/PopulateTerminalDropParticipant.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/symbolEditor/PopulateTerminalDropParticipant.java
new file mode 100644 (file)
index 0000000..6211b04
--- /dev/null
@@ -0,0 +1,252 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.modeling.ui.symbolEditor;\r
+\r
+import java.awt.datatransfer.Transferable;\r
+import java.awt.datatransfer.UnsupportedFlavorException;\r
+import java.awt.dnd.DnDConstants;\r
+import java.awt.dnd.DropTargetDragEvent;\r
+import java.awt.dnd.DropTargetDropEvent;\r
+import java.awt.dnd.DropTargetEvent;\r
+import java.awt.geom.Point2D;\r
+import java.io.IOException;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
+import org.simantics.diagram.synchronization.graph.ElementWriter;\r
+import org.simantics.diagram.ui.DiagramModelHints;\r
+import org.simantics.g2d.diagram.DiagramHints;\r
+import org.simantics.g2d.diagram.DiagramMutator;\r
+import org.simantics.g2d.diagram.DiagramUtils;\r
+import org.simantics.g2d.diagram.IDiagram;\r
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
+import org.simantics.g2d.dnd.DnDHints;\r
+import org.simantics.g2d.dnd.ElementClassDragItem;\r
+import org.simantics.g2d.dnd.IDnDContext;\r
+import org.simantics.g2d.dnd.IDragItem;\r
+import org.simantics.g2d.dnd.IDropTargetParticipant;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.ElementUtils;\r
+import org.simantics.g2d.element.IElement;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.symbolEditor.PopulateTerminal;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+import org.simantics.ui.dnd.LocalObjectTransferable;\r
+import org.simantics.ui.utils.ResourceAdaptionUtils;\r
+import org.simantics.utils.datastructures.Callback;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
+import org.simantics.utils.logging.TimeLogger;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class PopulateTerminalDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant {\r
+\r
+    private static final Key KEY_TERMINAL_RELATION = new KeyOf(Resource.class, "TERMINAL_RELATION");\r
+\r
+    protected GraphToDiagramSynchronizer synchronizer;\r
+    protected Resource                   symbolDiagram;\r
+\r
+    public PopulateTerminalDropParticipant(Resource symbolDiagram, GraphToDiagramSynchronizer synchronizer) {\r
+        this.symbolDiagram = symbolDiagram;\r
+        this.synchronizer = synchronizer;\r
+    }\r
+\r
+    @Override\r
+    public void dragEnter(final DropTargetDragEvent dtde, final IDnDContext dp) {\r
+        Transferable tr = dtde.getTransferable();\r
+        if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {\r
+\r
+            Session session = synchronizer.getSession();\r
+\r
+            try {\r
+                tr.getTransferData(LocalObjectTransferable.FLAVOR);\r
+                final Resource[] resources = ResourceAdaptionUtils.toResources(LocalObjectTransfer.getTransfer()\r
+                        .getObject());\r
+\r
+                int itemsAdded = session.syncRequest(new Read<Integer>() {\r
+                    @Override\r
+                    public Integer perform(ReadGraph g) throws DatabaseException {\r
+                        int items = 0;\r
+\r
+                        Layer0 L0 = Layer0.getInstance(g);\r
+                        DiagramResource DIA = DiagramResource.getInstance(g);\r
+                        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+                        ModelingResources MOD = ModelingResources.getInstance(g);\r
+\r
+                        Resource symbol = g.getPossibleObject(symbolDiagram, STR.Defines);\r
+                        if (symbol == null)\r
+                            return 0;\r
+                        Resource componentType = g.getPossibleObject(symbol, MOD.SymbolToComponentType);\r
+                        if (componentType == null)\r
+                            return 0;\r
+                        Set<Resource> connectionRelationsOfSymbol = new HashSet<Resource>( g.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, STR.ConnectionRelation)) );\r
+\r
+//                        System.out.println("Symbol: " + NameUtils.getURIOrSafeNameInternal(g, symbolDiagram));\r
+//                        System.out.println("Component type: " + NameUtils.getURIOrSafeNameInternal(g, componentType));\r
+//                        System.out.println("Connection relations: " + connectionRelationsOfSymbol);\r
+\r
+                        Set<Resource> usedConnectionRelations = new HashSet<Resource>();\r
+                        for (Resource terminal : g.syncRequest(new ObjectsWithType(symbolDiagram, L0.ConsistsOf, DIA.Terminal))) {\r
+                            Resource binds = DiagramGraphUtil.getPossibleConnectionPointOfTerminal(g, terminal);\r
+                            if(binds != null)\r
+                                for (Resource connRel : g.getObjects(binds, MOD.DiagramConnectionRelationToConnectionRelation))\r
+                                    usedConnectionRelations.add(connRel);\r
+                        }\r
+\r
+                        for (Resource resource : resources) {\r
+                            //System.out.println("Name: " + NameUtils.getSafeName(g, resource));\r
+                            IDragItem di = null;\r
+                            Resource connectionRelation = null;\r
+\r
+                            if (g.isInstanceOf(resource, STR.ConnectionRelation)) {\r
+                                if (!connectionRelationsOfSymbol.contains(resource))\r
+                                    continue;\r
+                                Resource terminal = g.getPossibleObject(resource, MOD.ConnectionRelationToTerminal);\r
+                                if (terminal == null)\r
+                                    terminal = MOD.TestTerminal;\r
+                                di = new ElementClassDragItem(synchronizer.getNodeClass(g, terminal));\r
+                                connectionRelation = resource;\r
+                            }\r
+                            /* TODO should we replace this with something?\r
+                               else if (g.isInstanceOf(resource, STR.ConnectionPointDefinition)) {\r
+                                Resource connectionType = g.getPossibleObject(resource, STR.HasConnectionType);\r
+                                Resource connectionDirection = g.getPossibleObject(resource, STR.HasConnectionDirection);\r
+                                Collection<Resource> terminals = connectionType == null || connectionDirection == null\r
+                                        ? Collections.<Resource> emptyList() : g.getObjects(connectionType,\r
+                                                g.getInverse(STR.SupportsConnectionType));\r
+                                if (terminals.isEmpty())\r
+                                    di = new ElementClassDragItem(synchronizer.getNodeClass(g, MOD.TestTerminal));\r
+                                else\r
+                                    for (Resource t : terminals)\r
+                                        if (connectionDirection.equals(g.getPossibleObject(t, STR.SupportsDirection))) {\r
+                                            di = new ElementClassDragItem(synchronizer.getNodeClass(t));\r
+                                            break;\r
+                                        }\r
+\r
+                                connectionRelation = g.getSingleObject(resource, L0.ConcernsRelation);\r
+                            }*/\r
+\r
+                            if (di != null && connectionRelation != null && !usedConnectionRelations.contains(connectionRelation)) {\r
+                                di.getHintContext().setHint(KEY_TERMINAL_RELATION, connectionRelation);\r
+                                dp.add( di );\r
+                                ++items;\r
+                            }\r
+                        }\r
+                        return items;\r
+                    }\r
+                });\r
+\r
+                if (itemsAdded > 0 ) {\r
+                    dp.getHints().setHint(DnDHints.KEY_DND_GRID_COLUMNS, Integer.valueOf(1));\r
+                    dtde.acceptDrag(DnDConstants.ACTION_COPY);\r
+                }\r
+\r
+            } catch (DatabaseException e) {\r
+                ErrorLogger.defaultLogError(e);\r
+            } catch (UnsupportedFlavorException e) {\r
+                ErrorLogger.defaultLogError(e);\r
+            } catch (IOException e) {\r
+                ErrorLogger.defaultLogError(e);\r
+            } catch (IllegalArgumentException e) {\r
+                ErrorLogger.defaultLogError(e);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public void dragExit(DropTargetEvent dte, IDnDContext dp) {\r
+        // System.out.println("exit");\r
+    }\r
+\r
+    @Override\r
+    public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) {\r
+        // System.out.println("over");\r
+    }\r
+\r
+    @Override\r
+    public void drop(DropTargetDropEvent dtde, final IDnDContext dp) {\r
+        TimeLogger.resetTimeAndLog(getClass(), "drop");\r
+    \r
+        final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);\r
+        if (d == null)\r
+            return;\r
+\r
+        DiagramUtils.mutateDiagram(d, mutator -> {\r
+            IDragItem items[] = dp.toArray();\r
+\r
+            for (IDragItem i : items) {\r
+                if (!(i instanceof ElementClassDragItem))\r
+                    continue;\r
+                final Resource relation = i.getHintContext().getHint(KEY_TERMINAL_RELATION);\r
+                if (relation == null)\r
+                    continue;\r
+\r
+                ElementClassDragItem res = (ElementClassDragItem) i;\r
+                ElementClass ec = res.getElementClass();\r
+\r
+                Point2D pos = dp.getItemPosition(i);\r
+                // System.out.println(pos);\r
+                assert (pos != null);\r
+\r
+                IElement element = mutator.newElement(ec);\r
+                ElementUtils.setPos(element, new Point2D.Double(pos.getX(), pos.getY()));\r
+                element.setHint(DiagramModelHints.KEY_ELEMENT_WRITER, new ElementWriter() {\r
+\r
+                    @Override\r
+                    public void addToGraph(WriteGraph g, IElement element, Resource terminal) throws DatabaseException {\r
+                        PopulateTerminal.addToGraph(g, symbolDiagram, relation, terminal);\r
+                    }\r
+\r
+                    @Override\r
+                    public void removeFromGraph(WriteGraph graph, Resource elementResource) {\r
+                    }\r
+                });\r
+\r
+                dp.remove(i);\r
+            }\r
+        });\r
+\r
+        getContext().getContentContext().setDirty();\r
+    }\r
+\r
+    @Override\r
+    public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) {\r
+        dtde.acceptDrag(DnDConstants.ACTION_COPY);\r
+    }\r
+\r
+    @Override\r
+    public int getAllowedOps() {\r
+        return DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;\r
+    }\r
+\r
+    @Override\r
+    public double getPriority() {\r
+       return 9.0;\r
+    }\r
+    \r
+}
\ No newline at end of file