001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.dnd;
011:
012: import org.eclipse.swt.internal.wpf.*;
013: import org.eclipse.swt.*;
014: import org.eclipse.swt.graphics.*;
015: import org.eclipse.swt.widgets.*;
016:
017: /**
018: *
019: * Class <code>DropTarget</code> defines the target object for a drag and drop transfer.
020: *
021: * IMPORTANT: This class is <em>not</em> intended to be subclassed.
022: *
023: * <p>This class identifies the <code>Control</code> over which the user must position the cursor
024: * in order to drop the data being transferred. It also specifies what data types can be dropped on
025: * this control and what operations can be performed. You may have several DropTragets in an
026: * application but there can only be a one to one mapping between a <code>Control</code> and a <code>DropTarget</code>.
027: * The DropTarget can receive data from within the same application or from other applications
028: * (such as text dragged from a text editor like Word).</p>
029: *
030: * <code><pre>
031: * int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
032: * Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
033: * DropTarget target = new DropTarget(label, operations);
034: * target.setTransfer(types);
035: * </code></pre>
036: *
037: * <p>The application is notified of data being dragged over this control and of when a drop occurs by
038: * implementing the interface <code>DropTargetListener</code> which uses the class
039: * <code>DropTargetEvent</code>. The application can modify the type of drag being performed
040: * on this Control at any stage of the drag by modifying the <code>event.detail</code> field or the
041: * <code>event.currentDataType</code> field. When the data is dropped, it is the responsibility of
042: * the application to copy this data for its own purposes.
043: *
044: * <code><pre>
045: * target.addDropListener (new DropTargetListener() {
046: * public void dragEnter(DropTargetEvent event) {};
047: * public void dragOver(DropTargetEvent event) {};
048: * public void dragLeave(DropTargetEvent event) {};
049: * public void dragOperationChanged(DropTargetEvent event) {};
050: * public void dropAccept(DropTargetEvent event) {}
051: * public void drop(DropTargetEvent event) {
052: * // A drop has occurred, copy over the data
053: * if (event.data == null) { // no data to copy, indicate failure in event.detail
054: * event.detail = DND.DROP_NONE;
055: * return;
056: * }
057: * label.setText ((String) event.data); // data copied to label text
058: * }
059: * });
060: * </pre></code>
061: *
062: * <dl>
063: * <dt><b>Styles</b></dt> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK</dd>
064: * <dt><b>Events</b></dt> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged,
065: * DND.DropAccept, DND.Drop </dd>
066: * </dl>
067: */
068: public class DropTarget extends Widget {
069:
070: static final String DEFAULT_DROP_TARGET_EFFECT = "DEFAULT_DROP_TARGET_EFFECT"; //$NON-NLS-1$
071: static final String DROPTARGETID = "DropTarget"; //$NON-NLS-1$
072:
073: static int checkStyle(int style) {
074: if (style == SWT.NONE)
075: return DND.DROP_MOVE;
076: return style;
077: }
078:
079: // info for registering as a droptarget
080: Control control;
081: Listener controlListener;
082: Transfer[] transferAgents = new Transfer[0];
083: DropTargetEffect dropEffect;
084:
085: int jniRef;
086: int dragEnterEventHandler;
087: int dragLeaveEventHandler;
088: int dragOverEventHandler;
089: int dropEventHandler;
090:
091: // Track application selections
092: TransferData selectedDataType;
093: int selectedOperation;
094:
095: // workaround - There is no event for "operation changed" so track operation based on key state
096: int keyOperation = -1;
097:
098: /**
099: * Creates a new <code>DropTarget</code> to allow data to be dropped on the specified
100: * <code>Control</code>.
101: * Creating an instance of a DropTarget may cause system resources to be allocated
102: * depending on the platform. It is therefore mandatory that the DropTarget instance
103: * be disposed when no longer required.
104: *
105: * @param control the <code>Control</code> over which the user positions the cursor to drop the data
106: * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of
107: * DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
108: *
109: * @exception SWTException <ul>
110: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
111: * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
112: * </ul>
113: * @exception SWTError <ul>
114: * <li>ERROR_CANNOT_INIT_DROP - unable to initiate drop target; this will occur if more than one
115: * drop target is created for a control or if the operating system will not allow the creation
116: * of the drop target</li>
117: * </ul>
118: *
119: * <p>NOTE: ERROR_CANNOT_INIT_DROP should be an SWTException, since it is a
120: * recoverable error, but can not be changed due to backward compatibility.</p>
121: *
122: * @see Widget#dispose
123: * @see DropTarget#checkSubclass
124: * @see DND#DROP_NONE
125: * @see DND#DROP_COPY
126: * @see DND#DROP_MOVE
127: * @see DND#DROP_LINK
128: */
129: public DropTarget(Control control, int style) {
130: super (control, checkStyle(style));
131: this .control = control;
132: if (control.getData(DROPTARGETID) != null)
133: DND.error(DND.ERROR_CANNOT_INIT_DROP);
134: control.setData(DROPTARGETID, this );
135:
136: jniRef = OS.NewGlobalRef(this );
137: if (jniRef == 0)
138: SWT.error(SWT.ERROR_NO_HANDLES);
139:
140: hookEventHandlers();
141:
142: controlListener = new Listener() {
143: public void handleEvent(Event event) {
144: if (!DropTarget.this .isDisposed()) {
145: DropTarget.this .dispose();
146: }
147: }
148: };
149: control.addListener(SWT.Dispose, controlListener);
150:
151: this .addListener(SWT.Dispose, new Listener() {
152: public void handleEvent(Event event) {
153: onDispose();
154: }
155: });
156:
157: Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT);
158: if (effect instanceof DropTargetEffect) {
159: dropEffect = (DropTargetEffect) effect;
160: } else if (control instanceof Table) {
161: dropEffect = new TableDropTargetEffect((Table) control);
162: } else if (control instanceof Tree) {
163: dropEffect = new TreeDropTargetEffect((Tree) control);
164: }
165: }
166:
167: /**
168: * Adds the listener to the collection of listeners who will
169: * be notified when a drag and drop operation is in progress, by sending
170: * it one of the messages defined in the <code>DropTargetListener</code>
171: * interface.
172: *
173: * <p><ul>
174: * <li><code>dragEnter</code> is called when the cursor has entered the drop target boundaries
175: * <li><code>dragLeave</code> is called when the cursor has left the drop target boundaries and just before
176: * the drop occurs or is cancelled.
177: * <li><code>dragOperationChanged</code> is called when the operation being performed has changed
178: * (usually due to the user changing the selected modifier key(s) while dragging)
179: * <li><code>dragOver</code> is called when the cursor is moving over the drop target
180: * <li><code>dropAccept</code> is called just before the drop is performed. The drop target is given
181: * the chance to change the nature of the drop or veto the drop by setting the <code>event.detail</code> field
182: * <li><code>drop</code> is called when the data is being dropped
183: * </ul></p>
184: *
185: * @param listener the listener which should be notified
186: *
187: * @exception IllegalArgumentException <ul>
188: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
189: * </ul>
190: * @exception SWTException <ul>
191: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
192: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
193: * </ul>
194: *
195: * @see DropTargetListener
196: * @see #removeDropListener
197: * @see DropTargetEvent
198: */
199: public void addDropListener(DropTargetListener listener) {
200: if (listener == null)
201: DND.error(SWT.ERROR_NULL_ARGUMENT);
202: DNDListener typedListener = new DNDListener(listener);
203: typedListener.dndWidget = this ;
204: addListener(DND.DragEnter, typedListener);
205: addListener(DND.DragLeave, typedListener);
206: addListener(DND.DragOver, typedListener);
207: addListener(DND.DragOperationChanged, typedListener);
208: addListener(DND.Drop, typedListener);
209: addListener(DND.DropAccept, typedListener);
210: }
211:
212: boolean checkEventArgs(int eventArgs) {
213: if (isDisposed())
214: return false;
215: int routedEventType = OS.RoutedEventArgs_typeid();
216: int source = 0;
217: if (OS.Type_IsInstanceOfType(routedEventType, eventArgs)) {
218: source = OS.RoutedEventArgs_OriginalSource(eventArgs);
219: }
220: OS.GCHandle_Free(routedEventType);
221: if (source == 0)
222: return true;
223: if (OS.Object_Equals(source, control.handle)) {
224: OS.GCHandle_Free(source);
225: return true;
226: }
227: Widget widget = getDisplay().findWidget(source);
228: OS.GCHandle_Free(source);
229: if (widget == control)
230: return true;
231:
232: if (widget instanceof TreeItem) {
233: Composite parent = ((TreeItem) widget).getParent();
234: if (parent == control)
235: return true;
236: } else if (widget instanceof TableItem) {
237: Composite parent = ((TableItem) widget).getParent();
238: if (parent == control)
239: return true;
240: }
241: return false;
242: }
243:
244: protected void checkSubclass() {
245: String name = getClass().getName();
246: String validName = DropTarget.class.getName();
247: if (!validName.equals(name)) {
248: DND.error(SWT.ERROR_INVALID_SUBCLASS);
249: }
250: }
251:
252: void DragEnter(int sender, int dragEventArgs) {
253: if (!checkEventArgs(dragEventArgs))
254: return;
255:
256: selectedDataType = null;
257: selectedOperation = DND.DROP_NONE;
258: keyOperation = -1;
259:
260: DNDEvent event = new DNDEvent();
261: if (!setEventData(event, dragEventArgs)) {
262: freeData(event.dataTypes);
263: return;
264: }
265:
266: int allowedOperations = event.operations;
267: TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length];
268: System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0,
269: allowedDataTypes.length);
270: notifyListeners(DND.DragEnter, event);
271:
272: if (event.detail == DND.DROP_DEFAULT) {
273: event.detail = (allowedOperations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE
274: : DND.DROP_NONE;
275: }
276:
277: selectedDataType = null;
278: for (int i = 0; i < allowedDataTypes.length; i++) {
279: if (sameType(allowedDataTypes[i], event.dataType)) {
280: selectedDataType = allowedDataTypes[i];
281: break;
282: }
283: }
284:
285: selectedOperation = DND.DROP_NONE;
286: if (selectedDataType != null
287: && ((allowedOperations & event.detail) != 0)) {
288: selectedOperation = event.detail;
289: }
290:
291: freeData(event.dataTypes);
292: OS.RoutedEventArgs_Handled(dragEventArgs, true);
293: }
294:
295: void DragLeave(int sender, int dragEventArgs) {
296: if (!checkEventArgs(dragEventArgs))
297: return;
298:
299: keyOperation = -1;
300: DNDEvent event = new DNDEvent();
301: event.widget = this ;
302: event.time = (int) System.currentTimeMillis();
303: event.detail = DND.DROP_NONE;
304: notifyListeners(DND.DragLeave, event);
305: OS.RoutedEventArgs_Handled(dragEventArgs, true);
306: }
307:
308: void DragOver(int sender, int dragEventArgs) {
309: if (!checkEventArgs(dragEventArgs))
310: return;
311:
312: int oldKeyOperation = keyOperation;
313: DNDEvent event = new DNDEvent();
314: if (!setEventData(event, dragEventArgs)) {
315: freeData(event.dataTypes);
316: keyOperation = -1;
317: OS.DragEventArgs_Effects(dragEventArgs,
318: OS.DragDropEffects_None);
319: return;
320: }
321:
322: int allowedOperations = event.operations;
323: TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length];
324: System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0,
325: allowedDataTypes.length);
326:
327: if (keyOperation == oldKeyOperation) {
328: event.type = DND.DragOver;
329: event.dataType = selectedDataType;
330: event.detail = selectedOperation;
331: } else {
332: event.type = DND.DragOperationChanged;
333: event.dataType = selectedDataType;
334: }
335: notifyListeners(event.type, event);
336:
337: if (event.detail == DND.DROP_DEFAULT) {
338: event.detail = (allowedOperations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE
339: : DND.DROP_NONE;
340: }
341:
342: selectedDataType = null;
343: for (int i = 0; i < allowedDataTypes.length; i++) {
344: if (sameType(allowedDataTypes[i], event.dataType)) {
345: selectedDataType = allowedDataTypes[i];
346: break;
347: }
348: }
349:
350: selectedOperation = DND.DROP_NONE;
351: if (selectedDataType != null
352: && ((allowedOperations & event.detail) == event.detail)) {
353: selectedOperation = event.detail;
354: }
355:
356: freeData(event.dataTypes);
357: OS.DragEventArgs_Effects(dragEventArgs,
358: opToOsOp(selectedOperation));
359: OS.RoutedEventArgs_Handled(dragEventArgs, true);
360: }
361:
362: void Drop(int sender, int dragEventArgs) {
363: if (!checkEventArgs(dragEventArgs))
364: return;
365:
366: DNDEvent event = new DNDEvent();
367: event.widget = this ;
368: event.time = (int) System.currentTimeMillis();
369: if (dropEffect != null) {
370: Point position = getPosition(dragEventArgs);
371: event.item = dropEffect.getItem(position.x, position.y);
372: }
373: event.detail = DND.DROP_NONE;
374: notifyListeners(DND.DragLeave, event);
375:
376: event = new DNDEvent();
377: if (!setEventData(event, dragEventArgs)) {
378: keyOperation = -1;
379: freeData(event.dataTypes);
380: return;
381: }
382: keyOperation = -1;
383: int allowedOperations = event.operations;
384: TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length];
385: System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0,
386: allowedDataTypes.length);
387: event.dataType = selectedDataType;
388: event.detail = selectedOperation;
389: notifyListeners(DND.DropAccept, event);
390:
391: selectedDataType = null;
392: for (int i = 0; i < allowedDataTypes.length; i++) {
393: if (sameType(allowedDataTypes[i], event.dataType)) {
394: selectedDataType = allowedDataTypes[i];
395: break;
396: }
397: }
398: selectedOperation = DND.DROP_NONE;
399: if (selectedDataType != null
400: && (allowedOperations & event.detail) == event.detail) {
401: selectedOperation = event.detail;
402: }
403:
404: if (selectedOperation == DND.DROP_NONE) {
405: freeData(event.dataTypes);
406: return;
407: }
408:
409: // Get Data in a Java format
410: Object object = null;
411: for (int i = 0; i < transferAgents.length; i++) {
412: Transfer transfer = transferAgents[i];
413: if (transfer != null
414: && transfer.isSupportedType(selectedDataType)) {
415: object = transfer.nativeToJava(selectedDataType);
416: break;
417: }
418: }
419: if (object == null) {
420: selectedOperation = DND.DROP_NONE;
421: }
422:
423: event.detail = selectedOperation;
424: event.dataType = selectedDataType;
425: event.data = object;
426: notifyListeners(DND.Drop, event);
427:
428: selectedOperation = DND.DROP_NONE;
429: if ((allowedOperations & event.detail) == event.detail) {
430: selectedOperation = event.detail;
431: }
432:
433: freeData(event.dataTypes);
434: OS.DragEventArgs_Effects(dragEventArgs,
435: opToOsOp(selectedOperation));
436: OS.RoutedEventArgs_Handled(dragEventArgs, true);
437: }
438:
439: void freeData(TransferData[] dataTypes) {
440: if (dataTypes == null)
441: return;
442: for (int i = 0; i < dataTypes.length; i++) {
443: if (dataTypes[i].pValue != 0)
444: OS.GCHandle_Free(dataTypes[i].pValue);
445: }
446: }
447:
448: /**
449: * Returns the Control which is registered for this DropTarget. This is the control over which the
450: * user positions the cursor to drop the data.
451: *
452: * @return the Control which is registered for this DropTarget
453: */
454: public Control getControl() {
455: return control;
456: }
457:
458: int getData(int pDataObject, int type) {
459: int pFormat = Transfer.getWPFFormat(type);
460: int result = 0;
461: if (OS.DataObject_GetDataPresent(pDataObject, pFormat, true)) {
462: result = OS.DataObject_GetData(pDataObject, pFormat, true);
463: }
464: OS.GCHandle_Free(pFormat);
465: return result;
466: }
467:
468: /**
469: * Returns the drop effect for this DropTarget. This drop effect will be
470: * used during a drag and drop to display the drag under effect on the
471: * target widget.
472: *
473: * @return the drop effect that is registered for this DropTarget
474: *
475: * @since 3.3
476: */
477: public DropTargetEffect getDropTargetEffect() {
478: return dropEffect;
479: }
480:
481: int getOperationFromKeyState(int keyState) {
482: boolean ctrl = (keyState & OS.DragDropKeyStates_ControlKey) != 0;
483: boolean shift = (keyState & OS.DragDropKeyStates_ShiftKey) != 0;
484: boolean alt = (keyState & OS.DragDropKeyStates_AltKey) != 0;
485: if (alt) {
486: if (ctrl || shift)
487: return DND.DROP_DEFAULT;
488: return DND.DROP_LINK;
489: }
490: if (ctrl && shift)
491: return DND.DROP_LINK;
492: if (ctrl)
493: return DND.DROP_COPY;
494: if (shift)
495: return DND.DROP_MOVE;
496: return DND.DROP_DEFAULT;
497: }
498:
499: Point getPosition(int dragEventArgs) {
500: int position = OS.DragEventArgs_GetPosition(dragEventArgs,
501: control.handle);
502: Point pt = control.getDisplay().map(control, null,
503: (int) OS.Point_X(position), (int) OS.Point_Y(position));
504: OS.GCHandle_Free(position);
505: return pt;
506: }
507:
508: /**
509: * Returns a list of the data types that can be transferred to this DropTarget.
510: *
511: * @return a list of the data types that can be transferred to this DropTarget
512: */
513: public Transfer[] getTransfer() {
514: return transferAgents;
515: }
516:
517: void hookEventHandlers() {
518: int handle = control.handle;
519: OS.UIElement_AllowDrop(handle, true);
520:
521: dragEnterEventHandler = OS.gcnew_DragEventHandler(jniRef,
522: "DragEnter");
523: OS.UIElement_DragEnter(handle, dragEnterEventHandler);
524:
525: dragLeaveEventHandler = OS.gcnew_DragEventHandler(jniRef,
526: "DragLeave");
527: OS.UIElement_DragLeave(handle, dragLeaveEventHandler);
528:
529: dragOverEventHandler = OS.gcnew_DragEventHandler(jniRef,
530: "DragOver");
531: OS.UIElement_DragOver(handle, dragOverEventHandler);
532:
533: dropEventHandler = OS.gcnew_DragEventHandler(jniRef, "Drop");
534: OS.UIElement_Drop(handle, dropEventHandler);
535: }
536:
537: void onDispose() {
538: if (control == null)
539: return;
540: if (controlListener != null)
541: control.removeListener(SWT.Dispose, controlListener);
542: unhookEventHandlers();
543: if (jniRef != 0)
544: OS.DeleteGlobalRef(jniRef);
545: jniRef = 0;
546: controlListener = null;
547: control.setData(DROPTARGETID, null);
548: transferAgents = null;
549: control = null;
550: }
551:
552: int osOpToOp(int osOperation) {
553: int operation = 0;
554: if ((osOperation & OS.DragDropEffects_Copy) != 0) {
555: operation |= DND.DROP_COPY;
556: }
557: if ((osOperation & OS.DragDropEffects_Link) != 0) {
558: operation |= DND.DROP_LINK;
559: }
560: if ((osOperation & OS.DragDropEffects_Move) != 0) {
561: operation |= DND.DROP_MOVE;
562: }
563: return operation;
564: }
565:
566: int opToOsOp(int operation) {
567: int osOperation = 0;
568: if ((operation & DND.DROP_COPY) != 0) {
569: osOperation |= OS.DragDropEffects_Copy;
570: }
571: if ((operation & DND.DROP_LINK) != 0) {
572: osOperation |= OS.DragDropEffects_Link;
573: }
574: if ((operation & DND.DROP_MOVE) != 0) {
575: osOperation |= OS.DragDropEffects_Move;
576: }
577: return osOperation;
578: }
579:
580: /**
581: * Removes the listener from the collection of listeners who will
582: * be notified when a drag and drop operation is in progress.
583: *
584: * @param listener the listener which should be notified
585: *
586: * @exception IllegalArgumentException <ul>
587: * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
588: * </ul>
589: * @exception SWTException <ul>
590: * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
591: * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
592: * </ul>
593: *
594: * @see DropTargetListener
595: * @see #addDropListener
596: */
597: public void removeDropListener(DropTargetListener listener) {
598: if (listener == null)
599: DND.error(SWT.ERROR_NULL_ARGUMENT);
600: removeListener(DND.DragEnter, listener);
601: removeListener(DND.DragLeave, listener);
602: removeListener(DND.DragOver, listener);
603: removeListener(DND.DragOperationChanged, listener);
604: removeListener(DND.Drop, listener);
605: removeListener(DND.DropAccept, listener);
606: }
607:
608: boolean sameType(TransferData data1, TransferData data2) {
609: if (data1 == data2)
610: return true;
611: if (data1 == null || data2 == null)
612: return false;
613: return data1.type == data2.type;
614: }
615:
616: /**
617: * Specifies the drop effect for this DropTarget. This drop effect will be
618: * used during a drag and drop to display the drag under effect on the
619: * target widget.
620: *
621: * @param effect the drop effect that is registered for this DropTarget
622: *
623: * @since 3.3
624: */
625: public void setDropTargetEffect(DropTargetEffect effect) {
626: dropEffect = effect;
627: }
628:
629: boolean setEventData(DNDEvent event, int dragEventArgs) {
630: Point position = getPosition(dragEventArgs);
631:
632: // get allowed operations
633: int style = getStyle();
634: int operations = osOpToOp(OS
635: .DragEventArgs_Effects(dragEventArgs))
636: & style;
637: if (operations == DND.DROP_NONE)
638: return false;
639:
640: // get current operation
641: int operation = getOperationFromKeyState(OS
642: .DragEventArgs_KeyStates(dragEventArgs));
643: keyOperation = operation;
644: if (operation == DND.DROP_DEFAULT) {
645: if ((style & DND.DROP_DEFAULT) == 0) {
646: operation = (operations & DND.DROP_MOVE) != 0 ? DND.DROP_MOVE
647: : DND.DROP_NONE;
648: }
649: } else {
650: if ((operation & operations) == 0)
651: operation = DND.DROP_NONE;
652: }
653:
654: // Get allowed transfer types
655: TransferData[] dataTypes = new TransferData[0];
656: int pDataObject = OS.DragEventArgs_Data(dragEventArgs);
657: for (int i = 0; i < transferAgents.length; i++) {
658: Transfer transfer = transferAgents[i];
659: if (transfer != null) {
660: int[] types = transfer.getTypeIds();
661: for (int j = 0; j < types.length; j++) {
662: TransferData data = new TransferData();
663: data.type = types[j];
664: data.pValue = getData(pDataObject, data.type);
665: if (data.pValue != 0) {
666: TransferData[] newDataTypes = new TransferData[dataTypes.length + 1];
667: System.arraycopy(dataTypes, 0, newDataTypes, 0,
668: dataTypes.length);
669: newDataTypes[dataTypes.length] = data;
670: dataTypes = newDataTypes;
671: break;
672: }
673: }
674: }
675: }
676: OS.GCHandle_Free(pDataObject);
677: if (dataTypes.length == 0)
678: return false;
679:
680: event.widget = this ;
681: event.x = position.x;
682: event.y = position.y;
683: event.time = (int) System.currentTimeMillis();
684: event.feedback = DND.FEEDBACK_SELECT;
685: event.dataTypes = dataTypes;
686: event.dataType = dataTypes[0];
687: event.operations = operations;
688: event.detail = operation;
689: if (dropEffect != null) {
690: event.item = dropEffect.getItem(position.x, position.y);
691: }
692: return true;
693: }
694:
695: /**
696: * Specifies the data types that can be transferred to this DropTarget. If data is
697: * being dragged that does not match one of these types, the drop target will be notified of
698: * the drag and drop operation but the currentDataType will be null and the operation
699: * will be DND.NONE.
700: *
701: * @param transferAgents a list of Transfer objects which define the types of data that can be
702: * dropped on this target
703: *
704: * @exception IllegalArgumentException <ul>
705: * <li>ERROR_NULL_ARGUMENT - if transferAgents is null</li>
706: * </ul>
707: */
708: public void setTransfer(Transfer[] transferAgents) {
709: if (transferAgents == null)
710: DND.error(SWT.ERROR_NULL_ARGUMENT);
711: this .transferAgents = transferAgents;
712: }
713:
714: void unhookEventHandlers() {
715: int handle = control.handle;
716: OS.UIElement_AllowDrop(handle, false);
717:
718: int dragEnterEvent = OS.UIElement_DragEnterEvent();
719: OS.UIElement_RemoveHandler(handle, dragEnterEvent,
720: dragEnterEventHandler);
721: OS.GCHandle_Free(dragEnterEventHandler);
722: OS.GCHandle_Free(dragEnterEvent);
723: dragEnterEventHandler = 0;
724:
725: int dragLeaveEvent = OS.UIElement_DragLeaveEvent();
726: OS.UIElement_RemoveHandler(handle, dragLeaveEvent,
727: dragLeaveEventHandler);
728: OS.GCHandle_Free(dragLeaveEventHandler);
729: OS.GCHandle_Free(dragLeaveEvent);
730: dragLeaveEventHandler = 0;
731:
732: int dragOverEvent = OS.UIElement_DragOverEvent();
733: OS.UIElement_RemoveHandler(handle, dragOverEvent,
734: dragOverEventHandler);
735: OS.GCHandle_Free(dragOverEventHandler);
736: OS.GCHandle_Free(dragOverEvent);
737: dragOverEventHandler = 0;
738:
739: int dropEvent = OS.UIElement_DropEvent();
740: OS.UIElement_RemoveHandler(handle, dropEvent, dropEventHandler);
741: OS.GCHandle_Free(dropEventHandler);
742: OS.GCHandle_Free(dropEvent);
743: dropEventHandler = 0;
744: }
745:
746: }
|