Merge branch 'release/5.18.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / EditorUtil.java
index ca2634e76669447cd8d900f254463ee08e022d78..695c5f684b277ce6e8ea9f89c5f3df339ec69137 100644 (file)
@@ -9,14 +9,18 @@
 
 package eu.etaxonomy.taxeditor.editor;
 
+import java.util.Collection;
 import java.util.HashSet;
-import java.util.Set;
+import java.util.List;
 import java.util.UUID;
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.operations.IOperationHistory;
 import org.eclipse.core.commands.operations.IUndoContext;
+import org.eclipse.e4.ui.model.application.MApplication;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
+import org.eclipse.e4.ui.workbench.modeling.EModelService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -24,34 +28,38 @@ import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.TreeNode;
 import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.handlers.HandlerUtil;
 
-import eu.etaxonomy.cdm.api.service.ITaxonService;
-import eu.etaxonomy.cdm.model.common.ITreeNode;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.taxon.Synonym;
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
+import eu.etaxonomy.taxeditor.bulkeditor.input.TaxonEditorInput;
+import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.DescriptiveDataSetEditor;
+import eu.etaxonomy.taxeditor.editor.descriptiveDataSet.matrix.CharacterMatrixPart;
 import eu.etaxonomy.taxeditor.editor.e4.TaxonEditorInputE4;
-import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditor;
 import eu.etaxonomy.taxeditor.editor.group.authority.CdmAuthorityEditorInput;
+import eu.etaxonomy.taxeditor.editor.group.authority.e4.CdmAuthorityEditorE4;
 import eu.etaxonomy.taxeditor.editor.internal.TaxeditorEditorPlugin;
-import eu.etaxonomy.taxeditor.editor.key.KeyEditor;
-import eu.etaxonomy.taxeditor.editor.key.polytomous.PolytomousKeyEditorInput;
 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
 import eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4;
-import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditor;
-import eu.etaxonomy.taxeditor.editor.view.checklist.ChecklistEditorInput;
+import eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart;
+import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView;
+import eu.etaxonomy.taxeditor.editor.view.derivate.DerivateViewEditorInput;
 import eu.etaxonomy.taxeditor.model.AbstractUtility;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.security.RequiredPermissions;
 import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
+import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 /**
  * Utility for the editor package
@@ -62,259 +70,281 @@ import eu.etaxonomy.taxeditor.store.CdmStore;
  */
 public class EditorUtil extends AbstractUtility {
 
-       private static boolean isSaving = false;
+    private static final String NAME_EDITOR_ID = "eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4";
 
-       /**
-        * Opens a new editor window with the given input
-        *
-        * @param input
-        * @param editorId
-        * @return
-        * @return
-        * @throws PartInitException
-        */
-       private static IEditorPart open(final IEditorInput input,
-                       final String editorId) throws PartInitException {
-               IEditorPart editor = getActivePage().openEditor(input, editorId);
-               if(input != null &&
-                       editor.getEditorInput() != null &&
-                       input != editor.getEditorInput() &&
-                       input instanceof CdmEntitySessionInput) {
-                   ((CdmEntitySessionInput)input).dispose();
-               }
-               return editor;
-       }
+    private static boolean factsVisible = true;
 
-       /**
-        * Opens a new editor window with the given TaxonEditorInput
-        *
-        * @param input
-        *            a {@link eu.etaxonomy.taxeditor.editor.TaxonEditorInput}
-        *            object.
-        * @throws org.eclipse.ui.PartInitException
-        *             if any.
-        */
-       public static void open(TaxonEditorInput input) throws PartInitException {
-               open(input, MultiPageTaxonEditor.ID);
-       }
+    private static boolean mediaVisible = true;
 
-       public static void open(PolytomousKeyEditorInput input)
-                       throws PartInitException {
-               open(input, KeyEditor.ID);
-       }
+    public static void openDescriptiveDataSetEditor(UUID descriptiveDataSetUuid, EModelService modelService, EPartService partService, MApplication application){
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            if(part.getObject() instanceof DescriptiveDataSetEditor
+                && ((DescriptiveDataSetEditor) part.getObject()).getDescriptiveDataSet().getUuid().equals(descriptiveDataSetUuid)){
+                partService.showPart(part, PartState.ACTIVATE);
+                return;
+            }
+        }
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVEDATASET_DESCRIPTIVEDATASETEDITOR;
+        MPart part = showPart(partId, modelService, partService, application);
+        DescriptiveDataSetEditor editor = (DescriptiveDataSetEditor) part.getObject();
+        editor.init(descriptiveDataSetUuid);
+    }
+
+    public static void openCharacterMatrix(UUID descriptiveDataSetUuid, EModelService modelService, EPartService partService, MApplication application){
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            if(part.getObject() instanceof CharacterMatrixPart
+                && ((CharacterMatrixPart) part.getObject()).getDescriptiveDataSet().getUuid().equals(descriptiveDataSetUuid)){
+                partService.showPart(part, PartState.ACTIVATE);
+                return;
+            }
+        }
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_DESCRIPTIVEDATASET_MATRIX_CHARACTERMATRIXPART;
+        MPart part = showPart(partId, modelService, partService, application);
+        CharacterMatrixPart editor = (CharacterMatrixPart) part.getObject();
+        editor.init(descriptiveDataSetUuid, true);
+    }
+
+    public static void openDistributionEditor(UuidAndTitleCache parentUuidAndTitleCache, EModelService modelService, EPartService partService, MApplication application){
+        Collection<MPart> parts = partService.getParts();
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_CHECKLIST_E4_DISTRIBUTIONEDITORPART;
+        checkAndCloseFactsAndMediaParts(partService);
+        MPart part = showPart(partId, modelService, partService, application);
+        DistributionEditorPart editor = (DistributionEditorPart) part.getObject();
+        editor.init(parentUuidAndTitleCache);
+    }
+
+    public static void openDistributionEditor(List<UuidAndTitleCache> parentTaxonUuidList, EModelService modelService, EPartService partService, MApplication application){
+        Collection<MPart> parts = partService.getParts();
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_CHECKLIST_E4_DISTRIBUTIONEDITORPART;
+        checkAndCloseFactsAndMediaParts(partService);
+        MPart part = showPart(partId, modelService, partService, application);
+        DistributionEditorPart editor = (DistributionEditorPart) part.getObject();
+        editor.init(parentTaxonUuidList);
+    }
+
+    public static void checkAndCloseFactsAndMediaParts(EPartService partService) {
+        String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4;
+        String partIdMedia = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4;
+        MPart part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4);
+        if (factsVisible || (part1!=null && part1.getWidget() != null && partService.isPartVisible(part1))){
+            factsVisible = true;
+        }else{
+            factsVisible = false;
+        }
+        part1 = partService.findPart(AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4);
+        if (mediaVisible || (part1!=null && part1.getWidget() != null && partService.isPartVisible(part1))){
+            mediaVisible = true;
+        }else{
+            mediaVisible = false;
+        }
+        closePart(partIdMedia, partService);
+        closePart(partIdFactualData, partService);
+    }
+
+
+    public static void openSpecimenEditor(DerivateViewEditorInput input, EModelService modelService, EPartService partService, MApplication application){
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DERIVATE_DERIVATEVIEW;
+        MPart part = showPart(partId, modelService, partService, application);
+        DerivateView derivateView = (DerivateView) part.getObject();
+        derivateView.init(input);
+    }
+
+    public static void openRightsEditor(CdmAuthorityEditorInput input, EModelService modelService, EPartService partService, MApplication application){
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            if(part.getObject() instanceof CdmAuthorityEditorE4
+                && ((CdmAuthorityEditorE4) part.getObject()).getInput().getGroup().equals(input.getGroup())){
+                partService.showPart(part, PartState.ACTIVATE);
+                return;
+            }
+        }
+        String partId = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_GROUP_AUTHORITY_E4_CDMAUTHORITYEDITORE4;
+        MPart part = showPart(partId, modelService, partService, application);
+        CdmAuthorityEditorE4 authorityView = (CdmAuthorityEditorE4) part.getObject();
+        authorityView.init(input);
+    }
+
+    public static MPart showPart(String partId, EModelService modelService, EPartService partService, MApplication application){
+        MPart part = partService.findPart(partId);
+        if(part==null || modelService.getPartDescriptor(partId).isAllowMultiple()){
+            part = partService.createPart(partId);
+        }
+        MPartStack editorAreaPartStack = WorkbenchUtility.getEditorAreaPartStack(application, modelService);
+        if(editorAreaPartStack!=null){
+            editorAreaPartStack.getChildren().add(part);
+        }
+
+        return partService.showPart(part, PartState.ACTIVATE);
 
-       public static void open(CdmAuthorityEditorInput input)
-                       throws PartInitException {
-               open(input, CdmAuthorityEditor.ID);
+    }
+
+    public static MPart showPart(String partId, EModelService modelService, EPartService partService){
+        MPart part = partService.findPart(partId);
+        if(part==null || modelService.getPartDescriptor(partId).isAllowMultiple()){
+            part = partService.createPart(partId);
+            partService.activate(part);
+        }else{
+            partService.activate(part);
+        }
+
+       return part;
+    }
+
+       public static void openTaxonNodeE4(UUID taxonNodeUuid, EModelService modelService, EPartService partService, MApplication application) {
+           TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(taxonNodeUuid);
+           openNameEditor_internal(input, modelService, partService, application);
        }
 
-       /**
-        * Opens a new ChecklistView for the given input
-        * @param input a {@link ChecklistEditorInput} representing the selected checklist
-        * @throws PartInitException
-        */
-       public static void open(ChecklistEditorInput input)
-               throws PartInitException {
-           open(input, ChecklistEditor.ID);
+       public static void openTaxonBaseE4(UUID taxonBaseUuid, EModelService modelService, EPartService partService, MApplication application) {
+           TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
+           openNameEditor_internal(input, modelService, partService, application);
        }
 
-       /**
-        * Opens a new {@link DataImportEditor} for the given input
-        * @param input a {@link DataImportEditorInput}
-        * @throws PartInitException
-        */
-//     public static void open(DataImportEditorInput<?> input)
-//             throws PartInitException {
-//         if(input instanceof BioCaseEditorInput){
-//             open(input, SpecimenImportEditor.ID);
-//         }
-//         else if(input instanceof GbifImportEditorInput){
-//             open(input, GbifImportEditor.ID);
-//         }
-//     }
+    public static void openTaxonBaseE4(UUID taxonBaseUuid) {
+        //FIXME E4 this can probably be removed when fully migrated
+        TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
 
-       /**
-        * Taxon Editors may be opened by supplying a taxon node uuid. Session gets
-        * initialised here and is passed to the editor
-        *
-        * @param taxonNodeUuid
-        *            a {@link java.util.UUID} object.
-        * @throws java.lang.Exception
-        *             if any.
-        */
-       public static void openTaxonNodeE4(UUID taxonNodeUuid) throws Exception {
-           //FIXME E4 this can probably be removed when fully migrated
-        TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(taxonNodeUuid);
         EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
-        MPart part = partService.createPart("eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4");
-        partService.showPart(part, PartState.ACTIVATE);
+        EModelService modelService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EModelService.class);
+        openNameEditor_internal(input, modelService, partService, null);
+    }
+
+    private static void openNameEditor_internal(TaxonEditorInputE4 input, EModelService modelService, EPartService partService, MApplication application) {
+        TaxonBase taxonBase = input.getTaxon();
+        TaxonNode node = input.getTaxonNode();
+        if(taxonBase==null){
+            return;
+        }
+        boolean hasPermission = false;
+//        if (node != null){
+            hasPermission = CdmStore.currentAuthentiationHasPermission(node, RequiredPermissions.TAXON_EDIT);
+//        }
+//        if (!hasPermission){
+//            MessagingUtils.warningDialog(Messages.EditorUtil_MISSING_PERMISSION, TaxonEditorInputE4.class, Messages.EditorUtil_MISSING_PERMISSION_MESSAGE);
+//            return;
+//        }
+        if (taxonBase.isOrphaned()) {
+            if(taxonBase.isInstanceOf(Synonym.class)){
+                MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON_MESSAGE);
+                return;
+            }
+            else{
+                MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_TAXON_MESSAGE);
+                return;
+            }
+        }
+
+
+        Collection<MPart> parts = partService.getParts();
+        //check if part is already opened
+        for (MPart part : parts) {
+               if(part.getObject() instanceof TaxonNameEditorE4
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(input.getTaxon().getUuid())){
+                   if (part.isDirty()){
+                       forceUserSaveE4Editor(((TaxonNameEditorE4) part.getObject()), getShell());
+                   }
+                partService.hidePart(part);
+                break;
+            }
+        }
+        MPart part = showPart(NAME_EDITOR_ID, modelService, partService, application);
+
         TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
+//        editor.setDisabled();
         editor.init(input);
-       }
+//        editor.setEnabled();
+        editor.setFocus();
+        if (factsVisible){
+            showFacts(modelService, partService);
+            factsVisible = false;
+        }
 
-       public static void openTaxonBaseE4(UUID taxonBaseUuid) throws PartInitException{
-           //FIXME E4 this can probably be removed when fully migrated
-           TaxonBase taxonBase = CdmStore.getService(ITaxonService.class).find(taxonBaseUuid);
+        if (mediaVisible){
+            showMedia(modelService, partService);
+            mediaVisible = false;
+        }
 
-           if (taxonBase != null && taxonBase.isOrphaned()) {
-               if(taxonBase.isInstanceOf(Synonym.class)){
-                   MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_ACCEPTED_TAXON_MESSAGE);
-                   return;
-               }
-               else{
-                   MessagingUtils.warningDialog(Messages.EditorUtil_ORPHAN_TAXON, TaxonEditorInputE4.class, Messages.EditorUtil_ORPHAN_TAXON_MESSAGE);
-                   return;
-               }
-           }
 
-           TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstanceFromTaxonBase(taxonBaseUuid);
-           EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
-           MPart part = partService.createPart("eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4");
-           partService.showPart(part, PartState.ACTIVATE);
-           TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
-           editor.init(input);
-       }
+    }
 
-       /**
-        * <p>
-        * findEditorByTaxonNodeUuid
-        * </p>
-        *
-        * @param taxonNodeUuid
-        *            a {@link java.util.UUID} object.
-        * @return a {@link org.eclipse.ui.IEditorPart} object.
-        * @throws java.lang.Exception
-        *             if any.
-        */
-       public static IEditorPart findEditorByTaxonNodeUuid(UUID taxonNodeUuid)
-                       throws Exception {
-               IEditorInput input = TaxonEditorInput.NewInstance(taxonNodeUuid);
-               return getActivePage().findEditor(input);
-       }
+    public static void showMedia(EModelService modelService, EPartService partService) {
+        String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_MEDIA_E4_MEDIAVIEWPARTE4;
+        showPart(partIdFactualData, modelService, partService);
+
+    }
+
+    public static void showFacts(EModelService modelService, EPartService partService) {
+        String partIdFactualData = AppModelId.PARTDESCRIPTOR_EU_ETAXONOMY_TAXEDITOR_EDITOR_VIEW_DESCRIPTIVE_E4_FACTUALDATAPARTE4;
+        showPart(partIdFactualData, modelService, partService);
+
+    }
+
+    public static Collection<MPart> checkForChanges(UUID taxonUUID, EPartService partService ){
+        Collection<MPart> parts = partService.getParts();
+        Collection<MPart> dirtyParts = new HashSet();
+        //check if part is already opened
+        boolean isDirty = false;
+        for (MPart part : parts) {
+            if(part.getObject() instanceof TaxonNameEditorE4
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(taxonUUID)){
+                if (part.isDirty()){
+                    dirtyParts.add(part);
+                }
+
+                break;
+            }else if (taxonUUID == null){
+                if (part.isDirty()){
+                    dirtyParts.add(part);
+                }
+            }
+        }
+        return dirtyParts;
+    }
+
+    public static Collection<IE4SavablePart> checkForTaxonChanges(UUID taxonUUID, EPartService partService ){
+        Collection<MPart> parts = partService.getParts();
+        Collection<IE4SavablePart> dirtyParts = new HashSet<>();
+        //check if part is already opened
+        for (MPart part : parts) {
+            if(part.getObject() instanceof TaxonNameEditorE4
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon()!=null
+                    && ((TaxonNameEditorE4) part.getObject()).getTaxon().getUuid().equals(taxonUUID)){
+                if (part.isDirty()){
+                    dirtyParts.add((IE4SavablePart) part);
+                }
+
+                break;
+            }else if (taxonUUID == null){
+                if (part.isDirty() && (part.getObject() instanceof TaxonNameEditorE4 || (part.getObject() instanceof BulkEditorE4 && ((BulkEditorE4)part.getObject()).getEditorInput() instanceof TaxonEditorInput))){
+                    dirtyParts.add((IE4SavablePart) part.getObject());
+                }
+            }
+        }
+        return dirtyParts;
+    }
 
        /**
         * An uninitialized taxon is one that hasn't been saved yet. As such, it
         * should appear in neither the list of recent names nor in the taxonomic
         * tree when opened.
         *
-        * @throws org.eclipse.ui.PartInitException
-        *             if any.
         * @param parentNodeUuid
         *            a {@link java.util.UUID} object.
         */
-       public static void openEmptyE4(UUID parentNodeUuid) throws PartInitException {
+       public static void openEmptyE4(UUID parentNodeUuid) {
                TaxonEditorInputE4 input = TaxonEditorInputE4
                                .NewEmptyInstance(parentNodeUuid);
         EPartService partService = TaxeditorEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getService(EPartService.class);
-        MPart part = partService.createPart("eu.etaxonomy.taxeditor.editor.name.e4.TaxonNameEditorE4");
-        partService.showPart(part, PartState.ACTIVATE);
+        MPart part = partService.createPart(NAME_EDITOR_ID);
+        part = partService.showPart(part, PartState.ACTIVATE);
         TaxonNameEditorE4 editor = (TaxonNameEditorE4) part.getObject();
         editor.init(input);
        }
 
-       /**
-        * <p>
-        * setSaving
-        * </p>
-        *
-        * @param isSaving
-        *            a boolean.
-        */
-       public static void setSaving(boolean isSaving) {
-               EditorUtil.isSaving = isSaving;
-       }
-
-       /**
-        * <p>
-        * isSaving
-        * </p>
-        *
-        * @return a boolean.
-        */
-       public static boolean isSaving() {
-               return isSaving;
-       }
-
-       /**
-        * Returns a set of all currently open <code>MultiPageTaxonEditor</code>s.
-        *
-        * @return a {@link java.util.Set} object.
-        */
-       public static Set<IEditorPart> getOpenEditors() {
-               Set<IEditorPart> taxonEditors = new HashSet<IEditorPart>();
-
-               if (getActivePage() != null) {
-                       for (IEditorReference reference : getActivePage()
-                                       .getEditorReferences()) {
-                               IEditorPart editor = reference.getEditor(false);
-                               if (editor instanceof MultiPageTaxonEditor) {
-                                       taxonEditors.add(editor);
-                               }
-                       }
-               }
-
-               return taxonEditors;
-       }
-
-       /**
-        * Returns the currently active taxon editor
-        *
-        * @return the taxon editor that has focus
-        */
-       public static MultiPageTaxonEditor getActiveMultiPageTaxonEditor() {
-               Object editorPart = getActiveE4Editor();
-               if (editorPart != null && editorPart instanceof MultiPageTaxonEditor) {
-                       MultiPageTaxonEditor editor = (MultiPageTaxonEditor) editorPart;
-                       editor.getConversationHolder().bind();
-                       return editor;
-               }
-               return null;
-       }
-
-       /**
-        * <p>
-        * getActiveEditorPage
-        * </p>
-        *
-        * @param page
-        *            a {@link eu.etaxonomy.taxeditor.editor.Page} object.
-        * @return a {@link org.eclipse.ui.IEditorPart} object.
-        */
-       public static IEditorPart getActiveEditorPage(Page page) {
-               MultiPageTaxonEditor editor = getActiveMultiPageTaxonEditor();
-
-               return editor != null ? editor.getPage(page) : null;
-       }
-
-       /**
-        * Returns the selection of the currently active taxon editor
-        *
-        * @return a {@link org.eclipse.jface.viewers.ISelection} object.
-        */
-       public static ISelection getCurrentSelection() {
-               if (getActiveMultiPageTaxonEditor() == null) {
-                       return null;
-               } else {
-                       return getActiveMultiPageTaxonEditor().getSite()
-                                       .getSelectionProvider().getSelection();
-               }
-       }
-
-       /**
-        * <p>
-        * getUndoContext
-        * </p>
-        *
-        * @param editor
-        *            a {@link eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor}
-        *            object.
-        * @return a {@link org.eclipse.core.commands.operations.IUndoContext}
-        *         object.
-        */
-       public static IUndoContext getUndoContext(MultiPageTaxonEditor editor) {
-               return editor.getUndoContext();
-       }
-
        /**
         * <p>
         * getUndoContext
@@ -327,7 +357,23 @@ public class EditorUtil extends AbstractUtility {
                return IOperationHistory.GLOBAL_UNDO_CONTEXT;
        }
 
-       /**
+       public static boolean isFactsVisible() {
+        return factsVisible;
+    }
+
+    public static void setFactsVisible(boolean factsVisible) {
+        EditorUtil.factsVisible = factsVisible;
+    }
+
+    public static boolean isMediaVisible() {
+        return mediaVisible;
+    }
+
+    public static void setMediaVisible(boolean mediaVisible) {
+        EditorUtil.mediaVisible = mediaVisible;
+    }
+
+    /**
         * <p>
         * forceUserSave
         * </p>
@@ -354,7 +400,7 @@ public class EditorUtil extends AbstractUtility {
                return true;
        }
 
-       public static boolean forceUserSaveE4Editor(TaxonNameEditorE4 editor, Shell shell) {
+       public static boolean forceUserSaveE4Editor(IE4SavablePart editor, Shell shell) {
            if (editor.isDirty()) {
 
                boolean doSave = MessageDialog
@@ -397,25 +443,6 @@ public class EditorUtil extends AbstractUtility {
                return TaxeditorEditorPlugin.PLUGIN_ID;
        }
 
-       public static void openPolytomousKey(UUID polytomousKeyUuid)
-                       throws Exception {
-               PolytomousKeyEditorInput input = PolytomousKeyEditorInput
-                               .NewInstance(polytomousKeyUuid);
-               open(input);
-       }
-
-//     public static void openPolytomousKeyEditor(UUID polytomousKeyUuid, String name)
-//             throws Exception {
-//         PolytomousKeyEditorInput input = new PolytomousKeyEditorInput(polytomousKeyUuid, name);
-//         open(input);
-//     }
-
-       public static void openCdmAuthorities(UUID groupUuid)
-                       throws Exception {
-               CdmAuthorityEditorInput input = CdmAuthorityEditorInput.NewInstance(groupUuid);
-               open(input);
-       }
-
        /**
         * Iterates recursively over all originals having the given specimen as a derivate.
         * The first {@link DerivedUnit} with no more originals or the first {@link FieldUnit} is returned
@@ -423,21 +450,22 @@ public class EditorUtil extends AbstractUtility {
         * @return either a FieldUnit or a the topmost DerivedUnit (which can be itself)
         */
        public static SpecimenOrObservationBase<?> getTopMostDerivate(SpecimenOrObservationBase<?> specimen){
+           if(specimen==null){
+               return null;
+           }
            if(specimen.isInstanceOf(FieldUnit.class)){
                return specimen;
            }
-           else if(specimen instanceof DerivedUnit
-                   && ((DerivedUnit) specimen).getOriginals()!=null
-                   && !((DerivedUnit) specimen).getOriginals().isEmpty()){
-               for(SpecimenOrObservationBase<?> original:((DerivedUnit) specimen).getOriginals()){
-                   return getTopMostDerivate(original);
+           else if(specimen.isInstanceOf(DerivedUnit.class)){
+               DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(specimen, DerivedUnit.class);
+               if(derivedUnit.getOriginals()!=null
+                       && !(derivedUnit.getOriginals().isEmpty())){
+                   for(SpecimenOrObservationBase<?> original:((DerivedUnit) specimen).getOriginals()){
+                       return getTopMostDerivate(original);
+                   }
                }
-               //needed to add this for compilation although this is unreachable
-               return specimen;
-           }
-           else{
-               return specimen;
            }
+           return specimen;
        }
 
     /**
@@ -455,27 +483,89 @@ public class EditorUtil extends AbstractUtility {
         return null;
     }
 
-    public static boolean closeObsoleteEditor(TaxonNode taxonNode, IWorkbenchPage activePage){
-        boolean result = true;
-        for (IEditorReference ref : activePage.getEditorReferences()) {
-            try {
-                String treeIndex = ((ITreeNode)taxonNode).treeIndex();
+    public static void closeObsoleteEditor(TaxonNodeDto taxonNode, EPartService partService){
+        String treeIndex = taxonNode.getTreeIndex();
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            Object object = part.getObject();
+            if(object instanceof TaxonNameEditorE4){
+                TaxonNameEditorE4 taxonEditor = (TaxonNameEditorE4)object;
+                TaxonNode node = taxonEditor.getEditorInput().getTaxonNode();
+                if (node.treeIndex()!= null){
+                       if(node.treeIndex().startsWith(treeIndex)){
+                           if (part.isDirty()){
+                               forceUserSaveE4Editor(taxonEditor, getShell());
+                           }
+                           partService.hidePart(part);
+                       }
+                }else{
+                       logger.debug("The taxonnode of taxon " + node.getTaxon().getTitleCache() + " uuid: " + node.getUuid() + " has no treeindex");;
+                }
+            }
+        }
+    }
+
+    public static void closeObsoleteEditorWithChildren(TaxonNodeDto taxonNode, EPartService partService){
+        String treeIndex = taxonNode.getTreeIndex();
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            Object object = part.getObject();
+            if(object instanceof TaxonNameEditorE4){
+                TaxonNameEditorE4 taxonEditor = (TaxonNameEditorE4)object;
+                TaxonNode node = taxonEditor.getEditorInput().getTaxonNode();
+                if (node.treeIndex()!= null){
+                    if(node.treeIndex().startsWith(treeIndex)){
+                        if (part.isDirty()){
+                            forceUserSaveE4Editor(taxonEditor, getShell());
+                        }
+                        partService.hidePart(part);
+                    }
+                }else{
+                    logger.debug("The taxonnode of taxon " + node.getTaxon().getTitleCache() + " uuid: " + node.getUuid() + " has no treeindex");;
+                }
+            }
+        }
+    }
 
 
-                IEditorInput input = ref.getEditorInput();
-                if (input instanceof TaxonEditorInput) {
-                    TaxonNode node = ((TaxonEditorInput) input).getTaxonNode();
-                    //if node is a child of taxonNode then close the editor
-                    if( ((ITreeNode) node).treeIndex().startsWith(treeIndex)){
-                    //if (taxonNode.equals(node)) {
-                        result &= activePage.closeEditor(ref.getEditor(false), true);
+    public static void closeObsoleteDescriptiveDatasetEditor(UUID datasetUuid, EPartService partService){
 
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            Object object = part.getObject();
+            if(object instanceof DescriptiveDataSetEditor){
+                DescriptiveDataSetEditor editor = (DescriptiveDataSetEditor)object;
+                DescriptiveDataSet descDataSet = editor.getDescriptiveDataSet();
+                if(descDataSet.getUuid().equals(datasetUuid)){
+                    if (part.isDirty()){
+                        forceUserSaveE4Editor(editor, getShell());
                     }
+                    partService.hidePart(part);
                 }
-            } catch (PartInitException e) {
-                continue;
+
             }
         }
-        return result;
     }
+
+
+    public static void closePart(String partID, EPartService partService){
+
+        Collection<MPart> parts = partService.getParts();
+        for (MPart part : parts) {
+            String elementId = part.getElementId();
+            if (elementId.equals(partID)){
+                partService.hidePart(part);
+            }
+        }
+    }
+
+    public static void updateEditor(TaxonNode taxonNode, TaxonNameEditorE4 editor){
+        String treeIndex = taxonNode.treeIndex();
+        TaxonNode node = editor.getEditorInput().getTaxonNode();
+        if(node.treeIndex().equals(treeIndex)){
+               TaxonEditorInputE4 input = TaxonEditorInputE4.NewInstance(node.getUuid());
+               editor.init(input);
+        }
+    }
+
 }