Add status bar info for hierarchies found
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / derivate / DerivateView.java
index f8eeb6fb46db96559b522004d6a16e247d53fdf7..a6504a980626b40a4448e55fae4ee02630f7b8fb 100644 (file)
@@ -7,7 +7,6 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.UUID;
 
@@ -30,30 +29,41 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.ISaveablePart2;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.ISelectionService;
 import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.EditorPart;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
+import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
-import eu.etaxonomy.cdm.api.service.molecular.ISequenceService;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.molecular.Sequence;
 import eu.etaxonomy.cdm.model.molecular.SingleRead;
 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.persistence.hibernate.CdmDataChangeMap;
 import eu.etaxonomy.taxeditor.editor.EditorUtil;
 import eu.etaxonomy.taxeditor.editor.Messages;
+import eu.etaxonomy.taxeditor.editor.MultiPageTaxonEditor;
 import eu.etaxonomy.taxeditor.editor.view.derivate.searchFilter.DerivateSearchCompositeController;
+import eu.etaxonomy.taxeditor.model.IContextListener;
+import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
 import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
+import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
 import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
 import eu.etaxonomy.taxeditor.store.CdmStore;
-import eu.etaxonomy.taxeditor.view.AbstractCdmViewPart;
 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateContentProvider;
 import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
 
@@ -61,8 +71,9 @@ import eu.etaxonomy.taxeditor.view.derivateSearch.DerivateLabelProvider;
  * Displays the derivate hierarchy of the specimen specified in the editor input.
  *
  */
-public class DerivateView extends AbstractCdmViewPart implements IPartContentHasFactualData, ISaveablePart2,
-        IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia {
+public class DerivateView extends EditorPart implements IPartContentHasFactualData, IConversationEnabled,
+        ICdmEntitySessionEnabled, IDirtyMarkable, IPostOperationEnabled, IPartContentHasDetails, IPartContentHasSupplementalData, IPartContentHasMedia,
+        IContextListener, ISelectionListener {
     public static final String ID = "eu.etaxonomy.taxeditor.editor.view.derivate.DerivateView"; //$NON-NLS-1$
 
     public static final String YOU_NEED_TO_SAVE_BEFORE_PERFORMING_THIS_ACTION = Messages.DerivateView_YOU_NEED_TO_SAVE;
@@ -94,11 +105,6 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
 
     private DerivateLabelProvider labelProvider;
 
-    private Set<SingleRead> multiLinkSingleReads;
-
-    private ISelection selection = null;
-
-
     private DerivateContentProvider contentProvider;
 
     private DerivateSearchCompositeController derivateSearchCompositeController;
@@ -121,10 +127,24 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
      */
     private boolean listenToSelectionChange;
 
+    private Taxon selectedTaxon;
+
+    private ISelectionService selectionService;
+
     /**
      * Default constructor
      */
     public DerivateView() {
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+        this.setSite(site);
+        this.setInput(input);
         this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
         this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
 
@@ -134,6 +154,8 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
         if (CdmStore.isActive()) {
             cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
         }
+        //listen to context changes
+        CdmStore.getContextManager().addContextListener(this);
     }
 
     @Override
@@ -143,11 +165,11 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
 
         //---search and filter---
         derivateSearchCompositeController = new DerivateSearchCompositeController(parent, this);
-        derivateSearchCompositeController.setEnabled(CdmStore.isActive());
         GridData gridDataSearchBar = new GridData();
         gridDataSearchBar.horizontalAlignment = GridData.FILL;
         gridDataSearchBar.grabExcessHorizontalSpace = true;
         derivateSearchCompositeController.setLayoutData(gridDataSearchBar);
+        derivateSearchCompositeController.setEnabled(CdmStore.isActive());
 
         //---tree viewer---
         viewer = new TreeViewer(new Tree(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION));
@@ -163,6 +185,7 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
         labelProvider.setConversation(conversation);
         viewer.setLabelProvider(labelProvider);
         viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
+        viewer.getTree().setEnabled(CdmStore.isActive());
         // Propagate selection from viewer
         getSite().setSelectionProvider(viewer);
 
@@ -187,7 +210,7 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
     }
 
     public void updateRootEntities() {
-        updateRootEntities(null);
+        updateRootEntities((Collection)null);
     }
 
     public void updateRootEntities(Collection<UUID> derivativeUuids) {
@@ -195,11 +218,38 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
             if (!conversation.isBound()) {
                 conversation.bind();
             }
+            /*
+             * If the active session is not the session of the Derivate Editor then we will
+             * save it, bind temporarily to our session and rebind to the original session.
+             * This happens e.g. if a selection change happens in the taxon editor and
+             * "Link with editor" is enabled. The selection change event and thus the
+             * loading in updateRootEntities() happens in the session of the taxon
+             * editor.
+             */
+            ICdmEntitySession previousCdmEntitySession = CdmStore.getCurrentSessionManager().getActiveSession();
+            if(cdmEntitySession != null) {
+                cdmEntitySession.bind();
+            }
+
+            List<SpecimenOrObservationBase> derivates = null;
             if(derivativeUuids!=null){
                 this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
                 this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
-                for (UUID uuid : derivativeUuids) {
-                    SpecimenOrObservationBase<?> derivate = CdmStore.getService(IOccurrenceService.class).load(uuid, SPECIMEN_INIT_STRATEGY);
+                derivates = CdmStore.getService(IOccurrenceService.class).load(new ArrayList(derivativeUuids), SPECIMEN_INIT_STRATEGY);
+            }
+            updateRootEntities(derivates);
+            previousCdmEntitySession.bind();
+        }
+    }
+
+
+    public void updateRootEntities(List<SpecimenOrObservationBase> derivates) {
+
+            if(derivates!=null){
+                this.derivateToRootEntityMap = new HashMap<SpecimenOrObservationBase<?>, SpecimenOrObservationBase<?>>();
+                this.rootElements = new HashSet<SpecimenOrObservationBase<?>>();
+                for (SpecimenOrObservationBase derivate : derivates) {
+
                     if(derivate instanceof FieldUnit){
                         derivateToRootEntityMap.put(derivate, derivate);
                     }
@@ -217,9 +267,11 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
                     rootElements.add(specimen);
                 }
             }
+            labelProvider.initCache(rootElements);
             viewer.setInput(rootElements);
-            refreshTree();
-        }
+
+            getEditorSite().getActionBars().getStatusLineManager().setMessage(rootElements.size() +" derivative hierarchies found");
+
     }
 
     @Override
@@ -250,10 +302,6 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
     public void doSaveAs() {
     }
 
-    public Set<SpecimenOrObservationBase<?>> getRootElements() {
-        return rootElements;
-    }
-
     @Override
     public String getTitleToolTip() {
         return Messages.DerivateView_DERIVATIVE_EDITOR;
@@ -280,7 +328,7 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
     public void setFocus() {
         viewer.getControl().setFocus();
         //make sure to bind again if maybe in another view the conversation was unbound
-        if(!conversation.isBound()){
+        if(conversation!=null && !conversation.isBound()){
             conversation.bind();
         }
         if(cdmEntitySession != null) {
@@ -297,19 +345,11 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
         return conversation;
     }
 
-    /**
-     * @return the viewer
-     */
-    @Override
-    public TreeViewer getViewer() {
-        return viewer;
-    }
-
     @Override
     public void changed(Object element) {
         setDirty(true);
         firePropertyChange(IEditorPart.PROP_DIRTY);
-        viewer.refresh();
+        viewer.update(new TreeNode(element), null);
     }
 
     @Override
@@ -352,8 +392,6 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
      * Refreshes the derivate hierarchy tree
      */
     public void refreshTree(){
-        generateMultiLinkSingleReads();
-        labelProvider.setMultiLinkSingleReads(multiLinkSingleReads);
         viewer.refresh();
     }
 
@@ -364,25 +402,15 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
         viewer.setInput(rootElements);
     }
 
-    private void generateMultiLinkSingleReads() {
-        Set<SingleRead> multiLinkSingleReads = new HashSet<SingleRead>();
-        for(Entry<SingleRead, Collection<Sequence>> entry:CdmStore.getService(ISequenceService.class).getSingleReadSequencesMap().entrySet()){
-            if(entry.getValue().size()>1){
-                multiLinkSingleReads.add(entry.getKey());
-            }
-        }
-        this.multiLinkSingleReads = multiLinkSingleReads;
-    }
-
     /**
      * @return a set of {@link SingleRead}s that have multiple parents
      */
     public Set<SingleRead> getMultiLinkSingleReads() {
-        return this.multiLinkSingleReads;
+        return DerivateLabelProvider.getMultiLinkSingleReads();
     }
 
-    public ISelection getSelection() {
-        return selection;
+    public Object getSelectionInput() {
+        return selectedTaxon;
     }
 
     public DerivateLabelProvider getLabelProvider() {
@@ -409,12 +437,7 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
         return true;
     }
 
-    public void removeHierarchy(SpecimenOrObservationBase<?> specimenOrObservationBase) {
-        SpecimenOrObservationBase<?> rootElement = derivateToRootEntityMap.remove(specimenOrObservationBase);
-        rootElements.remove(rootElement);
-    }
-
-    public void addHierarchy(FieldUnit fieldUnit) {
+    public void addFieldUnit(FieldUnit fieldUnit) {
         rootElements.add(fieldUnit);
         derivateToRootEntityMap.put(fieldUnit, fieldUnit);
     }
@@ -437,32 +460,103 @@ public class DerivateView extends AbstractCdmViewPart implements IPartContentHas
 
     @Override
     public void selectionChanged(IWorkbenchPart part, ISelection selection) {
-        if(listenToSelectionChange && selection instanceof IStructuredSelection){
-            Object selectedElement = ((IStructuredSelection) selection).getFirstElement();
-            if(selectedElement instanceof Taxon){
-                Collection<SpecimenOrObservationBase> fieldUnits = CdmStore.getService(IOccurrenceService.class).listFieldUnitsByAssociatedTaxon((Taxon) selectedElement, null, null);
-                viewer.setInput(fieldUnits);
+        if(viewer.getTree().isDisposed()){
+            return;
+        }
+        if(listenToSelectionChange){
+            if(part instanceof MultiPageTaxonEditor){
+                selectedTaxon = ((MultiPageTaxonEditor) part).getTaxon();
+            }
+            else if(selection instanceof IStructuredSelection){
+                Object selectedElement = ((IStructuredSelection) selection).getFirstElement();
+                if(selectedElement instanceof CdmBase){
+                    if(((CdmBase) selectedElement).isInstanceOf(TaxonNode.class)){
+                        selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, TaxonNode.class).getTaxon();
+                    }
+                    else if(((CdmBase) selectedElement).isInstanceOf(Taxon.class)){
+                        selectedTaxon = HibernateProxyHelper.deproxy(selectedElement, Taxon.class);
+                    }
+                }
             }
+            if(selectedTaxon!=null){
+                Collection<SpecimenOrObservationBase> fieldUnits = CdmStore.getService(IOccurrenceService.class).listFieldUnitsByAssociatedTaxon(selectedTaxon, null, null);
+                Collection<UUID> uuids = new HashSet<UUID>();
+                for (SpecimenOrObservationBase specimenOrObservationBase : fieldUnits) {
+                    uuids.add(specimenOrObservationBase.getUuid());
+                }
+                updateRootEntities(uuids);
+                setPartName("Derivative Editor: " + selectedTaxon.getName());
+            }
+        }
+    }
+
+    public TreeViewer getViewer() {
+        return viewer;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<SpecimenOrObservationBase<?>> getRootEntities() {
+        return new ArrayList<SpecimenOrObservationBase<?>>(rootElements);
+    }
+
+    public void toggleListenToSelectionChange() {
+        listenToSelectionChange = !listenToSelectionChange;
+        derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
+        if(!listenToSelectionChange){
+            selectedTaxon = null;
+            setPartName("Derivative Editor");
+        }
+        else if(selectedTaxon==null){
+            setPartName("Derivative Editor [no taxon selected]");
         }
     }
 
+    public boolean isListenToSelectionChange(){
+        return listenToSelectionChange;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void createViewer(Composite parent) {
-        // TODO Auto-generated method stub
+    public void contextAboutToStop(IMemento memento, IProgressMonitor monitor) {
+    }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void contextStop(IMemento memento, IProgressMonitor monitor) {
+        derivateSearchCompositeController.setEnabled(false);
+        viewer.getTree().setEnabled(false);
+        viewer.setInput(null);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public boolean isSaveOnCloseNeeded() {
-        return isDirty();
+    public void contextStart(IMemento memento, IProgressMonitor monitor) {
+        derivateSearchCompositeController.setEnabled(!listenToSelectionChange);
+        viewer.getTree().setEnabled(true);
+        refreshTree();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public int promptToSaveOnClose() {
-        return ISaveablePart2.DEFAULT;
+    public void contextRefresh(IProgressMonitor monitor) {
     }
 
-    public void toggleListenToSelectionChange() {
-        listenToSelectionChange = !listenToSelectionChange;
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void workbenchShutdown(IMemento memento, IProgressMonitor monitor) {
     }
+
 }