package edu.ualberta.med.biobank.treeview.listeners;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.widgets.TreeItem;
import edu.ualberta.med.biobank.common.wrappers.ContainerWrapper;
import edu.ualberta.med.biobank.common.wrappers.ModelWrapper;
import edu.ualberta.med.biobank.gui.common.BgcLogger;
import edu.ualberta.med.biobank.gui.common.BgcPlugin;
import edu.ualberta.med.biobank.treeview.AdapterBase;
import edu.ualberta.med.biobank.treeview.admin.ContainerAdapter;
public class ContainerDragDropListener implements DropTargetListener,
DragSourceListener {
protected static BgcLogger log = BgcLogger
.getLogger(ContainerDragDropListener.class.getName());
private final TreeViewer treeViewer;
private ContainerAdapter srcContainerAdapter;
private ContainerWrapper srcContainer;
private boolean dstLocationSelected;
public ContainerDragDropListener(TreeViewer treeViewerI) {
this.treeViewer = treeViewerI;
this.srcContainer = null;
this.dstLocationSelected = false;
}
private ContainerWrapper getSelectedContainer() {
TreeSelection ts = (TreeSelection) treeViewer.getSelection();
if (ts == null || ts.isEmpty())
return null;
if (ts.getFirstElement() instanceof ContainerAdapter) {
if (ts.size() != 1)
BgcPlugin
.openError(
Messages.ContainerDragDropListener_move_multiple_error_title,
Messages.ContainerDragDropListener_move_multiple_error_msg);
srcContainerAdapter = (ContainerAdapter) ts.getFirstElement();
if (srcContainerAdapter != null)
return (ContainerWrapper) srcContainerAdapter.getModelObject();
}
return null;
}
@Override
public void dragOver(DropTargetEvent event) {
event.feedback = DND.FEEDBACK_NONE;
if (event.item != null && srcContainer != null) {
TreeItem item = (TreeItem) event.item;
ModelWrapper<?> wrapper = ((AdapterBase) (item.getData()))
.getModelObject();
if ((wrapper instanceof ContainerWrapper)) {
try {
ContainerWrapper container = (ContainerWrapper) wrapper;
if (container.getContainerType()
.getChildContainerTypeCollection().size() != 0) {
if (container.getContainerType()
.getChildContainerTypeCollection()
.contains(srcContainer.getContainerType())) {
if (!container.isContainerFull()) {
event.feedback |= DND.FEEDBACK_SELECT;
event.feedback |= DND.FEEDBACK_EXPAND;
}
} else {
/*
* TODO expand only when an ancestor can hold the
* srcContainerType. It does not make sense to
* expand a branch when none of the children of that
* branch can hold the src container.
*/
event.feedback |= DND.FEEDBACK_EXPAND;
}
}
} catch (Exception ex) {
BgcPlugin
.openAsyncError(
Messages.ContainerDragDropListener_drag_error_title,
ex);
}
}
}
dstLocationSelected = ((event.feedback & DND.FEEDBACK_SELECT) != 0);
}
@Override
public void dragEnter(DropTargetEvent event) {
//
}
@Override
public void dragLeave(DropTargetEvent event) {
//
}
@Override
public void dragOperationChanged(DropTargetEvent event) {
//
}
@Override
public void drop(DropTargetEvent event) {
if (!dstLocationSelected || event.item == null) {
event.detail = DND.DROP_NONE;
return;
}
TreeItem item = (TreeItem) event.item;
ModelWrapper<?> wrapper = ((AdapterBase) (item.getData()))
.getModelObject();
if (wrapper != null && (wrapper instanceof ContainerWrapper)) {
ContainerWrapper dstContainer = (ContainerWrapper) wrapper;
try {
/* sanity checks */
if (dstContainer.getContainerType()
.getChildContainerTypeCollection()
.contains(srcContainer.getContainerType())
&& !dstContainer.isContainerFull()) {
// TODO implement the moving of containers here.
System.out.println("Valid Drag Detected:"); //$NON-NLS-1$
System.out.println(srcContainer + " --> " //$NON-NLS-1$
+ dstContainer);
srcContainerAdapter.moveContainer(dstContainer);
return;
}
BgcPlugin
.openError(
Messages.ContainerDragDropListener_state_error_title,
Messages.ContainerDragDropListener_state_error_msg);
} catch (Exception ex) {
BgcPlugin
.openAsyncError(
Messages.ContainerDragDropListener_drop_error_title,
ex);
}
}
event.detail = DND.DROP_NONE;
}
@Override
public void dropAccept(DropTargetEvent event) {
//
}
@Override
public void dragStart(DragSourceEvent event) {
ContainerWrapper container = getSelectedContainer();
if (container != null && container.hasParentContainer()) {
event.doit = true;
srcContainer = container;
} else {
event.doit = false;
srcContainer = null;
}
dstLocationSelected = false;
}
@Override
public void dragSetData(DragSourceEvent event) {
event.data = getSelectedContainer();
event.doit = true;
}
@Override
public void dragFinished(DragSourceEvent event) {
srcContainer = null;
dstLocationSelected = false;
}
/* TODO move containers in tree view */
@SuppressWarnings("unused")
private void moveContainerTo(ContainerAdapter containerAdapter) {
// containerAdapter.moveSpecimens();
}
}