commit ff46c6caf32fb1cc7e5c40bb18c73153806a60a3
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Wed Jul 12 20:36:31 2017 +0200

    ref #6806 Add context menu to feature tree editor
    
     - menu item for add, remove feature and export feature tree
    (experimental)

diff --git a/eu.etaxonomy.taxeditor.store/fragment.e4xmi b/eu.etaxonomy.taxeditor.store/fragment.e4xmi
index 7bc9c4a82..6a8750770 100644
--- a/eu.etaxonomy.taxeditor.store/fragment.e4xmi
+++ b/eu.etaxonomy.taxeditor.store/fragment.e4xmi
@@ -9,6 +9,16 @@
     <elements xsi:type="basic:PartDescriptor" xmi:id="_J-3UEEqgEeeN-dEYnw7m3g" elementId="eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor" label="%partdescriptor.label.featureTreeEditor" allowMultiple="true" closeable="true" dirtyable="true" contributionURI="bundleclass://eu.etaxonomy.taxeditor.store/eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor">
       <tags>nonRestore</tags>
       <handlers xmi:id="_H_c_EEq2EeeN-dEYnw7m3g" elementId="eu.etaxonomy.taxeditor.featuretree.handler.SaveHandler" contributionURI="bundleclass://eu.etaxonomy.taxeditor.workbench/eu.etaxonomy.taxeditor.workbench.SaveHandler" command="_LlbAMEq2EeeN-dEYnw7m3g"/>
+      <handlers xmi:id="_3wq0cGceEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.featuretree.e4.handler.AddFeatureHandler" contributionURI="bundleclass://eu.etaxonomy.taxeditor.store/eu.etaxonomy.taxeditor.featuretree.e4.handler.AddFeatureHandler" command="_oftL0GceEee0qLTtA2ZpVQ"/>
+      <handlers xmi:id="_rVEdIGcjEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.featuretree.e4.handler.RemoveFeatureHandler" contributionURI="bundleclass://eu.etaxonomy.taxeditor.store/eu.etaxonomy.taxeditor.featuretree.e4.handler.RemoveFeatureHandler" command="_fNBtQGcjEee0qLTtA2ZpVQ"/>
+      <handlers xmi:id="_VSc2UGcqEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.featuretree.e4.handler.FeatureTreeExportHandler" contributionURI="bundleclass://eu.etaxonomy.taxeditor.store/eu.etaxonomy.taxeditor.featuretree.e4.handler.FeatureTreeExportHandler" command="_I_yx4GcqEee0qLTtA2ZpVQ"/>
+      <menus xsi:type="menu:PopupMenu" xmi:id="__Jwh4GceEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.popupmenu.featureTreeEditor">
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_Beb6QGcfEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.handledmenuitem.removeFeature" label="Remove Feature" command="_fNBtQGcjEee0qLTtA2ZpVQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_eWBz0GcjEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.handledmenuitem.addFeature" label="Add Feature" command="_oftL0GceEee0qLTtA2ZpVQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_7vaEcGcqEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.handledmenuitem.exportFeatureTree" label="Export Feature Tree" command="_I_yx4GcqEee0qLTtA2ZpVQ">
+          <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_-91IQGcqEee0qLTtA2ZpVQ" coreExpressionId="isShowExperimentalFeatures"/>
+        </children>
+      </menus>
     </elements>
   </fragments>
   <fragments xsi:type="fragment:StringModelFragment" xmi:id="_3rW8wCXaEeex9MwMOgUeWw" featurename="children" parentElementId="eu.etaxonomy.taxeditor.menu.showView" positionInList="after:bulkeditor.menus.openmenu">
@@ -32,4 +42,9 @@
       <parameters xmi:id="_BylIUCZzEeeQLpuomSmVoQ" elementId="eu.etaxonomy.taxeditor.store.showView.parameter.sessionView" name="eu.etaxonomy.taxeditor.workbench.commandparameter.partName" value="eu.etaxonomy.taxeditor.view.sessions.SessionsViewPart"/>
     </elements>
   </fragments>
+  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_mPdAcGceEee0qLTtA2ZpVQ" featurename="commands" parentElementId="org.eclipse.e4.legacy.ide.application">
+    <elements xsi:type="commands:Command" xmi:id="_oftL0GceEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.command.featureTree.addFeature" commandName="Add Feature" description="Add a feature to the feature tree"/>
+    <elements xsi:type="commands:Command" xmi:id="_fNBtQGcjEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.command.featureTree.removeFeature" commandName="Remove Feature" description="Removes a feature from the feature tree"/>
+    <elements xsi:type="commands:Command" xmi:id="_I_yx4GcqEee0qLTtA2ZpVQ" elementId="eu.etaxonomy.taxeditor.store.command.featureTree.exportTree" commandName="Export Feature Tree"/>
+  </fragments>
 </fragment:ModelFragments>
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java
index 9b52a339c..7627d6a2b 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureTreeEditor.java
@@ -24,10 +24,12 @@ import org.eclipse.core.runtime.IStatus;
 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.EMenuService;
 import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
 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.wizard.WizardDialog;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
@@ -78,7 +80,7 @@ public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
 
 	/** {@inheritDoc} */
     @PostConstruct
-    public void createControl(Composite parent){
+    public void createControl(Composite parent, EMenuService menuService){
         if (CdmStore.isActive()){
             if(conversation == null){
                 conversation = CdmStore.createConversation();
@@ -110,6 +112,9 @@ public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
                         }
                     }
                 }, new AddButtonListener(), new RemoveSelectionListener(), new FeatureTreeExportListener(composite.getDisplay().getActiveShell(), composite));
+
+        //create context menu
+        menuService.registerContextMenu(composite.getViewer().getControl(), "eu.etaxonomy.taxeditor.store.popupmenu.featureTreeEditor");
     }
 
 	public void setDirty(boolean isDirty){
@@ -156,6 +161,14 @@ public class FeatureTreeEditor implements ICdmEntitySessionEnabled,
         }
 	}
 
+	public void refresh(){
+	    composite.getViewer().refresh();
+	}
+
+	public TreeViewer getViewer(){
+	    return composite.getViewer();
+	}
+
 	@Persist
 	public void save(){
         if (!conversation.isBound()) {
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddFeatureHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddFeatureHandler.java
new file mode 100644
index 000000000..db6b2d4a2
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddFeatureHandler.java
@@ -0,0 +1,63 @@
+/**
+* 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.e4.handler;
+
+import java.util.Collection;
+
+import javax.inject.Named;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+
+import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
+import eu.etaxonomy.cdm.model.description.Feature;
+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.e4.FeatureTreeEditor;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * @author pplitzner
+ * @since Jul 12, 2017
+ *
+ */
+public class AddFeatureHandler {
+
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell,
+            @Named(IServiceConstants.ACTIVE_PART)MPart thisPart) {
+        FeatureTreeEditor editor = ((FeatureTreeEditor) thisPart.getObject());
+        AvailableFeaturesWizard wizard = new AvailableFeaturesWizard();
+        WizardDialog dialog = new WizardDialog(shell, wizard);
+
+        if (dialog.open() == IStatus.OK) {
+            FeatureNode parent = ((FeatureTree) editor.getViewer().getInput()).getRoot();
+            Collection<Feature> additionalFeatures = wizard.getAdditionalFeatures();
+            for (Feature feature : additionalFeatures) {
+                if (!editor.getSelectedFeatureTree().getDistinctFeatures().contains(feature)) {
+                    CdmStore.getService(IFeatureNodeService.class).addChildFeatureNode(parent.getUuid(), feature.getUuid());
+                }
+            }
+            thisPart.setDirty(true);
+            editor.getViewer().refresh();
+            editor.getViewer().expandToLevel(parent, 1);
+        }
+    }
+
+    @CanExecute
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart) {
+        return thisPart.getObject() instanceof FeatureTreeEditor && ((FeatureTreeEditor) thisPart.getObject()).getSelectedFeatureTree()!=null;
+    }
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/FeatureTreeExportHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/FeatureTreeExportHandler.java
new file mode 100644
index 000000000..f546e8216
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/FeatureTreeExportHandler.java
@@ -0,0 +1,64 @@
+/**
+* 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.e4.handler;
+
+import java.io.File;
+
+import javax.inject.Named;
+
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.progress.IProgressConstants;
+
+import eu.etaxonomy.cdm.io.descriptive.owl.out.OwlExportConfigurator;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * @author pplitzner
+ * @since Jul 12, 2017
+ *
+ */
+public class FeatureTreeExportHandler {
+
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell,
+            @Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        FeatureTreeEditor editor = ((FeatureTreeEditor) thisPart.getObject());
+        FeatureTree selectedFeatureTree = editor.getSelectedFeatureTree();
+        if(selectedFeatureTree==null){
+            MessagingUtils.informationDialog("Export not possible", "There is no feature tree selected.");
+            return;
+        }
+        DirectoryDialog dialog = new DirectoryDialog(shell);
+        String directoryString = dialog.open();
+        if(directoryString!=null){
+            // create job
+            Job job = CdmStore.getExportManager().createIOServiceJob(OwlExportConfigurator.NewInstance(null, null, selectedFeatureTree), new File(directoryString+"/owl.owl"));
+            // configure the job
+            job.setProperty(IProgressConstants.KEEP_PROPERTY, true);
+            job.setUser(true);
+            // schedule job
+            job.schedule();
+        }
+    }
+
+    @CanExecute
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        return thisPart.getObject() instanceof FeatureTreeEditor && ((FeatureTreeEditor) thisPart.getObject()).getSelectedFeatureTree()!=null;
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureHandler.java
new file mode 100644
index 000000000..987028fab
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureHandler.java
@@ -0,0 +1,50 @@
+/**
+* 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.e4.handler;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
+import eu.etaxonomy.cdm.api.service.config.FeatureNodeDeletionConfigurator;
+import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
+/**
+ * @author pplitzner
+ * @since Jul 12, 2017
+ *
+ */
+public class RemoveFeatureHandler {
+
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
+        IStructuredSelection selection = (IStructuredSelection) editor.getViewer().getSelection();
+        for (Object selectedObject : selection.toArray()) {
+            FeatureNode featureNode = (FeatureNode) selectedObject;
+            CdmStore.getService(IFeatureNodeService.class).deleteFeatureNode(featureNode.getUuid(), new FeatureNodeDeletionConfigurator());
+        }
+        thisPart.setDirty(true);
+        editor.refresh();
+    }
+
+    @CanExecute
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection,
+            @Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        return thisPart.getObject() instanceof FeatureTreeEditor && selection!=null && !selection.isEmpty();
+    }
+
+}
