|
Lines 1-5
Link Here
|
| 1 |
/******************************************************************************* |
1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 2000, 2006 IBM Corporation and others. |
2 |
* Copyright (c) 2007 IBM Corporation and others. |
| 3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
| 4 |
* are made available under the terms of the Eclipse Public License v1.0 |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
| 5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
|
Lines 10-297
Link Here
|
| 10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
| 11 |
package org.eclipse.jdt.internal.ui.dnd; |
11 |
package org.eclipse.jdt.internal.ui.dnd; |
| 12 |
|
12 |
|
| 13 |
import org.eclipse.core.runtime.Assert; |
|
|
| 14 |
|
| 15 |
import org.eclipse.swt.dnd.DND; |
13 |
import org.eclipse.swt.dnd.DND; |
|
|
14 |
import org.eclipse.swt.dnd.DropTargetAdapter; |
| 16 |
import org.eclipse.swt.dnd.DropTargetEvent; |
15 |
import org.eclipse.swt.dnd.DropTargetEvent; |
| 17 |
import org.eclipse.swt.dnd.DropTargetListener; |
16 |
import org.eclipse.swt.dnd.TransferData; |
| 18 |
import org.eclipse.swt.graphics.Point; |
17 |
import org.eclipse.swt.graphics.Point; |
| 19 |
import org.eclipse.swt.graphics.Rectangle; |
18 |
import org.eclipse.swt.graphics.Rectangle; |
| 20 |
import org.eclipse.swt.widgets.Item; |
19 |
import org.eclipse.swt.widgets.Item; |
| 21 |
import org.eclipse.swt.widgets.TableItem; |
20 |
import org.eclipse.swt.widgets.TableItem; |
| 22 |
import org.eclipse.swt.widgets.TreeItem; |
21 |
import org.eclipse.swt.widgets.TreeItem; |
| 23 |
|
22 |
|
| 24 |
import org.eclipse.jface.viewers.StructuredViewer; |
23 |
import org.eclipse.jface.viewers.ISelection; |
|
|
24 |
import org.eclipse.jface.viewers.IStructuredSelection; |
| 25 |
import org.eclipse.jface.viewers.Viewer; |
| 25 |
|
26 |
|
| 26 |
/** |
27 |
/** |
| 27 |
* A drag and drop adapter to be used together with structured viewers. |
28 |
* This adapter class provides generic drag-and-drop support for a viewer. |
| 28 |
* The adapater delegates the <code>dragEnter</code>, <code>dragOperationChanged |
29 |
* <p> |
| 29 |
* </code>, <code>dragOver</code> and <code>dropAccept</code> method to the |
30 |
* Subclasses must implement the following methods: |
| 30 |
* <code>validateDrop</code> method. Furthermore it adds location feedback. |
31 |
* <ul> |
|
|
32 |
* <li><code>validateDrop</code> - identifies valid drop targets in viewer</li> |
| 33 |
* <li><code>performDrop</code> - carries out a drop into a viewer</li> |
| 34 |
* </ul> |
| 35 |
* The <code>setFeedbackEnabled</code> method can be called to turn on and off |
| 36 |
* visual insertion feedback (on by default). |
| 37 |
* </p> |
| 38 |
* <p> |
| 39 |
* THIS IS (ALMOST) A ONE-TO-ONE COPY OF PLATFORMS ViewerDropAdapter |
| 40 |
* REFERE THERE FIRST IF YOU NEED TO FIX SOMETHING. |
| 41 |
* </p> |
| 31 |
*/ |
42 |
*/ |
| 32 |
public class JdtViewerDropAdapter implements DropTargetListener { |
43 |
public abstract class JdtViewerDropAdapter extends DropTargetAdapter { |
| 33 |
|
|
|
| 34 |
/** |
| 35 |
* Constant describing the position of the mouse cursor relative |
| 36 |
* to the target object. This means the mouse is not positioned |
| 37 |
* over or near any valid target. |
| 38 |
*/ |
| 39 |
public static final int LOCATION_NONE= DND.FEEDBACK_NONE; |
| 40 |
|
| 41 |
/** |
| 42 |
* Constant describing the position of the mouse cursor relative |
| 43 |
* to the target object. This means the mouse is positioned |
| 44 |
* directly on the target. |
| 45 |
*/ |
| 46 |
public static final int LOCATION_ON= DND.FEEDBACK_SELECT; |
| 47 |
|
| 48 |
/** |
| 49 |
* Constant describing the position of the mouse cursor relative |
| 50 |
* to the target object. This means the mouse is positioned |
| 51 |
* slightly before the target. |
| 52 |
*/ |
| 53 |
public static final int LOCATION_BEFORE= DND.FEEDBACK_INSERT_BEFORE; |
| 54 |
|
| 55 |
/** |
| 56 |
* Constant describing the position of the mouse cursor relative |
| 57 |
* to the target object. This means the mouse is positioned |
| 58 |
* slightly after the target. |
| 59 |
*/ |
| 60 |
public static final int LOCATION_AFTER= DND.FEEDBACK_INSERT_AFTER; |
| 61 |
|
| 62 |
/** |
| 63 |
* The threshold used to determine if the mouse is before or after |
| 64 |
* an item. |
| 65 |
*/ |
| 66 |
private static final int LOCATION_EPSILON= 5; |
| 67 |
|
| 68 |
|
| 69 |
private static final int ITEM_MARGIN_LEFT= 40; |
| 70 |
private static final int ITEM_MARGIN_RIGTH= 10; |
| 71 |
|
| 72 |
/** |
| 73 |
* Style to enable location feedback. |
| 74 |
*/ |
| 75 |
public static final int INSERTION_FEEDBACK= 1 << 1; |
| 76 |
|
| 77 |
private StructuredViewer fViewer; |
| 78 |
private int fFeedback; |
| 79 |
private boolean fShowInsertionFeedback; |
| 80 |
private boolean fFullWidthMatchesItem; |
| 81 |
private int fRequestedOperation; |
| 82 |
private int fLastOperation; |
| 83 |
protected int fLocation; |
| 84 |
protected Object fTarget; |
| 85 |
|
| 86 |
|
| 87 |
|
| 88 |
public JdtViewerDropAdapter(StructuredViewer viewer, int feedback) { |
| 89 |
Assert.isNotNull(viewer); |
| 90 |
fViewer= viewer; |
| 91 |
fFeedback= feedback; |
| 92 |
fLastOperation= -1; |
| 93 |
fFullWidthMatchesItem= true; |
| 94 |
} |
| 95 |
|
44 |
|
| 96 |
/** |
45 |
/** |
| 97 |
* Controls whether the drop adapter shows insertion feedback or not. |
46 |
* Constant describing the position of the cursor relative |
| 98 |
* |
47 |
* to the target object. This means the mouse is positioned |
| 99 |
* @param showInsertionFeedback <code>true</code> if the drop adapter is supposed |
48 |
* slightly before the target. |
| 100 |
* to show insertion feedback. Otherwise <code>false</code> |
49 |
* @see #getCurrentLocation() |
| 101 |
*/ |
50 |
*/ |
| 102 |
public void showInsertionFeedback(boolean showInsertionFeedback) { |
51 |
public static final int LOCATION_BEFORE = 1; |
| 103 |
fShowInsertionFeedback= showInsertionFeedback; |
52 |
|
| 104 |
} |
53 |
/** |
| 105 |
|
54 |
* Constant describing the position of the cursor relative |
| 106 |
/** |
55 |
* to the target object. This means the mouse is positioned |
| 107 |
* Controls whether the drop adapter matches an tree or table item on the full width of the viewer. |
56 |
* slightly after the target. |
| 108 |
* |
57 |
* @see #getCurrentLocation() |
| 109 |
* @param enable <code>true</code> if the drop adapter is supposed |
58 |
*/ |
| 110 |
* to test the horizontal distance |
59 |
public static final int LOCATION_AFTER = 2; |
| 111 |
*/ |
60 |
|
| 112 |
protected void setFullWidthMatchesItem(boolean enable) { |
61 |
/** |
| 113 |
fFullWidthMatchesItem= enable; |
62 |
* Constant describing the position of the cursor relative |
| 114 |
} |
63 |
* to the target object. This means the mouse is positioned |
| 115 |
|
64 |
* directly on the target. |
| 116 |
/** |
65 |
* @see #getCurrentLocation() |
| 117 |
* Returns the viewer this adapter is working on. |
66 |
*/ |
| 118 |
*/ |
67 |
public static final int LOCATION_ON = 3; |
| 119 |
protected StructuredViewer getViewer() { |
68 |
|
| 120 |
return fViewer; |
69 |
/** |
| 121 |
} |
70 |
* Constant describing the position of the cursor relative |
| 122 |
|
71 |
* to the target object. This means the mouse is not positioned |
| 123 |
//---- Hooks to override ----------------------------------------------------- |
72 |
* over or near any valid target. |
| 124 |
|
73 |
* @see #getCurrentLocation() |
| 125 |
/** |
74 |
*/ |
| 126 |
* The actual drop has occurred. Calls <code>drop(Object target, DropTargetEvent event) |
75 |
public static final int LOCATION_NONE = 4; |
| 127 |
* </code>. |
76 |
|
| 128 |
* @see DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent) |
77 |
/** |
| 129 |
*/ |
78 |
* The viewer to which this drop support has been added. |
| 130 |
public void drop(DropTargetEvent event) { |
79 |
*/ |
| 131 |
drop(fTarget, event); |
80 |
private Viewer viewer; |
| 132 |
} |
81 |
|
| 133 |
|
82 |
/** |
| 134 |
/** |
83 |
* The current operation. |
| 135 |
* The actual drop has occurred. |
84 |
*/ |
| 136 |
* @param target the drop target in form of a domain element. |
85 |
private int currentOperation = DND.DROP_NONE; |
| 137 |
* @param event the drop traget event |
86 |
|
| 138 |
*/ |
87 |
/** |
| 139 |
public void drop(Object target, DropTargetEvent event) { |
88 |
* The last valid operation. |
| 140 |
} |
89 |
*/ |
| 141 |
|
90 |
private int lastValidOperation = DND.DROP_NONE; |
| 142 |
/** |
91 |
|
| 143 |
* Checks if the drop is valid. The method calls <code>validateDrop |
92 |
/** |
| 144 |
* (Object target, DropTargetEvent event). Implementors can alter the |
93 |
* The data item currently under the mouse. |
| 145 |
* <code>currentDataType</code> field and the <code>detail</code> field |
94 |
*/ |
| 146 |
* to give feedback about drop acceptence. |
95 |
private Object currentTarget; |
| 147 |
*/ |
96 |
|
| 148 |
public void validateDrop(DropTargetEvent event) { |
97 |
/** |
| 149 |
validateDrop(fTarget, event, fRequestedOperation); |
98 |
* Information about the position of the mouse relative to the |
| 150 |
} |
99 |
* target (before, on, or after the target. Location is one of |
| 151 |
|
100 |
* the <code>LOCATION_* </code> constants defined in this type. |
| 152 |
/** |
101 |
*/ |
| 153 |
* Checks if the drop on the current target is valid. The method |
102 |
private int currentLocation; |
| 154 |
* can alter the <code>currentDataType</code> field and the <code> |
103 |
|
| 155 |
* detail</code> field to give feedback about drop acceptence. |
104 |
/** |
| 156 |
* @param target the drop target in form of a domain element. |
105 |
* A flag that allows adapter users to turn the insertion |
| 157 |
* @param event the drop traget event |
106 |
* feedback on or off. Default is <code>true</code>. |
| 158 |
* @param operation the operation requested by the user. |
107 |
*/ |
| 159 |
*/ |
108 |
private boolean feedbackEnabled = true; |
| 160 |
public void validateDrop(Object target, DropTargetEvent event, int operation) { |
109 |
|
| 161 |
} |
110 |
/** |
| 162 |
|
111 |
* A flag that allows adapter users to turn auto scrolling |
| 163 |
public void dragEnter(DropTargetEvent event) { |
112 |
* on or off. Default is <code>true</code>. |
| 164 |
dragOperationChanged(event); |
113 |
*/ |
| 165 |
} |
114 |
private boolean scrollEnabled = true; |
| 166 |
|
115 |
|
| 167 |
public void dragLeave(DropTargetEvent event) { |
116 |
/** |
| 168 |
fTarget= null; |
117 |
* A flag that allows adapter users to turn auto |
| 169 |
fLocation= LOCATION_NONE; |
118 |
* expanding on or off. Default is <code>true</code>. |
| 170 |
} |
119 |
*/ |
| 171 |
|
120 |
private boolean expandEnabled = true; |
| 172 |
public void dragOperationChanged(DropTargetEvent event) { |
121 |
|
| 173 |
fRequestedOperation= event.detail; |
122 |
/** |
| 174 |
fTarget= computeTarget(event); |
123 |
* A flag that allows adapter users to turn selection feedback |
| 175 |
fLocation= computeLocation(event); |
124 |
* on or off. Default is <code>true</code>. |
| 176 |
validateDrop(event); |
125 |
*/ |
| 177 |
fLastOperation= event.detail; |
126 |
private boolean selectFeedbackEnabled = true; |
| 178 |
computeFeedback(event); |
127 |
|
| 179 |
} |
128 |
/** |
| 180 |
|
129 |
* Creates a new drop adapter for the given viewer. |
| 181 |
public void dragOver(DropTargetEvent event) { |
130 |
* |
| 182 |
Object oldTarget= fTarget; |
131 |
* @param viewer the viewer |
| 183 |
fTarget= computeTarget(event); |
132 |
*/ |
| 184 |
|
133 |
protected JdtViewerDropAdapter(Viewer viewer) { |
| 185 |
//set the location feedback |
134 |
this.viewer = viewer; |
| 186 |
int oldLocation= fLocation; |
135 |
} |
| 187 |
fLocation= computeLocation(event); |
136 |
|
| 188 |
if (oldLocation != fLocation || oldTarget != fTarget || fLastOperation != event.detail) { |
137 |
/** |
| 189 |
validateDrop(event); |
138 |
* Returns the position of the given event's coordinates relative to its target. |
| 190 |
fLastOperation= event.detail; |
139 |
* The position is determined to be before, after, or on the item, based on |
| 191 |
} else { |
140 |
* some threshold value. |
| 192 |
event.detail= fLastOperation; |
141 |
* |
|
|
142 |
* @param event the event |
| 143 |
* @return one of the <code>LOCATION_* </code>constants defined in this class |
| 144 |
*/ |
| 145 |
protected int determineLocation(DropTargetEvent event) { |
| 146 |
if (!(event.item instanceof Item)) { |
| 147 |
return LOCATION_NONE; |
| 148 |
} |
| 149 |
Item item = (Item) event.item; |
| 150 |
Point coordinates = new Point(event.x, event.y); |
| 151 |
coordinates = viewer.getControl().toControl(coordinates); |
| 152 |
if (item != null) { |
| 153 |
Rectangle bounds = getBounds(item); |
| 154 |
if (bounds == null) { |
| 155 |
return LOCATION_NONE; |
| 156 |
} |
| 157 |
if ((coordinates.y - bounds.y) < 5) { |
| 158 |
return LOCATION_BEFORE; |
| 159 |
} |
| 160 |
if ((bounds.y + bounds.height - coordinates.y) < 5) { |
| 161 |
return LOCATION_AFTER; |
| 162 |
} |
| 163 |
} |
| 164 |
return LOCATION_ON; |
| 165 |
} |
| 166 |
|
| 167 |
/** |
| 168 |
* Returns the target item of the given drop event. |
| 169 |
* |
| 170 |
* @param event the event |
| 171 |
* @return The target of the drop, may be <code>null</code>. |
| 172 |
*/ |
| 173 |
protected Object determineTarget(DropTargetEvent event) { |
| 174 |
return event.item == null ? null : event.item.getData(); |
| 175 |
} |
| 176 |
|
| 177 |
/* (non-Javadoc) |
| 178 |
* Method declared on DropTargetAdapter. |
| 179 |
* The mouse has moved over the drop target. If the |
| 180 |
* target item has changed, notify the action and check |
| 181 |
* that it is still enabled. |
| 182 |
*/ |
| 183 |
private void doDropValidation(DropTargetEvent event) { |
| 184 |
currentOperation= validateDrop(currentTarget, lastValidOperation, event.currentDataType); |
| 185 |
event.detail = currentOperation; |
| 186 |
} |
| 187 |
|
| 188 |
/* (non-Javadoc) |
| 189 |
* Method declared on DropTargetAdapter. |
| 190 |
* The drag has entered this widget's region. See |
| 191 |
* if the drop should be allowed. |
| 192 |
*/ |
| 193 |
public void dragEnter(DropTargetEvent event) { |
| 194 |
currentTarget = determineTarget(event); |
| 195 |
lastValidOperation = event.detail; |
| 196 |
doDropValidation(event); |
| 197 |
} |
| 198 |
|
| 199 |
/* (non-Javadoc) |
| 200 |
* Method declared on DropTargetAdapter. |
| 201 |
* The drop operation has changed, see if the action |
| 202 |
* should still be enabled. |
| 203 |
*/ |
| 204 |
public void dragOperationChanged(DropTargetEvent event) { |
| 205 |
currentTarget = determineTarget(event); |
| 206 |
lastValidOperation = event.detail; |
| 207 |
doDropValidation(event); |
| 208 |
} |
| 209 |
|
| 210 |
/* (non-Javadoc) |
| 211 |
* Method declared on DropTargetAdapter. |
| 212 |
* The mouse has moved over the drop target. If the |
| 213 |
* target item has changed, notify the action and check |
| 214 |
* that it is still enabled. |
| 215 |
*/ |
| 216 |
public void dragOver(DropTargetEvent event) { |
| 217 |
//use newly revealed item as target if scrolling occurs |
| 218 |
Object target = determineTarget(event); |
| 219 |
|
| 220 |
//set the location feedback |
| 221 |
int oldLocation = currentLocation; |
| 222 |
currentLocation = determineLocation(event); |
| 223 |
setFeedback(event, currentLocation); |
| 224 |
|
| 225 |
//see if anything has really changed before doing validation. |
| 226 |
if (target != currentTarget || currentLocation != oldLocation) { |
| 227 |
currentTarget = target; |
| 228 |
doDropValidation(event); |
| 229 |
} |
| 230 |
} |
| 231 |
|
| 232 |
/* (non-Javadoc) |
| 233 |
* Method declared on DropTargetAdapter. |
| 234 |
* The user has dropped something on the desktop viewer. |
| 235 |
*/ |
| 236 |
public void drop(DropTargetEvent event) { |
| 237 |
currentLocation = determineLocation(event); |
| 238 |
|
| 239 |
//perform the drop behavior |
| 240 |
currentOperation= performDrop(event.data); |
| 241 |
event.detail= currentOperation; |
| 242 |
} |
| 243 |
|
| 244 |
/* (non-Javadoc) |
| 245 |
* Method declared on DropTargetAdapter. |
| 246 |
* Last chance for the action to disable itself |
| 247 |
*/ |
| 248 |
public void dropAccept(DropTargetEvent event) { |
| 249 |
event.detail= validateDrop(currentTarget, event.detail, event.currentDataType); |
| 250 |
} |
| 251 |
|
| 252 |
/** |
| 253 |
* Returns the bounds of the given SWT tree or table item. |
| 254 |
* |
| 255 |
* @param item the SWT Item |
| 256 |
* @return the bounds, or <code>null</code> if it is not a known type of item |
| 257 |
*/ |
| 258 |
protected Rectangle getBounds(Item item) { |
| 259 |
if (item instanceof TreeItem) { |
| 260 |
return ((TreeItem) item).getBounds(); |
| 261 |
} |
| 262 |
if (item instanceof TableItem) { |
| 263 |
return ((TableItem) item).getBounds(0); |
| 264 |
} |
| 265 |
return null; |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Returns a constant describing the position of the mouse relative to the |
| 270 |
* target (before, on, or after the target. |
| 271 |
* |
| 272 |
* @return one of the <code>LOCATION_* </code> constants defined in this type |
| 273 |
*/ |
| 274 |
protected int getCurrentLocation() { |
| 275 |
return currentLocation; |
| 276 |
} |
| 277 |
|
| 278 |
/** |
| 279 |
* Returns the current operation. |
| 280 |
* |
| 281 |
* @return a <code>DROP_*</code> constant from class <code>DND</code> |
| 282 |
* |
| 283 |
* @see DND#DROP_COPY |
| 284 |
* @see DND#DROP_MOVE |
| 285 |
* @see DND#DROP_LINK |
| 286 |
* @see DND#DROP_NONE |
| 287 |
*/ |
| 288 |
protected int getCurrentOperation() { |
| 289 |
return currentOperation; |
| 290 |
} |
| 291 |
|
| 292 |
/** |
| 293 |
* Returns the target object currently under the mouse. |
| 294 |
* |
| 295 |
* @return the current target object |
| 296 |
*/ |
| 297 |
protected Object getCurrentTarget() { |
| 298 |
return currentTarget; |
| 299 |
} |
| 300 |
|
| 301 |
/** |
| 302 |
* Returns whether visible insertion feedback should be presented to the user. |
| 303 |
* <p> |
| 304 |
* Typical insertion feedback is the horizontal insertion bars that appear |
| 305 |
* between adjacent items while dragging. |
| 306 |
* </p> |
| 307 |
* |
| 308 |
* @return <code>true</code> if visual feedback is desired, and <code>false</code> if not |
| 309 |
*/ |
| 310 |
public boolean getFeedbackEnabled() { |
| 311 |
return feedbackEnabled; |
| 312 |
} |
| 313 |
|
| 314 |
/** |
| 315 |
* Returns the object currently selected by the viewer. |
| 316 |
* |
| 317 |
* @return the selected object, or <code>null</code> if either no object or |
| 318 |
* multiple objects are selected |
| 319 |
*/ |
| 320 |
protected Object getSelectedObject() { |
| 321 |
ISelection selection = viewer.getSelection(); |
| 322 |
if (selection instanceof IStructuredSelection && !selection.isEmpty()) { |
| 323 |
IStructuredSelection structured = (IStructuredSelection) selection; |
| 324 |
return structured.getFirstElement(); |
| 325 |
} |
| 326 |
return null; |
| 327 |
} |
| 328 |
|
| 329 |
/** |
| 330 |
* @return the viewer to which this drop support has been added. |
| 331 |
*/ |
| 332 |
protected Viewer getViewer() { |
| 333 |
return viewer; |
| 334 |
} |
| 335 |
|
| 336 |
/** |
| 337 |
* @deprecated this method should not be used. Exception handling has been |
| 338 |
* removed from DropTargetAdapter methods overridden by this class. |
| 339 |
* Handles any exception that occurs during callback, including |
| 340 |
* rethrowing behavior. |
| 341 |
* <p> |
| 342 |
* [Issue: Implementation prints stack trace and eats exception to avoid |
| 343 |
* crashing VA/J. |
| 344 |
* Consider conditionalizing the implementation to do one thing in VAJ |
| 345 |
* and something more reasonable in other operating environments. |
| 346 |
* ] |
| 347 |
* </p> |
| 348 |
* |
| 349 |
* @param exception the exception |
| 350 |
* @param event the event |
| 351 |
*/ |
| 352 |
protected void handleException(Throwable exception, DropTargetEvent event) { |
| 353 |
// Currently we never rethrow because VA/Java crashes if an SWT |
| 354 |
// callback throws anything. Generally catching Throwable is bad, but in |
| 355 |
// this cases it's better than hanging the image. |
| 356 |
exception.printStackTrace(); |
| 357 |
event.detail = DND.DROP_NONE; |
| 358 |
} |
| 359 |
|
| 360 |
/** |
| 361 |
* Performs any work associated with the drop. |
| 362 |
* <p> |
| 363 |
* Subclasses must implement this method to provide drop behavior. |
| 364 |
* </p> |
| 365 |
* |
| 366 |
* @param data the drop data |
| 367 |
* @return <code>true</code> if the drop was successful, and |
| 368 |
* <code>false</code> otherwise |
| 369 |
*/ |
| 370 |
public abstract int performDrop(Object data); |
| 371 |
|
| 372 |
/* (non-Javadoc) |
| 373 |
* Method declared on DropTargetAdapter. |
| 374 |
* The mouse has moved over the drop target. If the |
| 375 |
* target item has changed, notify the action and check |
| 376 |
* that it is still enabled. |
| 377 |
*/ |
| 378 |
private void setFeedback(DropTargetEvent event, int location) { |
| 379 |
if (feedbackEnabled) { |
| 380 |
switch (location) { |
| 381 |
case LOCATION_BEFORE: |
| 382 |
event.feedback = DND.FEEDBACK_INSERT_BEFORE; |
| 383 |
break; |
| 384 |
case LOCATION_AFTER: |
| 385 |
event.feedback = DND.FEEDBACK_INSERT_AFTER; |
| 386 |
break; |
| 387 |
case LOCATION_ON: |
| 388 |
default: |
| 389 |
event.feedback = DND.FEEDBACK_SELECT; |
| 390 |
break; |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
// Explicitly inhibit SELECT feedback if desired |
| 395 |
if (!selectFeedbackEnabled) { |
| 396 |
event.feedback &= ~DND.FEEDBACK_SELECT; |
| 193 |
} |
397 |
} |
| 194 |
computeFeedback(event); |
398 |
|
| 195 |
} |
399 |
if (expandEnabled) { |
| 196 |
|
400 |
event.feedback |= DND.FEEDBACK_EXPAND; |
| 197 |
public void dropAccept(DropTargetEvent event) { |
|
|
| 198 |
fTarget= computeTarget(event); |
| 199 |
validateDrop(event); |
| 200 |
fLastOperation= event.detail; |
| 201 |
} |
| 202 |
|
| 203 |
/** |
| 204 |
* Returns the data held by <code>event.item</code>. Inside a viewer |
| 205 |
* this corresponds to the items data model element. |
| 206 |
*/ |
| 207 |
protected Object computeTarget(DropTargetEvent event) { |
| 208 |
if (event.item == null) { |
| 209 |
return null; |
| 210 |
} |
| 211 |
if (!fFullWidthMatchesItem) { |
| 212 |
Point coordinates= fViewer.getControl().toControl(new Point(event.x, event.y)); |
| 213 |
Rectangle bounds= getBounds((Item) event.item); |
| 214 |
if (coordinates.x < bounds.x - ITEM_MARGIN_LEFT || coordinates.x >= bounds.x + bounds.width + ITEM_MARGIN_RIGTH) { |
| 215 |
event.item= null; // too far away |
| 216 |
return null; |
| 217 |
} |
| 218 |
} |
| 219 |
return event.item.getData(); |
| 220 |
} |
| 221 |
|
| 222 |
/** |
| 223 |
* Returns the position of the given coordinates relative to the given target. |
| 224 |
* The position is determined to be before, after, or on the item, based on |
| 225 |
* some threshold value. The return value is one of the LOCATION_* constants |
| 226 |
* defined in this class. |
| 227 |
*/ |
| 228 |
protected int computeLocation(DropTargetEvent event) { |
| 229 |
if (!(event.item instanceof Item)) |
| 230 |
return LOCATION_NONE; |
| 231 |
|
| 232 |
Item item= (Item) event.item; |
| 233 |
Point coordinates= fViewer.getControl().toControl(new Point(event.x, event.y)); |
| 234 |
Rectangle bounds= getBounds(item); |
| 235 |
if (bounds == null) { |
| 236 |
return LOCATION_NONE; |
| 237 |
} |
| 238 |
if ((coordinates.y - bounds.y) < LOCATION_EPSILON) { |
| 239 |
return LOCATION_BEFORE; |
| 240 |
} |
401 |
} |
| 241 |
if ((bounds.y + bounds.height - coordinates.y) < LOCATION_EPSILON) { |
402 |
if (scrollEnabled) { |
| 242 |
return LOCATION_AFTER; |
403 |
event.feedback |= DND.FEEDBACK_SCROLL; |
| 243 |
} |
404 |
} |
| 244 |
return LOCATION_ON; |
405 |
} |
| 245 |
} |
|
|
| 246 |
|
| 247 |
/** |
| 248 |
* Returns the bounds of the given item, or <code>null</code> if it is not a |
| 249 |
* valid type of item. |
| 250 |
*/ |
| 251 |
private Rectangle getBounds(Item item) { |
| 252 |
if (item instanceof TreeItem) |
| 253 |
return ((TreeItem) item).getBounds(); |
| 254 |
|
| 255 |
if (item instanceof TableItem) |
| 256 |
return ((TableItem) item).getBounds(0); |
| 257 |
|
| 258 |
return null; |
| 259 |
} |
| 260 |
|
406 |
|
| 261 |
/** |
407 |
/** |
| 262 |
* Sets the drag under feedback corresponding to the value of <code>fLocation</code> |
408 |
* Sets whether visible insertion feedback should be presented to the user. |
| 263 |
* and the <code>INSERTION_FEEDBACK</code> style bit. |
409 |
* <p> |
| 264 |
*/ |
410 |
* Typical insertion feedback is the horizontal insertion bars that appear |
| 265 |
protected void computeFeedback(DropTargetEvent event) { |
411 |
* between adjacent items while dragging. |
| 266 |
if (!fShowInsertionFeedback && fLocation != LOCATION_NONE) { |
412 |
* </p> |
| 267 |
event.feedback= DND.FEEDBACK_SELECT; |
413 |
* |
| 268 |
} else { |
414 |
* @param value |
| 269 |
event.feedback= fLocation; |
415 |
* <code>true</code> if visual feedback is desired, and |
| 270 |
} |
416 |
* <code>false</code> if not |
| 271 |
event.feedback|= fFeedback; |
417 |
*/ |
| 272 |
} |
418 |
public void setFeedbackEnabled(boolean value) { |
| 273 |
|
419 |
feedbackEnabled = value; |
| 274 |
/** |
420 |
} |
| 275 |
* Sets the drop operation to </code>DROP_NODE<code>. |
421 |
|
| 276 |
*/ |
422 |
/** |
| 277 |
protected void clearDropOperation(DropTargetEvent event) { |
423 |
* Sets whether selection feedback should be provided during dragging. |
| 278 |
event.detail= DND.DROP_NONE; |
424 |
* |
| 279 |
} |
425 |
* @param value <code>true</code> if selection feedback is desired, and |
| 280 |
|
426 |
* <code>false</code> if not |
| 281 |
/** |
427 |
* |
| 282 |
* Returns the requested drop operation. |
428 |
* @since 3.2 |
| 283 |
*/ |
429 |
*/ |
| 284 |
protected int getRequestedOperation() { |
430 |
public void setSelectionFeedbackEnabled(boolean value) { |
| 285 |
return fRequestedOperation; |
431 |
selectFeedbackEnabled = value; |
| 286 |
} |
432 |
} |
| 287 |
|
433 |
|
| 288 |
protected void setDefaultFeedback(int feedback) { |
434 |
/** |
| 289 |
fFeedback= feedback; |
435 |
* Sets whether auto scrolling and expanding should be provided during dragging. |
| 290 |
} |
436 |
* |
| 291 |
|
437 |
* @param value <code>true</code> if scrolling and expanding is desired, and |
| 292 |
//---- helper methods to test DnD |
438 |
* <code>false</code> if not |
| 293 |
|
439 |
* @since 2.0 |
| 294 |
public void internalTestSetLocation(int location) { |
440 |
*/ |
| 295 |
fLocation= location; |
441 |
public void setScrollExpandEnabled(boolean value) { |
|
|
442 |
expandEnabled = value; |
| 443 |
scrollEnabled = value; |
| 444 |
} |
| 445 |
|
| 446 |
/** |
| 447 |
* Sets whether auto expanding should be provided during dragging. |
| 448 |
* |
| 449 |
* @param value <code>true</code> if expanding is desired, and |
| 450 |
* <code>false</code> if not |
| 451 |
* @since 3.4 |
| 452 |
*/ |
| 453 |
public void setExpandEnabled(boolean value) { |
| 454 |
expandEnabled = value; |
| 455 |
} |
| 456 |
|
| 457 |
/** |
| 458 |
* Sets whether auto scrolling should be provided during dragging. |
| 459 |
* |
| 460 |
* @param value <code>true</code> if scrolling is desired, and |
| 461 |
* <code>false</code> if not |
| 462 |
* @since 3.4 |
| 463 |
*/ |
| 464 |
public void setScrollEnabled(boolean value) { |
| 465 |
scrollEnabled = value; |
| 466 |
} |
| 467 |
|
| 468 |
/** |
| 469 |
* Validates dropping on the given object. This method is called whenever some |
| 470 |
* aspect of the drop operation changes. |
| 471 |
* <p> |
| 472 |
* Subclasses must implement this method to define which drops make sense. |
| 473 |
* </p> |
| 474 |
* |
| 475 |
* @param target the object that the mouse is currently hovering over, or |
| 476 |
* <code>null</code> if the mouse is hovering over empty space |
| 477 |
* @param operation the current drag operation (copy, move, etc.) |
| 478 |
* @param transferType the current transfer type |
| 479 |
* @return <code>true</code> if the drop is valid, and <code>false</code> |
| 480 |
* otherwise |
| 481 |
*/ |
| 482 |
public abstract int validateDrop(Object target, int operation, |
| 483 |
TransferData transferType); |
| 484 |
|
| 485 |
/** |
| 486 |
* For testing only. The location should not be set otherwise. |
| 487 |
* @param location the location to assume |
| 488 |
*/ |
| 489 |
protected void setCurrentLocation(int location) { |
| 490 |
currentLocation= location; |
| 296 |
} |
491 |
} |
| 297 |
} |
492 |
} |