/*******************************************************************************
* Copyright (c) 2011 Oak Ridge National Laboratory.
* 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
******************************************************************************/
package org.csstudio.ui.util.dnd;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Control;
/**
* General purpose utility to allowing Drag-and-Drop "Drop" of any
* adaptable or serializable object.
* <p>
* Filters the received items to match the desired type, based on the
* order or preference specified. Can also accept plain text.
*
* @author Gabriele Carcassi
* @author Kay Kasemir
*/
abstract public class ControlSystemDropTarget
{
final private DropTarget target;
/** Initialize 'drop' target
* @param control Control onto which items may be dropped
* @param accepted (Base) class of accepted items
*/
public ControlSystemDropTarget(final Control control,
final Class<?>... accepted)
{
target = new DropTarget(control, DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK);
final List<Transfer> supportedTransfers = new ArrayList<Transfer>();
for (Class<?> clazz : accepted)
{
if (clazz == String.class)
supportedTransfers.add(TextTransfer.getInstance());
if (clazz == File.class)
supportedTransfers.add(FileTransfer.getInstance());
else
{
final SerializableItemTransfer xfer = SerializableItemTransfer.getTransfer(clazz.getName());
if (xfer != null)
supportedTransfers.add(xfer);
}
}
target.setTransfer(supportedTransfers.toArray(new Transfer[supportedTransfers.size()]));
target.addDropListener(new DropTargetAdapter()
{
/** Used internally by the system when a DnD operation enters the control.
* {@inheritDoc}
*/
@Override
public void dragEnter(final DropTargetEvent event)
{
// Seems DropTarget it is not honoring the order of the transferData:
// Making sure is right
boolean done = false;
for (Transfer transfer : target.getTransfer()) {
for (TransferData data : event.dataTypes) {
if (transfer.isSupportedType(data)) {
event.currentDataType = data;
done = true;
break;
}
}
if (done)
break;
}
if ((event.operations & DND.DROP_COPY) != 0)
event.detail = DND.DROP_COPY;
else
event.detail = DND.DROP_NONE;
}
/** Data was dropped into the target.
* Check the actual type, handle received data.
*/
@Override
public void drop(final DropTargetEvent event)
{
handleDrop(event.data);
}
});
}
/** To be implemented by derived class.
*
* Will be called for each 'dropped' item that
* has the accepted data type
*
* @param item Control system item
*/
abstract public void handleDrop(Object item);
}