blob: 09e0f8c2697a6544aedafb6f4b89cda632b62f3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Obeo.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.acceleo.ui.interpreter.internal.view;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.acceleo.ui.interpreter.internal.view.actions.NewVariableAction;
import org.eclipse.acceleo.ui.interpreter.view.Variable;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.views.navigator.LocalSelectionTransfer;
/**
* This listener will be registered against the "Variables" TreeViewer in order to allow drop operations on
* that viewer from workspace selections.
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
*/
public class VariableDropListener extends DropTargetAdapter {
/** Keeps a reference towards the viewer against which this listener is registered. */
private TreeViewer viewer;
/**
* Creates a new drop listener for the given <code>viewer</code>.
*
* @param viewer
* The viewer against which this drop listener is registered.
*/
public VariableDropListener(TreeViewer viewer) {
this.viewer = viewer;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.swt.dnd.DropTargetAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
*/
@Override
public void dragEnter(DropTargetEvent event) {
if (!LocalSelectionTransfer.getInstance().isSupportedType(event.currentDataType)) {
return;
}
event.detail = DND.DROP_COPY;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.swt.dnd.DropTargetAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
*/
@Override
public void drop(DropTargetEvent event) {
Collection<?> selection = getSelection(event);
if (!selection.isEmpty()) {
Widget targetItem = event.item;
if (targetItem instanceof TreeItem) {
Object targetVariable = targetItem.getData();
while (targetItem != null && !(targetVariable instanceof Variable)) {
targetItem = ((TreeItem)targetItem).getParentItem();
if (targetItem != null) {
targetVariable = targetItem.getData();
}
}
if (targetVariable instanceof Variable) {
addToVariable((Variable)targetVariable, selection);
} else {
createNewVariable(selection);
}
} else {
createNewVariable(selection);
}
}
}
/**
* Adds the given selection to the values of <code>targetVariable</code>.
*
* @param targetVariable
* Variable into which we are to add values.
* @param selection
* The values that are to be added to <code>targetVariable</code>.
*/
@SuppressWarnings("unchecked")
private void addToVariable(Variable targetVariable, Collection<?> selection) {
Collection<Object> newValue;
final Object currentValue = targetVariable.getValue();
if (currentValue instanceof Collection<?>) {
newValue = (Collection<Object>)currentValue;
} else {
newValue = new ArrayList<Object>();
if (currentValue != null) {
newValue.add(currentValue);
}
}
newValue.addAll(selection);
// if there is but a single value, simply use it
if (newValue.size() == 1) {
targetVariable.setValue(newValue.iterator().next());
} else {
targetVariable.setValue(newValue);
}
viewer.refresh();
}
/**
* Creates a new variable to hold the given selection.
*
* @param selection
* The selection for which to create a Variable.
*/
private void createNewVariable(Collection<?> selection) {
final Object variableValue;
if (selection.size() == 1) {
variableValue = selection.iterator().next();
} else {
variableValue = selection;
}
NewVariableAction action = new NewVariableAction(viewer, variableValue);
action.run();
}
/**
* Tries and extract the selected objects from the drop event.
*
* @param event
* The drop event from which to extract a selection.
* @return The list containing the event's selection, an empty list if none.
*/
private Collection<?> getSelection(DropTargetEvent event) {
if (event.data instanceof IStructuredSelection) {
@SuppressWarnings("unchecked")
List<Object> objectList = ((IStructuredSelection)event.data).toList();
List<Object> variablesValues = new ArrayList<Object>();
for (Object object : objectList) {
EObject variableEObject = null;
if (object instanceof EObject) {
variableEObject = (EObject)object;
} else if (object instanceof IAdaptable) {
variableEObject = (EObject)((IAdaptable)object).getAdapter(EObject.class);
} else {
variableEObject = (EObject)Platform.getAdapterManager().getAdapter(object, EObject.class);
}
if (variableEObject != null) {
variablesValues.add(variableEObject);
} else {
variablesValues.add(object);
}
}
return variablesValues;
}
return Collections.emptyList();
}
}