ref #8146 Adapt character matrix to termType model change
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / descriptiveDataSet / DescriptiveDataSetEditor.java
index fc6625c0826c383fcfbd68d7ec545b5be0ccad36..abde54554a43a13dfef148c808fdf1a28af479cf 100644 (file)
@@ -17,6 +17,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -29,14 +30,19 @@ import org.eclipse.e4.core.contexts.IEclipseContext;
 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.EMenuService;
 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.StructuredSelection;
 import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.DND;
 import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.KeyAdapter;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.ModifyEvent;
@@ -48,26 +54,28 @@ import org.eclipse.swt.widgets.Shell;
 
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
+import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
 import eu.etaxonomy.cdm.api.service.ITermService;
-import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
-import eu.etaxonomy.cdm.model.description.FeatureTree;
+import eu.etaxonomy.cdm.model.common.TermType;
 import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
+import eu.etaxonomy.cdm.model.description.FeatureTree;
 import eu.etaxonomy.cdm.model.location.NamedArea;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
 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.IPartContentHasSupplementalData;
 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;
 
@@ -78,7 +86,7 @@ import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
  *
  */
 public class DescriptiveDataSetEditor implements IE4SavablePart, IConversationEnabled, ICdmEntitySessionEnabled,
-IPartContentHasDetails, IDirtyMarkable {
+IPartContentHasDetails, IPartContentHasSupplementalData, IDirtyMarkable {
 
     private DescriptiveDataSetComposite composite;
 
@@ -99,7 +107,8 @@ IPartContentHasDetails, IDirtyMarkable {
     private ModifyListener labelModifyListener;
 
     @PostConstruct
-    public void create(Composite parent, IEclipseContext context, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell){
+    public void create(Composite parent, IEclipseContext context, @Named(IServiceConstants.ACTIVE_SHELL)Shell shell,
+            EMenuService menuService){
         if (CdmStore.isActive()){
             if(conversation == null){
                 conversation = CdmStore.createConversation();
@@ -124,29 +133,46 @@ IPartContentHasDetails, IDirtyMarkable {
             }
         };
         composite.getRankMin().addSelectionChangedListener(event->dirty.setDirty(true));
+        composite.getRankMin().setText("Select min rank...");
         composite.getRankMax().addSelectionChangedListener(event->dirty.setDirty(true));
-
-        composite.getBtnChooseArea().addSelectionListener(new SelectionAdapter() {
-
+        composite.getRankMin().setText("Select max rank...");
+        composite.getBtnRemoveRankMin().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);
-                }
+             composite.getRankMin().setElement(null);
+             dirty.setDirty(true);
+            }
+        });
+        composite.getBtnRemoveRankMax().addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
+                composite.getRankMax().setElement(null);
                 dirty.setDirty(true);
             }
         });
-        composite.getBtnRemoveArea().addSelectionListener(new SelectionAdapter() {
+
+        composite.getBtnChooseArea().addSelectionListener(new SelectionAdapter() {
 
             @Override
             public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
-                composite.removeArea();
-                dirty.setDirty(true);
+                AreasSelectionDialog areasSelectionDialog = new AreasSelectionDialog(composite.getShell(), composite.getAreas());
+                if(areasSelectionDialog.open()==Window.OK){
+                    List<TermDto> selectedAreas = areasSelectionDialog.getSelectedAreas();
+                    if(selectedAreas!=null){
+                        composite.setAreas(selectedAreas);
+                        dirty.setDirty(true);
+                    }
+                }
             }
         });
 
-        composite.getFeatureTreeEditorComposite().init(null, null, e->selectionService.setSelection(e.getSelection()), this, null);
+        composite.getFeatureTreeEditorComposite().init("Character Tree",
+                TermType.Character,
+                null,
+                null,
+                e->selectionService.setSelection(e.getSelection()),
+                this,
+                null);
 
         //add drag'n'drop support
         Transfer[] transfers = new Transfer[] {LocalSelectionTransfer.getTransfer()};
@@ -156,21 +182,15 @@ IPartContentHasDetails, IDirtyMarkable {
             @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.DescriptiveDataSetEditor_DELETE_FAIL_TITLE, this.getClass(), Messages.DescriptiveDataSetEditor_DELETE_FAIL_MESSAGE);
-                        return;
-                    }
-                    Iterator<Object> iterator = selection.iterator();
-                    while(iterator.hasNext()){
-                        Object next = iterator.next();
-                        TaxonNode taxonNode = (TaxonNode) next;
-                        removeTaxonNode(taxonNode);
-                    }
+                    removeSelectedTaxonNodes();
                 }
             }
         });
 
+
+        //create context menu
+        menuService.registerContextMenu(composite.getTaxonNodeTree().getControl(), "eu.etaxonomy.taxeditor.editor.descriptiveDataSet.DescriptiveDataSetEditor.popupmenu.specimeneditor");
+
     }
 
     public void init(UUID descriptiveDataSetUuid) {
@@ -191,14 +211,22 @@ IPartContentHasDetails, IDirtyMarkable {
         }
         Set<NamedArea> geoFilter = descriptiveDataSet.getGeoFilter();
         if(geoFilter!=null && !geoFilter.isEmpty()){
-            composite.setArea(geoFilter.iterator().next());
+            Set<TermDto> terms = geoFilter.stream().map(filter->TermDto.fromTerm(filter, true)).collect(Collectors.toSet());
+            composite.setAreas(new ArrayList<>(terms));
         }
         Set<TaxonNode> taxonSubtreeFilter = descriptiveDataSet.getTaxonSubtreeFilter();
         if(taxonSubtreeFilter!=null){
             composite.getTaxonNodeTree().setInput(taxonSubtreeFilter);
         }
-
         composite.getTxt_label().addModifyListener(labelModifyListener);
+        composite.getTxt_label().addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                super.focusGained(e);
+                selectionService.setSelection(new StructuredSelection(descriptiveDataSet));
+            }
+        });
+        selectionService.setSelection(new StructuredSelection(descriptiveDataSet));
     }
 
     public void addTaxonNode(TaxonNodeDto taxonNodeDto){
@@ -226,11 +254,21 @@ IPartContentHasDetails, IDirtyMarkable {
         dirty.setDirty(true);
     }
 
-    private void removeTaxonNode(TaxonNode taxonNode){
+    public void removeSelectedTaxonNodes(){
+        IStructuredSelection selection = (IStructuredSelection) composite.getTaxonNodeTree().getSelection();
+        if(selection.toList().stream().anyMatch(object->!(object instanceof TaxonNode))){
+            MessagingUtils.warningDialog(Messages.DescriptiveDataSetEditor_DELETE_FAIL_TITLE, this.getClass(), Messages.DescriptiveDataSetEditor_DELETE_FAIL_MESSAGE);
+            return;
+        }
+        Iterator<Object> iterator = selection.iterator();
         Viewer taxonTreeViewer = getTaxonTreeViewer();
         Collection<TaxonNode> input = (Collection<TaxonNode>) taxonTreeViewer.getInput();
-        input.remove(taxonNode);
-        descriptiveDataSet.removeTaxonSubtree(taxonNode);
+        while(iterator.hasNext()){
+            Object next = iterator.next();
+            TaxonNode taxonNode = (TaxonNode) next;
+            input.remove(taxonNode);
+            descriptiveDataSet.removeTaxonSubtree(taxonNode);
+        }
         taxonTreeViewer.setInput(input);
         dirty.setDirty(true);
     }
@@ -238,11 +276,7 @@ IPartContentHasDetails, IDirtyMarkable {
     @Persist
     @Override
     public void save(IProgressMonitor monitor) {
-        NamedArea area = composite.getArea();
-        Set<NamedArea> areas = new HashSet<>();
-        if(area!=null){
-            areas.add(area);
-        }
+        Collection<TermDto> areas = composite.getAreas();
         Object input = composite.getTaxonNodeTree().getInput();
         if(input!=null){
             descriptiveDataSet.setTaxonSubtreeFilter(new HashSet<>());//clear existing filter
@@ -275,7 +309,11 @@ IPartContentHasDetails, IDirtyMarkable {
         descriptiveDataSet.setMaxRank(rankMax);
         descriptiveDataSet.setMinRank(rankMin);
         descriptiveDataSet.setDescriptiveSystem(characters);
-        descriptiveDataSet.setGeoFilter(areas);
+        List<DefinedTermBase> terms = CdmStore.getService(ITermService.class)
+                .load(areas.stream().map(area -> area.getUuid()).collect(Collectors.toList()), null);
+        Set<NamedArea> areaTerms = new HashSet<>();
+        terms.forEach(term->areaTerms.add((NamedArea) term));
+        descriptiveDataSet.setGeoFilter(areaTerms);
 
         conversation.commit();
         CdmStore.getService(IDescriptiveDataSetService.class).merge(descriptiveDataSet, true);
@@ -283,6 +321,11 @@ IPartContentHasDetails, IDirtyMarkable {
         dirty.setDirty(false);
     }
 
+    @Override
+    public boolean isDirty() {
+        return dirty.isDirty();
+    }
+
     @PreDestroy
     public void dispose() {
         if (conversation != null) {