ref #7086 Fix focus problem when saving
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / workingSet / WorkingSetEditor.java
index 56aa97258115a42c2a4860c79e1a11dc21270a5b..9abb7bdded91ac918193b92c1fa145e56a005476 100644 (file)
@@ -8,8 +8,12 @@
 */
 package eu.etaxonomy.taxeditor.editor.workingSet;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
@@ -25,47 +29,60 @@ 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.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
 import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.DND;
 import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
-import eu.etaxonomy.cdm.api.service.IOccurrenceService;
+import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.ITermService;
 import eu.etaxonomy.cdm.api.service.IWorkingSetService;
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.description.FeatureTree;
-import eu.etaxonomy.cdm.model.description.SpecimenDescription;
 import eu.etaxonomy.cdm.model.description.WorkingSet;
 import eu.etaxonomy.cdm.model.location.NamedArea;
 import eu.etaxonomy.cdm.model.name.Rank;
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
-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.l10n.Messages;
+import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
+import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.ui.dialog.selection.NamedAreaSelectionDialog;
 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 /**
+ * Editor for configuring WorkingSets
  * @author pplitzner
  * @since Nov 21, 2017
  *
  */
-public class WorkingSetEditor implements IE4SavablePart{
+public class WorkingSetEditor implements IE4SavablePart, IConversationEnabled, ICdmEntitySessionEnabled,
+IPartContentHasDetails, IDirtyMarkable {
 
     private WorkingSetComposite composite;
 
     private ConversationHolder conversation;
 
+    private ICdmEntitySession cdmEntitySession;
+
     private WorkingSet workingSet;
 
     private final int dndOperations = DND.DROP_MOVE;
@@ -73,12 +90,20 @@ public class WorkingSetEditor implements IE4SavablePart{
     @Inject
     private MDirtyable dirty;
 
+    @Inject
+    private ESelectionService selectionService;
+
     private ModifyListener labelModifyListener;
 
     @PostConstruct
     public void create(Composite parent, IEclipseContext context, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell){
-        if(CdmStore.isActive() && conversation==null){
-            conversation = CdmStore.createConversation();
+        if (CdmStore.isActive()){
+            if(conversation == null){
+                conversation = CdmStore.createConversation();
+            }
+            if(cdmEntitySession == null){
+                cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true);
+            }
         }
         else{
             return;
@@ -91,30 +116,64 @@ public class WorkingSetEditor implements IE4SavablePart{
         labelModifyListener = new ModifyListener() {
             @Override
             public void modifyText(ModifyEvent e) {
+                workingSet.setLabel(composite.getTxt_label().getText());
                 dirty.setDirty(true);
             }
         };
         composite.getRankMin().addSelectionChangedListener(event->dirty.setDirty(true));
         composite.getRankMax().addSelectionChangedListener(event->dirty.setDirty(true));
 
-        composite.getTextAreaText().addListener(SWT.MouseDown, event-> {
-            NamedArea area = NamedAreaSelectionDialog.select(shell, null, null);
-            if(area!=null){
-                composite.setArea(area);
+        composite.getBtnChooseArea().addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
+                NamedArea area = NamedAreaSelectionDialog.select(shell, null, null);
+                if(area!=null){
+                    composite.setArea(area);
+                }
+                dirty.setDirty(true);
+            }
+        });
+        composite.getBtnRemoveArea().addSelectionListener(new SelectionAdapter() {
+
+            @Override
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
+                composite.removeArea();
+                dirty.setDirty(true);
             }
-            dirty.setDirty(true);
         });
 
+        composite.getFeatureTreeEditorComposite().init(null, null, e->selectionService.setSelection(e.getSelection()), null, null);
+
         //add drag'n'drop support
         Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer()};
         composite.getTaxonNodeTree().addDropSupport(dndOperations, transfers, new TaxonNodeDropAdapter(this));
 
+        composite.getTaxonNodeTree().getTree().addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent e) {
+                if(e.character==SWT.DEL){
+                    IStructuredSelection selection = (IStructuredSelection) composite.getTaxonNodeTree().getSelection();
+                    if(selection.toList().stream().anyMatch(object->!(object instanceof TaxonNode))){
+                        MessagingUtils.warningDialog(Messages.WorkingSetEditor_DELETE_FAIL_TITLE, this.getClass(), Messages.WorkingSetEditor_DELETE_FAIL_MESSAGE);
+                        return;
+                    }
+                    Iterator<Object> iterator = selection.iterator();
+                    while(iterator.hasNext()){
+                        Object next = iterator.next();
+                        TaxonNode taxonNode = (TaxonNode) next;
+                        removeTaxonNode(taxonNode);
+                    }
+                }
+            }
+        });
+
     }
 
     public void init(UUID workingSetUuid) {
         this.workingSet = CdmStore.getService(IWorkingSetService.class).load(workingSetUuid);
-        if(workingSet.getTitleCache()!=null){
-            composite.getTxt_label().setText(workingSet.getTitleCache());
+        if(workingSet.getLabel()!=null){
+            composite.getTxt_label().setText(workingSet.getLabel());
         }
         if(workingSet.getDescriptiveSystem()!=null){
             composite.setCharacters(workingSet.getDescriptiveSystem());
@@ -131,13 +190,40 @@ public class WorkingSetEditor implements IE4SavablePart{
         if(geoFilter!=null && !geoFilter.isEmpty()){
             composite.setArea(geoFilter.iterator().next());
         }
+        Set<TaxonNode> taxonSubtreeFilter = workingSet.getTaxonSubtreeFilter();
+        if(taxonSubtreeFilter!=null){
+            composite.getTaxonNodeTree().setInput(taxonSubtreeFilter);
+        }
 
         composite.getTxt_label().addModifyListener(labelModifyListener);
     }
 
-    /**
-     * {@inheritDoc}
-     */
+    public void addTaxonNode(TaxonNode taxonNode){
+        //load into WS editor session
+        taxonNode = getCdmEntitySession().load(taxonNode, false);
+        Viewer taxonTreeViewer = getTaxonTreeViewer();
+        Object input = taxonTreeViewer.getInput();
+        Collection<TaxonNode> treeNodes;
+        if(input==null){
+            treeNodes = new ArrayList<>();
+        }
+        else{
+            treeNodes = (Collection<TaxonNode>) input;
+        }
+        treeNodes.add(taxonNode);
+        taxonTreeViewer.setInput(treeNodes);
+        dirty.setDirty(true);
+    }
+
+    private void removeTaxonNode(TaxonNode taxonNode){
+        Viewer taxonTreeViewer = getTaxonTreeViewer();
+        Collection<TaxonNode> input = (Collection<TaxonNode>) taxonTreeViewer.getInput();
+        input.remove(taxonNode);
+        workingSet.removeTaxonSubtree(taxonNode);
+        taxonTreeViewer.setInput(input);
+        dirty.setDirty(true);
+    }
+
     @Persist
     @Override
     public void save(IProgressMonitor monitor) {
@@ -148,26 +234,22 @@ public class WorkingSetEditor implements IE4SavablePart{
         }
         Object input = composite.getTaxonNodeTree().getInput();
         if(input!=null){
+            workingSet.setTaxonSubtreeFilter(new HashSet<>());//clear existing filter
             Collection<ITaxonTreeNode> taxonNodes = (Collection<ITaxonTreeNode>) input;
             for (ITaxonTreeNode taxonTreeNode : taxonNodes) {
                 if(taxonTreeNode instanceof TaxonNode){
                     TaxonNode taxonNode = (TaxonNode)taxonTreeNode;
                     workingSet.addTaxonSubtree(taxonNode);
-                    Set<NamedArea> descriptions;
-                    if(taxonNode!=null && taxonNode.getTaxon()!=null){
-                        Taxon taxon = HibernateProxyHelper.deproxy(taxonNode.getTaxon(), Taxon.class);
-                        Collection<SpecimenOrObservationBase> specimens = CdmStore.getService(IOccurrenceService.class).listByAssociatedTaxon(SpecimenOrObservationBase.class, null, taxon, null, null, null, null, null);
-                        for (SpecimenOrObservationBase specimen : specimens) {
-                            Set<SpecimenDescription> specimenDescriptions = specimen.getSpecimenDescriptions();
-                            for (SpecimenDescription specimenDescription : specimenDescriptions) {
-                                workingSet.addDescription(specimenDescription);
-                            }
-                        }
-                    }
                 }
             }
         }
         FeatureTree characters = composite.getCharacters();
+        if(characters!=null){
+            //save characters because they can be modified in this editor
+            characters.getDistinctFeatures().forEach(character->CdmStore.getService(ITermService.class).merge(character,true));
+        }
+
+
         DefinedTermBase rankMaxSelection = composite.getRankMax().getSelection();
         Rank rankMax = null;
         if(rankMaxSelection instanceof Rank){
@@ -190,23 +272,72 @@ public class WorkingSetEditor implements IE4SavablePart{
         dirty.setDirty(false);
     }
 
-    @Focus
-    public void setFocus(){
-        if(conversation!=null){
-            conversation.bind();
-        }
-    }
-
     @PreDestroy
-    public void dispose(){
-        if(conversation!=null){
+    public void dispose() {
+        if (conversation != null) {
             conversation.close();
             conversation = null;
         }
+        if(cdmEntitySession != null) {
+            cdmEntitySession.dispose();
+            cdmEntitySession = null;
+        }
+        dirty.setDirty(false);
+    }
+
+    @Focus
+    public void setFocus() {
+        if(composite!=null){
+            composite.setFocus();
+        }
+        if (getConversationHolder() != null) {
+            getConversationHolder().bind();
+        }
+        if(cdmEntitySession != null) {
+            cdmEntitySession.bind();
+        }
     }
 
     public Viewer getTaxonTreeViewer() {
         return composite.getTaxonNodeTree();
     }
 
+    public WorkingSet getWorkingSet() {
+        return workingSet;
+    }
+
+    @Override
+    public void update(CdmDataChangeMap arg0) {
+    }
+
+    @Override
+    public ICdmEntitySession getCdmEntitySession() {
+        return cdmEntitySession;
+    }
+
+    @Override
+    public Collection<WorkingSet> getRootEntities() {
+        return null;
+    }
+
+    @Override
+    public Map<Object, List<String>> getPropertyPathsMap() {
+        return null;
+    }
+
+    @Override
+    public ConversationHolder getConversationHolder() {
+        return conversation;
+    }
+
+    @Override
+    public void changed(Object element) {
+        dirty.setDirty(true);
+    }
+
+    @Override
+    public void forceDirty() {
+        dirty.setDirty(true);
+    }
+
 }