commit cf3499355498af8ab4a78ceaa2e875cebb0d406a
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Thu Nov 15 10:26:07 2018 +0100

    Ask for saving before executing operations

diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDropAdapter.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDropAdapter.java
index 67f00c973..078e9cd5e 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDropAdapter.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/FeatureNodeDropAdapter.java
@@ -13,6 +13,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
 import org.eclipse.jface.util.LocalSelectionTransfer;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -35,9 +36,13 @@ import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.TermVocabularySelectionDialog;
 import eu.etaxonomy.taxeditor.view.webimport.termimport.wrapper.OntologyTermWrapper;
+import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 public class FeatureNodeDropAdapter extends ViewerDropAdapter {
 
+    public static final String SAVE_CHANGES_TITLE = "Unsaved changes";
+    public static final String SAVE_CHANGES_MESSAGE = "The editor has unsaved changes. You need to save before performind this operation. Save now?";
+
     private MDirtyable dirtyable;
     private IE4SavablePart savablePart;
 
@@ -49,6 +54,14 @@ public class FeatureNodeDropAdapter extends ViewerDropAdapter {
 
 	@Override
 	public boolean performDrop(Object data) {
+        if(dirtyable.isDirty()){
+            if(MessagingUtils.confirmDialog(SAVE_CHANGES_TITLE, SAVE_CHANGES_MESSAGE)){
+                savablePart.save(new NullProgressMonitor());
+            }
+            else{
+                return false;
+            }
+        }
 		Object currentTarget = getCurrentTarget();
 		FeatureNode target = null;
 		if(currentTarget instanceof FeatureTree){
@@ -140,7 +153,6 @@ public class FeatureNodeDropAdapter extends ViewerDropAdapter {
 		        }
 		    }
 		}
-		dirtyable.setDirty(true);
 		viewer.refresh();
 		return true;
 	}
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddChildFeatureHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddChildFeatureHandler.java
index c6c8f20fb..5f1a5b29f 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddChildFeatureHandler.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/AddChildFeatureHandler.java
@@ -13,6 +13,7 @@ import java.util.Collection;
 import javax.inject.Named;
 
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
@@ -26,8 +27,10 @@ import org.eclipse.swt.widgets.Shell;
 import eu.etaxonomy.cdm.model.description.Feature;
 import eu.etaxonomy.cdm.model.description.FeatureNode;
 import eu.etaxonomy.taxeditor.featuretree.AvailableFeaturesWizard;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
 import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddFeatureOperation;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
  * @author pplitzner
@@ -41,6 +44,16 @@ public class AddChildFeatureHandler {
             @Named(IServiceConstants.ACTIVE_PART)MPart thisPart,
             @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection) {
         FeatureTreeEditor editor = ((FeatureTreeEditor) thisPart.getObject());
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
         AvailableFeaturesWizard wizard = new AvailableFeaturesWizard();
         WizardDialog dialog = new WizardDialog(shell, wizard);
 
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
index f7dfc432f..d4c2d69d4 100644
--- 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
@@ -13,6 +13,7 @@ import java.util.Collection;
 import javax.inject.Named;
 
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
@@ -27,8 +28,10 @@ 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.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
 import eu.etaxonomy.taxeditor.featuretree.e4.operation.AddFeatureOperation;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
  * @author pplitzner
@@ -42,6 +45,18 @@ public class AddFeatureHandler {
             @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection,
             @Named(IServiceConstants.ACTIVE_PART)MPart thisPart) {
         FeatureTreeEditor editor = ((FeatureTreeEditor) thisPart.getObject());
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
+
         AvailableFeaturesWizard wizard = new AvailableFeaturesWizard();
         WizardDialog dialog = new WizardDialog(shell, wizard);
 
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/CreateFeatureTreeHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/CreateFeatureTreeHandler.java
index 34c07a0f8..1625e27ed 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/CreateFeatureTreeHandler.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/CreateFeatureTreeHandler.java
@@ -12,6 +12,7 @@ import java.util.List;
 
 import javax.inject.Named;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 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;
@@ -19,8 +20,10 @@ import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
 import org.eclipse.e4.ui.services.IServiceConstants;
 
 import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
 import eu.etaxonomy.taxeditor.featuretree.e4.operation.CreateFeatureTreeOperation;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
  * @author pplitzner
@@ -31,9 +34,21 @@ public class CreateFeatureTreeHandler {
 
     @Execute
     public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
+
         FeatureTree tree = FeatureTree.NewInstance();
         tree.setTitleCache("New feature tree", true);
-        FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
         CreateFeatureTreeOperation operation = new CreateFeatureTreeOperation(tree, editor, editor);
         editor.addOperation(operation);
         List<FeatureTree> trees = (List<FeatureTree>) editor.getViewer().getInput();
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
index 88f11a6a5..13f0cab6d 100644
--- 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
@@ -12,10 +12,12 @@ import java.io.File;
 
 import javax.inject.Named;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 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.core.di.annotations.Optional;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
 import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -25,6 +27,9 @@ 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.FeatureNodeDropAdapter;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 /**
@@ -36,7 +41,20 @@ public class FeatureTreeExportHandler {
 
     @Execute
     public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell,
-            @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection){
+            @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection,
+            @Named(IServiceConstants.ACTIVE_PART)MPart thisPart){
+        FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
         FeatureTree selectedFeatureTree = (FeatureTree) selection.getFirstElement();
         DirectoryDialog dialog = new DirectoryDialog(shell);
         String directoryString = dialog.open();
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/PasteFeatureHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/PasteFeatureHandler.java
index 3c254b738..58ede00ec 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/PasteFeatureHandler.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/PasteFeatureHandler.java
@@ -3,6 +3,7 @@ package eu.etaxonomy.taxeditor.featuretree.e4.handler;
 
 import javax.inject.Named;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
@@ -15,7 +16,9 @@ import org.eclipse.jface.viewers.IStructuredSelection;
 
 import eu.etaxonomy.cdm.api.service.IFeatureNodeService;
 import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 public class PasteFeatureHandler {
@@ -23,8 +26,19 @@ public class PasteFeatureHandler {
     @Execute
     public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part,
             @Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection){
-        ISelection clipBoardSelection = LocalSelectionTransfer.getTransfer().getSelection();
         FeatureTreeEditor editor = (FeatureTreeEditor)part.getObject();
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
+        ISelection clipBoardSelection = LocalSelectionTransfer.getTransfer().getSelection();
         FeatureNode parentNode = (FeatureNode) selection.getFirstElement();
         FeatureNode copiedNode = (FeatureNode) ((IStructuredSelection)clipBoardSelection).getFirstElement();
 
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
index a7b470bed..796c99ff2 100644
--- 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
@@ -10,6 +10,7 @@ package eu.etaxonomy.taxeditor.featuretree.e4.handler;
 
 import javax.inject.Named;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
@@ -19,8 +20,10 @@ import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.viewers.IStructuredSelection;
 
 import eu.etaxonomy.cdm.model.description.FeatureNode;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
 import eu.etaxonomy.taxeditor.featuretree.e4.operation.RemoveFeatureOperation;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.workbench.part.IE4ViewerPart;
 
 /**
@@ -34,6 +37,17 @@ public class RemoveFeatureHandler {
     public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart,
             @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection){
         FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
         for (Object selectedObject : selection.toArray()) {
             FeatureNode featureNode = (FeatureNode) selectedObject;
             RemoveFeatureOperation operation = new RemoveFeatureOperation(featureNode, editor, editor);
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureTreeHandler.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureTreeHandler.java
index 8736f6709..d56157de3 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureTreeHandler.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/e4/handler/RemoveFeatureTreeHandler.java
@@ -12,6 +12,7 @@ import java.util.List;
 
 import javax.inject.Named;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.core.di.annotations.Optional;
@@ -21,8 +22,10 @@ import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.viewers.IStructuredSelection;
 
 import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.taxeditor.featuretree.e4.FeatureNodeDropAdapter;
 import eu.etaxonomy.taxeditor.featuretree.e4.FeatureTreeEditor;
 import eu.etaxonomy.taxeditor.featuretree.e4.operation.RemoveFeatureTreeOperation;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 
 /**
  * @author pplitzner
@@ -35,6 +38,17 @@ public class RemoveFeatureTreeHandler {
     public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart thisPart,
             @Named(IServiceConstants.ACTIVE_SELECTION)IStructuredSelection selection){
         FeatureTreeEditor editor = (FeatureTreeEditor) thisPart.getObject();
+
+        if (editor.isDirty()) {
+            if (MessagingUtils.confirmDialog(FeatureNodeDropAdapter.SAVE_CHANGES_TITLE,
+                    FeatureNodeDropAdapter.SAVE_CHANGES_MESSAGE)){
+                editor.save(new NullProgressMonitor());
+            }
+            else{
+                return;
+            }
+        }
+
         List<FeatureTree> trees = (List<FeatureTree>) editor.getViewer().getInput();
         for (Object selectedObject : selection.toArray()) {
             FeatureTree featureTree = (FeatureTree) selectedObject;
