/** * <p>Copyright: Copyright (c) 2013</p> * <p>Company: �������ӹɷ����޹�˾</p> */ package com.hundsun.ares.studio.jres.metadata.ui.editors.dnd; import java.util.Collection; 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.common.util.EList; 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.domain.EditingDomain; import org.eclipse.emf.edit.ui.dnd.LocalTransfer; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerDropAdapter; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; import org.eclipse.swt.widgets.TreeItem; import com.hundsun.ares.studio.jres.metadata.ui.viewer.MetadataViewerUtil; import com.hundsun.ares.studio.jres.model.metadata.MenuItem; import com.hundsun.ares.studio.jres.model.metadata.MenuList; import com.hundsun.ares.studio.jres.model.metadata.MetadataPackage; /** * @author wangxh * */ public class MenuDropAdapter extends ViewerDropAdapter { private EditingDomain domain; private EObject dropTargetContainer; public MenuDropAdapter(TreeViewer viewer, EditingDomain domain) { super(viewer); this.domain = domain; } // ����ֻ��ͨ��UI����ȡ����ǰ�� protected Object determineTarget(DropTargetEvent event) { dropTargetContainer = determainDropTargetContainer(event); return super.determineTarget(event); } private EObject determainDropTargetContainer(DropTargetEvent event) { if (!(event.item instanceof TreeItem)) { return null; } TreeItem item = (TreeItem) event.item; if (item.getData() instanceof MenuItem) { Object data = item.getData(); if(data instanceof MenuItem){ MenuItem parent = (MenuItem)data; int location = determineLocation(event); if (location == LOCATION_ON) return parent; else if (location == LOCATION_AFTER || location == LOCATION_BEFORE) { return parent.eContainer(); } } } return MetadataViewerUtil.getMetadataModel(getColumnViewer()); } @Override public boolean performDrop(Object data) { // int operation = getCurrentOperation(); Collection<?> elements = extractDragSource(data); Object target = getCurrentTarget(); int location = getCurrentLocation(); EStructuralFeature feature = dropTargetContainer instanceof MenuList ? MetadataPackage.Literals.METADATA_RESOURCE_DATA__ITEMS : MetadataPackage.Literals.MENU_ITEM__SUB_ITEMS; EList<?> list = (EList<?>) dropTargetContainer.eGet(feature); int index = list.indexOf(target); if (target.equals(dropTargetContainer)) { index = 0; } else { if (location == LOCATION_AFTER) index++; } Command command = null; CompoundCommand cmd = new CompoundCommand(); EObject owner = getOwner(); if (dropTargetContainer == owner) { // ͬһ��container�µ��϶������ƶ�˳�� for (Object element : elements) { int curIndex = list.indexOf(element); if(curIndex<index){ cmd.append(MoveCommand.create(domain, dropTargetContainer, feature, element, index-1)); }else{ cmd.append(MoveCommand.create(domain, dropTargetContainer, feature, element, index)); index++; } } } else { EStructuralFeature ft = owner instanceof MenuList ? MetadataPackage.Literals.METADATA_RESOURCE_DATA__ITEMS : MetadataPackage.Literals.MENU_ITEM__SUB_ITEMS; cmd.append(RemoveCommand.create(domain, owner, ft, elements)); // ��ͬ��container�µ��϶������ƶ��������˵����� cmd.append(AddCommand.create(domain, dropTargetContainer, feature, elements, index)); } command = cmd; if (command != null) domain.getCommandStack().execute(command); return true; } @Override public boolean validateDrop(Object target, int operation, TransferData transferType) { Collection<?> source = getDragSource(getCurrentEvent()); if (source == null || source.isEmpty()) return false; if (dropTargetContainer == null) return false; Object[] elements = source.toArray(); // 1. ����ֻ��Item����ֻ�з��飻 ������ͬһ�㣬ͬһ���������� if (!allUnderSameContainer(elements)) return false; // 2. target�Ƿ��� // int location = getCurrentLocation(); if (target instanceof MenuItem) { return true; } return false; } /** * ָ����Ԫ���Ƿ��ڵ�ǰ�������� * ���Ԫ��������Item��Ҳ��Category��Ҳ����false * @param elements * @return */ private boolean allUnderSameContainer(Object[] elements) { if (elements == null || elements.length == 0) return false; if (elements.length == 1) return true; EStructuralFeature feature = getFeature(elements[0]); EObject owner = getOwner(); @SuppressWarnings("rawtypes") EList list = (EList) owner.eGet(feature); for (Object element : elements) { if (!list.contains(element)) return false; } return true; } protected EObject getOwner() { IStructuredSelection sel = (IStructuredSelection) getViewer().getSelection(); Object obj = sel.getFirstElement(); if(obj != null && obj instanceof MenuItem){ return ((MenuItem)obj).eContainer(); } return null; } private EStructuralFeature getFeature(Object element) { if(element instanceof MenuItem){ MenuItem item = (MenuItem)element; if(item.eContainer() instanceof MenuItem){ return MetadataPackage.Literals.MENU_ITEM__SUB_ITEMS; }else{ return MetadataPackage.Literals.METADATA_RESOURCE_DATA__ITEMS; } } // should not happen return null; } private ColumnViewer getColumnViewer(){ return (ColumnViewer) getViewer(); } protected Collection<?> getDragSource(DropTargetEvent event) { // Check whether the current data type can be transfered locally. // LocalTransfer localTransfer = LocalTransfer.getInstance(); if (!localTransfer.isSupportedType(event.currentDataType)) { // Iterate over the data types to see if there is a data type that // supports a local transfer. // TransferData[] dataTypes = event.dataTypes; for (int i = 0; i < dataTypes.length; ++i) { TransferData transferData = dataTypes[i]; // If the local transfer supports this data type, switch to that // data type // if (localTransfer.isSupportedType(transferData)) { event.currentDataType = transferData; } } return null; } else { // Transfer the data and, if non-null, extract it. // Object object = localTransfer.nativeToJava(event.currentDataType); return object == null ? null : extractDragSource(object); } } /** * This extracts a collection of dragged source objects from the given * object retrieved from the transfer agent. This default implementation * converts a structured selection into a collection of elements. */ protected Collection<?> extractDragSource(Object object) { // Transfer the data and convert the structured selection to a // collection of objects. // if (object instanceof IStructuredSelection) { List<?> list = ((IStructuredSelection) object).toList(); return list; } else { return Collections.EMPTY_LIST; } } }