blob: 859c973ab4979a504f1b4225f116b546ac176a07 [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* 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:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*
*/
package org.eclipse.osbp.vaadin.emf.actions;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.osbp.vaadin.emf.api.IModelingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.shared.ui.dd.VerticalDropLocation;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Tree.TreeTargetDetails;
@SuppressWarnings("serial")
public class EmfTreeDndHandler implements DropHandler {
private static final Logger LOGGER = LoggerFactory
.getLogger(EmfTreeDndHandler.class);
private final IModelingContext modelingContext;
private final Tree tree;
public EmfTreeDndHandler(IModelingContext modelingContext, Tree tree) {
super();
this.modelingContext = modelingContext;
this.tree = tree;
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
@SuppressWarnings("unchecked")
@Override
public void drop(DragAndDropEvent event) {
DataBoundTransferable t = (DataBoundTransferable) event
.getTransferable();
// Make sure the drag source is the same tree
if (t.getSourceComponent() != tree)
return;
TreeTargetDetails target = (TreeTargetDetails) event.getTargetDetails();
// Get ids of the dragged item and the target item
EObject sourceItemId = (EObject) t.getData("itemId");
EObject targetItemId = (EObject) target.getItemIdOver();
if (sourceItemId == null || targetItemId == null) {
return;
}
// On which side of the target the item was dropped
VerticalDropLocation location = target.getDropLocation();
EStructuralFeature feature = sourceItemId.eContainingFeature();
boolean isMany = feature.isMany();
EObject targetParent = null;
EObject sourceParent = sourceItemId.eContainer();
int targetIndex = -1;
// Drop right on an item -> make it a child
if (location == VerticalDropLocation.MIDDLE) {
if (targetItemId.eContainer() == sourceItemId.eContainer()) {
targetParent = targetItemId.eContainer();
if (isMany) {
List<EObject> collection = (List<EObject>) targetParent
.eGet(feature);
targetIndex = collection.indexOf(targetItemId) + 1;
}
} else {
targetParent = targetItemId;
targetIndex = -1;
}
} else if (location == VerticalDropLocation.TOP
|| location == VerticalDropLocation.BOTTOM) {
if(targetItemId.eClass().getEAllStructuralFeatures().contains(feature)) {
// we drop it in the targetItemId
targetParent = targetItemId;
if (isMany && targetParent.eGet(feature) instanceof List) {
if (location == VerticalDropLocation.TOP) {
// targetIndex = index > 0 ? index - 1 : -1;
} else if (location == VerticalDropLocation.BOTTOM) {
targetIndex = -1;
}
}
}else{
targetParent = targetItemId.eContainer();
if (isMany && targetParent.eGet(feature) instanceof List) {
List<EObject> collection = (List<EObject>) targetParent
.eGet(feature);
int index = collection.indexOf(targetItemId);
if (location == VerticalDropLocation.TOP) {
targetIndex = index > 0 ? index - 1 : -1;
} else if (location == VerticalDropLocation.BOTTOM) {
targetIndex = index;
}
}
}
}
if (!targetParent.eClass().getEAllStructuralFeatures()
.contains(feature)) {
LOGGER.error("Feature " + feature.getName()
+ " is not contained in droptarget "
+ targetParent.eClass().getName());
return;
}
boolean isMove = targetParent == sourceParent;
if (isMany) {
if (isMove) {
// move if same parent
Command command = MoveCommand.create(
modelingContext.getEditingDomain(), targetParent,
feature, sourceItemId, targetIndex);
if (command.canExecute()) {
modelingContext.getCommandStack().execute(command);
}
} else {
// remove and add if new parent
Command remove = RemoveCommand.create(
modelingContext.getEditingDomain(),
Collections.singletonList(sourceItemId));
Command add = AddCommand.create(
modelingContext.getEditingDomain(), targetParent,
feature, sourceItemId, targetIndex);
CompoundCommand command = new CompoundCommand();
command.append(remove);
command.append(add);
if (command.canExecute()) {
modelingContext.getCommandStack().execute(command);
}
}
} else {
Command command = SetCommand.create(
modelingContext.getEditingDomain(), targetParent, feature,
sourceItemId);
if (command.canExecute()) {
modelingContext.getCommandStack().execute(command);
}
}
}
}