import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
import eu.etaxonomy.cdm.model.description.FeatureNode;
import eu.etaxonomy.cdm.model.description.FeatureTree;
import eu.etaxonomy.taxeditor.featuretree.AvailableFeaturesWizard;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
+import eu.etaxonomy.taxeditor.model.ImageResources;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
import eu.etaxonomy.taxeditor.store.CdmStore;
import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
public class FeatureTreeEditor implements
ModifyListener, ISelectionChangedListener {
+ private TreeViewer viewer;
+ private Label label_title;
+ private Button button_add;
+ private Button button_remove;
private FeatureTree featureTree;
+ private Text text_title;
+ private Button btnOpenFeatureTree;
private ConversationHolder conversation;
@Inject
private Shell shell;
- private FeatureTreeSelectionComposite featureTreeSelectionComposite;
-
- private FeatureTreeAddRemoveButtonComposite featureTreeAddRemoveButtonComposite;
-
- private FeatureTreeViewerComposite featureTreeViewerComposite;
-
@Inject
public FeatureTreeEditor(@Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
this.shell = shell;
composite.setLayout(new GridLayout());
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- initFeatureTreeSelection(shell, composite);
+ Composite composite_treeTitle = new Composite(composite, SWT.NULL);
+ composite_treeTitle.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true,
+ false));
+ composite_treeTitle.setLayout(new GridLayout(3, false));
+
+ label_title = new Label(composite_treeTitle, SWT.NULL);
+ label_title.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+ label_title.setText("Feature Tree");
+
+ text_title = new Text(composite_treeTitle, SWT.BORDER);
+ text_title.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+ btnOpenFeatureTree = new Button(composite_treeTitle, SWT.NONE);
+ btnOpenFeatureTree.setToolTipText("Open Tree");
+ btnOpenFeatureTree.setImage(ImageResources.getImage(ImageResources.BROWSE_ICON));
Composite composite_treeContent = new Composite(composite, SWT.NULL);
composite_treeContent.setLayoutData(new GridData(SWT.FILL, SWT.FILL,
true, true));
composite_treeContent.setLayout(new GridLayout(2, false));
- initViewer(composite_treeContent);
-
- initAddRemoveButtons(composite_treeContent);
-
+ viewer = new TreeViewer(composite_treeContent);
+ Tree tree = viewer.getTree();
+ tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ viewer.getControl().setLayoutData(
+ new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Composite composite_buttons = new Composite(composite_treeContent,
+ SWT.NULL);
+ composite_buttons.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false,
+ false));
+ composite_buttons.setLayout(new GridLayout());
+
+ button_add = new Button(composite_buttons, SWT.PUSH);
+ button_add.setToolTipText("Add a feature to this feature tree.");
+ button_add.setImage(ImageResources.getImage(ImageResources.ADD_EDIT));
+ button_remove = new Button(composite_buttons, SWT.PUSH);
+ button_remove.setToolTipText("Remove a feature from this feature tree.");
+ button_remove.setImage(ImageResources.getImage(ImageResources.TRASH_ICON));
+
+ init(shell);
}
- private void initFeatureTreeSelection(Shell shell, Composite composite) {
- featureTreeSelectionComposite = new FeatureTreeSelectionComposite(composite, SWT.NULL);
- featureTreeSelectionComposite.getBtnOpenFeatureTree().addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
- if(tree!=null){
- setSelectedTree(tree);
- }
- }
- });
- }
-
- private void initAddRemoveButtons(Composite composite_treeContent) {
- featureTreeAddRemoveButtonComposite = new FeatureTreeAddRemoveButtonComposite(composite_treeContent, SWT.NULL);
- featureTreeAddRemoveButtonComposite.getButtonAdd().addSelectionListener(new AddButtonListener());
- featureTreeAddRemoveButtonComposite.getButtonRemove().addSelectionListener(new RemoveSelectionListener());
- }
-
- private void initViewer(Composite composite_treeContent) {
- featureTreeViewerComposite = new FeatureTreeViewerComposite(composite_treeContent, SWT.NULL);
- featureTreeViewerComposite.getViewer().addSelectionChangedListener(this);
- }
-
private void setDirty(boolean isDirty){
this.dirty.setDirty(isDirty);
}
+ private void init(Shell shell) {
+ viewer.setContentProvider(new FeatureTreeContentProvider());
+ viewer.setLabelProvider(new FeatureTreeLabelProvider());
+
+ int ops = DND.DROP_COPY | DND.DROP_MOVE;
+ Transfer[] transfers = new Transfer[] { FeatureNodeTransfer
+ .getInstance() };
+ viewer.addDragSupport(ops, transfers, new FeatureNodeDragListener(
+ viewer));
+ viewer.addDropSupport(ops, transfers,
+ new FeatureNodeDropAdapter(viewer));
+
+ viewer.addSelectionChangedListener(this);
+
+ button_add.addSelectionListener(new AddButtonListener());
+ button_remove.addSelectionListener(new RemoveSelectionListener());
+
+ btnOpenFeatureTree.addSelectionListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
+ if(tree!=null){
+ setSelectedTree(tree);
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ }
+
public void setSelectedTree(FeatureTree featureTree) {
this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
- featureTreeViewerComposite.getViewer().setInput(featureTree);
+ viewer.setInput(featureTree);
- featureTreeSelectionComposite.getTextTitle().removeModifyListener(this);
- featureTreeSelectionComposite.getTextTitle().setText(featureTree.getTitleCache());
- featureTreeSelectionComposite.getTextTitle().addModifyListener(this);
+ text_title.removeModifyListener(this);
+ text_title.setText(featureTree.getTitleCache());
+ text_title.addModifyListener(this);
}
/** {@inheritDoc} */
@Override
public void modifyText(ModifyEvent e) {
- featureTree.setTitleCache(featureTreeSelectionComposite.getTextTitle().getText(), true);
+ featureTree.setTitleCache(text_title.getText(), true);
setDirty(true);
}
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
- featureTreeAddRemoveButtonComposite.getButtonAdd().setEnabled(selection.size() <= 1);
- featureTreeAddRemoveButtonComposite.getButtonRemove().setEnabled(selection.size() > 0);
+ button_add.setEnabled(selection.size() <= 1);
+ button_remove.setEnabled(selection.size() > 0);
}
@Persist
WizardDialog dialog = new WizardDialog(shell, wizard);
if (dialog.open() == IStatus.OK) {
- IStructuredSelection selection = (IStructuredSelection) featureTreeViewerComposite.getViewer()
+ IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
FeatureNode parent = (FeatureNode) (selection.getFirstElement() != null ? selection
- .getFirstElement() : ((FeatureTree) featureTreeViewerComposite.getViewer().getInput())
+ .getFirstElement() : ((FeatureTree) viewer.getInput())
.getRoot());
Collection<Feature> additionalFeatures = wizard
.getAdditionalFeatures();
parent.addChild(child);
}
setDirty(true);
- featureTreeViewerComposite.getViewer().refresh();
+ viewer.refresh();
}
}
private class RemoveSelectionListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
- IStructuredSelection selection = (IStructuredSelection) featureTreeViewerComposite.getViewer()
+ IStructuredSelection selection = (IStructuredSelection) viewer
.getSelection();
for (Object selectedObject : selection.toArray()) {
}
setDirty(true);
- featureTreeViewerComposite.getViewer().refresh();
+ viewer.refresh();
+ }
+ }
+
+ private class FeatureNodeDragListener extends DragSourceAdapter {
+
+ private final TreeViewer viewer;
+
+ public FeatureNodeDragListener(TreeViewer viewer) {
+ this.viewer = viewer;
+ }
+
+ /**
+ * Method declared on DragSourceListener
+ */
+ @Override
+ public void dragFinished(DragSourceEvent event) {
+ if (!event.doit) {
+ return;
+ }
+ // if the featureNode was moved, remove it from the source viewer
+ if (event.detail == DND.DROP_MOVE) {
+ IStructuredSelection selection = (IStructuredSelection) viewer
+ .getSelection();
+ viewer.refresh();
+ }
+ }
+
+ /**
+ * Method declared on DragSourceListener
+ */
+ @Override
+ public void dragSetData(DragSourceEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) viewer
+ .getSelection();
+ FeatureNode[] featureNodes = (FeatureNode[]) selection.toList()
+ .toArray(new FeatureNode[selection.size()]);
+ if (FeatureNodeTransfer.getInstance().isSupportedType(
+ event.dataType)) {
+ event.data = featureNodes;
+ }
}
+
+ /**
+ * Method declared on DragSourceListener
+ */
+ @Override
+ public void dragStart(DragSourceEvent event) {
+ event.doit = !viewer.getSelection().isEmpty();
+ }
+
}
+ private class FeatureNodeDropAdapter extends ViewerDropAdapter {
+
+ protected FeatureNodeDropAdapter(Viewer viewer) {
+ super(viewer);
+ }
+
+ @Override
+ public boolean performDrop(Object data) {
+ FeatureNode target = (FeatureNode) getCurrentTarget();
+ int position = 0;
+
+ if (target != null) {
+ int location = getCurrentLocation();
+ FeatureNode parent = target.getParent();
+ if (location == LOCATION_BEFORE) {
+ position = Math.max(0, parent.getIndex(target) - 1);
+ target = parent;
+ }
+
+ if (location == LOCATION_AFTER) {
+ position = parent.getIndex(target);
+ target = parent;
+ }
+ }
+
+ // set target to root node if there is no target specified
+ if (target == null) {
+ FeatureTree featureTree = (FeatureTree) getViewer().getInput();
+ target = featureTree.getRoot();
+ }
+
+ Object[] droppedObjects = (Object[]) data;
+ TreeViewer viewer = (TreeViewer) getViewer();
+
+ // cannot drop a feature node onto itself
+ for (Object droppedObject : droppedObjects) {
+ if (droppedObject == null) {
+ MessagingUtils.warningDialog(
+ "Operation not supported yet",
+ this,
+ "We are currently unable to change the order of freshly created "
+ + "feature trees nodes. Please close and reopen the dialog to change the order of features.");
+ return false;
+ }
+ if (droppedObject.equals(target)) {
+ return false;
+ }
+ }
+ for (Object droppedObject : droppedObjects) {
+ FeatureNode droppedNode = (FeatureNode) droppedObject;
+ target.addChild(droppedNode, position);
+ viewer.add(target, droppedNode);
+ viewer.reveal(droppedNode);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean validateDrop(Object target, int operation,
+ TransferData transferData) {
+ return FeatureNodeTransfer.getInstance().isSupportedType(
+ transferData);
+ }
+
+ }
}