1 11 package org.eclipse.jface.viewers; 12 13 import org.eclipse.swt.dnd.DND; 14 import org.eclipse.swt.dnd.DropTargetAdapter; 15 import org.eclipse.swt.dnd.DropTargetEvent; 16 import org.eclipse.swt.dnd.TransferData; 17 import org.eclipse.swt.graphics.Point; 18 import org.eclipse.swt.graphics.Rectangle; 19 import org.eclipse.swt.widgets.Item; 20 import org.eclipse.swt.widgets.TableItem; 21 import org.eclipse.swt.widgets.TreeItem; 22 23 35 public abstract class ViewerDropAdapter extends DropTargetAdapter { 36 37 43 public static final int LOCATION_BEFORE = 1; 44 45 51 public static final int LOCATION_AFTER = 2; 52 53 59 public static final int LOCATION_ON = 3; 60 61 67 public static final int LOCATION_NONE = 4; 68 69 72 private Viewer viewer; 73 74 77 private int currentOperation = DND.DROP_NONE; 78 79 82 private int lastValidOperation = DND.DROP_NONE; 83 84 87 private Object currentTarget; 88 89 94 private int currentLocation; 95 96 100 private boolean feedbackEnabled = true; 101 102 106 private boolean scrollExpandEnabled = true; 107 108 112 private boolean selectFeedbackEnabled = true; 113 114 119 protected ViewerDropAdapter(Viewer viewer) { 120 this.viewer = viewer; 121 } 122 123 131 protected int determineLocation(DropTargetEvent event) { 132 if (!(event.item instanceof Item)) { 133 return LOCATION_NONE; 134 } 135 Item item = (Item) event.item; 136 Point coordinates = new Point(event.x, event.y); 137 coordinates = viewer.getControl().toControl(coordinates); 138 if (item != null) { 139 Rectangle bounds = getBounds(item); 140 if (bounds == null) { 141 return LOCATION_NONE; 142 } 143 if ((coordinates.y - bounds.y) < 5) { 144 return LOCATION_BEFORE; 145 } 146 if ((bounds.y + bounds.height - coordinates.y) < 5) { 147 return LOCATION_AFTER; 148 } 149 } 150 return LOCATION_ON; 151 } 152 153 159 protected Object determineTarget(DropTargetEvent event) { 160 return event.item == null ? null : event.item.getData(); 161 } 162 163 169 private void doDropValidation(DropTargetEvent event) { 170 if (event.detail != DND.DROP_NONE) { 172 lastValidOperation = event.detail; 173 } 174 if (validateDrop(currentTarget, event.detail, event.currentDataType)) { 176 currentOperation = lastValidOperation; 177 } else { 178 currentOperation = DND.DROP_NONE; 179 } 180 event.detail = currentOperation; 181 } 182 183 188 public void dragEnter(DropTargetEvent event) { 189 currentTarget = determineTarget(event); 190 doDropValidation(event); 191 } 192 193 198 public void dragOperationChanged(DropTargetEvent event) { 199 currentTarget = determineTarget(event); 200 doDropValidation(event); 201 } 202 203 209 public void dragOver(DropTargetEvent event) { 210 Object target = determineTarget(event); 212 213 int oldLocation = currentLocation; 215 currentLocation = determineLocation(event); 216 setFeedback(event, currentLocation); 217 218 if (target != currentTarget || currentLocation != oldLocation) { 220 currentTarget = target; 221 doDropValidation(event); 222 } 223 } 224 225 229 public void drop(DropTargetEvent event) { 230 currentLocation = determineLocation(event); 231 232 if (!performDrop(event.data)) { 234 event.detail = DND.DROP_NONE; 235 } 236 currentOperation = event.detail; 237 } 238 239 243 public void dropAccept(DropTargetEvent event) { 244 if (!validateDrop(currentTarget, event.detail, event.currentDataType)) { 245 event.detail = DND.DROP_NONE; 246 } 247 } 248 249 255 protected Rectangle getBounds(Item item) { 256 if (item instanceof TreeItem) { 257 return ((TreeItem) item).getBounds(); 258 } 259 if (item instanceof TableItem) { 260 return ((TableItem) item).getBounds(0); 261 } 262 return null; 263 } 264 265 271 protected int getCurrentLocation() { 272 return currentLocation; 273 } 274 275 285 protected int getCurrentOperation() { 286 return currentOperation; 287 } 288 289 294 protected Object getCurrentTarget() { 295 return currentTarget; 296 } 297 298 307 public boolean getFeedbackEnabled() { 308 return feedbackEnabled; 309 } 310 311 317 protected Object getSelectedObject() { 318 ISelection selection = viewer.getSelection(); 319 if (selection instanceof IStructuredSelection && !selection.isEmpty()) { 320 IStructuredSelection structured = (IStructuredSelection) selection; 321 return structured.getFirstElement(); 322 } 323 return null; 324 } 325 326 329 protected Viewer getViewer() { 330 return viewer; 331 } 332 333 349 protected void handleException(Throwable exception, DropTargetEvent event) { 350 exception.printStackTrace(); 354 event.detail = DND.DROP_NONE; 355 } 356 357 367 public abstract boolean performDrop(Object data); 368 369 375 private void setFeedback(DropTargetEvent event, int location) { 376 if (feedbackEnabled) { 377 switch (location) { 378 case LOCATION_BEFORE: 379 event.feedback = DND.FEEDBACK_INSERT_BEFORE; 380 break; 381 case LOCATION_AFTER: 382 event.feedback = DND.FEEDBACK_INSERT_AFTER; 383 break; 384 case LOCATION_ON: 385 default: 386 event.feedback = DND.FEEDBACK_SELECT; 387 break; 388 } 389 } 390 391 if (!selectFeedbackEnabled) { 393 event.feedback &= ~DND.FEEDBACK_SELECT; 394 } 395 396 if (scrollExpandEnabled) { 397 event.feedback |= DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL; 398 } 399 } 400 401 412 public void setFeedbackEnabled(boolean value) { 413 feedbackEnabled = value; 414 } 415 416 424 public void setSelectionFeedbackEnabled(boolean value) { 425 selectFeedbackEnabled = value; 426 } 427 428 435 public void setScrollExpandEnabled(boolean value) { 436 scrollExpandEnabled = value; 437 } 438 439 453 public abstract boolean validateDrop(Object target, int operation, 454 TransferData transferType); 455 } 456 | Popular Tags |