Merge branch 'develop' into featureTreeEditor
authorPatrick Plitzner <p.plitzner@bgbm.org>
Wed, 28 Jun 2017 10:12:56 +0000 (12:12 +0200)
committerPatrick Plitzner <p.plitzner@bgbm.org>
Wed, 28 Jun 2017 10:12:56 +0000 (12:12 +0200)
eu.etaxonomy.taxeditor.editor/META-INF/MANIFEST.MF
eu.etaxonomy.taxeditor.editor/fragment.e4xmi
eu.etaxonomy.taxeditor.editor/icons/Ontology.xml [new file with mode: 0644]
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDragListener.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDropAdapter.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterEditor.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDragListener.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDropAdapter.java [new file with mode: 0644]
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureTreeLabelProvider.java
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java

index 3a08ee2b1230e0983ea30826fcbe1fe30b3aeb88..f217ee884145f7b02a22ca8f8f8ee6b06dbe03f1 100644 (file)
@@ -36,7 +36,8 @@ Require-Bundle: org.eclipse.ui,
  org.eclipse.e4.ui.di
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-ActivationPolicy: lazy
-Import-Package: javax.inject;version="1.0.0",
+Import-Package: javax.annotation;version="1.0.0";resolution:=optional,
+ javax.inject;version="1.0.0",
  org.eclipse.core.databinding.beans,
  org.eclipse.core.databinding.observable.list,
  org.eclipse.core.databinding.observable.map,
index 85719aa92f22e108a8e302e204f3efcda724eb58..22f76757afd8f940a0e0597fdbcb8e1d54e6463e 100644 (file)
@@ -54,6 +54,7 @@
         <children xsi:type="menu:HandledMenuItem" xmi:id="_wg0-oDulEeeOtqC_3qh40A" elementId="eu.etaxonomy.taxeditor.editor.handledmenuitem.commandlabel54" label="%command.label.54" iconURI="platform:/plugin/eu.etaxonomy.taxeditor.editor/icons/deep-delete-16x16-32.png" command="_fKT-wDulEeeOtqC_3qh40A"/>
       </menus>
     </elements>
+    <elements xsi:type="basic:PartDescriptor" xmi:id="_R7vxEECaEeeL5JDzMOYK6g" elementId="eu.etaxonomy.taxeditor.editor.workingSet.CharacterEditor" label="Character Editor" closeable="true" dirtyable="true" contributionURI="bundleclass://eu.etaxonomy.taxeditor.editor/eu.etaxonomy.taxeditor.editor.workingSet.CharacterEditor"/>
   </fragments>
   <fragments xsi:type="fragment:StringModelFragment" xmi:id="__mwtMDVpEee_b7RlBzTDRw" featurename="commands" parentElementId="xpath:/">
     <elements xsi:type="commands:Command" xmi:id="_BjF3ADVqEee_b7RlBzTDRw" elementId="eu.etaxonomy.taxeditor.editor.command.specimeneditor.create_field_unit" commandName="%command.commandname.1"/>
@@ -71,4 +72,9 @@
     <elements xsi:type="commands:Command" xmi:id="_N0wLsDumEeeOtqC_3qh40A" elementId="eu.etaxonomy.taxeditor.editor.derivative.copySingleReadToClipBoard" commandName="%command.name.COPY_SINGLE_READ_TO_CLIPBOARD"/>
     <elements xsi:type="commands:Command" xmi:id="_YPp1wDvREeeOtqC_3qh40A" elementId="eu.etaxonomy.taxeditor.editor.derivate.delete" commandName="Delete"/>
   </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_pZmusEalEeeXMc6kSYO7Xg" featurename="children" parentElementId="eu.etaxonomy.taxeditor.menu.showView">
+    <elements xsi:type="menu:HandledMenuItem" xmi:id="_tvph4EalEeeXMc6kSYO7Xg" elementId="eu.etaxonomy.taxeditor.editor.handledmenuitem.featuretreeeditor" label="Character Editor" command="_WPjpoDSnEeek0dKsFNy--Q">
+      <parameters xmi:id="_wJkmoEalEeeXMc6kSYO7Xg" elementId="eu.etaxonomy.taxeditor.editor.parameter.0" name="eu.etaxonomy.taxeditor.workbench.commandparameter.partName" value="eu.etaxonomy.taxeditor.editor.workingSet.CharacterEditor"/>
+    </elements>
+  </fragments>
 </fragment:ModelFragments>
diff --git a/eu.etaxonomy.taxeditor.editor/icons/Ontology.xml b/eu.etaxonomy.taxeditor.editor/icons/Ontology.xml
new file mode 100644 (file)
index 0000000..5266690
Binary files /dev/null and b/eu.etaxonomy.taxeditor.editor/icons/Ontology.xml differ
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDragListener.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDragListener.java
new file mode 100644 (file)
index 0000000..7b127f6
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.editor.workingSet;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.dnd.DragSourceEvent;
+
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDragListener;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
+
+/**
+ * @author pplitzner
+ * @since Jun 2, 2017
+ *
+ */
+public class CharacterDragListener extends FeatureNodeDragListener {
+
+    private TreeViewer structureViewer;
+    private TreeViewer propertyViewer;
+
+    /**
+     * @param propertyViewer
+     */
+    public CharacterDragListener(TreeViewer structureViewer, TreeViewer propertyViewer) {
+        super(propertyViewer);
+        this.structureViewer = structureViewer;
+        this.propertyViewer = propertyViewer;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void dragSetData(DragSourceEvent event) {
+        FeatureNode structure = (FeatureNode) ((IStructuredSelection) structureViewer.getSelection()).getFirstElement();
+        FeatureNode property = (FeatureNode) ((IStructuredSelection) propertyViewer.getSelection()).getFirstElement();
+        FeatureNode[] character = new FeatureNode[2];
+        character[0] = structure;
+        character[1] = property;
+        if (FeatureNodeTransfer.getInstance().isSupportedType(event.dataType)) {
+            event.data = character;
+        }
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDropAdapter.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterDropAdapter.java
new file mode 100644 (file)
index 0000000..14f2562
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+* Copyright (C) 2009 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.editor.workingSet;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.swt.dnd.TransferData;
+
+import eu.etaxonomy.cdm.model.description.Character;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
+
+/**
+ *
+ * @author pplitzner
+ * @date Jun 1, 2017
+ *
+ */
+public class CharacterDropAdapter extends ViewerDropAdapter {
+
+       protected CharacterDropAdapter(Viewer viewer) {
+           super(viewer);
+       }
+
+       @Override
+       public boolean performDrop(Object data) {
+
+           FeatureNode target = (FeatureNode) getCurrentTarget();
+               int currentLocation = getCurrentLocation();
+               Object[] characterData = (Object[]) data;
+
+               //create new Character
+               if(characterData.length==2){
+                   FeatureNode structureNode = (FeatureNode) characterData[0];
+                   FeatureNode propertyNode = (FeatureNode) characterData[1];
+                   String label = structureNode.getFeature().toString()+" "+propertyNode.getFeature().toString();
+                   Character character = Character.NewInstance(structureNode, propertyNode, null, label, label);
+                   FeatureNode characterNode = FeatureNode.NewInstance(character);
+
+                   if(getViewer().getInput()==null){
+                       //create new feature tree
+                       FeatureTree featureTree = FeatureTree.NewInstance();
+                       getViewer().setInput(featureTree);
+                   }
+            if(target==null){
+                FeatureNode root = ((FeatureTree)getViewer().getInput()).getRoot();
+                root.addChild(characterNode);
+            }
+            else{
+                target.addChild(characterNode);
+            }
+               }
+               getViewer().refresh();
+               return true;
+       }
+
+       @Override
+       public boolean validateDrop(Object target, int operation,
+                       TransferData transferType) {
+               boolean transferDataIsSupported = FeatureNodeTransfer.getInstance().isSupportedType(transferType);
+               return transferDataIsSupported;
+       }
+
+}
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterEditor.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/CharacterEditor.java
new file mode 100644 (file)
index 0000000..9479cb2
--- /dev/null
@@ -0,0 +1,338 @@
+// $Id$
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.editor.workingSet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.ui.di.Focus;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.model.application.ui.MDirtyable;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
+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.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.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
+import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.description.Character;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDragListener;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeDropAdapter;
+import eu.etaxonomy.taxeditor.featuretree.FeatureNodeTransfer;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeContentProvider;
+import eu.etaxonomy.taxeditor.featuretree.FeatureTreeLabelProvider;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditorComposite;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.ui.dialog.selection.FeatureTreeSelectionDialog;
+
+/**
+ * @author pplitzner
+ * @date 24.05.2017
+ *
+ */
+public class CharacterEditor implements ICdmEntitySessionEnabled, ISelectionChangedListener, ModifyListener{
+
+
+    private FeatureTreeEditorComposite featureTreeEditorComposite;
+    private TreeViewer treeViewerProperties;
+    private TreeViewer treeViewerStructures;
+    private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
+    private Button btnAddCharacter;
+
+    @Inject
+    private ESelectionService selService;
+
+    @Inject
+    private MDirtyable dirty;
+
+    private ConversationHolder conversation;
+
+    private ICdmEntitySession cdmEntitySession;
+
+    private FeatureTree featureTree;
+
+    public CharacterEditor() {
+        if(conversation==null){
+            conversation = CdmStore.createConversation();
+        }
+        if (CdmStore.isActive()) {
+            cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+        }
+    }
+
+    /**
+     * Create contents of the view part.
+     */
+    @PostConstruct
+    public void createControls(Composite parent, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
+        parent.setLayout(new GridLayout(1, false));
+
+        SashForm sashForm = new SashForm(parent, SWT.NONE);
+        sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        formToolkit.adapt(sashForm);
+        formToolkit.paintBordersFor(sashForm);
+
+        Composite composite = new Composite(sashForm, SWT.NONE);
+        formToolkit.adapt(composite);
+        formToolkit.paintBordersFor(composite);
+        composite.setLayout(new GridLayout(1, false));
+
+        Label lblNewLabel = new Label(composite, SWT.NONE);
+        lblNewLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
+        formToolkit.adapt(lblNewLabel, true, true);
+        lblNewLabel.setText("Structures");
+
+        treeViewerStructures = new TreeViewer(composite, SWT.BORDER);
+        Tree tree = treeViewerStructures.getTree();
+        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+        Composite composite_1 = new Composite(sashForm, SWT.NONE);
+        formToolkit.adapt(composite_1);
+        formToolkit.paintBordersFor(composite_1);
+        composite_1.setLayout(new GridLayout(1, false));
+
+        Label lblNewLabel_1 = new Label(composite_1, SWT.NONE);
+        lblNewLabel_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));
+        formToolkit.adapt(lblNewLabel_1, true, true);
+        lblNewLabel_1.setText("Properties");
+
+        treeViewerProperties = new TreeViewer(composite_1, SWT.BORDER);
+        Tree tree_1 = treeViewerProperties.getTree();
+        tree_1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+        Composite composite_2 = new Composite(sashForm, SWT.NONE);
+        formToolkit.adapt(composite_2);
+        formToolkit.paintBordersFor(composite_2);
+        composite_2.setLayout(new GridLayout(1, false));
+
+        btnAddCharacter = new Button(composite_2, SWT.NONE);
+        btnAddCharacter.setText(">>");
+        btnAddCharacter.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, true, 1, 1));
+        formToolkit.adapt(btnAddCharacter, true, true);
+
+        Composite composite_3 = new Composite(sashForm, SWT.NONE);
+        formToolkit.adapt(composite_3);
+        formToolkit.paintBordersFor(composite_3);
+        composite_3.setLayout(new GridLayout(1, false));
+
+        featureTreeEditorComposite = new FeatureTreeEditorComposite(composite_3, SWT.BORDER);
+        featureTreeEditorComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+        featureTreeEditorComposite.getButton_add().setVisible(false);
+        featureTreeEditorComposite.getButton_remove().setVisible(false);
+        featureTreeEditorComposite.init(new FeatureNodeDragListener(featureTreeEditorComposite.getViewer()), new FeatureNodeDropAdapter(featureTreeEditorComposite.getViewer()), this, new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FeatureTree tree = FeatureTreeSelectionDialog.select(shell, conversation, null);
+                if(tree!=null){
+                    setSelectedTree(tree);
+                }
+            }
+        }, new SelectionAdapter() {
+        }, new SelectionAdapter() {
+        });
+        sashForm.setWeights(new int[] {3, 3, 1, 3});
+
+        init();
+    }
+
+    @Focus
+    public void focus(){
+        featureTreeEditorComposite.getViewer().getControl().setFocus();
+        if(conversation!=null && !conversation.isBound()){
+            conversation.bind();
+        }
+        if(cdmEntitySession != null) {
+            cdmEntitySession.bind();
+        }
+    }
+
+    public void setSelectedTree(FeatureTree featureTree) {
+        this.featureTree = HibernateProxyHelper.deproxy(featureTree, FeatureTree.class);
+        this.featureTree.setRoot(HibernateProxyHelper.deproxy(featureTree.getRoot(), FeatureNode.class));
+        featureTreeEditorComposite.getViewer().setInput(featureTree);
+
+        featureTreeEditorComposite.getText_title().removeModifyListener(this);
+        featureTreeEditorComposite.getText_title().setText(featureTree.getTitleCache());
+        featureTreeEditorComposite.getText_title().addModifyListener(this);
+    }
+
+    private void init(){
+        int dndOperations = DND.DROP_COPY | DND.DROP_MOVE;
+        Transfer[] transfers = new Transfer[] { FeatureNodeTransfer.getInstance() };
+
+        FeatureTree structureFeatureTree = CdmStore.getService(IFeatureTreeService.class).load(UUID.fromString("3a953dd1-2b5f-482f-9a33-664ee7ef6c68"));
+        treeViewerStructures.setContentProvider(new FeatureTreeContentProvider());
+        treeViewerStructures.setLabelProvider(new FeatureTreeLabelProvider());
+        treeViewerStructures.setInput(structureFeatureTree);
+
+        FeatureTree propertiesFeatureTree = CdmStore.getService(IFeatureTreeService.class).load(UUID.fromString("e283bbf5-bda3-449d-98de-3601ac8a8bbd"));
+        treeViewerProperties.setContentProvider(new FeatureTreeContentProvider());
+        treeViewerProperties.setLabelProvider(new FeatureTreeLabelProvider());
+        treeViewerProperties.addDragSupport(dndOperations, transfers, new CharacterDragListener(treeViewerStructures, treeViewerProperties));
+        treeViewerProperties.setInput(propertiesFeatureTree);
+
+        btnAddCharacter.addSelectionListener(new SelectionAdapter() {
+            /**
+             * {@inheritDoc}
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                ISelection structureTreeSelection = treeViewerStructures.getSelection();
+                ISelection propertyTreeSelection = treeViewerProperties.getSelection();
+                if(structureTreeSelection==null || propertyTreeSelection==null || featureTree==null){
+                    MessagingUtils.warningDialog("Cannot perform action", CharacterEditor.this,
+                            "You have to select a structure, a property and a feature tree to perform this action.");
+                    return;
+                }
+                //get selected structure and property
+                FeatureNode structureNode = (FeatureNode) ((TreeSelection)structureTreeSelection).getFirstElement();
+                FeatureNode propertyNode = (FeatureNode) ((TreeSelection)propertyTreeSelection).getFirstElement();
+                //create new Character
+                String label = structureNode.getFeature().toString()+" "+propertyNode.getFeature().toString();
+                Character character = Character.NewInstance(structureNode, propertyNode, null, label, label);
+//                CdmStore.getService(ITermService.class).saveOrUpdate(character);
+
+                //add new Character to feature tree
+                FeatureNode parent = ((FeatureTree) featureTreeEditorComposite.getViewer().getInput()).getRoot();
+                CdmStore.getService(IFeatureNodeService.class).addChildFeaturNode(parent.getUuid(), character.getUuid());
+
+                setDirty(true);
+                featureTreeEditorComposite.getViewer().refresh();
+            }
+        });
+    }
+
+    @Persist
+    public void save(){
+        if (!conversation.isBound()) {
+            conversation.bind();
+        }
+
+        // commit the conversation and start a new transaction immediately
+        conversation.commit(true);
+
+        CdmStore.getService(IFeatureTreeService.class).saveOrUpdate(featureTree);
+
+        this.setDirty(false);
+    }
+
+    @PreDestroy
+    public void dispose(){
+        if(conversation!=null){
+            conversation.close();
+        }
+        if(cdmEntitySession != null) {
+            cdmEntitySession.dispose();
+        }
+    }
+
+    @Override
+    public Map<Object, List<String>> getPropertyPathsMap() {
+        List<String> propertyPaths = Arrays.asList(new String[] {
+                "children", //$NON-NLS-1$
+                "feature", //$NON-NLS-1$
+                "featureTree", //$NON-NLS-1$
+        });
+        Map<Object, List<String>> propertyPathMap =
+                new HashMap<Object, List<String>>();
+        propertyPathMap.put(FeatureNode.class,propertyPaths);
+        return propertyPathMap;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<FeatureTree> getRootEntities() {
+        List<FeatureTree> root = new ArrayList<>();
+        root.add(featureTree);
+        return root;
+    }
+
+    @Override
+    public ICdmEntitySession getCdmEntitySession() {
+        return cdmEntitySession;
+    }
+
+    @Focus
+    public void setFocus() {
+        if(conversation!=null && !conversation.isBound()){
+            conversation.bind();
+        }
+    }
+
+    public TreeViewer getTreeViewerProperties() {
+        return treeViewerProperties;
+    }
+    public TreeViewer getTreeViewerStructures() {
+        return treeViewerStructures;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void selectionChanged(SelectionChangedEvent event) {
+        //propagate selection
+        IStructuredSelection isel = (IStructuredSelection) event.getSelection();
+        selService.setSelection((isel.size() == 1 ? isel.getFirstElement() : isel.toArray()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void modifyText(ModifyEvent e) {
+        featureTree.setTitleCache(featureTreeEditorComposite.getText_title().getText(), true);
+        setDirty(true);
+    }
+
+    public void setDirty(boolean isDirty) {
+        dirty.setDirty(isDirty);
+    }
+
+}
index ce3d5489275b41616fbbacc8796c5e5e3be9c53b..de4a8932b1f0d3ad37c13a824ff0dbd067dc2c13 100644 (file)
@@ -15,6 +15,7 @@ Export-Package: eu.etaxonomy.cdm,
  eu.etaxonomy.taxeditor.editor.definedterm,
  eu.etaxonomy.taxeditor.editor.definedterm.input,
  eu.etaxonomy.taxeditor.featuretree,
+ eu.etaxonomy.taxeditor.featuretree.e4,
  eu.etaxonomy.taxeditor.handler,
  eu.etaxonomy.taxeditor.handler.defaultHandler,
  eu.etaxonomy.taxeditor.io,
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDragListener.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDragListener.java
new file mode 100644 (file)
index 0000000..048d298
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.featuretree;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceAdapter;
+import org.eclipse.swt.dnd.DragSourceEvent;
+
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+
+/**
+ * @author pplitzner
+ * @since Jun 2, 2017
+ *
+ */
+public 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 (event.detail == DND.DROP_MOVE) {
+            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();
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDropAdapter.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/FeatureNodeDropAdapter.java
new file mode 100644 (file)
index 0000000..a3f7c71
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+* Copyright (C) 2017 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+package eu.etaxonomy.taxeditor.featuretree;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.swt.dnd.TransferData;
+
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+
+/**
+ * @author pplitzner
+ * @since Jun 2, 2017
+ *
+ */
+public class FeatureNodeDropAdapter extends ViewerDropAdapter {
+
+    public 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);
+    }
+
+}
\ No newline at end of file
index 1f2f7131c8bf05ee00f1796adb82575e9fff1f80..f436a4e83c1879d9545dd6ef40e5c2f4307c8ecc 100644 (file)
@@ -1,8 +1,8 @@
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* European Distributed Institute of Taxonomy
 * http://www.e-taxonomy.eu
-* 
+*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * See LICENSE.TXT at the top of this package for the full license terms.
 */
@@ -16,37 +16,27 @@ import eu.etaxonomy.cdm.model.description.FeatureNode;
 import eu.etaxonomy.cdm.model.description.FeatureTree;
 
 /**
- * <p>FeatureTreeLabelProvider class.</p>
  *
  * @author n.hoffmann
  * @created Aug 5, 2010
  * @version 1.0
  */
 public class FeatureTreeLabelProvider extends LabelProvider {
-       
-       private Feature feature;
-               
+
        /** {@inheritDoc} */
        @Override
        public String getText(Object element) {
                if(element instanceof FeatureTree){
                        return ((FeatureTree) element).getTitleCache();
                }else if(element instanceof FeatureNode){
-                       feature = ((FeatureNode) element).getFeature();
-                       
-                       if(feature != null)
-                               return feature.getTitleCache();
-                       
+                   Feature feature = ((FeatureNode) element).getFeature();
+                       if(feature != null) {
+                           //FIXME why is there no titleCache already in the DB?
+                return feature.generateTitle();
+            }
+
                }
                return "No label provided";
        }
-       
-       /**
-        * <p>Getter for the field <code>feature</code>.</p>
-        *
-        * @return a {@link eu.etaxonomy.cdm.model.description.Feature} object.
-        */
-       public Feature getFeature(){
-               return feature;
-       }
+
 }
index c03ddae1716d578f840212b1e08d5018ec5aeadb..d090ec6c7a4574c0144fe026e76b3655aaaec005 100644 (file)
@@ -125,6 +125,10 @@ public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
                composite.getText_title().addModifyListener(this);
        }
 
+    public FeatureTree getSelectedFeatureTree(){
+        return this.featureTree;
+    }
+
        /** {@inheritDoc} */
        @Override
        public void modifyText(ModifyEvent e) {