]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/editor/SubscriptionDropParticipant.java
c410414d2276a3b2930a00d4938b5b2f6563a837
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / editor / SubscriptionDropParticipant.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * 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.charts.editor;\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.io.IOException;\r
21 import java.util.ArrayList;\r
22 import java.util.Collection;\r
23 import java.util.Collections;\r
24 import java.util.List;\r
25 \r
26 import org.eclipse.jface.viewers.ISelection;\r
27 import org.simantics.Simantics;\r
28 import org.simantics.charts.query.AddChartItem;\r
29 import org.simantics.charts.query.ChartItemDescriptor;\r
30 import org.simantics.charts.ui.AddVariableToChartAction;\r
31 import org.simantics.charts.ui.ChartDropActionFactory;\r
32 import org.simantics.charts.ui.ChartVariable;\r
33 import org.simantics.databoard.util.ObjectUtils;\r
34 import org.simantics.db.ReadGraph;\r
35 import org.simantics.db.Resource;\r
36 import org.simantics.db.common.request.UnaryRead;\r
37 import org.simantics.db.exception.DatabaseException;\r
38 import org.simantics.db.layer0.SelectionHints;\r
39 import org.simantics.db.layer0.request.PossibleModel;\r
40 import org.simantics.db.layer0.variable.RVI;\r
41 import org.simantics.db.layer0.variable.Variable;\r
42 import org.simantics.db.layer0.variable.VariableReference;\r
43 import org.simantics.db.layer0.variable.Variables;\r
44 import org.simantics.db.request.Read;\r
45 import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
46 import org.simantics.g2d.dnd.DragItem;\r
47 import org.simantics.g2d.dnd.IDnDContext;\r
48 import org.simantics.g2d.dnd.IDragItem;\r
49 import org.simantics.g2d.dnd.IDropTargetParticipant;\r
50 import org.simantics.modeling.ModelingResources;\r
51 import org.simantics.modeling.PropertyVariables;\r
52 import org.simantics.modeling.PropertyVariablesImpl;\r
53 import org.simantics.modeling.utils.VariableReferences;\r
54 import org.simantics.ui.dnd.LocalObjectTransfer;\r
55 import org.simantics.ui.dnd.LocalObjectTransferable;\r
56 import org.simantics.ui.selection.WorkbenchSelectionElement;\r
57 import org.simantics.utils.ui.ErrorLogger;\r
58 import org.simantics.utils.ui.ISelectionUtils;\r
59 import org.simantics.utils.ui.dialogs.ShowMessage;\r
60 \r
61 /**\r
62  * @author Tuukka Lehtonen\r
63  */\r
64 public class SubscriptionDropParticipant extends AbstractDiagramParticipant implements IDropTargetParticipant { \r
65 \r
66     private static class SubscriptionItemDragItem extends DragItem<ChartItemDescriptor> {\r
67         public SubscriptionItemDragItem(ChartItemDescriptor obj) {\r
68             super(obj);\r
69         }\r
70     }\r
71 \r
72     private static class VariableReferenceDragItem extends DragItem<VariableReference> {\r
73         public VariableReferenceDragItem(VariableReference obj) {\r
74             super(obj);\r
75         }\r
76     }\r
77     \r
78     Resource container;\r
79     Resource model;\r
80 \r
81     public SubscriptionDropParticipant(Resource container) {\r
82         this.container = container;\r
83         try {\r
84                         model = Simantics.getSession().sync( new PossibleModel( container ) );\r
85                 } catch (DatabaseException e) {\r
86                 }\r
87     }\r
88 \r
89     @Override\r
90     public void dragEnter(DropTargetDragEvent dtde, IDnDContext dp) {\r
91         // The transferable doesn't know LOT\r
92         if (!dtde.isDataFlavorSupported(LocalObjectTransferable.FLAVOR)) {\r
93             dtde.rejectDrag();\r
94             return;\r
95         }\r
96 \r
97         // The source cannot link, too bad\r
98         if ((dtde.getSourceActions() & DnDConstants.ACTION_LINK) == 0) {\r
99             dtde.rejectDrag();\r
100             return;\r
101         }\r
102 \r
103         // Ensure the content is usable\r
104         try {\r
105             Transferable t = dtde.getTransferable();\r
106             Object data = t.getTransferData(LocalObjectTransferable.FLAVOR);\r
107             data = LocalObjectTransfer.getTransfer().getObject();\r
108 \r
109             List<IDragItem> items = new ArrayList<IDragItem>();\r
110 \r
111             final List<Resource> resources = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Resource.class);\r
112             if (!resources.isEmpty()) {\r
113                 // Support SubscriptionItem drags\r
114                 items.addAll( Simantics.getSession().syncRequest(new Read<List<IDragItem>>() {\r
115                     @Override\r
116                     public List<IDragItem> perform(ReadGraph graph) throws DatabaseException {\r
117                         List<IDragItem> result = new ArrayList<IDragItem>();\r
118                         //Layer0 L0 = Layer0.getInstance(graph);\r
119                         ModelingResources MOD = ModelingResources.getInstance(graph);\r
120                         Resource targetModel = graph.syncRequest(new PossibleModel(container));\r
121                         if (targetModel != null) {\r
122                             for (Resource r : resources) {\r
123                                 //System.out.println( graph.getPossibleRelatedValue(r, L0.HasName) );\r
124                                 if (graph.isInstanceOf(r, MOD.Subscription_Item)) {\r
125                                     Resource model = graph.syncRequest(new PossibleModel(r));\r
126                                     if (ObjectUtils.objectEquals(targetModel, model))\r
127                                         result.add( new SubscriptionItemDragItem( AddChartItem.createDescriptor(graph, r) ) );\r
128                                 }\r
129                             }\r
130                         }\r
131                         return result;\r
132                     }\r
133                 }) );\r
134             }\r
135 \r
136             if(data instanceof RVI) {\r
137 \r
138                 VariableReferenceDragItem vrdi = new VariableReferenceDragItem(Simantics.getSession().sync(new UnaryRead<RVI, VariableReference>((RVI)data) {\r
139                     @Override\r
140                     public VariableReference perform(ReadGraph graph) throws DatabaseException {\r
141                         return new VariableReference(parameter, Variables.getDatatype(graph, model, parameter), null);\r
142                     }\r
143                 }));\r
144                 items.add( vrdi );\r
145 \r
146             } else {\r
147                 // Variable/PropertyVariable are mutually exclusive\r
148                 List<IDragItem> varItems = null;\r
149 \r
150                 // 1st try Variable\r
151                 final List<Variable> vars2 = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, Variable.class);\r
152                 if (!vars2.isEmpty()) {\r
153                     varItems = Simantics.getSession().syncRequest( new Read<List<IDragItem>>() {\r
154                         @Override\r
155                         public List<IDragItem> perform(ReadGraph graph) throws DatabaseException {\r
156                             return toDragItems( graph.syncRequest(VariableReferences.variablesToReferences(model, vars2)) );\r
157                         }\r
158                     } );\r
159                 }\r
160                 if (varItems == null || varItems.isEmpty()) {\r
161                     // Try legacy PropertyVariables\r
162                     final List<PropertyVariables> vars = ISelectionUtils.getPossibleKeys(data, SelectionHints.KEY_MAIN, PropertyVariables.class);\r
163                     if (!vars.isEmpty()) {\r
164                         varItems = Simantics.getSession().syncRequest( new Read<List<IDragItem>>() {\r
165                             @Override\r
166                             public List<IDragItem> perform(ReadGraph graph) throws DatabaseException {\r
167                                 List<PropertyVariables> vars2 = PropertyVariablesImpl.resolve(graph, vars);\r
168                                 return toDragItems( graph.syncRequest(VariableReferences.toReferences(model, vars2)) );\r
169                             }\r
170                         } );\r
171                     }\r
172                 }\r
173                 if (varItems != null)\r
174                     items.addAll(varItems);\r
175 \r
176                 // Try WorkbenchSelectionElement\r
177                 if (data instanceof ISelection) {\r
178                     final List<WorkbenchSelectionElement> wses = ISelectionUtils.filterSelection((ISelection)data, WorkbenchSelectionElement.class);\r
179                     if (!wses.isEmpty()) {\r
180                         items.addAll( Simantics.getSession().syncRequest( new Read<List<IDragItem>>() {\r
181                             @Override\r
182                             public List<IDragItem> perform(ReadGraph graph) throws DatabaseException {\r
183                                 List<Variable> wsevars = new ArrayList<Variable>();\r
184                                 ChartVariable av = new ChartVariable(graph);\r
185                                 for(WorkbenchSelectionElement wse : wses) {\r
186                                     Variable v = wse.getContent(av);\r
187                                     if(v != null) {\r
188                                         wsevars.add(v);\r
189                                     }\r
190                                 }\r
191                                 return toDragItems( graph.syncRequest(VariableReferences.variablesToReferences(model, wsevars)) );\r
192                             }\r
193                         } ) );\r
194                     }\r
195                 }\r
196             }\r
197 \r
198             if (items.isEmpty()) {\r
199                 dtde.rejectDrag();\r
200             } else {\r
201                 // Accept, make sure it is Link\r
202                 for (IDragItem i : items)\r
203                     dp.add(i);\r
204                 dtde.acceptDrag( DnDConstants.ACTION_LINK );\r
205             }\r
206         } catch (UnsupportedFlavorException e) {\r
207             throw new RuntimeException(e);\r
208         } catch (IOException e) {\r
209             ErrorLogger.defaultLogError(e);\r
210             dtde.rejectDrag();\r
211         } catch (DatabaseException e) {\r
212             ErrorLogger.defaultLogError(e);\r
213             dtde.rejectDrag();\r
214         }\r
215     }\r
216 \r
217     @Override\r
218     public void dragExit(DropTargetEvent dte, IDnDContext dp) {\r
219         for (IDragItem i : dp.getItemsByClass(SubscriptionItemDragItem.class))\r
220             dp.remove(i);\r
221         for (IDragItem i : dp.getItemsByClass(VariableReferenceDragItem.class))\r
222             dp.remove(i);\r
223     }\r
224 \r
225     @Override\r
226     public void dragOver(DropTargetDragEvent dtde, IDnDContext dp) {\r
227     }\r
228 \r
229     @Override\r
230     public void drop(DropTargetDropEvent dtde, IDnDContext dp) {\r
231         // Subscription Item\r
232         Collection<SubscriptionItemDragItem> subs = dp.getItemsByClass(SubscriptionItemDragItem.class);\r
233         if (!subs.isEmpty()) {\r
234             List<ChartItemDescriptor> cicr = new ArrayList<ChartItemDescriptor>();\r
235             for (SubscriptionItemDragItem sidi : subs) {\r
236                 cicr.add(sidi.getObject());\r
237             }\r
238             ChartDropActionFactory.addPlots(container, cicr, Collections.<Resource>emptySet()).run();\r
239             dtde.dropComplete(true);\r
240             return;\r
241         }\r
242         \r
243         // Variable Reference\r
244         Collection<VariableReferenceDragItem> vrdis = dp.getItemsByClass(VariableReferenceDragItem.class);\r
245         if (!vrdis.isEmpty()) {\r
246             List<VariableReference> refs = new ArrayList<VariableReference>();\r
247             for (VariableReferenceDragItem vrdi : vrdis) {\r
248                 refs.add( vrdi.getObject() );\r
249             }\r
250             Resource chart = container;\r
251             try {\r
252                 AddVariableToChartAction a = new AddVariableToChartAction( chart, null, refs );\r
253                                 a.init();\r
254                     a.run();\r
255                     dtde.dropComplete(true);\r
256                         } catch (DatabaseException e) {\r
257                                 ShowMessage.showError(e.getClass().getName(), e.getMessage());\r
258                     dtde.dropComplete(true);\r
259                         }\r
260             return;\r
261         }\r
262         \r
263         dtde.rejectDrop();\r
264     }\r
265 \r
266     @Override\r
267     public void dropActionChanged(DropTargetDragEvent dtde, IDnDContext dp) {\r
268         dtde.acceptDrag( DnDConstants.ACTION_LINK );\r
269     }\r
270 \r
271     @Override\r
272     public int getAllowedOps() {\r
273         return DnDConstants.ACTION_LINK;\r
274     }\r
275 \r
276     private static List<IDragItem> toDragItems(Collection<VariableReference> references) {\r
277         List<IDragItem> result = new ArrayList<IDragItem>(references.size());\r
278         for (VariableReference vr : references) {\r
279             VariableReferenceDragItem di = new VariableReferenceDragItem( vr );\r
280             result.add( di );\r
281         }\r
282         return result;\r
283     }\r
284     \r
285     @Override\r
286     public double getPriority() {\r
287         return 10.0;\r
288     }\r
289 \r
290 }