blob: 7db51206c7cab307c34324ce788af7e8a24905c3 [file] [log] [blame]
package org.eclipse.swt.dnd;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.photon.*;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved
*/
/**
*
* 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 == 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> <dd>DND.DROP_NONE, DND.DROP_COPY, DND.DROP_MOVE, DND.DROP_LINK
* <dt><b>Events</b> <dd>DND.DragEnter, DND.DragLeave, DND.DragOver, DND.DragOperationChanged,
* DND.Drop, DND.DropAccept
* </dl>
*/
public class DropTarget extends Widget {
private Callback dropProc;
private Callback transferProc;
private Callback dragProc;
// info for registering as a droptarget
private Control control;
private Listener controlListener;
private Transfer[] transferAgents = new Transfer[0];
// info about data being dragged over site
private TransferData selectedDataType;
private TransferData[] dataTypes;
private int dropTransferObject;
private DragUnderEffect effect;
public DropTarget(Control control, int style) {
super (control, checkStyle(style));
this.control = control;
controlListener = new Listener () {
public void handleEvent (Event event) {
if (!DropTarget.this.isDisposed()){
DropTarget.this.dispose();
}
}
};
control.addListener (SWT.Dispose, controlListener);
this.addListener (SWT.Dispose, new Listener () {
public void handleEvent (Event event) {
//onDispose();
}
});
if (control instanceof Tree) {
effect = new TreeDragUnderEffect((Tree)control);
} else if (control instanceof Table) {
effect = new TableDragUnderEffect((Table)control);
} else {
effect = new NoDragUnderEffect(control);
}
}
/**
* Adds the listener to receive events.
* <p>
*
* @param listener the listener
*
* @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
* when called from the wrong thread
* @exception SWTError(ERROR_WIDGET_DISPOSED)
* when the widget has been disposed
* @exception SWTError(ERROR_NULL_ARGUMENT)
* when listener is null
*/
public void addDropListener(DropTargetListener listener) {
if (listener == null) DND.error (SWT.ERROR_NULL_ARGUMENT);
DNDListener typedListener = new DNDListener (listener);
addListener (DND.DragEnter, typedListener);
addListener (DND.DragLeave, typedListener);
addListener (DND.DragOver, typedListener);
addListener (DND.DragOperationChanged, typedListener);
addListener (DND.Drop, typedListener);
addListener (DND.DropAccept, typedListener);
}
static int checkStyle (int style) {
if (style == SWT.NONE) return DND.DROP_MOVE;
return style;
}
/**
* 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;
}
public Display getDisplay () {
if (control == null) DND.error(SWT.ERROR_WIDGET_DISPOSED);
return control.getDisplay ();
}
/**
* Returns the list of data types that can be transferred to this DropTarget.
*
* @return the list of data types that can be transferred to this DropTarget
*
*/
public Transfer[] getTransfer(){
return transferAgents;
}
public void notifyListeners (int eventType, Event event) {
Point coordinates = new Point(event.x, event.y);
coordinates = control.toControl(coordinates);
if (this.control instanceof Tree) {
event.item = ((Tree)control).getItem(coordinates);
}
if (this.control instanceof Table) {
event.item = ((Table)control).getItem(coordinates);
}
super.notifyListeners(eventType, event);
}
/**
* Adds the listener to receive events.
* <p>
*
* @param listener the listener
*
* @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
* when called from the wrong thread
* @exception SWTError(ERROR_WIDGET_DISPOSED)
* when the widget has been disposed
* @exception SWTError(ERROR_NULL_ARGUMENT)
* when listener is null
*/
public void removeDropListener(DropTargetListener listener) {
if (listener == null) DND.error (SWT.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);
}
public void setTransfer(Transfer[] transferAgents){
}
protected void checkSubclass () {
String name = getClass().getName ();
String validName = DropTarget.class.getName();
if (!validName.equals(name)) {
DND.error (SWT.ERROR_INVALID_SUBCLASS);
}
}
}