2 * Copyright (C) 2018 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.taxeditor
.editor
.descriptiveDataSet
.matrix
;
11 import java
.util
.ArrayList
;
12 import java
.util
.Collection
;
13 import java
.util
.HashSet
;
14 import java
.util
.Iterator
;
15 import java
.util
.List
;
17 import java
.util
.stream
.Collectors
;
19 import org
.apache
.commons
.lang3
.StringUtils
;
20 import org
.eclipse
.jface
.dialogs
.Dialog
;
21 import org
.eclipse
.jface
.viewers
.ArrayContentProvider
;
22 import org
.eclipse
.jface
.viewers
.ColumnLabelProvider
;
23 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
24 import org
.eclipse
.jface
.viewers
.ITableLabelProvider
;
25 import org
.eclipse
.jface
.viewers
.TableViewer
;
26 import org
.eclipse
.jface
.viewers
.TableViewerColumn
;
27 import org
.eclipse
.jface
.viewers
.Viewer
;
28 import org
.eclipse
.jface
.viewers
.ViewerComparator
;
29 import org
.eclipse
.swt
.SWT
;
30 import org
.eclipse
.swt
.custom
.ScrolledComposite
;
31 import org
.eclipse
.swt
.events
.FocusEvent
;
32 import org
.eclipse
.swt
.events
.FocusListener
;
33 import org
.eclipse
.swt
.events
.SelectionAdapter
;
34 import org
.eclipse
.swt
.events
.SelectionEvent
;
35 import org
.eclipse
.swt
.graphics
.Image
;
36 import org
.eclipse
.swt
.layout
.GridData
;
37 import org
.eclipse
.swt
.layout
.GridLayout
;
38 import org
.eclipse
.swt
.widgets
.Button
;
39 import org
.eclipse
.swt
.widgets
.Composite
;
40 import org
.eclipse
.swt
.widgets
.Control
;
41 import org
.eclipse
.swt
.widgets
.Label
;
42 import org
.eclipse
.swt
.widgets
.Shell
;
43 import org
.eclipse
.swt
.widgets
.Table
;
44 import org
.eclipse
.swt
.widgets
.Text
;
46 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptiveDataSetService
;
47 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
48 import eu
.etaxonomy
.cdm
.persistence
.dto
.SpecimenNodeWrapper
;
49 import eu
.etaxonomy
.taxeditor
.editor
.l10n
.Messages
;
50 import eu
.etaxonomy
.taxeditor
.model
.AbstractUtility
;
51 import eu
.etaxonomy
.taxeditor
.model
.ImageResources
;
52 import eu
.etaxonomy
.taxeditor
.preference
.Resources
;
53 import eu
.etaxonomy
.taxeditor
.store
.CdmStore
;
54 import eu
.etaxonomy
.taxeditor
.store
.StoreUtil
;
57 * Dialog to choose specimens for the character matrix.<br>
58 * Filters specimens that have already been added.
63 public class SpecimenSelectionDialog
extends Dialog
{
68 private static final String TAXONOMIC_SUBTREE_FILTER
= "Taxonomic Subtree Filter: ";
70 private static String TEXT_FILTER_DEFAULT
= "Enter text filter";
72 private TableViewer list
;
74 private Collection
<SpecimenNodeWrapper
> selectedSpecimens
= new ArrayList
<>();
75 private CharacterMatrix matrix
;
76 private Text txtTextFilter
;
77 private List
<String
> treeIndexList
;
78 private List
<String
> taxonTitleList
;
79 private Label l_title
;
83 public SpecimenSelectionDialog(Shell parentShell
, CharacterMatrix matrix
, List
<String
> treeIndex
, List
<String
> taxonTitleList
) {
86 this.treeIndexList
= treeIndex
;
87 this.taxonTitleList
= taxonTitleList
;
91 protected Control
createDialogArea(Composite parent
) {
92 Composite composite
= (Composite
) super.createDialogArea(parent
);
93 GridLayout gl_composite
= new GridLayout();
94 gl_composite
.numColumns
= 2;
95 composite
.setLayout(gl_composite
);
96 Composite composite_1
= new Composite(composite
, SWT
.NONE
);
97 composite_1
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false, 2, 2));
98 composite_1
.setLayout(new GridLayout(5, false));
100 l_title
= new Label(composite_1
, SWT
.NULL
);
101 l_title_filter
= new Label(composite_1
, SWT
.NULL
);
102 GridData gridData
= new GridData();
103 gridData
.horizontalAlignment
= GridData
.BEGINNING
;
104 gridData
.horizontalSpan
= 3;
105 l_title_filter
.setLayoutData(gridData
);
106 l_title
.setText(TAXONOMIC_SUBTREE_FILTER
);
107 if (taxonTitleList
!= null && !taxonTitleList
.isEmpty()){
108 Iterator
<String
> iterator
= taxonTitleList
.iterator();
109 String titleString
=iterator
.next();
110 while(iterator
.hasNext() ){
111 titleString
+= ", "+ iterator
.next();
113 l_title_filter
.setText(titleString
);
115 l_title_filter
.setText(" - ");
117 Button btnRemoveFilterButton
= new Button(composite_1
, SWT
.NONE
);
118 btnRemoveFilterButton
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false, 1, 1));
119 btnRemoveFilterButton
.setToolTipText(Messages
.SpecimenSelectionDialog_REMOVE_FILTER
);
120 btnRemoveFilterButton
.setImage(ImageResources
.getImage(ImageResources
.TRASH_ICON
));
121 btnRemoveFilterButton
.addSelectionListener(new SelectionAdapter() {
123 public void widgetSelected(SelectionEvent e
) {
124 // txtTextFilter.setText("");
125 treeIndexList
= null;
126 l_title
.setText(TAXONOMIC_SUBTREE_FILTER
);
127 l_title_filter
.setText(" - ");
132 Label l_textFilter
= new Label(composite_1
, SWT
.NULL
);
133 GridData data_label
= new GridData(SWT
.LEFT
, SWT
.CENTER
, false, false, 1, 1);
136 l_textFilter
.setLayoutData(data_label
);
137 l_textFilter
.setText("Specimen Filter");
138 l_textFilter
.setAlignment(SWT
.RIGHT
);
139 l_textFilter
.setToolTipText("Filters for taxon name and specimen titlecache");
140 txtTextFilter
= new Text(composite_1
, SWT
.BORDER
);
141 txtTextFilter
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, false, 2, 1));
142 txtTextFilter
.setText(TEXT_FILTER_DEFAULT
);
143 txtTextFilter
.addFocusListener(new FocusListener() {
146 public void focusGained(FocusEvent e
) {
147 txtTextFilter
.setForeground(AbstractUtility
.getColor(Resources
.SEARCH_VIEW_FOCUS
));
148 if (TEXT_FILTER_DEFAULT
.equals(txtTextFilter
.getText())) {
149 StoreUtil
.setTextWithoutModifyListeners(txtTextFilter
, "");
154 public void focusLost(FocusEvent e
) {
155 if (CdmUtils
.isBlank(txtTextFilter
.getText())){
156 txtTextFilter
.setForeground(AbstractUtility
.getColor(Resources
.SEARCH_VIEW_FOREGROUND
));
157 StoreUtil
.setTextWithoutModifyListeners(txtTextFilter
, TEXT_FILTER_DEFAULT
);
161 txtTextFilter
.addModifyListener(e
->applyFilter());
163 Button btnRefreshButton
= new Button(composite_1
, SWT
.NONE
);
164 btnRefreshButton
.setLayoutData(new GridData(SWT
.RIGHT
, SWT
.CENTER
, false, false, 1, 1));
165 btnRefreshButton
.setToolTipText(Messages
.SpecimenSelectionDialog_REFRESH
);
166 btnRefreshButton
.setImage(ImageResources
.getImage(ImageResources
.REFRESH
));
167 btnRefreshButton
.addSelectionListener(new SelectionAdapter() {
169 public void widgetSelected(SelectionEvent e
) {
177 Composite composite_2
= new Composite(composite
, SWT
.NONE
);
178 composite_2
.setLayoutData(new GridData(SWT
.FILL
, SWT
.TOP
, true, false, 2, 1));
179 composite_2
.setLayout(new GridLayout(2, false));
180 Label lblNewLabel
= new Label(composite_2
, SWT
.NONE
);
181 lblNewLabel
.setImage(ImageResources
.getImage(ImageResources
.WARNING_ICON
));
183 Label lblNewLabel_1
= new Label(composite_2
, SWT
.NONE
);
184 lblNewLabel_1
.setText(": Specimen not associated with taxon");
186 ScrolledComposite scrolledComposite
= new ScrolledComposite(composite
, SWT
.BORDER
| SWT
.H_SCROLL
| SWT
.V_SCROLL
);
187 scrolledComposite
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true, 2, 1));
188 scrolledComposite
.setExpandHorizontal(true);
189 scrolledComposite
.setExpandVertical(true);
191 list
= new TableViewer(scrolledComposite
, SWT
.H_SCROLL
| SWT
.V_SCROLL
| SWT
.FULL_SELECTION
| SWT
.MULTI
);
192 Table table
= list
.getTable();
195 TableViewerColumn columnTaxon
= new TableViewerColumn(list
, SWT
.NONE
);
196 columnTaxon
.getColumn().setText("Taxon");
197 columnTaxon
.getColumn().setWidth(200);
198 columnTaxon
.getColumn().setResizable(true);
199 columnTaxon
.getColumn().setMoveable(true);
200 TableViewerColumn columnType
= new TableViewerColumn(list
, SWT
.NONE
);
201 columnType
.getColumn().setText("Type");
202 columnType
.getColumn().setWidth(150);
203 columnType
.getColumn().setResizable(true);
204 columnType
.getColumn().setMoveable(true);
205 TableViewerColumn columnSpecimen
= new TableViewerColumn(list
, SWT
.NONE
);
206 columnSpecimen
.getColumn().setText("Specimen");
207 columnSpecimen
.getColumn().setResizable(true);
208 columnSpecimen
.getColumn().setMoveable(true);
209 columnSpecimen
.getColumn().setWidth(400);
211 table
.setHeaderVisible(true);
212 table
.setLinesVisible(true);
213 scrolledComposite
.setContent(table
);
214 scrolledComposite
.setMinSize(table
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
));
215 list
.setContentProvider(new ArrayContentProvider());
216 list
.setLabelProvider(new SpecimenListLabelProvider());
218 ViewerComparator comp
= new ViewerComparator() {
220 public int compare(Viewer viewer
, Object o1
, Object o2
) {
231 return ((SpecimenNodeWrapper
)o1
).getTaxonNode().getTitleCache().compareTo(((SpecimenNodeWrapper
)o2
).getTaxonNode().getTitleCache());
234 catch(NullPointerException e
){
241 list
.setComparator(comp
);
244 if(matrix
.getSpecimenCache()==null || matrix
.getSpecimenCache().isEmpty()){
247 if(treeIndexList
!=null){
248 filterByTaxonNode( null);
253 columnSpecimen
.getColumn().pack();
258 private void refreshInput(){
262 private void applyFilter(){
263 Set
<SpecimenNodeWrapper
> result
= new HashSet
<>();
264 Collection
<SpecimenNodeWrapper
> specimenCache
= matrix
.getSpecimenCache();
265 String text
= txtTextFilter
.getText();
267 //filter for treeIndexList is missing
268 if(CdmUtils
.isBlank(text
) || text
.equals(TEXT_FILTER_DEFAULT
)){
269 result
= new HashSet
<>(specimenCache
);
272 if(!txtTextFilter
.getForeground().equals(AbstractUtility
.getColor(Resources
.SEARCH_VIEW_FOREGROUND
))
273 &&!CdmUtils
.isBlank(text
)){
274 result
.addAll(specimenCache
.stream()
275 .filter(wrapper
->wrapper
.getUuidAndTitleCache().getTitleCache().toLowerCase().contains(text
.toLowerCase()))
276 .collect(Collectors
.toList()));
277 result
.addAll(specimenCache
.stream()
278 .filter(wrapper
->wrapper
.getTaxonNode().getTitleCache().toLowerCase().contains(text
.toLowerCase()))
279 .collect(Collectors
.toList()));
282 filterByTaxonNode(result
);
286 private void loadSpecimens(){
287 ArrayList
<SpecimenNodeWrapper
> specimenList
= new ArrayList
<>(CdmStore
.getService(IDescriptiveDataSetService
.class).loadSpecimens(matrix
.getDescriptiveDataSet().getUuid()));
288 // Collections.sort(specimenList, new Comparator<SpecimenNodeWrapper>() {
291 // public int compare(SpecimenNodeWrapper o1, SpecimenNodeWrapper o2) {
302 // return o1.getTaxonNode().getTitleCache().compareTo(o2.getTaxonNode().getTitleCache());
304 // catch(NullPointerException e){
309 matrix
.setSpecimenCache(specimenList
);
313 protected void configureShell(Shell newShell
) {
314 super.configureShell(newShell
);
315 newShell
.setText(Messages
.SpecimenSelectionDialog_SELECT_SPECIMENS
);
316 newShell
.setMinimumSize(500, 600);
317 newShell
.setSize(800, 600);
321 protected void okPressed() {
322 selectedSpecimens
.clear();
323 selectedSpecimens
= ((IStructuredSelection
)list
.getSelection()).toList();
328 protected boolean isResizable() {
332 public Collection
<SpecimenNodeWrapper
> getSpecimen(){
333 return selectedSpecimens
;
336 private class SpecimenListLabelProvider
extends ColumnLabelProvider
implements ITableLabelProvider
{
339 public String
getToolTipText(Object element
) {
340 if(element
instanceof SpecimenNodeWrapper
341 && ((SpecimenNodeWrapper
) element
).getTaxonDescriptionUuid()==null){
342 return "Does not have and IndividualsAssociation with the taxon";
348 public Image
getColumnImage(Object element
, int columnIndex
) {
349 if(element
instanceof SpecimenNodeWrapper
&& columnIndex
== 2
350 && ((SpecimenNodeWrapper
) element
).getTaxonDescriptionUuid()==null){
351 return ImageResources
.getImage(ImageResources
.WARNING_ICON
);
357 public String
getColumnText(Object element
, int columnIndex
) {
358 if(element
instanceof SpecimenNodeWrapper
){
359 SpecimenNodeWrapper wrapper
= (SpecimenNodeWrapper
)element
;
360 switch (columnIndex
) {
362 return wrapper
.getTaxonNode().getTitleCache();
364 return wrapper
.getType().getLabel();
366 return wrapper
.getUuidAndTitleCache().getTitleCache();
375 private void filterByTaxonNode( Collection
<SpecimenNodeWrapper
> specimenCache
){
376 Collection
<SpecimenNodeWrapper
> result
= new ArrayList
<>();
377 if (specimenCache
== null){
378 specimenCache
= matrix
.getSpecimenCache();
380 if (treeIndexList
!= null){
381 for (String treeIndex
: this.treeIndexList
){
382 if (StringUtils
.isNotBlank(treeIndex
)){
383 result
.addAll(specimenCache
.stream()
384 .filter(wrapper
->wrapper
.getTaxonNode().getTreeIndex().startsWith(treeIndex
))
385 .collect(Collectors
.toList()));
389 result
.addAll(specimenCache
);
393 list
.setInput(result
);