]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.symbolEditor;\r
13 \r
14 import java.awt.datatransfer.Transferable;\r
15 import java.awt.datatransfer.UnsupportedFlavorException;\r
16 import java.awt.dnd.DnDConstants;\r
17 import java.awt.dnd.DropTargetDragEvent;\r
18 import java.awt.dnd.DropTargetDropEvent;\r
19 import java.awt.dnd.DropTargetEvent;\r
20 import java.awt.geom.Point2D;\r
21 import java.io.IOException;\r
22 import java.util.HashSet;\r
23 import java.util.Set;\r
24 \r
25 import org.simantics.db.ReadGraph;\r
26 import org.simantics.db.Resource;\r
27 import org.simantics.db.Session;\r
28 import org.simantics.db.WriteGraph;\r
29 import org.simantics.db.common.request.ObjectsWithType;\r
30 import org.simantics.db.exception.DatabaseException;\r
31 import org.simantics.db.request.Read;\r
32 import org.simantics.diagram.adapter.GraphToDiagramSynchronizer;\r
33 import org.simantics.diagram.stubs.DiagramResource;\r
34 import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
35 import org.simantics.diagram.synchronization.graph.ElementWriter;\r
36 import org.simantics.diagram.ui.DiagramModelHints;\r
37 import org.simantics.g2d.diagram.DiagramHints;\r
38 import org.simantics.g2d.diagram.DiagramMutator;\r
39 import org.simantics.g2d.diagram.DiagramUtils;\r
40 import org.simantics.g2d.diagram.IDiagram;\r
41 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
42 import org.simantics.g2d.dnd.DnDHints;\r
43 import org.simantics.g2d.dnd.ElementClassDragItem;\r
44 import org.simantics.g2d.dnd.IDnDContext;\r
45 import org.simantics.g2d.dnd.IDragItem;\r
46 import org.simantics.g2d.dnd.IDropTargetParticipant;\r
47 import org.simantics.g2d.element.ElementClass;\r
48 import org.simantics.g2d.element.ElementUtils;\r
49 import org.simantics.g2d.element.IElement;\r
50 import org.simantics.layer0.Layer0;\r
51 import org.simantics.modeling.ModelingResources;\r
52 import org.simantics.modeling.symbolEditor.PopulateTerminal;\r
53 import org.simantics.structural.stubs.StructuralResource2;\r
54 import org.simantics.ui.dnd.LocalObjectTransfer;\r
55 import org.simantics.ui.dnd.LocalObjectTransferable;\r
56 import org.simantics.ui.utils.ResourceAdaptionUtils;\r
57 import org.simantics.utils.datastructures.Callback;\r
58 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
59 import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
60 import org.simantics.utils.logging.TimeLogger;\r
61 import org.simantics.utils.ui.ErrorLogger;\r
62 \r
63 /**\r
64  * @author Tuukka Lehtonen\r
65  */\r
66 public class PopulateTerminalDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant {\r
67 \r
68     private static final Key KEY_TERMINAL_RELATION = new KeyOf(Resource.class, "TERMINAL_RELATION");\r
69 \r
70     protected GraphToDiagramSynchronizer synchronizer;\r
71     protected Resource                   symbolDiagram;\r
72 \r
73     public PopulateTerminalDropParticipant(Resource symbolDiagram, GraphToDiagramSynchronizer synchronizer) {\r
74         this.symbolDiagram = symbolDiagram;\r
75         this.synchronizer = synchronizer;\r
76     }\r
77 \r
78     @Override\r
79     public void dragEnter(final DropTargetDragEvent dtde, final IDnDContext dp) {\r
80         Transferable tr = dtde.getTransferable();\r
81         if (tr.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {\r
82 \r
83             Session session = synchronizer.getSession();\r
84 \r
85             try {\r
86                 tr.getTransferData(LocalObjectTransferable.FLAVOR);\r
87                 final Resource[] resources = ResourceAdaptionUtils.toResources(LocalObjectTransfer.getTransfer()\r
88                         .getObject());\r
89 \r
90                 int itemsAdded = session.syncRequest(new Read<Integer>() {\r
91                     @Override\r
92                     public Integer perform(ReadGraph g) throws DatabaseException {\r
93                         int items = 0;\r
94 \r
95                         Layer0 L0 = Layer0.getInstance(g);\r
96                         DiagramResource DIA = DiagramResource.getInstance(g);\r
97                         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
98                         ModelingResources MOD = ModelingResources.getInstance(g);\r
99 \r
100                         Resource symbol = g.getPossibleObject(symbolDiagram, STR.Defines);\r
101                         if (symbol == null)\r
102                             return 0;\r
103                         Resource componentType = g.getPossibleObject(symbol, MOD.SymbolToComponentType);\r
104                         if (componentType == null)\r
105                             return 0;\r
106                         Set<Resource> connectionRelationsOfSymbol = new HashSet<Resource>( g.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, STR.ConnectionRelation)) );\r
107 \r
108 //                        System.out.println("Symbol: " + NameUtils.getURIOrSafeNameInternal(g, symbolDiagram));\r
109 //                        System.out.println("Component type: " + NameUtils.getURIOrSafeNameInternal(g, componentType));\r
110 //                        System.out.println("Connection relations: " + connectionRelationsOfSymbol);\r
111 \r
112                         Set<Resource> usedConnectionRelations = new HashSet<Resource>();\r
113                         for (Resource terminal : g.syncRequest(new ObjectsWithType(symbolDiagram, L0.ConsistsOf, DIA.Terminal))) {\r
114                             Resource binds = DiagramGraphUtil.getPossibleConnectionPointOfTerminal(g, terminal);\r
115                             if(binds != null)\r
116                                 for (Resource connRel : g.getObjects(binds, MOD.DiagramConnectionRelationToConnectionRelation))\r
117                                     usedConnectionRelations.add(connRel);\r
118                         }\r
119 \r
120                         for (Resource resource : resources) {\r
121                             //System.out.println("Name: " + NameUtils.getSafeName(g, resource));\r
122                             IDragItem di = null;\r
123                             Resource connectionRelation = null;\r
124 \r
125                             if (g.isInstanceOf(resource, STR.ConnectionRelation)) {\r
126                                 if (!connectionRelationsOfSymbol.contains(resource))\r
127                                     continue;\r
128                                 Resource terminal = g.getPossibleObject(resource, MOD.ConnectionRelationToTerminal);\r
129                                 if (terminal == null)\r
130                                     terminal = MOD.TestTerminal;\r
131                                 di = new ElementClassDragItem(synchronizer.getNodeClass(g, terminal));\r
132                                 connectionRelation = resource;\r
133                             }\r
134                             /* TODO should we replace this with something?\r
135                                else if (g.isInstanceOf(resource, STR.ConnectionPointDefinition)) {\r
136                                 Resource connectionType = g.getPossibleObject(resource, STR.HasConnectionType);\r
137                                 Resource connectionDirection = g.getPossibleObject(resource, STR.HasConnectionDirection);\r
138                                 Collection<Resource> terminals = connectionType == null || connectionDirection == null\r
139                                         ? Collections.<Resource> emptyList() : g.getObjects(connectionType,\r
140                                                 g.getInverse(STR.SupportsConnectionType));\r
141                                 if (terminals.isEmpty())\r
142                                     di = new ElementClassDragItem(synchronizer.getNodeClass(g, MOD.TestTerminal));\r
143                                 else\r
144                                     for (Resource t : terminals)\r
145                                         if (connectionDirection.equals(g.getPossibleObject(t, STR.SupportsDirection))) {\r
146                                             di = new ElementClassDragItem(synchronizer.getNodeClass(t));\r
147                                             break;\r
148                                         }\r
149 \r
150                                 connectionRelation = g.getSingleObject(resource, L0.ConcernsRelation);\r
151                             }*/\r
152 \r
153                             if (di != null && connectionRelation != null && !usedConnectionRelations.contains(connectionRelation)) {\r
154                                 di.getHintContext().setHint(KEY_TERMINAL_RELATION, connectionRelation);\r
155                                 dp.add( di );\r
156                                 ++items;\r
157                             }\r
158                         }\r
159                         return items;\r
160                     }\r
161                 });\r
162 \r
163                 if (itemsAdded > 0 ) {\r
164                     dp.getHints().setHint(DnDHints.KEY_DND_GRID_COLUMNS, Integer.valueOf(1));\r
165                     dtde.acceptDrag(DnDConstants.ACTION_COPY);\r
166                 }\r
167 \r
168             } catch (DatabaseException e) {\r
169                 ErrorLogger.defaultLogError(e);\r
170             } catch (UnsupportedFlavorException e) {\r
171                 ErrorLogger.defaultLogError(e);\r
172             } catch (IOException e) {\r
173                 ErrorLogger.defaultLogError(e);\r
174             } catch (IllegalArgumentException e) {\r
175                 ErrorLogger.defaultLogError(e);\r
176             }\r
177         }\r
178 \r
179     }\r
180 \r
181     @Override\r
182     public void dragExit(DropTargetEvent dte, IDnDContext dp) {\r
183         // System.out.println("exit");\r
184     }\r
185 \r
186     @Override\r
187     public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) {\r
188         // System.out.println("over");\r
189     }\r
190 \r
191     @Override\r
192     public void drop(DropTargetDropEvent dtde, final IDnDContext dp) {\r
193         TimeLogger.resetTimeAndLog(getClass(), "drop");\r
194     \r
195         final IDiagram d = getHint(DiagramHints.KEY_DIAGRAM);\r
196         if (d == null)\r
197             return;\r
198 \r
199         DiagramUtils.mutateDiagram(d, mutator -> {\r
200             IDragItem items[] = dp.toArray();\r
201 \r
202             for (IDragItem i : items) {\r
203                 if (!(i instanceof ElementClassDragItem))\r
204                     continue;\r
205                 final Resource relation = i.getHintContext().getHint(KEY_TERMINAL_RELATION);\r
206                 if (relation == null)\r
207                     continue;\r
208 \r
209                 ElementClassDragItem res = (ElementClassDragItem) i;\r
210                 ElementClass ec = res.getElementClass();\r
211 \r
212                 Point2D pos = dp.getItemPosition(i);\r
213                 // System.out.println(pos);\r
214                 assert (pos != null);\r
215 \r
216                 IElement element = mutator.newElement(ec);\r
217                 ElementUtils.setPos(element, new Point2D.Double(pos.getX(), pos.getY()));\r
218                 element.setHint(DiagramModelHints.KEY_ELEMENT_WRITER, new ElementWriter() {\r
219 \r
220                     @Override\r
221                     public void addToGraph(WriteGraph g, IElement element, Resource terminal) throws DatabaseException {\r
222                         PopulateTerminal.addToGraph(g, symbolDiagram, relation, terminal);\r
223                     }\r
224 \r
225                     @Override\r
226                     public void removeFromGraph(WriteGraph graph, Resource elementResource) {\r
227                     }\r
228                 });\r
229 \r
230                 dp.remove(i);\r
231             }\r
232         });\r
233 \r
234         getContext().getContentContext().setDirty();\r
235     }\r
236 \r
237     @Override\r
238     public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) {\r
239         dtde.acceptDrag(DnDConstants.ACTION_COPY);\r
240     }\r
241 \r
242     @Override\r
243     public int getAllowedOps() {\r
244         return DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK;\r
245     }\r
246 \r
247     @Override\r
248     public double getPriority() {\r
249         return 9.0;\r
250     }\r
251     \r
252 }