package info.limpet.stackedcharts.ui.editor.drop;
import info.limpet.stackedcharts.model.Chart;
import info.limpet.stackedcharts.model.Dataset;
import info.limpet.stackedcharts.model.ScatterSet;
import info.limpet.stackedcharts.ui.editor.parts.AxisEditPart;
import info.limpet.stackedcharts.ui.editor.parts.ChartEditPart;
import info.limpet.stackedcharts.ui.editor.parts.ChartPaneEditPart;
import info.limpet.stackedcharts.ui.editor.parts.ScatterSetContainerEditPart;
import info.limpet.stackedcharts.ui.view.adapter.AdapterRegistry;
import info.limpet.stackedcharts.ui.view.adapter.IStackedDatasetAdapter;
import info.limpet.stackedcharts.ui.view.adapter.IStackedScatterSetAdapter;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.util.TransferDropTargetListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
/**
* base for classes supporting the drop process, including establishing if the
* target is valid
*
* @author ian
*
*/
abstract public class CoreDropTargetListener implements
TransferDropTargetListener {
private final GraphicalViewer viewer;
protected AbstractGraphicalEditPart feedback;
protected CoreDropTargetListener(GraphicalViewer viewer) {
this.viewer = viewer;
}
/**
* whether this listener applies to this event
*
* @param event
* @return
*/
abstract boolean appliesTo(DropTargetEvent event);
/**
* find the object being passed over
*
* @param event
* the event
* @param viewer
* our figure
* @return the nearest edit part
*/
final protected EditPart findPart(DropTargetEvent event) {
org.eclipse.swt.graphics.Point cP = viewer.getControl().toControl(
event.x, event.y);
EditPart findObjectAt = viewer.findObjectAt(new Point(cP.x, cP.y));
return findObjectAt;
}
protected void addFeedback(AbstractGraphicalEditPart figure) {
if (figure != null) {
figure.getFigure().setBackgroundColor(ColorConstants.lightGray);
}
}
protected void removeFeedback(AbstractGraphicalEditPart figure) {
if (figure != null) {
figure.getFigure()
.setBackgroundColor(AxisEditPart.BACKGROUND_COLOR);
}
}
protected CommandStack getCommandStack() {
return viewer.getEditDomain().getCommandStack();
}
protected List<Dataset> convertSelectionToDataset(
StructuredSelection selection) {
IStackedDatasetAdapter adapter = new AdapterRegistry();
List<Dataset> element = new ArrayList<Dataset>();
for (Object object : selection.toArray()) {
if (adapter.canConvertToDataset(object)) {
final List<Dataset> converted = adapter
.convertToDataset(object);
if (converted != null) {
element.addAll(converted);
}
}
}
return element;
}
protected List<ScatterSet> convertSelectionToScatterSet(
StructuredSelection selection) {
IStackedScatterSetAdapter adapter = new AdapterRegistry();
List<ScatterSet> element = new ArrayList<ScatterSet>();
for (Object object : selection.toArray()) {
if (adapter.canConvertToScatterSet(object)) {
final List<ScatterSet> converted = adapter
.convertToScatterSet(object);
if (converted != null) {
element.addAll(converted);
}
}
}
return element;
}
protected static boolean canDropSelection(final Chart chart,
ISelection selection) {
boolean canDrop = true;
// NOTE: this section has been deliberately commented out.
// The Debrief convert() method sometimes opens a dialog to
// ask the user which data to display (for a tree-view item
// that is actually several collections. So, we can't call
// convert() for drag-over operations, we can only call
// it after a drop
//
// We'll have to reconsider the logic here.
// AdapterRegistry adapter = new AdapterRegistry();
// if (selection instanceof StructuredSelection)
// {
// // check the selection
// for (Object obj : ((StructuredSelection) selection).toArray())
// {
// if (adapter.canConvert(obj))
// {
// List<Dataset> convert = adapter.convert(obj);
// if (convert.size() == 0)
// {
// continue;
// }
// for (Dataset dataset : convert)
// {
// if (!canDropDataset(chart, dataset))
// {
// canDrop = false;
// break;
// }
// }
// }
// }
// }
return canDrop;
}
@Override
public final void dragOver(DropTargetEvent event) {
EditPart target = findPart(event);
if (feedback == target) {
// drop out, we're still passing over the same object
return;
}
if (LocalSelectionTransfer.getTransfer().isSupportedType(
event.currentDataType)) {
// get the chart model
Chart chart = null;
AbstractGraphicalEditPart editPart = (AbstractGraphicalEditPart) target;
if (editPart instanceof ChartPaneEditPart) {
ChartPaneEditPart chartPanel = (ChartPaneEditPart) editPart;
chart = (Chart) chartPanel.getModel();
} else if (editPart instanceof AxisEditPart) {
AxisEditPart axis = (AxisEditPart) editPart;
ChartPaneEditPart chartEditPane = (ChartPaneEditPart) axis
.getParent();
ChartEditPart chartPane = (ChartEditPart) chartEditPane
.getParent();
chart = (Chart) chartPane.getModel();
} else if (editPart instanceof ScatterSetContainerEditPart) {
ScatterSetContainerEditPart scatter= (ScatterSetContainerEditPart) editPart;
chart = (Chart) scatter.getParent().getModel();
}
if (canDropSelection(chart, LocalSelectionTransfer.getTransfer()
.getSelection())) {
removeFeedback(feedback);
feedback = (AbstractGraphicalEditPart) target;
addFeedback(feedback);
event.detail = DND.DROP_COPY;
} else {
removeFeedback(feedback);
feedback = null;
event.detail = DND.DROP_NONE;
}
} else {
removeFeedback(feedback);
feedback = null;
event.detail = DND.DROP_NONE;
}
}
@Override
final public void dragOperationChanged(DropTargetEvent event) {
}
@Override
final public void dragLeave(DropTargetEvent event) {
removeFeedback(feedback);
feedback = null;
}
@Override
final public void dragEnter(DropTargetEvent event) {
}
@Override
final public boolean isEnabled(DropTargetEvent event) {
return LocalSelectionTransfer.getTransfer().isSupportedType(
event.currentDataType);
}
@Override
final public Transfer getTransfer() {
return LocalSelectionTransfer.getTransfer();
}
final public void reset() {
removeFeedback(feedback);
feedback = null;
}
@Override
final public void dropAccept(DropTargetEvent event) {
}
}