commit 6ff2e71ed74be927ea56a60ad47fab30f19f8e55
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Wed Jan 17 13:47:59 2018 +0100

    ref #7095 Cache specimens for specimen selection dialog

diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
index 78089ebf5..da8539157 100644
--- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
+++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/CharacterMatrix.java
@@ -185,6 +185,8 @@ public class CharacterMatrix implements IE4SavablePart, IPartContentHasDetails,
 
     private EventList<RowWrapper> descriptions;
 
+    private Collection<SpecimenOrObservationBase> specimenCache = null;
+
     @PostConstruct
     public void create(Composite parent) {
         if(CdmStore.isActive() && conversation==null){
@@ -560,7 +562,7 @@ public class CharacterMatrix implements IE4SavablePart, IPartContentHasDetails,
         btnAddDescription.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
-                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(natTable.getShell(), workingSet);
+                SpecimenSelectionDialog dialog = new SpecimenSelectionDialog(natTable.getShell(), CharacterMatrix.this);
                 if(dialog.open()==Window.OK){
                     Collection<SpecimenOrObservationBase> specimens = dialog.getSpecimen();
                     boolean hasAdded = false;
@@ -744,6 +746,18 @@ public class CharacterMatrix implements IE4SavablePart, IPartContentHasDetails,
         return natTable;
     }
 
+    public WorkingSet getWorkingSet() {
+        return workingSet;
+    }
+
+    public Collection<SpecimenOrObservationBase> getSpecimenCache() {
+        return specimenCache;
+    }
+
+    public void setSpecimenCache(Collection<SpecimenOrObservationBase> specimenCache) {
+        this.specimenCache = specimenCache;
+    }
+
     @Persist
     @Override
     public void save(IProgressMonitor monitor) {
diff --git a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenSelectionDialog.java b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenSelectionDialog.java
index b2bbc3347..953a71ae8 100644
--- a/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenSelectionDialog.java
+++ b/eu.etaxonomy.taxeditor.editor/src/main/java/eu/etaxonomy/taxeditor/editor/workingSet/matrix/SpecimenSelectionDialog.java
@@ -20,18 +20,24 @@ import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
 
 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.filter.TaxonNodeFilter;
-import eu.etaxonomy.cdm.model.description.WorkingSet;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.taxeditor.model.ImageResources;
 import eu.etaxonomy.taxeditor.store.CdmStore;
 
 /**
@@ -43,30 +49,50 @@ public class SpecimenSelectionDialog extends Dialog {
 
     private TableViewer list;
 
-    private WorkingSet workingSet;
+    private Collection<SpecimenOrObservationBase> selectedSpecimens = new ArrayList<>();
+    private CharacterMatrix matrix;
 
-    Collection<SpecimenOrObservationBase> selectedSpecimens = new ArrayList<>();
-
-    protected SpecimenSelectionDialog(Shell parentShell, WorkingSet workingSet) {
+    protected SpecimenSelectionDialog(Shell parentShell, CharacterMatrix matrix) {
         super(parentShell);
-        this.workingSet = workingSet;
+        this.matrix = matrix;
     }
 
     @Override
     protected Control createDialogArea(Composite parent) {
         Composite composite = (Composite) super.createDialogArea(parent);
-        composite.setLayout(new FillLayout());
+        composite.setLayout(new GridLayout());
+
+        Button btnRefreshButton = new Button(composite, SWT.NONE);
+        btnRefreshButton.setToolTipText("Refresh");
+        btnRefreshButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+        btnRefreshButton.setImage(ImageResources.getImage(ImageResources.REFRESH));
+        btnRefreshButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                loadSpecimens();
+                list.setInput(matrix.getSpecimenCache());
+            }
+        });
         list = new TableViewer(composite);
+        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
-        Set<SpecimenOrObservationBase> specimens = new HashSet<>();
+        if(matrix.getSpecimenCache()==null){
+            loadSpecimens();
+        }
+        list.setInput(matrix.getSpecimenCache());
+        return composite;
+    }
 
+    private void loadSpecimens(){
+        Set<SpecimenOrObservationBase> specimens = new HashSet<>();
         //set filter parameters
-        TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(workingSet.getMinRank(), workingSet.getMaxRank());
-        workingSet.getGeoFilter().forEach(area -> filter.orArea(area.getUuid()));
-        workingSet.getTaxonSubtreeFilter().forEach(node -> filter.orSubtree(node));
+        TaxonNodeFilter filter = TaxonNodeFilter.NewRankInstance(matrix.getWorkingSet().getMinRank(), matrix.getWorkingSet().getMaxRank());
+        matrix.getWorkingSet().getGeoFilter().forEach(area -> filter.orArea(area.getUuid()));
+        matrix.getWorkingSet().getTaxonSubtreeFilter().forEach(node -> filter.orSubtree(node));
 
         ITaxonNodeService taxonNodeService = CdmStore.getService(ITaxonNodeService.class);
         List<UUID> filteredNodes = taxonNodeService.uuidList(filter);
@@ -80,8 +106,7 @@ public class SpecimenSelectionDialog extends Dialog {
                 specimens.addAll(CdmStore.getService(IOccurrenceService.class).findByTitle(config).getRecords());
             }
         }
-        list.setInput(specimens);
-        return composite;
+        matrix.setSpecimenCache(specimens);
     }
 
     @Override
@@ -113,7 +138,7 @@ public class SpecimenSelectionDialog extends Dialog {
         public Object[] getElements(Object inputElement) {
             return ((Collection<SpecimenOrObservationBase>) inputElement).stream().filter(specimen ->
                 specimen.getDescriptions().stream().noneMatch(description ->
-                workingSet.getDescriptions().contains(description))).toArray();
+                matrix.getWorkingSet().getDescriptions().contains(description))).toArray();
         }
     }
 }
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/ImageResources.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/ImageResources.java
index 237fbc38a..b3bccc30d 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/ImageResources.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/model/ImageResources.java
@@ -120,6 +120,7 @@ public class ImageResources {
 	public static final String LOCK_ICON = "lock";
 
 	public static final String SYNCED = "synced";
+	public static final String REFRESH = "refresh";
 
 	/** Constant <code>LOCK_OPEN_ICON="lock_open"</code> */
 	public static final String LOCK_OPEN_ICON = "lock_open";
@@ -347,6 +348,8 @@ public class ImageResources {
 		        "lock.png");
 		registerImage(registry, SYNCED,
 		        "synced.gif");
+		registerImage(registry, REFRESH,
+		        "refresh.gif");
 		registerImage(registry, LOCK_OPEN_ICON,
 		        "lock_open.png");
 		registerImage(registry, SWITCH_VIEW_TYPE,
