Mercurial > projects > dwt-win
diff dwt/dnd/DropTarget.d @ 135:242e33c0e383
Added dnd source, ByteArrayTransfer,Clipboard completed
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Wed, 13 Feb 2008 04:51:22 +0100 |
parents | |
children | 04e357b8343d |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dnd/DropTarget.d Wed Feb 13 04:51:22 2008 +0100 @@ -0,0 +1,709 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwt.dnd.DropTarget; + +import dwt.DWT; +import dwt.DWTError; +import dwt.DWTException; +import dwt.internal.ole.win32.COM; +import dwt.internal.win32.OS; +import dwt.widgets.Control; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Table; +import dwt.widgets.Tree; +import dwt.widgets.Widget; + +/** + * + * Class <code>DropTarget</code> defines the target object for a drag and drop transfer. + * + * IMPORTANT: This class is <em>not</em> intended to be subclassed. + * + * <p>This class identifies the <code>Control</code> over which the user must position the cursor + * in order to drop the data being transferred. It also specifies what data types can be dropped on + * this control and what operations can be performed. You may have several DropTragets in an + * application but there can only be a one to one mapping between a <code>Control</code> and a <code>DropTarget</code>. + * The DropTarget can receive data from within the same application or from other applications + * (such as text dragged from a text editor like Word).</p> + * + * <code><pre> + * int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK; + * Transfer[] types = new Transfer[] {TextTransfer.getInstance()}; + * DropTarget target = new DropTarget(label, operations); + * target.setTransfer(types); + * </code></pre> + * + * <p>The application is notified of data being dragged over this control and of when a drop occurs by + * implementing the interface <code>DropTargetListener</code> which uses the class + * <code>DropTargetEvent</code>. The application can modify the type of drag being performed + * on this Control at any stage of the drag by modifying the <code>event.detail</code> field or the + * <code>event.currentDataType</code> field. When the data is dropped, it is the responsibility of + * the application to copy this data for its own purposes. + * + * <code><pre> + * target.addDropListener (new DropTargetListener() { + * public void dragEnter(DropTargetEvent event) {}; + * public void dragOver(DropTargetEvent event) {}; + * public void dragLeave(DropTargetEvent event) {}; + * public void dragOperationChanged(DropTargetEvent event) {}; + * public void dropAccept(DropTargetEvent event) {} + * public void drop(DropTargetEvent event) { + * // A drop has occurred, copy over the data + * if (event.data is null) { // no data to copy, indicate failure in event.detail + * event.detail = DND.DROP_NONE; + * return; + * } + * label.setText ((String) event.data); // data copied to label text + * } + * }); + * </pre></code> + * + * <dl> + * <dt><b>Styles</b></dt> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK</dd> + * <dt><b>Events</b></dt> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged, + * DND.DropAccept, DND.Drop </dd> + * </dl> + */ +public class DropTarget : Widget { + + Control control; + Listener controlListener; + Transfer[] transferAgents = new Transfer[0]; + DropTargetEffect dropEffect; + + // Track application selections + TransferData selectedDataType; + int selectedOperation; + + // workaround - There is no event for "operation changed" so track operation based on key state + int keyOperation = -1; + + // workaround - The dataobject address is only passed as an argument in drag enter and drop. + // To allow applications to query the data values during the drag over operations, + // maintain a reference to it. + IDataObject iDataObject; + + // interfaces + COMObject iDropTarget; + int refCount; + + static final String DEFAULT_DROP_TARGET_EFFECT = "DEFAULT_DROP_TARGET_EFFECT"; //$NON-NLS-1$ + static final String DROPTARGETID = "DropTarget"; //$NON-NLS-1$ + +/** + * Creates a new <code>DropTarget</code> to allow data to be dropped on the specified + * <code>Control</code>. + * Creating an instance of a DropTarget may cause system resources to be allocated + * depending on the platform. It is therefore mandatory that the DropTarget instance + * be disposed when no longer required. + * + * @param control the <code>Control</code> over which the user positions the cursor to drop the data + * @param style the bitwise OR'ing of allowed operations; this may be a combination of any of + * DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK + * + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + * @exception DWTError <ul> + * <li>ERROR_CANNOT_INIT_DROP - unable to initiate drop target; this will occur if more than one + * drop target is created for a control or if the operating system will not allow the creation + * of the drop target</li> + * </ul> + * + * <p>NOTE: ERROR_CANNOT_INIT_DROP should be an DWTException, since it is a + * recoverable error, but can not be changed due to backward compatibility.</p> + * + * @see Widget#dispose + * @see DropTarget#checkSubclass + * @see DND#DROP_NONE + * @see DND#DROP_COPY + * @see DND#DROP_MOVE + * @see DND#DROP_LINK + */ +public this(Control control, int style) { + super (control, checkStyle(style)); + this.control = control; + if (control.getData(DROPTARGETID) !is null) { + DND.error(DND.ERROR_CANNOT_INIT_DROP); + } + control.setData(DROPTARGETID, this); + createCOMInterfaces(); + this.AddRef(); + + if (COM.CoLockObjectExternal(iDropTarget.getAddress(), true, true) !is COM.S_OK) + DND.error(DND.ERROR_CANNOT_INIT_DROP); + if (COM.RegisterDragDrop( control.handle, iDropTarget.getAddress()) !is COM.S_OK) + DND.error(DND.ERROR_CANNOT_INIT_DROP); + + controlListener = new Listener () { + public void handleEvent (Event event) { + if (!DropTarget.this.isDisposed()){ + DropTarget.this.dispose(); + } + } + }; + control.addListener (DWT.Dispose, controlListener); + + this.addListener(DWT.Dispose, new Listener () { + public void handleEvent (Event event) { + onDispose(); + } + }); + + Object effect = control.getData(DEFAULT_DROP_TARGET_EFFECT); + if (effect instanceof DropTargetEffect) { + dropEffect = (DropTargetEffect) effect; + } else if (control instanceof Table) { + dropEffect = new TableDropTargetEffect((Table) control); + } else if (control instanceof Tree) { + dropEffect = new TreeDropTargetEffect((Tree) control); + } +} + +static int checkStyle (int style) { + if (style is DWT.NONE) return DND.DROP_MOVE; + return style; +} + +/** + * Adds the listener to the collection of listeners who will + * be notified when a drag and drop operation is in progress, by sending + * it one of the messages defined in the <code>DropTargetListener</code> + * interface. + * + * <p><ul> + * <li><code>dragEnter</code> is called when the cursor has entered the drop target boundaries + * <li><code>dragLeave</code> is called when the cursor has left the drop target boundaries and just before + * the drop occurs or is cancelled. + * <li><code>dragOperationChanged</code> is called when the operation being performed has changed + * (usually due to the user changing the selected modifier key(s) while dragging) + * <li><code>dragOver</code> is called when the cursor is moving over the drop target + * <li><code>dropAccept</code> is called just before the drop is performed. The drop target is given + * the chance to change the nature of the drop or veto the drop by setting the <code>event.detail</code> field + * <li><code>drop</code> is called when the data is being dropped + * </ul></p> + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see DropTargetListener + * @see #removeDropListener + * @see DropTargetEvent + */ +public void addDropListener(DropTargetListener listener) { + if (listener is null) DND.error (DWT.ERROR_NULL_ARGUMENT); + DNDListener typedListener = new DNDListener (listener); + typedListener.dndWidget = this; + addListener (DND.DragEnter, typedListener); + addListener (DND.DragLeave, typedListener); + addListener (DND.DragOver, typedListener); + addListener (DND.DragOperationChanged, typedListener); + addListener (DND.Drop, typedListener); + addListener (DND.DropAccept, typedListener); +} + +int AddRef() { + refCount++; + return refCount; +} + +protected void checkSubclass () { + String name = getClass().getName (); + String validName = DropTarget.class.getName(); + if (!validName.equals(name)) { + DND.error (DWT.ERROR_INVALID_SUBCLASS); + } +} + +void createCOMInterfaces() { + // register each of the interfaces that this object implements + iDropTarget = new COMObject(new int[]{2, 0, 0, 5, 4, 0, 5}){ + public int method0(int[] args) {return QueryInterface(args[0], args[1]);} + public int method1(int[] args) {return AddRef();} + public int method2(int[] args) {return Release();} + public int method3(int[] args) {return DragEnter(args[0], args[1], args[2], args[3], args[4]);} + public int method4(int[] args) {return DragOver(args[0], args[1], args[2], args[3]);} + public int method5(int[] args) {return DragLeave();} + public int method6(int[] args) {return Drop(args[0], args[1], args[2], args[3], args[4]);} + }; + +} + +void disposeCOMInterfaces() { + if (iDropTarget !is null) + iDropTarget.dispose(); + iDropTarget = null; +} + +int DragEnter(int pDataObject, int grfKeyState, int pt_x, int pt_y, int pdwEffect) { + selectedDataType = null; + selectedOperation = DND.DROP_NONE; + if (iDataObject !is null) iDataObject.Release(); + iDataObject = null; + + DNDEvent event = new DNDEvent(); + if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) { + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_FALSE; + } + + // Remember the iDataObject because it is not passed into the DragOver callback + iDataObject = new IDataObject(pDataObject); + iDataObject.AddRef(); + + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + notifyListeners(DND.DragEnter, event); + refresh(); + if (event.detail is DND.DROP_DEFAULT) { + event.detail = (allowedOperations & DND.DROP_MOVE) !is 0 ? DND.DROP_MOVE : DND.DROP_NONE; + } + + selectedDataType = null; + for (int i = 0; i < allowedDataTypes.length; i++) { + if (TransferData.sameType(allowedDataTypes[i], event.dataType)){ + selectedDataType = allowedDataTypes[i]; + break; + } + } + + selectedOperation = DND.DROP_NONE; + if (selectedDataType !is null && ((allowedOperations & event.detail) !is 0)) { + selectedOperation = event.detail; + } + + OS.MoveMemory(pdwEffect, new int[] {opToOs(selectedOperation)}, 4); + return COM.S_OK; +} + +int DragLeave() { + keyOperation = -1; + + if (iDataObject is null) return COM.S_FALSE; + + DNDEvent event = new DNDEvent(); + event.widget = this; + event.time = OS.GetMessageTime(); + event.detail = DND.DROP_NONE; + notifyListeners(DND.DragLeave, event); + refresh(); + + iDataObject.Release(); + iDataObject = null; + return COM.S_OK; +} + +int DragOver(int grfKeyState, int pt_x, int pt_y, int pdwEffect) { + if (iDataObject is null) return COM.S_FALSE; + int oldKeyOperation = keyOperation; + + DNDEvent event = new DNDEvent(); + if (!setEventData(event, iDataObject.getAddress(), grfKeyState, pt_x, pt_y, pdwEffect)) { + keyOperation = -1; + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_FALSE; + } + + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + + if (keyOperation is oldKeyOperation) { + event.type = DND.DragOver; + event.dataType = selectedDataType; + event.detail = selectedOperation; + } else { + event.type = DND.DragOperationChanged; + event.dataType = selectedDataType; + } + notifyListeners(event.type, event); + refresh(); + if (event.detail is DND.DROP_DEFAULT) { + event.detail = (allowedOperations & DND.DROP_MOVE) !is 0 ? DND.DROP_MOVE : DND.DROP_NONE; + } + + selectedDataType = null; + for (int i = 0; i < allowedDataTypes.length; i++) { + if (TransferData.sameType(allowedDataTypes[i], event.dataType)){ + selectedDataType = allowedDataTypes[i]; + break; + } + } + + selectedOperation = DND.DROP_NONE; + if (selectedDataType !is null && ((allowedOperations & event.detail) is event.detail)) { + selectedOperation = event.detail; + } + + OS.MoveMemory(pdwEffect, new int[] {opToOs(selectedOperation)}, 4); + return COM.S_OK; +} + +int Drop(int pDataObject, int grfKeyState, int pt_x, int pt_y, int pdwEffect) { + DNDEvent event = new DNDEvent(); + event.widget = this; + event.time = OS.GetMessageTime(); + if (dropEffect !is null) { + event.item = dropEffect.getItem(pt_x, pt_y); + } + event.detail = DND.DROP_NONE; + notifyListeners(DND.DragLeave, event); + refresh(); + + event = new DNDEvent(); + if (!setEventData(event, pDataObject, grfKeyState, pt_x, pt_y, pdwEffect)) { + keyOperation = -1; + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_FALSE; + } + keyOperation = -1; + int allowedOperations = event.operations; + TransferData[] allowedDataTypes = new TransferData[event.dataTypes.length]; + System.arraycopy(event.dataTypes, 0, allowedDataTypes, 0, allowedDataTypes.length); + event.dataType = selectedDataType; + event.detail = selectedOperation; + notifyListeners(DND.DropAccept,event); + refresh(); + + selectedDataType = null; + for (int i = 0; i < allowedDataTypes.length; i++) { + if (TransferData.sameType(allowedDataTypes[i], event.dataType)){ + selectedDataType = allowedDataTypes[i]; + break; + } + } + selectedOperation = DND.DROP_NONE; + if (selectedDataType !is null && (allowedOperations & event.detail) is event.detail) { + selectedOperation = event.detail; + } + + if (selectedOperation is DND.DROP_NONE){ + OS.MoveMemory(pdwEffect, new int[] {COM.DROPEFFECT_NONE}, 4); + return COM.S_OK; + } + + // Get Data in a Java format + Object object = null; + for (int i = 0; i < transferAgents.length; i++){ + Transfer transfer = transferAgents[i]; + if (transfer !is null && transfer.isSupportedType(selectedDataType)){ + object = transfer.nativeToJava(selectedDataType); + break; + } + } + if (object is null){ + selectedOperation = DND.DROP_NONE; + } + + event.detail = selectedOperation; + event.dataType = selectedDataType; + event.data = object; + OS.ImageList_DragShowNolock(false); + try { + notifyListeners(DND.Drop,event); + } finally { + OS.ImageList_DragShowNolock(true); + } + refresh(); + selectedOperation = DND.DROP_NONE; + if ((allowedOperations & event.detail) is event.detail) { + selectedOperation = event.detail; + } + //notify source of action taken + OS.MoveMemory(pdwEffect, new int[] {opToOs(selectedOperation)}, 4); + return COM.S_OK; +} + +/** + * Returns the Control which is registered for this DropTarget. This is the control over which the + * user positions the cursor to drop the data. + * + * @return the Control which is registered for this DropTarget + */ +public Control getControl () { + return control; +} + +/** + * Returns the drop effect for this DropTarget. This drop effect will be + * used during a drag and drop to display the drag under effect on the + * target widget. + * + * @return the drop effect that is registered for this DropTarget + * + * @since 3.3 + */ +public DropTargetEffect getDropTargetEffect() { + return dropEffect; +} + +int getOperationFromKeyState(int grfKeyState) { + bool ctrl = (grfKeyState & OS.MK_CONTROL) !is 0; + bool shift = (grfKeyState & OS.MK_SHIFT) !is 0; + bool alt = (grfKeyState & OS.MK_ALT) !is 0; + if (alt) { + if (ctrl || shift) return DND.DROP_DEFAULT; + return DND.DROP_LINK; + } + if (ctrl && shift) return DND.DROP_LINK; + if (ctrl)return DND.DROP_COPY; + if (shift)return DND.DROP_MOVE; + return DND.DROP_DEFAULT; +} + +/** + * Returns a list of the data types that can be transferred to this DropTarget. + * + * @return a list of the data types that can be transferred to this DropTarget + */ +public Transfer[] getTransfer() { + return transferAgents; +} + +void onDispose () { + if (control is null) return; + + COM.RevokeDragDrop(control.handle); + + if (controlListener !is null) + control.removeListener(DWT.Dispose, controlListener); + controlListener = null; + control.setData(DROPTARGETID, null); + transferAgents = null; + control = null; + + COM.CoLockObjectExternal(iDropTarget.getAddress(), false, true); + + this.Release(); + + COM.CoFreeUnusedLibraries(); +} + +int opToOs(int operation) { + int osOperation = 0; + if ((operation & DND.DROP_COPY) !is 0){ + osOperation |= COM.DROPEFFECT_COPY; + } + if ((operation & DND.DROP_LINK) !is 0) { + osOperation |= COM.DROPEFFECT_LINK; + } + if ((operation & DND.DROP_MOVE) !is 0) { + osOperation |= COM.DROPEFFECT_MOVE; + } + return osOperation; +} + +int osToOp(int osOperation){ + int operation = 0; + if ((osOperation & COM.DROPEFFECT_COPY) !is 0){ + operation |= DND.DROP_COPY; + } + if ((osOperation & COM.DROPEFFECT_LINK) !is 0) { + operation |= DND.DROP_LINK; + } + if ((osOperation & COM.DROPEFFECT_MOVE) !is 0) { + operation |= DND.DROP_MOVE; + } + return operation; +} + +/* QueryInterface([in] iid, [out] ppvObject) + * Ownership of ppvObject transfers from callee to caller so reference count on ppvObject + * must be incremented before returning. Caller is responsible for releasing ppvObject. + */ +int QueryInterface(int riid, int ppvObject) { + + if (riid is 0 || ppvObject is 0) + return COM.E_INVALIDARG; + GUID guid = new GUID(); + COM.MoveMemory(guid, riid, GUID.sizeof); + if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIDropTarget)) { + OS.MoveMemory(ppvObject, new int[] {iDropTarget.getAddress()}, 4); + AddRef(); + return COM.S_OK; + } + + OS.MoveMemory(ppvObject, new int[] {0}, 4); + return COM.E_NOINTERFACE; +} + +int Release() { + refCount--; + + if (refCount is 0) { + disposeCOMInterfaces(); + COM.CoFreeUnusedLibraries(); + } + + return refCount; +} + +void refresh() { + if (control is null || control.isDisposed()) return; + int handle = control.handle; + RECT lpRect = new RECT(); + if (OS.GetUpdateRect(handle, lpRect, false)) { + OS.ImageList_DragShowNolock(false); + OS.RedrawWindow(handle, lpRect, 0, OS.RDW_UPDATENOW | OS.RDW_INVALIDATE); + OS.ImageList_DragShowNolock(true); + } +} + +/** + * Removes the listener from the collection of listeners who will + * be notified when a drag and drop operation is in progress. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see DropTargetListener + * @see #addDropListener + */ +public void removeDropListener(DropTargetListener listener) { + if (listener is null) DND.error (DWT.ERROR_NULL_ARGUMENT); + removeListener (DND.DragEnter, listener); + removeListener (DND.DragLeave, listener); + removeListener (DND.DragOver, listener); + removeListener (DND.DragOperationChanged, listener); + removeListener (DND.Drop, listener); + removeListener (DND.DropAccept, listener); +} + +/** + * Specifies the drop effect for this DropTarget. This drop effect will be + * used during a drag and drop to display the drag under effect on the + * target widget. + * + * @param effect the drop effect that is registered for this DropTarget + * + * @since 3.3 + */ +public void setDropTargetEffect(DropTargetEffect effect) { + dropEffect = effect; +} + +bool setEventData(DNDEvent event, int pDataObject, int grfKeyState, int pt_x, int pt_y, int pdwEffect) { + if (pDataObject is 0 || pdwEffect is 0) return false; + + // get allowed operations + int style = getStyle(); + int[] operations = new int[1]; + OS.MoveMemory(operations, pdwEffect, 4); + operations[0] = osToOp(operations[0]) & style; + if (operations[0] is DND.DROP_NONE) return false; + + // get current operation + int operation = getOperationFromKeyState(grfKeyState); + keyOperation = operation; + if (operation is DND.DROP_DEFAULT) { + if ((style & DND.DROP_DEFAULT) is 0) { + operation = (operations[0] & DND.DROP_MOVE) !is 0 ? DND.DROP_MOVE : DND.DROP_NONE; + } + } else { + if ((operation & operations[0]) is 0) operation = DND.DROP_NONE; + } + + // Get allowed transfer types + TransferData[] dataTypes = new TransferData[0]; + IDataObject dataObject = new IDataObject(pDataObject); + dataObject.AddRef(); + try { + int[] address = new int[1]; + if (dataObject.EnumFormatEtc(COM.DATADIR_GET, address) !is COM.S_OK) { + return false; + } + IEnumFORMATETC enumFormatetc = new IEnumFORMATETC(address[0]); + try { + // Loop over enumerator and save any types that match what we are looking for + int rgelt = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, FORMATETC.sizeof); + try { + int[] pceltFetched = new int[1]; + enumFormatetc.Reset(); + while (enumFormatetc.Next(1, rgelt, pceltFetched) is COM.S_OK && pceltFetched[0] is 1) { + TransferData transferData = new TransferData(); + transferData.formatetc = new FORMATETC(); + COM.MoveMemory(transferData.formatetc, rgelt, FORMATETC.sizeof); + transferData.type = transferData.formatetc.cfFormat; + transferData.pIDataObject = pDataObject; + for (int i = 0; i < transferAgents.length; i++){ + Transfer transfer = transferAgents[i]; + if (transfer !is null && transfer.isSupportedType(transferData)){ + TransferData[] newDataTypes = new TransferData[dataTypes.length + 1]; + System.arraycopy(dataTypes, 0, newDataTypes, 0, dataTypes.length); + newDataTypes[dataTypes.length] = transferData; + dataTypes = newDataTypes; + break; + } + } + } + } finally { + OS.GlobalFree(rgelt); + } + } finally { + enumFormatetc.Release(); + } + } finally { + dataObject.Release(); + } + if (dataTypes.length is 0) return false; + + event.widget = this; + event.x = pt_x; + event.y = pt_y; + event.time = OS.GetMessageTime(); + event.feedback = DND.FEEDBACK_SELECT; + event.dataTypes = dataTypes; + event.dataType = dataTypes[0]; + if (dropEffect !is null) { + event.item = dropEffect.getItem(pt_x, pt_y); + } + event.operations = operations[0]; + event.detail = operation; + return true; +} + +/** + * Specifies the data types that can be transferred to this DropTarget. If data is + * being dragged that does not match one of these types, the drop target will be notified of + * the drag and drop operation but the currentDataType will be null and the operation + * will be DND.NONE. + * + * @param transferAgents a list of Transfer objects which define the types of data that can be + * dropped on this target + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if transferAgents is null</li> + * </ul> + */ +public void setTransfer(Transfer[] transferAgents){ + if (transferAgents is null) DND.error(DWT.ERROR_NULL_ARGUMENT); + this.transferAgents = transferAgents; +} +}