package com.vaadin.tests.dd; import java.util.Collection; import com.vaadin.data.Item; import com.vaadin.data.util.HierarchicalContainer; import com.vaadin.event.DataBoundTransferable; import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.event.dd.acceptcriteria.Or; import com.vaadin.shared.ui.dd.VerticalDropLocation; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.AbstractSelect; import com.vaadin.ui.Tree; import com.vaadin.ui.Tree.TreeDragMode; import com.vaadin.ui.Tree.TreeTargetDetails; /** * DD playground. Better quality example/prototype codes in {@link DDTest2}. */ public class DDTest8 extends TestBase { @Override protected void setup() { final Tree t = new Tree( "Tree with criteria from AbstractSelect (OverItem, ContainsItem). Foo can be dragged anywhere, anything can be dropped on Foo or Bar. Bar5 subtree is also valid drop target."); final HierarchicalContainer idx = new HierarchicalContainer(); t.setContainerDataSource(idx); t.addItem("Foo"); t.addItem("Bar"); t.addItem("Bar1"); t.addItem("Bar2"); t.addItem("Bar3"); t.addItem("Bar4"); t.addItem("Bar5"); t.addItem("Child"); t.setParent("Child", "Foo"); t.setSizeFull(); t.setDragMode(TreeDragMode.NODE); /* * Moves items in tree (and could work in Table too). Also supports * "building" tree. * * TODO fix algorithm, broken in some cases. */ DropHandler itemSorter = new DropHandler() { @SuppressWarnings("unused") private void populateSubTree(HierarchicalContainer idx, HierarchicalContainer subtree, Object itemId) { Collection children = subtree.getChildren(itemId); if (children != null) { for (Object childId : children) { Item addItem = idx.addItem(childId); if (addItem != null) { // did not exist, populate properties Item item = subtree.getItem(itemId); Collection itemPropertyIds = item .getItemPropertyIds(); for (Object propId : itemPropertyIds) { addItem.getItemProperty(propId) .setValue( item.getItemProperty(propId) .getValue()); } } idx.setParent(childId, itemId); populateSubTree(idx, subtree, childId); } } } @SuppressWarnings("unused") private HierarchicalContainer getSubTree(HierarchicalContainer idx, Object itemId) { HierarchicalContainer hierarchicalContainer = new HierarchicalContainer(); Collection containerPropertyIds = idx .getContainerPropertyIds(); for (Object object : containerPropertyIds) { hierarchicalContainer.addContainerProperty(object, idx.getType(object), null); } hierarchicalContainer.addItem(itemId); copyChildren(idx, hierarchicalContainer, itemId); return hierarchicalContainer; } private void copyChildren(HierarchicalContainer source, HierarchicalContainer target, Object itemId) { Collection children = source.getChildren(itemId); if (children != null) { for (Object childId : children) { Item item = source.getItem(childId); Item addedItem = target.addItem(childId); target.setParent(childId, itemId); Collection itemPropertyIds = item .getItemPropertyIds(); for (Object propertyId : itemPropertyIds) { addedItem.getItemProperty(propertyId) .setValue( item.getItemProperty(propertyId) .getValue()); } copyChildren(source, target, childId); } } } @Override public void drop(DragAndDropEvent event) { TreeTargetDetails details = (TreeTargetDetails) event .getTargetDetails(); // TODO set properties, so same sorter could be used in Table Transferable transferable = event.getTransferable(); if (transferable instanceof DataBoundTransferable) { DataBoundTransferable transferrable2 = (DataBoundTransferable) transferable; Object itemId = transferrable2.getItemId(); Object itemIdOver = details.getItemIdOver(); // TODO could use the "folder" node id to make the drop // logic simpler Object itemIdInto = details.getItemIdInto(); VerticalDropLocation dropLocation = details .getDropLocation(); Object itemIdAfter = details.getItemIdAfter(); if (itemIdOver.equals(itemIdInto)) { // directly on a node t.setParent(itemId, itemIdOver); return; } idx.setParent(itemId, itemIdInto); if (dropLocation == null) { System.err.println("No detail of drop place available"); } idx.moveAfterSibling(itemId, itemIdAfter); } return; } @Override public AcceptCriterion getAcceptCriterion() { return new Or(new AbstractSelect.TargetItemIs(t, "Foo", "Bar"), new AbstractSelect.AcceptItem(t, "Foo"), t.new TargetInSubtree("Bar5") // ); } }; t.setDropHandler(itemSorter); getLayout().setSizeFull(); addComponent(t); } @Override protected String getDescription() { return "Random DD tests"; } @Override protected Integer getTicketNumber() { return 119; } }