Merge branch 'release/5.14.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / view / e4 / AbstractCdmEditorPartE4.java
index 4d18dc3aabae1b3a826788f0a5588975befc5563..60e424ad278503be116562b53a6d76db3a4aeb61 100644 (file)
@@ -8,36 +8,49 @@
 */
 package eu.etaxonomy.taxeditor.view.e4;
 
+import java.util.Collection;
 import java.util.Set;
 
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 import javax.inject.Named;
 
+import org.apache.log4j.Logger;
+import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.ui.di.PersistState;
+import org.eclipse.e4.ui.di.UISynchronize;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
 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.StructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.SWTException;
+import org.springframework.security.core.GrantedAuthority;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.ITermService;
+import eu.etaxonomy.cdm.api.service.IVocabularyService;
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
-import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.description.Distribution;
+import eu.etaxonomy.cdm.model.name.TaxonName;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
-import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
-import eu.etaxonomy.taxeditor.editor.IDistributionEditor;
 import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
+import eu.etaxonomy.taxeditor.security.RequiredPermissions;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.view.e4.details.DetailsPartE4;
 import eu.etaxonomy.taxeditor.view.e4.details.DetailsViewerE4;
 import eu.etaxonomy.taxeditor.workbench.WorkbenchUtility;
 import eu.etaxonomy.taxeditor.workbench.part.ISelectionElementEditingPart;
@@ -56,7 +69,8 @@ public abstract class AbstractCdmEditorPartE4
      * If it is <code>true</code> then it is currently delaying a selection.
      */
     private boolean isInDelay;
-
+    private boolean isEnabled = true;
+    private static final Logger logger = Logger.getLogger(AbstractCdmEditorPartE4.class);
 
     /**
      * This class invokes internal_selectionChanged() in a separate thread.
@@ -115,30 +129,56 @@ public abstract class AbstractCdmEditorPartE4
     @Inject
     protected ESelectionService selService;
 
+    @Inject
+    protected IEclipseContext context;
+
     protected abstract void selectionChanged_internal(Object selection, MPart activePart, MPart thisPart);
 
     @Inject
-    @Optional
     public void selectionChanged(
-            @Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
-            @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
-            MPart thisPart){
-        if(previousSelection==null ||
-                !previousSelection.equals(selection)){//skip redundant rendering of details view
-            Object savablePart = WorkbenchUtility.findSavablePart(this);
-            if(savablePart==null){
-                showEmptyPage();
-            }
-            if(delaySelection==null){
-                delaySelection = new DelaySelection(selection, activePart, thisPart);
-            }
-            delaySelection.setSelection(selection);
-            delaySelection.setActivePart(activePart);
-            delaySelection.setThisPart(thisPart);
-            if(!isInDelay){
-                isInDelay = true;
-                Display.getCurrent().asyncExec(delaySelection);
-            }
+            @Optional@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
+            @Optional@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
+            MPart thisPart, UISynchronize sync, EPartService partService){
+        //multiple selections are not supported
+        if(activePart!=null
+                && thisPart!=null
+                && !activePart.equals(thisPart)
+                && selection instanceof IStructuredSelection
+                && ((IStructuredSelection) selection).size()>1){
+            showEmptyPage();
+            return;
+        }
+        // no active editor found
+        if(activePart==thisPart && WorkbenchUtility.getActiveEditorPart(partService)==null){
+            showEmptyPage();
+            return;
+        }
+        if (viewer != null && viewer.getControl()!= null && viewer.getInput() != null && !viewer.getControl().isDisposed()){
+           try{
+               viewer.getControl().setEnabled(isEnabled);
+           }catch(SWTException e){
+              logger.debug("Something went wrong for viewer.getControl().setEnabled(true) in " + this.getClass().getSimpleName(), e);
+           }
+
+        }
+
+        if((previousSelection!=null && selection!=null) && (activePart != null &&  selectionProvidingPart != null && activePart.equals(selectionProvidingPart)) &&
+                (previousSelection==selection
+                || previousSelection.equals(selection)
+                || new StructuredSelection(selection).equals(previousSelection))
+                ) {
+            return;
+        }
+        if(delaySelection==null){
+            delaySelection = new DelaySelection(selection, activePart, thisPart);
+        }
+        delaySelection.setSelection(selection);
+        delaySelection.setActivePart(activePart);
+        delaySelection.setThisPart(thisPart);
+        if(!isInDelay){
+            isInDelay = true;
+            sync.asyncExec(delaySelection);
+            previousSelection = selection;
         }
     }
 
@@ -157,26 +197,66 @@ public abstract class AbstractCdmEditorPartE4
         return viewer;
     }
 
+    public boolean isEnabled() {
+        return isEnabled;
+    }
+
+    public void setEnabled(boolean isEnabled) {
+        this.isEnabled = isEnabled;
+    }
+
     protected void showViewer(IStructuredSelection selection, MPart activePart, Viewer viewer){
+        if(CdmStore.getCurrentSessionManager().getActiveSession()==null){
+            return;
+        }
         if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
             Object element = selection.getFirstElement();
             Object part = createPartObject(activePart);
+            if (viewer.getControl().isDisposed()){
+                return;
+            }
+            viewer.getControl().setEnabled(true);
             if(selection.getFirstElement()!=null){
                 if (element instanceof Taxon){
+
                     Taxon taxon = HibernateProxyHelper.deproxy(element, Taxon.class);
-                    if (taxon.isMisapplication()){
+                    if (part instanceof ITaxonEditor){
+                        TaxonNode node = ((ITaxonEditor) part).getTaxonNode();
+                        if (node != null){
+                            boolean doEnable = CdmStore.currentAuthentiationHasPermission(node,
+                                    RequiredPermissions.TAXON_EDIT);
+                             if (!doEnable){
+                                 //check whether there are explicit TaxonNode rights
+                                 boolean taxonnodePermissionExists = false;
+                                 Collection<? extends GrantedAuthority> authorities = CdmStore.getCurrentAuthentiation().getAuthorities();
+                                 for (GrantedAuthority grantedAuthority: authorities){
+                                     if (grantedAuthority.getAuthority().startsWith("TAXONNODE")){
+                                         taxonnodePermissionExists = true;
+                                     }
+                                 }
+                                 if (!taxonnodePermissionExists){
+                                     doEnable = true;
+                                 }
+                             }
+
+                            //TODO: differ between the views
+                            this.isEnabled = doEnable;
+                        }
+
+
+                    }
+                    if (taxon.isMisapplication() || taxon.isProparteSynonym() || taxon.isInvalidDesignation()){
 
                         if(part instanceof ITaxonEditor){
                             Taxon accepted = ((ITaxonEditor) part).getTaxon();
 
-                            //                                 Taxon accepted= ((ITaxonEditor)activePart).getTaxon();
                             Set<TaxonRelationship> rels =  taxon.getTaxonRelations(accepted);
 
-                            if (rels.iterator().hasNext()){
+                            if (rels != null && rels.iterator().hasNext() && !taxon.equals(accepted)){
                                 TaxonRelationship rel = rels.iterator().next();
-                                if (rel.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
+                                if ((rel.getType().isMisappliedNameOrInvalidDesignation() || rel.getType().isAnySynonym()) && !rel.getFromTaxon().equals(((ITaxonEditor) part).getTaxon())){
                                     viewer.setInput(rel);
-
+                                    selectionProvidingPart = activePart;
                                     return;
                                 }
                             }
@@ -185,15 +265,37 @@ public abstract class AbstractCdmEditorPartE4
 
                     }
                 }
-                if (element instanceof Distribution && part instanceof IDistributionEditor){
+                //unwrap term DTOs
+                if(element instanceof TermDto){
+                    element = CdmStore.getService(ITermService.class).load(((TermDto) element).getUuid());
+                }
+                else if(element instanceof TermVocabularyDto){
+                    element = CdmStore.getService(IVocabularyService.class).load(((TermVocabularyDto) element).getUuid());
+                }
+
+                selectionProvidingPart = activePart;
+                if (viewer instanceof DetailsViewerE4){
+
+                    if (selectionProvidingPart.getElementId().equals("eu.etaxonomy.taxeditor.editor.view.checklist.e4.DistributionEditorPart")){
+                        ((DetailsViewerE4)viewer).setDetailsEnabled(false);
+                    }else{
+                        ((DetailsViewerE4)viewer).setDetailsEnabled(isEnabled);
+                    }
                     ((DetailsViewerE4)viewer).setInput(element, part);
-                }else{
-                    viewer.setInput(element);
+
                 }
 
+                else{
+                    if (activePart.getObject() instanceof DetailsPartE4 && element instanceof TaxonName){
+                        selectionProvidingPart = ((DetailsPartE4)activePart.getObject()).getSelectionProvidingPart();
+                    }
+
+                    viewer.setInput(element);
+                    viewer.getControl().setEnabled(isEnabled);
+
+
+                }
             }
-            selectionProvidingPart = activePart;
-            previousSelection = selection;
         }
     }
 
@@ -207,10 +309,26 @@ public abstract class AbstractCdmEditorPartE4
     }
 
     protected void showEmptyPage() {
-        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed()){
+        if(viewer!=null && viewer.getControl()!=null && !viewer.getControl().isDisposed() ){
             viewer.setInput(null);
+            try{
+                   if (!viewer.getControl().isDisposed()){
+                       viewer.getControl().setEnabled(false);
+                   }
+            }catch(SWTException e){
+               if (PreferencesUtil.isShowUpWidgetIsDisposedMessages() && e.getMessage().equals("Widget is disposed")){
+                    MessagingUtils.errorDialog("Widget is disposed",
+                            null,
+                            MessagingUtils.WIDGET_IS_DISPOSED_MESSAGE,
+                            null,
+                            e,
+                            true);
+
+                }
+            }
+
         }
-        selectionProvidingPart = null;
+        reset();
         if(thisPart!=null){
             thisPart.setLabel(getViewName());
         }
@@ -245,9 +363,8 @@ public abstract class AbstractCdmEditorPartE4
      * {@inheritDoc}
      */
     @Override
-    public boolean postOperation(CdmBase objectAffectedByOperation) {
+    public boolean postOperation(Object objectAffectedByOperation) {
         changed(objectAffectedByOperation);
-        viewer.setInput(objectAffectedByOperation);
         return true;
     }
 
@@ -264,7 +381,7 @@ public abstract class AbstractCdmEditorPartE4
      * {@inheritDoc}
      */
     @Override
-    public Object getSelectionProvidingPart() {
+    public MPart getSelectionProvidingPart() {
         return selectionProvidingPart;
     }
 
@@ -272,6 +389,13 @@ public abstract class AbstractCdmEditorPartE4
     private void dispose() {
     }
 
+    private void reset(){
+        previousSelection = null;
+        selectionProvidingPart = null;
+        delaySelection = null;
+        context.deactivate();
+    }
+
     @PersistState
     private void persistState(){