blob: d8974904694f7888b1dfb2e350f813562a5434c0 [file] [log] [blame]
kchongb5b367d2007-03-12 17:52:55 +00001/*******************************************************************************
2 * Copyright (c) 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.wst.xsd.ui.internal.commands;
12
13import java.util.ArrayList;
14import java.util.Iterator;
15import java.util.List;
16
kchongc7560532008-04-14 18:08:00 +000017import org.eclipse.draw2d.PositionConstants;
kchongb5b367d2007-03-12 17:52:55 +000018import org.eclipse.draw2d.geometry.Point;
19import org.eclipse.gef.EditPart;
20import org.eclipse.gef.EditPartViewer;
21import org.eclipse.gef.GraphicalEditPart;
22import org.eclipse.gef.requests.ChangeBoundsRequest;
23import org.eclipse.wst.xsd.ui.internal.actions.MoveXSDElementAction;
24import org.eclipse.wst.xsd.ui.internal.adapters.XSDElementDeclarationAdapter;
kchongc7560532008-04-14 18:08:00 +000025import org.eclipse.wst.xsd.ui.internal.adapters.XSDWildcardAdapter;
kchongb5b367d2007-03-12 17:52:55 +000026import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.BaseFieldEditPart;
27import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.CompartmentEditPart;
28import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.ComplexTypeEditPart;
29import org.eclipse.wst.xsd.ui.internal.adt.design.editparts.StructureEditPart;
30import org.eclipse.wst.xsd.ui.internal.design.editparts.ModelGroupDefinitionReferenceEditPart;
31import org.eclipse.wst.xsd.ui.internal.design.editparts.ModelGroupEditPart;
32import org.eclipse.wst.xsd.ui.internal.design.editparts.TargetConnectionSpacingFigureEditPart;
33import org.eclipse.wst.xsd.ui.internal.design.editparts.XSDBaseFieldEditPart;
34import org.eclipse.wst.xsd.ui.internal.design.editparts.XSDGroupsForAnnotationEditPart;
35import org.eclipse.wst.xsd.ui.internal.design.figures.GenericGroupFigure;
36import org.eclipse.xsd.XSDConcreteComponent;
37import org.eclipse.xsd.XSDElementDeclaration;
38import org.eclipse.xsd.XSDModelGroup;
kchongc7560532008-04-14 18:08:00 +000039import org.eclipse.xsd.XSDWildcard;
kchongb5b367d2007-03-12 17:52:55 +000040
41
42public class XSDElementDragAndDropCommand extends BaseDragAndDropCommand
43{
44 protected ModelGroupEditPart topMostGroup;
45
46 public XSDElementDragAndDropCommand(EditPartViewer viewer, ChangeBoundsRequest request, GraphicalEditPart target, XSDBaseFieldEditPart itemToDrag, Point location)
47 {
48 super(viewer, request);
49 this.target = target;
50 this.itemToDrag = itemToDrag;
51 this.location = location;
52 setup();
53 }
kchongc7560532008-04-14 18:08:00 +000054
55 public XSDElementDragAndDropCommand(XSDBaseFieldEditPart itemToDrag, XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
56 {
57 super(itemToDrag.getViewer(), null);
58 this.itemToDrag = itemToDrag;
59 canExecute = false;
60 handleKeyboardDragAndDrop(leftField, rightField, direction);
61 }
62
63 protected void handleKeyboardDragAndDrop(XSDBaseFieldEditPart leftField, XSDBaseFieldEditPart rightField, int direction)
64 {
65 super.handleKeyboardDragAndDrop(leftField, rightField, direction);
66 if (direction == PositionConstants.NORTH)
67 {
68 if (target == null)
69 {
70 target = rightField;
71 this.location = target.getFigure().getBounds().getTop();
72 }
73 else if (!(leftField.getModel() instanceof XSDElementDeclarationAdapter)
74 || leftField.getModel() instanceof XSDWildcardAdapter)
75 {
76 target = rightField;
77 this.location = target.getFigure().getBounds().getTop();
78 }
79 }
kchong08c23ee2008-04-21 17:55:55 +000080 if (location == null) return;
kchongc7560532008-04-14 18:08:00 +000081 setup();
82 }
kchongb5b367d2007-03-12 17:52:55 +000083
84 protected void setup()
85 {
86 canExecute = false;
87
88 // Drop target is model group
89 if (target instanceof ModelGroupEditPart)
90 {
91 parentEditPart = (ModelGroupEditPart) target;
92 if (((GenericGroupFigure) parentEditPart.getFigure()).getIconFigure().getBounds().contains(location))
93 {
94 xsdComponentToDrag = (XSDConcreteComponent) ((XSDElementDeclarationAdapter) itemToDrag.getModel()).getTarget();
95 action = new MoveXSDElementAction(((ModelGroupEditPart) target).getXSDModelGroup(), xsdComponentToDrag, null, null);
96 canExecute = action.canMove();
97 }
98 }
99 else if (target instanceof BaseFieldEditPart)
100 {
101 targetSpacesList = new ArrayList();
102 // Calculate the list of all sibling field edit parts;
103 List targetEditPartSiblings = calculateFieldEditParts();
104 calculateModelGroupList();
105
106 doDrop(targetEditPartSiblings, itemToDrag);
107 }
108 }
109
110 protected void doDrop(List siblings, GraphicalEditPart movingEditPart)
111 {
112 commonSetup(siblings, movingEditPart);
113
114 // Can common this code up with XSDAttributeDragAndDropCommand...
kchongc7560532008-04-14 18:08:00 +0000115 if ((previousRefComponent instanceof XSDElementDeclaration || previousRefComponent instanceof XSDWildcard)
116 && (nextRefComponent instanceof XSDElementDeclaration || nextRefComponent instanceof XSDWildcard))
kchongb5b367d2007-03-12 17:52:55 +0000117 {
kchongc7560532008-04-14 18:08:00 +0000118 XSDModelGroup modelGroup = (XSDModelGroup) previousRefComponent.getContainer().getContainer();
kchongb5b367d2007-03-12 17:52:55 +0000119 if (parentEditPart != null)
120 modelGroup = ((ModelGroupEditPart) parentEditPart).getXSDModelGroup();
121 action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
122 }
kchongc7560532008-04-14 18:08:00 +0000123 else if (previousRefComponent == null && (nextRefComponent instanceof XSDElementDeclaration || nextRefComponent instanceof XSDWildcard))
kchongb5b367d2007-03-12 17:52:55 +0000124 {
125 if (closerSibling == ABOVE_IS_CLOSER)
126 {
127 if (leftSiblingEditPart == null)
128 {
129 action = new MoveXSDElementAction(topMostGroup.getXSDModelGroup(), xsdComponentToDrag, null, null, false);
130 }
131 else if (parentEditPart != null)
132 {
133 action = new MoveXSDElementAction(((ModelGroupEditPart) parentEditPart).getXSDModelGroup(), xsdComponentToDrag, previousRefComponent, nextRefComponent);
134 }
135 }
136 else
137 {
kchongc7560532008-04-14 18:08:00 +0000138 XSDModelGroup modelGroup = (XSDModelGroup) nextRefComponent.getContainer().getContainer();
kchongb5b367d2007-03-12 17:52:55 +0000139 action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
140 }
141 }
kchongc7560532008-04-14 18:08:00 +0000142 else if ((previousRefComponent instanceof XSDElementDeclaration || previousRefComponent instanceof XSDWildcard)
143 && nextRefComponent == null)
kchongb5b367d2007-03-12 17:52:55 +0000144 {
kchongc7560532008-04-14 18:08:00 +0000145 XSDModelGroup modelGroup = (XSDModelGroup)previousRefComponent.getContainer().getContainer();
kchongb5b367d2007-03-12 17:52:55 +0000146 if (parentEditPart != null)
147 modelGroup = ((ModelGroupEditPart) parentEditPart).getXSDModelGroup();
148 if (closerSibling == ABOVE_IS_CLOSER)
149 {
150 action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
151 }
152 else
153 {
154 if (rightSiblingEditPart == null)
155 {
156 action = new MoveXSDElementAction(topMostGroup.getXSDModelGroup(), xsdComponentToDrag, null, null, true);
157 }
158 else
159 {
160 action = new MoveXSDElementAction(modelGroup, xsdComponentToDrag, previousRefComponent, nextRefComponent);
161 }
162 }
163 }
164
165 if (action != null)
166 canExecute = action.canMove();
167 }
168
169 /**
170 * overrides base
171 */
172 protected boolean handleFirstAndLastDropTargets(int index, List siblings)
173 {
174 // This boolean is to handle the Top and Bottom drop targets for which we want to drop
175 // to the top most model group
176 // TODO: I need to rearrange this code better
177 boolean isHandled = false;
178 int pointerYLocation = location.y;
179 // We need to find the parent editpart, which is the model group
180 // Handle case where you drop to first position
181 if (index == 0 && siblings.size() > 0)
182 {
183 leftSiblingEditPart = null;
184 rightSiblingEditPart = (GraphicalEditPart) siblings.get(0);
185 int siblingYLocation = getZoomedBounds(rightSiblingEditPart.getFigure().getBounds()).getCenter().y;
186 closerSibling = BELOW_IS_CLOSER;
187 if (Math.abs(pointerYLocation - siblingYLocation) > getZoomedBounds(rightSiblingEditPart.getFigure().getBounds()).height / 4)
188 {
189 isHandled = true;
190 parentEditPart = topMostGroup;
191 if (topMostGroup != null)
192 closerSibling = ABOVE_IS_CLOSER;
193 }
194 }
195 // Handle case where you drop to last position
196 if (index > 0 && index == siblings.size())
197 {
198 leftSiblingEditPart = (GraphicalEditPart) siblings.get(index - 1);
199 int siblingYLocation = getZoomedBounds(leftSiblingEditPart.getFigure().getBounds()).getCenter().y;
200 if (Math.abs(pointerYLocation - siblingYLocation) > getZoomedBounds(leftSiblingEditPart.getFigure().getBounds()).height / 4)
201 {
202 isHandled = true;
203 parentEditPart = topMostGroup;
204 if (topMostGroup != null)
205 closerSibling = BELOW_IS_CLOSER;
206 }
207 }
208 return isHandled;
209 }
210
211 // Methods specific to element as drag source
212
213 // Model Group related helper method
214 protected void calculateModelGroupList()
215 {
216 EditPart editPart = target;
217 while (editPart != null)
218 {
219 if (editPart instanceof ModelGroupEditPart)
220 {
221 getModelGroupEditParts((ModelGroupEditPart) editPart);
222 }
223 else if (editPart instanceof ComplexTypeEditPart || editPart instanceof StructureEditPart)
224 {
225 boolean foundTop = false;
226 List list = editPart.getChildren();
227 for (Iterator i = list.iterator(); i.hasNext();)
228 {
229 Object child = i.next();
230 if (child instanceof CompartmentEditPart)
231 {
232 List compartmentList = ((CompartmentEditPart) child).getChildren();
233 for (Iterator it = compartmentList.iterator(); it.hasNext();)
234 {
235 Object obj = it.next();
236 if (obj instanceof XSDGroupsForAnnotationEditPart)
237 {
238 XSDGroupsForAnnotationEditPart groups = (XSDGroupsForAnnotationEditPart) obj;
239 List groupList = groups.getChildren();
240 for (Iterator iter = groupList.iterator(); iter.hasNext();)
241 {
242 Object groupChild = iter.next();
243 if (groupChild instanceof ModelGroupEditPart)
244 {
245 if (!foundTop)
246 {
247 foundTop = true;
248 topMostGroup = (ModelGroupEditPart) groupChild;
249 }
250 getModelGroupEditParts((ModelGroupEditPart) groupChild);
251 }
252 }
253 }
254 }
255 }
256 }
257 }
258 editPart = editPart.getParent();
259 }
260 }
261
262 // Model Group related helper method
263
264 protected List getModelGroupEditParts(ModelGroupEditPart modelGroupEditPart)
265 {
266 List modelGroupList = new ArrayList();
267 List list = modelGroupEditPart.getChildren();
268 for (Iterator i = list.iterator(); i.hasNext();)
269 {
270 Object object = i.next();
271 if (object instanceof TargetConnectionSpacingFigureEditPart)
272 {
273 targetSpacesList.add(object);
274 }
275 else if (object instanceof ModelGroupDefinitionReferenceEditPart)
276 {
277 ModelGroupDefinitionReferenceEditPart groupRef = (ModelGroupDefinitionReferenceEditPart) object;
278 List groupRefChildren = groupRef.getChildren();
279 for (Iterator it = groupRefChildren.iterator(); it.hasNext();)
280 {
281 Object o = it.next();
282 if (o instanceof ModelGroupEditPart)
283 {
284 getModelGroupEditParts((ModelGroupEditPart) o);
285 }
286 }
287 }
288 else if (object instanceof ModelGroupEditPart)
289 {
290 getModelGroupEditParts((ModelGroupEditPart) object);
291 }
292 }
293 return modelGroupList;
294 }
295}