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;
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 org.eclipse.swt.widgets.Text;
import eu.etaxonomy.cdm.api.service.IOccurrenceService;
-import eu.etaxonomy.cdm.api.service.ITaxonService;
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
-import eu.etaxonomy.cdm.model.description.WorkingSet;
-import eu.etaxonomy.cdm.model.name.Rank;
-import eu.etaxonomy.cdm.model.name.TaxonName;
+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;
+import eu.etaxonomy.taxeditor.ui.combo.taxon.TaxonNodeCombo;
/**
+ * Dialog to choose specimens for the character matrix.<br>
+ * Filters specimens that have already been added.
* @author pplitzner
* @since Jan 3, 2018
*
private TableViewer list;
- private WorkingSet workingSet;
+ private Collection<SpecimenOrObservationBase> selectedSpecimens = new ArrayList<>();
+ private CharacterMatrix matrix;
+ private Text txtTextFilter;
- Collection<SpecimenOrObservationBase> selectedSpecimens = new ArrayList<>();
+ private TaxonNodeCombo comboTaxon;
- 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);
- list = new TableViewer(composite);
- list.setContentProvider(new ArrayContentProvider());
- list.setLabelProvider(new DescriptionLabelProvider());
-
- //gather descriptions
- Set<TaxonNode> taxonNodes = workingSet.getTaxonSubtreeFilter();
- Set<SpecimenOrObservationBase> specimens = new HashSet<>();
- for (TaxonNode node : taxonNodes) {
- specimens.addAll(addSpecimensRecursively(node));
+ GridLayout gl_composite = new GridLayout();
+ composite.setLayout(gl_composite);
+
+ Composite composite_1 = new Composite(composite, SWT.NONE);
+ composite_1.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+ composite_1.setLayout(new GridLayout(3, false));
+
+ 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));
+ btnRefreshButton.setToolTipText(Messages.SpecimenSelectionDialog_REFRESH);
+ btnRefreshButton.setImage(ImageResources.getImage(ImageResources.REFRESH));
+ btnRefreshButton.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ loadSpecimens();
+ list.setInput(matrix.getSpecimenCache());
+ }
+ });
+ //table
+ list = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
+ Table table = list.getTable();
+ 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();
}
- list.setInput(specimens);
+ list.setInput(matrix.getSpecimenCache());
return composite;
}
- private Collection<SpecimenOrObservationBase> addSpecimensRecursively(TaxonNode node){
- Collection<SpecimenOrObservationBase> specimens = new HashSet<>();
- if(node.getTaxon()!=null){
- Taxon taxon = HibernateProxyHelper.deproxy(node.getTaxon(), Taxon.class);
- TaxonName name = taxon.getName();
- //filter by Rank
- if(name!=null &&
- (name.getRank().equals(workingSet.getMinRank())
- || name.getRank().isHigher(workingSet.getMinRank())
- || name.getRank().equals(workingSet.getMaxRank())
- || name.getRank().isLower(workingSet.getMaxRank()))){
- IOccurrenceService service = CdmStore.getService(IOccurrenceService.class);
- //TODO extend FindOccurrencesConfigurator to support area and rank filter
- // FindOccurrencesConfigurator config = new FindOccurrencesConfigurator();
- // config.setAssociatedTaxonNameUuid(taxon.getUuid());
- // service.findByTitle(config);
-
- specimens = service.listByAssociatedTaxon(SpecimenOrObservationBase.class, null, taxon, null, null, null, null, null);
- }
+ private void applyFilter(){
+ Stream<SpecimenWrapper> filteredWrappers =matrix.getSpecimenCache().stream();
+ if(comboTaxon.getSelection()!=null){
+ filteredWrappers =
+ filteredWrappers
+ .filter(wrapper->wrapper.getTaxonNode().equals(comboTaxon.getSelection()));
}
- List<TaxonNode> childNodes = node.getChildNodes();
- for (TaxonNode childNode : childNodes) {
- specimens.addAll(addSpecimensRecursively(childNode));
+ if(!CdmUtils.isBlank(txtTextFilter.getText())){
+ filteredWrappers =
+ filteredWrappers
+ .filter(wrapper->wrapper.getLabel().toLowerCase().contains(txtTextFilter.getText().toLowerCase()));
}
- return specimens;
+ list.setInput(filteredWrappers.collect(Collectors.toList()));
+ }
+
+ private void loadSpecimens(){
+ 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()));
+ matrix.getWorkingSet().getTaxonSubtreeFilter().forEach(node -> filter.orSubtree(node));
+ filter.setIncludeUnpublished(true);
+
+ ITaxonNodeService taxonNodeService = CdmStore.getService(ITaxonNodeService.class);
+ List<UUID> filteredNodes = taxonNodeService.uuidList(filter);
+ for (UUID uuid : filteredNodes) {
+ //TODO implement occurrence service for taxon nodes
+ // let it return UuidAndTitleCache
+ TaxonNode taxonNode = taxonNodeService.load(uuid);
+ Taxon taxon = taxonNode.getTaxon();
+ if(taxon!=null){
+ FindOccurrencesConfigurator config = new FindOccurrencesConfigurator();
+ config.setAssociatedTaxonUuid(taxon.getUuid());
+ List<SpecimenOrObservationBase> specimensForTaxon = CdmStore.getService(IOccurrenceService.class).findByTitle(config).getRecords();
+ specimensForTaxon.forEach(specimen->specimenCache.add(new SpecimenWrapper(specimen, taxonNode, specimen.getTitleCache())));
+ }
+ }
+ matrix.setSpecimenCache(specimenCache);
+ }
+
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(Messages.SpecimenSelectionDialog_SELECT_SPECIMENS);
+ 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 DescriptionLabelProvider extends LabelProvider{
- /**
- * {@inheritDoc}
- */
+ private class SpecimenListContentProvider implements IStructuredContentProvider{
@Override
- public Image getImage(Object element) {
- if(workingSet.getDescriptions().contains(element)){
- return ImageResources.getImage(ImageResources.SYNCED);
- }
+ public Object[] getElements(Object inputElement) {
+ 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 "";
+ }
}
}