ref #7095 Add text filter to specimen selection dialog
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / workingSet / matrix / SpecimenSelectionDialog.java
index 9a349b931803d3358a5b0447bc0bc67eedc01048..4519564aba800e304aa8cd1a1dfa9b601692f862 100644 (file)
@@ -10,19 +10,23 @@ package eu.etaxonomy.taxeditor.editor.workingSet.matrix;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -35,9 +39,11 @@ import org.eclipse.swt.widgets.Text;
 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
 import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
 import eu.etaxonomy.cdm.api.service.config.FindOccurrencesConfigurator;
+import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.ImageResources;
 import eu.etaxonomy.taxeditor.store.CdmStore;
@@ -77,9 +83,11 @@ public class SpecimenSelectionDialog extends Dialog {
 
         txtTextFilter = new Text(composite_1, SWT.BORDER);
         txtTextFilter.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+        txtTextFilter.addModifyListener(e->applyFilter());
 
         comboTaxon = new TaxonNodeCombo(composite_1, SWT.NONE);
         comboTaxon.setInput(matrix.getWorkingSet().getTaxonSubtreeFilter());
+        comboTaxon.addSelectionChangedListener(e->applyFilter());
 
         Button btnRefreshButton = new Button(composite_1, SWT.NONE);
         btnRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
@@ -92,13 +100,30 @@ public class SpecimenSelectionDialog extends Dialog {
                 list.setInput(matrix.getSpecimenCache());
             }
         });
-        list = new TableViewer(composite);
+        //table
+        list = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
         Table table = list.getTable();
-        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
-        list.setContentProvider(new DescriptionContentProvider());
-        list.setLabelProvider(new LabelProvider());
-
-        //gather descriptions
+        GridData gd_table = GridDataFactory.fillDefaults().create();
+        gd_table.grabExcessHorizontalSpace = true;
+        gd_table.grabExcessVerticalSpace = true;
+        table.setLayoutData(gd_table);
+        //table columns
+        TableViewerColumn columnTaxon = new TableViewerColumn(list, SWT.NONE);
+        columnTaxon.getColumn().setText("Taxon");
+        columnTaxon.getColumn().setWidth(200);
+        columnTaxon.getColumn().setResizable(true);
+        columnTaxon.getColumn().setMoveable(true);
+        TableViewerColumn columnSpecimen = new TableViewerColumn(list, SWT.NONE);
+        columnSpecimen.getColumn().setText("Specimen");
+        columnSpecimen.getColumn().setWidth(200);
+        columnSpecimen.getColumn().setResizable(true);
+        columnSpecimen.getColumn().setMoveable(true);
+        table.setHeaderVisible(true);
+        table.setLinesVisible(true);
+        list.setContentProvider(new SpecimenListContentProvider());
+        list.setLabelProvider(new SpecimenListLabelProvider());
+
+        //gather specimens
         if(matrix.getSpecimenCache()==null){
             loadSpecimens();
         }
@@ -106,8 +131,23 @@ public class SpecimenSelectionDialog extends Dialog {
         return composite;
     }
 
+    private void applyFilter(){
+        Stream<SpecimenWrapper> filteredWrappers =matrix.getSpecimenCache().stream();
+        if(comboTaxon.getSelection()!=null){
+            filteredWrappers =
+                    filteredWrappers
+                    .filter(wrapper->wrapper.getTaxonNode().equals(comboTaxon.getSelection()));
+        }
+        if(!CdmUtils.isBlank(txtTextFilter.getText())){
+            filteredWrappers =
+                    filteredWrappers
+                    .filter(wrapper->wrapper.getLabel().toLowerCase().contains(txtTextFilter.getText().toLowerCase()));
+        }
+        list.setInput(filteredWrappers.collect(Collectors.toList()));
+    }
+
     private void loadSpecimens(){
-        Set<SpecimenOrObservationBase> specimens = new HashSet<>();
+        List<SpecimenWrapper> specimenCache = new ArrayList<>();
         //set filter parameters
         TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(matrix.getWorkingSet().getMinRank(), matrix.getWorkingSet().getMaxRank());
         matrix.getWorkingSet().getGeoFilter().forEach(area -> filter.orArea(area.getUuid()));
@@ -119,14 +159,16 @@ public class SpecimenSelectionDialog extends Dialog {
         for (UUID uuid : filteredNodes) {
             //TODO implement occurrence service for taxon nodes
             // let it return UuidAndTitleCache
-            Taxon taxon = taxonNodeService.load(uuid).getTaxon();
+            TaxonNode taxonNode = taxonNodeService.load(uuid);
+            Taxon taxon = taxonNode.getTaxon();
             if(taxon!=null){
                 FindOccurrencesConfigurator config = new FindOccurrencesConfigurator();
                 config.setAssociatedTaxonUuid(taxon.getUuid());
-                specimens.addAll(CdmStore.getService(IOccurrenceService.class).findByTitle(config).getRecords());
+                List<SpecimenOrObservationBase> specimensForTaxon = CdmStore.getService(IOccurrenceService.class).findByTitle(config).getRecords();
+                specimensForTaxon.forEach(specimen->specimenCache.add(new SpecimenWrapper(specimen, taxonNode, specimen.getTitleCache())));
             }
         }
-        matrix.setSpecimenCache(specimens);
+        matrix.setSpecimenCache(specimenCache);
     }
 
     @Override
@@ -136,29 +178,53 @@ public class SpecimenSelectionDialog extends Dialog {
         newShell.setMinimumSize(500, 400);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected void okPressed() {
-        selectedSpecimens = ((IStructuredSelection)list.getSelection()).toList();
+        selectedSpecimens.clear();
+        List<SpecimenWrapper> wrappers = ((IStructuredSelection)list.getSelection()).toList();
+        wrappers.forEach(element->selectedSpecimens.add(element.getSpecimen()));
         super.okPressed();
     }
 
+    @Override
+    protected boolean isResizable() {
+        return true;
+    }
+
     public Collection<SpecimenOrObservationBase> getSpecimen(){
         return selectedSpecimens;
     }
 
-    private class DescriptionContentProvider extends ArrayContentProvider{
-
-        /**
-         * {@inheritDoc}
-         */
+    private class SpecimenListContentProvider implements IStructuredContentProvider{
         @Override
         public Object[] getElements(Object inputElement) {
-            return ((Collection<SpecimenOrObservationBase>) inputElement).stream().filter(specimen ->
-                specimen.getDescriptions().stream().noneMatch(description ->
+            return ((List<SpecimenWrapper>) inputElement).stream().filter(wrapper ->
+                wrapper.getSpecimen().getDescriptions().stream().noneMatch(description ->
                 matrix.getWorkingSet().getDescriptions().contains(description))).toArray();
         }
     }
+
+    private class SpecimenListLabelProvider extends LabelProvider implements ITableLabelProvider{
+
+        @Override
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        @Override
+        public String getColumnText(Object element, int columnIndex) {
+            if(element instanceof SpecimenWrapper){
+                SpecimenWrapper wrapper = (SpecimenWrapper)element;
+                switch (columnIndex) {
+                case 0:
+                    return wrapper.getTaxonNode().getTaxon().getName().getTitleCache();
+                case 1:
+                    return wrapper.getSpecimen().getTitleCache();
+                default:
+                    break;
+                }
+            }
+            return "";
+        }
+    }
 }