ref #8677: layout and labeling in aggregation config wizard
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / dialog / configurator / DistributionAggregationWizardPage.java
1 /**
2 * Copyright (C) 2019 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
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.
8 */
9 package eu.etaxonomy.taxeditor.ui.dialog.configurator;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collections;
14 import java.util.Comparator;
15 import java.util.EnumSet;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.eclipse.jface.layout.GridLayoutFactory;
22 import org.eclipse.jface.viewers.ArrayContentProvider;
23 import org.eclipse.jface.viewers.CheckStateChangedEvent;
24 import org.eclipse.jface.viewers.CheckboxTableViewer;
25 import org.eclipse.jface.viewers.ICheckStateListener;
26 import org.eclipse.jface.viewers.LabelProvider;
27 import org.eclipse.jface.wizard.WizardDialog;
28 import org.eclipse.jface.wizard.WizardPage;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.SelectionAdapter;
31 import org.eclipse.swt.events.SelectionEvent;
32 import org.eclipse.swt.events.SelectionListener;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Button;
36 import org.eclipse.swt.widgets.Combo;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Event;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Listener;
41
42 import eu.etaxonomy.cdm.api.application.CdmApplicationState;
43 import eu.etaxonomy.cdm.api.service.IClassificationService;
44 import eu.etaxonomy.cdm.api.service.ITermTreeService;
45 import eu.etaxonomy.cdm.api.service.description.DescriptionAggregationConfigurationBase.AggregationMode;
46 import eu.etaxonomy.cdm.api.service.description.DescriptionAggregationConfigurationBase.SourceMode;
47 import eu.etaxonomy.cdm.api.service.description.DistributionAggregationConfiguration;
48 import eu.etaxonomy.cdm.filter.LogicFilter;
49 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
50 import eu.etaxonomy.cdm.model.name.Rank;
51 import eu.etaxonomy.cdm.model.name.TaxonName;
52 import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
53 import eu.etaxonomy.cdm.model.taxon.Classification;
54 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
55 import eu.etaxonomy.cdm.model.term.TermTree;
56 import eu.etaxonomy.cdm.model.term.TermType;
57 import eu.etaxonomy.taxeditor.l10n.Messages;
58 import eu.etaxonomy.taxeditor.store.CdmStore;
59 import eu.etaxonomy.taxeditor.store.StoreUtil;
60 import eu.etaxonomy.taxeditor.ui.dialog.SuperAreaSelectionWizard;
61
62 /**
63 * @author k.luther
64 * @since 15.11.2019
65 */
66 public class DistributionAggregationWizardPage extends WizardPage implements Listener, SelectionListener{
67
68 private DistributionAggregationConfiguration configurator;
69
70 private Combo comboHigherRank;
71 private Combo comboLowerRank;
72
73 private Combo comboSourceMode;
74
75 private CheckboxTableViewer aggregationModeViewer;
76
77 private Button btnSelectSuperAreas;
78 private Button buttonSuperArea;
79 private Combo comboAreaLevel;
80 private Combo comboStatusOrder;
81
82
83 private Combo comboClassificationSelection;
84 private List<Classification> classifications;
85 private Classification selectedClassification;
86
87
88
89 private Button checkUseSelectedTaxonNode;
90 private Button checkUseSelectedClassification;
91 private Button checkUseSelectedSubtree;
92
93
94 private Button checkExportUnpublished;
95
96 private TaxonNode subTreeNode;
97 private CheckboxTableViewer sourceTypeViewer;
98 Object[] checkedElements;
99 Map<String, OriginalSourceType> typeMap = new HashMap();
100
101
102 /**
103 * @param pageName
104 */
105 public DistributionAggregationWizardPage(DistributionAggregationConfiguration configurator) {
106 super("Set Publish Flag Configuration");
107 this.configurator = configurator;
108
109 this.setDescription("Configure the aggregation");
110
111 }
112
113
114 @Override
115 public void createControl(Composite parent) {
116 final Composite composite = new Composite(parent, SWT.NULL);
117
118 String taxonStr = "";
119 int count = configurator.getTaxonNodeFilter().getSubtreeFilter().size();
120
121 for (LogicFilter<TaxonNode> filter: configurator.getTaxonNodeFilter().getSubtreeFilter()){
122 subTreeNode = CdmApplicationState.getCurrentAppConfig().getTaxonNodeService().load(filter.getUuid());
123 count--;
124 if (subTreeNode.hasTaxon()){
125 taxonStr += subTreeNode.getTaxon().getName().getTitleCache();
126 if (count>0){
127 taxonStr += ", ";
128 }
129 }
130 }
131 if (StringUtils.isNotBlank(taxonStr)){
132 checkUseSelectedSubtree= new Button(composite, SWT.RADIO);
133 checkUseSelectedSubtree.setText("Aggregation for selected subtree(s) "+ taxonStr);
134 checkUseSelectedSubtree.addListener(SWT.Selection, new Listener() {
135 @Override
136 public void handleEvent(Event e) {
137 Button b = (Button) e.widget;
138 GridData data = (GridData) comboClassificationSelection.getLayoutData();
139 data.exclude = b.getSelection();
140 comboClassificationSelection.setEnabled(!data.exclude);
141
142 updateHigherRankCombo();
143 }
144 });
145
146 checkUseSelectedTaxonNode= new Button(composite, SWT.RADIO);
147 checkUseSelectedTaxonNode.setText("Aggregation only for "+ taxonStr);
148 checkUseSelectedTaxonNode.addListener(SWT.Selection, new Listener() {
149 @Override
150 public void handleEvent(Event e) {
151 Button b = (Button) e.widget;
152 GridData data = (GridData) comboClassificationSelection.getLayoutData();
153 data.exclude = b.getSelection();
154 comboClassificationSelection.setEnabled(!data.exclude);
155 updateHigherRankCombo();
156 }
157
158
159 });
160 }
161 checkUseSelectedClassification= new Button(composite, SWT.RADIO);
162 checkUseSelectedClassification.setText("Aggregate selected classification");
163 checkUseSelectedClassification.addListener(SWT.Selection, new Listener() {
164 @Override
165 public void handleEvent(Event e) {
166 Button b = (Button) e.widget;
167 GridData data = (GridData) comboClassificationSelection.getLayoutData();
168 data.exclude = b.getSelection();
169 comboClassificationSelection.setEnabled(data.exclude);
170 updateHigherRankCombo();
171 }
172 });
173
174 GridLayoutFactory.fillDefaults();
175
176 if (subTreeNode!= null){
177 selectedClassification = subTreeNode.getClassification();
178 }
179 GridData gridDataClassificationCombo = new GridData();
180 gridDataClassificationCombo = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);
181 gridDataClassificationCombo.horizontalIndent = 5;
182
183 comboClassificationSelection = new Combo(composite, SWT.BORDER| SWT.READ_ONLY);
184 comboClassificationSelection.setLayoutData(gridDataClassificationCombo);
185 classifications = CdmStore.getService(IClassificationService.class).list(null, null, null, null, null);
186 Collections.sort(classifications, new Comparator<Classification>() {
187
188 @Override
189 public int compare(Classification o1, Classification o2) {
190 if (o1.equals(o2)){
191 return 0;
192 }
193 int result = o1.getTitleCache().compareTo(o2.getTitleCache());
194 if (result == 0){
195 return o1.getUuid().compareTo(o2.getUuid());
196 }
197 return result;
198 }
199 });
200 for(Classification tree : classifications){
201 comboClassificationSelection.add(tree.getName().getText(), classifications.indexOf(tree));
202
203 }
204
205 comboClassificationSelection.select(classifications.indexOf(selectedClassification));
206 comboClassificationSelection.addSelectionListener(this);
207
208 if (StringUtils.isNotBlank(taxonStr)){
209 checkUseSelectedSubtree.setSelection(true);
210 comboClassificationSelection.setEnabled(false);
211 }else{
212 checkUseSelectedClassification.setSelection(true);
213 }
214 Label separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
215 GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
216 gridData.horizontalSpan = 2;
217 gridData.verticalIndent = 5;
218 separator.setLayoutData(gridData);
219
220 GridLayout gridLayout = new GridLayout();
221 gridLayout.numColumns = 1;
222
223 composite.setLayout(gridLayout);
224 final Composite control = new Composite(composite, SWT.NULL);
225 GridLayout gridLayoutControl = new GridLayout();
226 gridLayoutControl.numColumns = 2;
227 control.setLayout(gridLayoutControl);
228 control.setLayoutData(new GridData(SWT.FILL, SWT.LEFT, true, true));
229
230 Label higherRankLabel = new Label(control, SWT.NULL);
231 higherRankLabel.setText("Highest rank");
232 comboHigherRank = new Combo(control, SWT.BORDER | SWT.READ_ONLY);
233 updateHigherRankCombo();
234 comboHigherRank.addListener(SWT.Selection, this);
235 Label lowerRankLabel = new Label(control, SWT.NULL);
236 lowerRankLabel.setText("Lowest rank");
237 comboLowerRank = new Combo(control, SWT.BORDER | SWT.READ_ONLY);
238 updateLowerRankCombo();
239 comboLowerRank.addListener(SWT.Selection, this);
240
241 separator = new Label(composite, SWT.HORIZONTAL | SWT.SEPARATOR);
242 gridData = new GridData(GridData.FILL_HORIZONTAL);
243 gridData.horizontalSpan = 2;
244 gridData.verticalIndent = 5;
245 separator.setLayoutData(gridData);
246
247 Label aggregationModeLabel = new Label(control, SWT.NULL);
248 aggregationModeLabel.setText("Aggregation mode");
249 aggregationModeLabel.setToolTipText("Selecting none would delete all existing aggregated distributions");
250 aggregationModeViewer = CheckboxTableViewer.newCheckList(control, SWT.BORDER | SWT.SINGLE);
251 aggregationModeViewer.setContentProvider(new ArrayContentProvider());
252 aggregationModeViewer.setLabelProvider(new LabelProvider(){
253 @Override
254 public String getText(Object element){
255 if (element instanceof AggregationMode){
256 if (((AggregationMode)element).equals(AggregationMode.ToParent)){
257 return "From child to parent taxon";
258 }
259 if (((AggregationMode)element).equals(AggregationMode.WithinTaxon)){
260 return "From sub area to super area";
261 }
262 }
263 return null;
264 }
265
266 });
267 List<AggregationMode> aggregationModeList = new ArrayList<>();
268 for (AggregationMode mode: AggregationMode.values()){
269 aggregationModeList.add(mode);
270 }
271
272 aggregationModeViewer.setInput(aggregationModeList);
273
274 aggregationModeViewer.addCheckStateListener(new ICheckStateListener(){
275 @Override
276 public void checkStateChanged( CheckStateChangedEvent event){
277 Object[] checked =aggregationModeViewer.getCheckedElements();
278 boolean areachecked = false;
279 for (int i = 0; i<checked.length;i++){
280 if (checked[i] instanceof AggregationMode){
281 if (((AggregationMode)checked[i]).equals(AggregationMode.WithinTaxon)){
282 areachecked = true;
283 }
284 }
285 }
286 comboAreaLevel.setEnabled(areachecked);
287 buttonSuperArea.setEnabled(areachecked);
288 getWizard().getContainer().updateButtons();
289 }
290 });
291 Label areaLevelLabel = new Label(control, SWT.NULL);
292 areaLevelLabel.setText("Area Level");
293 // areaLevelLabel.setToolTipText("Selecting none would delete all existing aggregated distributions");
294 comboAreaLevel = new Combo(control, SWT.BORDER | SWT.READ_ONLY);
295 List<NamedAreaLevel> namedAreaLevels = CdmStore.getTermManager().getAllTerms(TermType.NamedAreaLevel, null);
296 for (NamedAreaLevel level: namedAreaLevels) {
297 comboAreaLevel.add(level.getLabel());
298 comboAreaLevel.setData(level.getLabel(), level);
299 }
300 comboAreaLevel.addSelectionListener(this);
301 comboAreaLevel.setEnabled(false);
302 GridData gridData2 = new GridData();
303 gridData2.horizontalSpan = 2;
304 gridData2.horizontalAlignment = SWT.LEFT;
305
306 buttonSuperArea = new Button(control, SWT.PUSH );
307 buttonSuperArea.setLayoutData(gridData2);
308 buttonSuperArea.setEnabled(false);
309 buttonSuperArea.setText("Select Super Areas");
310 buttonSuperArea.setToolTipText("If area aggregation is selected, the super areas can be selected. If none are selected the top level areas are used.");
311 buttonSuperArea.addSelectionListener(new SelectionAdapter() {
312 @Override
313 public void widgetSelected(SelectionEvent event) {
314 SuperAreaSelectionWizard availableDistributionWizard = new SuperAreaSelectionWizard(configurator, (NamedAreaLevel)comboAreaLevel.getData(comboAreaLevel.getText()));
315 WizardDialog dialog = new WizardDialog(StoreUtil.getShell(),
316 availableDistributionWizard);
317 int open = dialog.open();
318 }
319 });
320
321
322
323
324 Label sourceModeLabel = new Label(control, SWT.NULL);
325 sourceModeLabel.setText("Source mode");
326 comboSourceMode = new Combo(control, SWT.BORDER| SWT.READ_ONLY);
327 comboSourceMode.setText(Messages.DistributionAggregationConfiguration_AggregationMode);
328 for (SourceMode mode :SourceMode.values()){
329 comboSourceMode.add(mode.toString());
330 comboSourceMode.setData(mode.toString(), mode);
331 }
332
333 comboSourceMode.addSelectionListener(this);
334
335 Label sourceTypeLabel = new Label(control, SWT.NULL);
336 sourceTypeLabel.setText("Source type");
337
338 sourceTypeViewer = CheckboxTableViewer.newCheckList(control, SWT.BORDER | SWT.SINGLE);
339 sourceTypeViewer.setContentProvider(new ArrayContentProvider());
340
341
342 sourceTypeViewer.addCheckStateListener(new ICheckStateListener(){
343 @Override
344 public void checkStateChanged( CheckStateChangedEvent event){
345 checkedElements=sourceTypeViewer.getCheckedElements();
346 getWizard().getContainer().updateButtons();
347 }
348 });
349
350 List<String> typeStrings = new ArrayList<>();
351 Arrays.stream(OriginalSourceType.values()).forEach(p ->typeMap.put(p.getMessage(), p));
352 Arrays.stream(OriginalSourceType.values()).forEach(p ->typeStrings.add(p.getMessage()));
353 // typeStrings.sort(new OriginalSourceTypeComparator(null));
354 sourceTypeViewer.setInput(typeStrings);
355 sourceTypeViewer.setChecked(OriginalSourceType.PrimaryMediaSource.getMessage(), true);
356 sourceTypeViewer.setChecked(OriginalSourceType.PrimaryTaxonomicSource.getMessage(), true);
357
358 //aggregation mode
359
360
361
362 Label selectStatusLabel = new Label(control, SWT.NULL);
363 selectStatusLabel.setText("Status order");
364 comboStatusOrder = new Combo(control, SWT.PUSH );
365 comboStatusOrder.add("Default - by vocabulary");
366 comboStatusOrder.setData("Default - by vocabulary", null);
367 for (TermTree tree: CdmStore.getService(ITermTreeService.class).list(TermType.PresenceAbsenceTerm, null, 0, null,null)){
368 comboStatusOrder.add(tree.getTitleCache());
369 comboStatusOrder.setData(tree.getTitleCache(), tree);
370 }
371
372 comboStatusOrder.addSelectionListener(this);
373
374
375 checkExportUnpublished = new Button(composite, SWT.CHECK);
376 checkExportUnpublished.setText("Export unpublished taxa");
377
378 GridLayoutFactory.fillDefaults();
379
380
381
382 setControl(composite);
383
384 }
385
386
387
388
389
390
391 @Override
392 public void widgetSelected(SelectionEvent e) {
393 if (e.getSource().equals(comboSourceMode)){
394 configurator.setToParentSourceMode((SourceMode)comboSourceMode.getData(comboSourceMode.getText()));
395 configurator.setWithinTaxonSourceMode((SourceMode)comboSourceMode.getData(comboSourceMode.getText()));
396 }
397
398 if (e.getSource().equals(comboAreaLevel)){
399 buttonSuperArea.setEnabled(StringUtils.isNotBlank(comboAreaLevel.getText()));
400 }
401
402
403 }
404
405
406 @Override
407 public void widgetDefaultSelected(SelectionEvent e) {
408 // TODO Auto-generated method stub
409
410 }
411
412
413 @Override
414 public void handleEvent(Event event) {
415 if (event.widget.equals(comboHigherRank)){
416 updateLowerRankCombo();
417 }
418 if (event.widget.equals(selectedClassification)){
419 updateHigherRankCombo();
420 updateLowerRankCombo();
421 }
422 if (event.widget.equals(this.checkUseSelectedClassification)){
423 updateHigherRankCombo();
424 updateLowerRankCombo();
425 }
426 if (event.widget.equals(this.checkUseSelectedSubtree)){
427 updateHigherRankCombo();
428 updateLowerRankCombo();
429 }
430 if (event.widget.equals(this.checkUseSelectedTaxonNode)){
431 updateHigherRankCombo();
432 updateLowerRankCombo();
433 }
434
435 }
436
437 private void updateHigherRankCombo() {
438 comboHigherRank.removeAll();
439
440 TaxonName name = null;
441 if (subTreeNode != null){
442 if (subTreeNode.getTaxon() != null){
443 name = subTreeNode.getTaxon().getName();
444 }
445 }
446 comboHigherRank.add("");
447 if (name != null){
448 for (Rank rank: CdmStore.getTermManager().getPreferredTerms(Rank.class)){
449 if (useClassification()){
450 comboHigherRank.add(rank.getLabel());
451 comboHigherRank.setData(rank.getLabel(), rank);
452 }else if (name != null && name.getRank().isHigher(rank)){
453 comboHigherRank.add(rank.getLabel());
454 comboHigherRank.setData(rank.getLabel(), rank);
455 }
456
457 }
458 }else{
459 for (Rank rank: CdmStore.getTermManager().getPreferredTerms(Rank.class)){
460 comboHigherRank.add(rank.getLabel());
461 comboHigherRank.setData(rank.getLabel(), rank);
462 }
463 }
464
465 }
466
467
468 private void updateLowerRankCombo() {
469 comboLowerRank.removeAll();
470 TaxonName name = null;
471 if (subTreeNode != null){
472 if (subTreeNode.getTaxon() != null){
473 name = subTreeNode.getTaxon().getName();
474 }
475 }
476 comboLowerRank.add("");
477 for (Rank rank: CdmStore.getTermManager().getPreferredTerms(Rank.class)){
478 if (subTreeNode == null && (comboHigherRank.getText() == null || (comboHigherRank.getData(comboHigherRank.getText()) != null && ((Rank)comboHigherRank.getData(comboHigherRank.getText())).isHigher(rank)))){
479 comboLowerRank.add(rank.getLabel());
480 comboLowerRank.setData(rank.getLabel(), rank);
481 }else if (name == null || name.getRank().isHigher(rank)) {
482 if(StringUtils.isBlank(comboHigherRank.getText()) || comboHigherRank.getData(comboHigherRank.getText()) != null && ((Rank)comboHigherRank.getData(comboHigherRank.getText())).isHigher(rank)){
483 // the rank is lower than higher rank and lower than the rank of the subtree name
484 comboLowerRank.add(rank.getLabel());
485 comboLowerRank.setData(rank.getLabel(), rank);
486 }
487 }
488 }
489
490
491 }
492
493 public Rank getHigherRank(){
494 if (StringUtils.isNotBlank(comboHigherRank.getText())){
495 return (Rank)comboHigherRank.getData(comboHigherRank.getText());
496 }
497 return null;
498 }
499
500 public Rank getLowerRank(){
501 if (StringUtils.isNotBlank(comboLowerRank.getText())){
502 return (Rank)comboLowerRank.getData(comboLowerRank.getText());
503 }
504 return null;
505 }
506
507 public SourceMode getSourceMode(){
508 if (StringUtils.isNotBlank(comboSourceMode.getText())){
509 return (SourceMode)comboSourceMode.getData(comboSourceMode.getText());
510 }
511 return null;
512 }
513
514 public TermTree getStatusOrder(){
515 if (StringUtils.isNotBlank(comboStatusOrder.getText())){
516 return (TermTree)comboStatusOrder.getData(comboStatusOrder.getText());
517 }
518 return null;
519 }
520
521 public boolean useClassification(){
522 return checkUseSelectedClassification.getSelection();
523 }
524
525 public boolean useSubtree(){
526 return checkUseSelectedSubtree.getSelection();
527 }
528
529 public boolean useTaxonNode(){
530 return checkUseSelectedTaxonNode.getSelection();
531 }
532
533 public boolean useUnpublishedData(){
534 return checkExportUnpublished.getSelection();
535 }
536
537 public EnumSet<OriginalSourceType> getSourceTypes(){
538 List<OriginalSourceType> list = new ArrayList<>();
539 for (Object o: sourceTypeViewer.getCheckedElements()){
540 String string = null;
541 if (o instanceof String){
542 string = (String)o;
543 }
544 if (string != null){
545 list.add(typeMap.get(string));
546 }
547 }
548
549 return EnumSet.copyOf(list);
550 }
551
552 public List<AggregationMode> getAggregationMode(){
553
554 List<AggregationMode> result = new ArrayList<>();
555 for (Object o: aggregationModeViewer.getCheckedElements()){
556 if (o instanceof AggregationMode){
557 result.add((AggregationMode)o);
558 }
559 }
560 return result;
561 }
562
563
564 public Classification getSelectedClassification() {
565 return selectedClassification;
566 }
567
568
569 public TaxonNode getSubTreeNode() {
570 return subTreeNode;
571 }
572 }