ref #7854 Implement NatTable for distribution editor
[taxeditor.git] / eu.etaxonomy.taxeditor.editor / src / main / java / eu / etaxonomy / taxeditor / editor / view / checklist / e4 / DistributionEditor.java
1 /**
2 * Copyright (C) 2018 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.editor.view.checklist.e4;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.SortedSet;
19 import java.util.TreeSet;
20 import java.util.UUID;
21
22 import javax.inject.Inject;
23
24 import org.apache.commons.collections4.map.LinkedMap;
25 import org.apache.log4j.Logger;
26 import org.eclipse.e4.ui.services.EMenuService;
27 import org.eclipse.jface.layout.GridDataFactory;
28 import org.eclipse.jface.layout.GridLayoutFactory;
29 import org.eclipse.jface.wizard.WizardDialog;
30 import org.eclipse.nebula.widgets.nattable.NatTable;
31 import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
32 import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
33 import org.eclipse.nebula.widgets.nattable.coordinate.PositionCoordinate;
34 import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
35 import org.eclipse.nebula.widgets.nattable.data.IRowDataProvider;
36 import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
37 import org.eclipse.nebula.widgets.nattable.extension.e4.selection.E4SelectionListener;
38 import org.eclipse.nebula.widgets.nattable.extension.glazedlists.filterrow.DefaultGlazedListsFilterStrategy;
39 import org.eclipse.nebula.widgets.nattable.filterrow.FilterRowHeaderComposite;
40 import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer;
41 import org.eclipse.nebula.widgets.nattable.freeze.FreezeHelper;
42 import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer;
43 import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
44 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
45 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
46 import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
47 import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
48 import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
49 import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
50 import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
51 import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
52 import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
53 import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
54 import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
55 import org.eclipse.nebula.widgets.nattable.layer.ILayer;
56 import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
57 import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
58 import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum;
59 import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
60 import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
61 import org.eclipse.swt.SWT;
62 import org.eclipse.swt.events.SelectionAdapter;
63 import org.eclipse.swt.events.SelectionEvent;
64 import org.eclipse.swt.layout.GridData;
65 import org.eclipse.swt.layout.GridLayout;
66 import org.eclipse.swt.widgets.Button;
67 import org.eclipse.swt.widgets.Composite;
68 import org.eclipse.swt.widgets.Label;
69 import org.eclipse.swt.widgets.Text;
70
71 import ca.odell.glazedlists.BasicEventList;
72 import ca.odell.glazedlists.EventList;
73 import eu.etaxonomy.cdm.api.service.IVocabularyService;
74 import eu.etaxonomy.cdm.api.service.dto.TaxonDistributionDTO;
75 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
76 import eu.etaxonomy.cdm.model.common.Language;
77 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
78 import eu.etaxonomy.cdm.model.common.OrderedTermComparator;
79 import eu.etaxonomy.cdm.model.common.TermIdInVocabularyComparator;
80 import eu.etaxonomy.cdm.model.common.TermLanguageComparator;
81 import eu.etaxonomy.cdm.model.common.TermVocabulary;
82 import eu.etaxonomy.cdm.model.description.DescriptionBase;
83 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
84 import eu.etaxonomy.cdm.model.description.Distribution;
85 import eu.etaxonomy.cdm.model.location.NamedArea;
86 import eu.etaxonomy.cdm.model.metadata.PreferencePredicate;
87 import eu.etaxonomy.cdm.model.reference.Reference;
88 import eu.etaxonomy.taxeditor.editor.EditorUtil;
89 import eu.etaxonomy.taxeditor.editor.l10n.Messages;
90 import eu.etaxonomy.taxeditor.model.AbstractUtility;
91 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
92 import eu.etaxonomy.taxeditor.preference.Resources;
93 import eu.etaxonomy.taxeditor.preference.wizard.AvailableDistributionWizard;
94 import eu.etaxonomy.taxeditor.store.CdmStore;
95 import eu.etaxonomy.taxeditor.store.StoreUtil;
96 import eu.etaxonomy.taxeditor.ui.dialog.selection.ReferenceSelectionDialog;
97
98 /**
99 * @author k.luther
100 * @since 27.11.2018
101 *
102 */
103 public class DistributionEditor extends Composite {
104
105
106 private static final String DISTRIBUTION_EDITOR = "Distribution Editor";
107 private static final String LOADING_TAXA = Messages.ChecklistEditor_LOAD_TAXA;
108 private static final String UNKNOWN = Messages.ChecklistEditor_UNKNOWN;
109 private static final String ELEMENT_COUNT = Messages.ChecklistEditor_ELEMENT_COUNT;
110 public static final String TYPE_FILTER_TEXT = "type filter text"; //$NON-NLS-1$
111
112 static final String TAXON_COLUMN = "taxon_column"; //$NON-NLS-1$
113 static final String RANK_COLUMN = "collector_column"; //$NON-NLS-1$
114
115 private static final Logger logger = Logger.getLogger(DistributionEditor.class);
116 @Inject
117 private EMenuService menuService;
118 private NatTable natTable;
119 private Label statusLabel;
120 private Label statusLabelSourceReference;
121 private Reference defaultSource;
122
123 private Map<Integer, NamedArea> areaToColumnIndexMap= new HashMap();
124 private int firstDataColumnIndex;
125
126 private ListDataProvider<TaxonDistributionDTO> bodyDataProvider;
127 private LinkedMap<String, String> propertyToLabelMap = new LinkedMap<>();
128
129 private boolean isShowRank;
130 private Integer countNodes;
131 private Text searchText;
132
133 EventList<TaxonDistributionDTO> taxonList;
134
135 SortedSet<DefinedTermBase> areas;
136 DistributionEditorPart part;
137 BodyLayerStack<TaxonDistributionDTO> bodyLayerStack;
138 private FreezeLayer freezeLayer;
139 private ConfigRegistry configRegistry;
140 private AbstractLayer topMostLayer;
141
142 private SelectionLayer selectionLayer;
143
144
145
146 // private FixedSummaryRowLayer summaryRowLayer;
147
148
149 /**
150 * @param parent
151 * @param style
152 */
153 public DistributionEditor(Composite parent, DistributionEditorPart part) {
154 super(parent, SWT.NULL);
155 this.part = part;
156 this.setLayout(new GridLayout());
157 GridLayoutFactory.fillDefaults().applyTo(parent);
158
159 Composite topComposite = new Composite(parent, SWT.NONE);
160 createTopComposite(topComposite);
161
162 Composite bottomComposite = new Composite(parent, SWT.NONE);
163 GridLayoutFactory.fillDefaults().applyTo(bottomComposite);
164
165 natTable = new NatTable(parent, false);
166 parent.pack();
167
168
169 // // natTable = new NatTable(parent, viewportLayer);
170 // natTable = new NatTable(parent, false);
171
172 createStatusBar(parent);
173 }
174
175 public boolean isShowRank() {
176 return isShowRank;
177 }
178
179 public void setShowRank(boolean isShowRank) {
180 this.isShowRank = isShowRank;
181 }
182
183 public int getFirstDataColumnIndex() {
184 return firstDataColumnIndex;
185 }
186
187 public void setFirstDataColumnIndex(int firstDataColumnIndex) {
188 this.firstDataColumnIndex = firstDataColumnIndex;
189 }
190
191 public LinkedMap<String, String> getPropertyToLabelMap() {
192 return propertyToLabelMap;
193 }
194
195 public void setPropertyToLabelMap(LinkedMap<String, String> propertyToLabelMap) {
196 this.propertyToLabelMap = propertyToLabelMap;
197 }
198
199 public Map<Integer, NamedArea> getAreaToColumnIndexMap() {
200 return areaToColumnIndexMap;
201 }
202
203
204 public void setAreaToColumnIndexMap(Map<Integer, NamedArea> areaToColumnIndexMap) {
205 this.areaToColumnIndexMap = areaToColumnIndexMap;
206 }
207
208
209
210 private void createStatusBar(Composite composite) {
211 GridData gridData = new GridData();
212 gridData.horizontalSpan = 1;
213 gridData.grabExcessHorizontalSpace = true;
214 gridData.horizontalAlignment = GridData.FILL;
215
216 statusLabel = new Label(composite, SWT.LEFT);
217 statusLabel.setText(ELEMENT_COUNT + (taxonList != null ? taxonList.size() : UNKNOWN));
218 statusLabel.setLayoutData(gridData);
219
220 statusLabelSourceReference = new Label(composite, SWT.RIGHT);
221
222 statusLabelSourceReference.setLayoutData(gridData);
223
224 if (defaultSource != null){
225 statusLabelSourceReference.setText("Default Source Reference: " + defaultSource.getAbbrevTitle() != null? defaultSource.getAbbrevTitle() : defaultSource.getAbbrevTitleCache());
226
227 }
228 }
229
230 private void applyStyles(){
231 ModernNatTableThemeConfiguration configuration = new ModernNatTableThemeConfiguration();
232 configuration.summaryRowHAlign = HorizontalAlignmentEnum.CENTER;
233 // NOTE: Getting the colors and fonts from the GUIHelper ensures that
234 // they are disposed properly (required by SWT)
235 configuration.cHeaderBgColor = GUIHelper.getColor(211, 211, 211);
236 configuration.rHeaderBgColor = GUIHelper.getColor(211, 211, 211);
237 natTable.addConfiguration(configuration);
238
239 }
240
241 private void configureNatTable(ConfigRegistry configRegistry,
242 AbstractLayer topMostLayer) {
243 /**
244 * CONFIGURATION
245 */
246 natTable.setConfigRegistry(configRegistry);
247
248 applyStyles();
249
250 //add default configuration because autoconfigure is set to false in constructor
251 natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
252
253 // override the default sort configuration and change the mouse bindings
254 // to sort on a single click
255
256 natTable.addConfiguration(new SingleClickSortConfiguration());
257 natTable.addConfiguration(new FilterRowConfiguration(this));
258
259 // add the header menu configuration for adding the column header menu
260 // with hide/show actions
261 natTable.addConfiguration(new DistributionEditorHeaderMenuConfiguration(natTable));
262
263 // add custom configuration for data conversion and add column labels to viewport layer
264 topMostLayer.addConfiguration(new DistributionCellEditorDataConversionConfiguration(this));
265
266 natTable.configure();
267 }
268
269 public void createTable(){
270 /**
271 * layers
272 */
273
274 createLayers();
275
276 /**
277 * configuration
278 */
279 configureNatTable( configRegistry, topMostLayer);
280
281 /**
282 * handlers and listeners
283 */
284 registerHandlersAndListeners(topMostLayer);
285 FreezeHelper.freeze(freezeLayer, bodyLayerStack.getViewPortLayer(),
286 new PositionCoordinate(bodyLayerStack.getViewPortLayer(), 0, 0),
287 new PositionCoordinate(bodyLayerStack.getViewPortLayer(), 0, -1));
288 //grab all space
289 GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
290
291 this.layout();
292 // boolean ok = natTable.doCommand(new ClientAreaResizeCommand(natTable));
293 // System.out.println(ok);
294 }
295
296
297 private void createLayers() {
298
299 DistributionColumnAccessor columnPropertyAccessor = new DistributionColumnAccessor(this);
300
301 DistributionEditorConfigLabelAccumulator labelAccumulator = new DistributionEditorConfigLabelAccumulator(this);
302 bodyLayerStack = new BodyLayerStack<>(taxonList, columnPropertyAccessor, new TaxonDistributionDtoComparator(), labelAccumulator);
303
304 bodyDataProvider = bodyLayerStack.getBodyDataProvider();
305
306
307
308 propertyToLabelMap.put(TAXON_COLUMN, Messages.ChecklistEditor_TAXON);
309 if (isShowRank){
310 propertyToLabelMap.put(RANK_COLUMN, Messages.ChecklistEditor_RANK);
311 }
312 configRegistry = new ConfigRegistry();
313
314 initLabels();
315 this.selectionLayer = bodyLayerStack.getSelectionLayer();
316
317
318
319 freezeLayer = new FreezeLayer(selectionLayer);
320 final CompositeFreezeLayer compositeFreezeLayer = new CompositeFreezeLayer(
321 freezeLayer, bodyLayerStack.getViewPortLayer(), selectionLayer);
322
323 // as the selection mouse bindings are registered for the region label
324 // GridRegion.BODY
325 // we need to set that region label to the viewport so the selection via mouse
326 // is working correctly
327 compositeFreezeLayer.setRegionName(GridRegion.BODY);
328
329
330 IDataProvider columnHeaderDataProvider =
331 new DefaultColumnHeaderDataProvider(propertyToLabelMap.values().toArray(new String[] {}), propertyToLabelMap);
332 DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
333 ILayer columnHeaderLayer = new ColumnHeaderLayer(
334 columnHeaderDataLayer,
335 compositeFreezeLayer,
336 selectionLayer);
337
338 FilterRowHeaderComposite<TaxonDistributionDTO> filterRowHeaderLayer =
339 new FilterRowHeaderComposite<>(
340 new DefaultGlazedListsFilterStrategy<>(
341 bodyLayerStack.getFilterList(),
342 columnPropertyAccessor,
343 configRegistry),
344 columnHeaderLayer,
345 columnHeaderDataLayer.getDataProvider(),
346 configRegistry);
347
348
349
350 // build the row header layer stack
351 IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(bodyDataProvider);
352 DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
353 ILayer rowHeaderLayer = new RowHeaderLayer(
354 rowHeaderDataLayer,
355 compositeFreezeLayer,
356 selectionLayer);
357
358
359
360 IDataProvider cornerDataProvider =
361 new DefaultCornerDataProvider(
362 columnHeaderDataProvider,
363 rowHeaderDataProvider);
364 DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
365 ILayer cornerLayer = new CornerLayer(
366 cornerDataLayer,
367 rowHeaderLayer,
368 filterRowHeaderLayer);
369
370 GridLayer gridLayer = new GridLayer(
371 compositeFreezeLayer,
372 filterRowHeaderLayer,
373 rowHeaderLayer,
374 cornerLayer);
375
376 natTable.setLayer(gridLayer);
377
378 topMostLayer = compositeFreezeLayer;
379
380
381 }
382
383 /**
384 * @param parent
385 * @return
386 */
387 private Text createSearchBar(Composite parent) {
388
389 Button button1 = new Button(parent, SWT.PUSH );
390 GridData gridData2 = new GridData();
391 gridData2.horizontalSpan = 1;
392 gridData2.horizontalAlignment = SWT.RIGHT;
393 button1.setLayoutData(gridData2);
394
395
396 button1.setText(Messages.ChecklistEditor_DIST_STATUS);
397 button1.setToolTipText(Messages.ChecklistEditor_DIST_STATUS_TOOLTIP);
398 button1.addSelectionListener(new SelectionAdapter() {
399 @Override
400 public void widgetSelected(SelectionEvent event) {
401 AvailableDistributionWizard availableDistributionWizard = new AvailableDistributionWizard();
402 WizardDialog dialog = new WizardDialog(StoreUtil.getShell(),
403 availableDistributionWizard);
404
405 int open = dialog.open();
406 if(open == 0){
407 reload();
408 }
409 }
410 });
411
412 Button button2 = new Button(parent, SWT.PUSH );
413 GridData gridData3 = new GridData();
414 gridData2.horizontalSpan = 1;
415 button2.setLayoutData(gridData3);
416
417
418 button2.setText(Messages.ChecklistEditor_DEFAULT_SOURCE);
419 button2.setToolTipText(Messages.ChecklistEditor_DEFAULT_SOURCE_TOOLTIP);
420 button2.addSelectionListener(new SelectionAdapter() {
421
422 @Override
423 public void widgetSelected(SelectionEvent event) {
424 defaultSource = ReferenceSelectionDialog.select(AbstractUtility.getShell(), null);
425
426 String defaultSourceStr = (defaultSource == null) ? "" : "Default Source Reference: " + defaultSource.getTitleCache();
427 if (defaultSourceStr.length()> 100){
428 defaultSourceStr = defaultSourceStr.substring(0, 98) + "...";
429 }
430 statusLabelSourceReference.setText(defaultSourceStr);
431
432 button2.setBackground(EditorUtil.getColor(Resources.COLOR_CONTROL_SELECTED));
433 }
434
435 });
436
437 parent.pack();
438 return searchText;
439 }
440 /**
441 * This method should only be called for adding new Distribution columns and reloading the table.<br>
442 * It will hide the old distribution column and load the newly added columns.<br>
443 * <p>
444 * <b>Notice:</b> for data update please use <b>refresh()</b>
445 *
446 */
447 @SuppressWarnings({ "unchecked", "rawtypes" })
448 public void reload(){
449 this.areaToColumnIndexMap.clear();
450 this.areas.clear();
451 this.propertyToLabelMap.clear();
452 createTable();
453 natTable.redraw();
454 }
455
456 /**
457 * @param parent
458 */
459 private void createTopComposite(Composite parent) {
460 GridLayout gridLayout = new GridLayout(3, false);
461 gridLayout.marginWidth = 0;
462 gridLayout.marginHeight = 0;
463 parent.setLayout(gridLayout);
464 searchText = createSearchBar(parent);
465
466
467 }
468 public void loadDistributions(List<TaxonDistributionDTO> taxonList) {
469 if (this.taxonList == null){
470 this.taxonList = new BasicEventList<>();
471 }
472 taxonList.stream().forEach(wrapper->DistributionEditor.this.taxonList.add(wrapper));
473 statusLabel.setText(ELEMENT_COUNT + (taxonList != null ? taxonList.size() : UNKNOWN));
474 }
475
476
477
478 public List<DescriptionBase> getDistributions() {
479 List<DescriptionBase> descriptions = new ArrayList();
480
481 // taxonList.forEach(taxonDto->taxonDto.getDistributionMap()
482 // .forEach((area, descriptionElements)->descElements.addAll(descriptionElements)));
483
484 taxonList.forEach(taxonDto -> taxonDto.getDescriptionsWrapper().getDescriptions().forEach(taxDesc -> descriptions.add(taxDesc)));
485
486 for (DescriptionBase description: descriptions){
487 List<DescriptionElementBase> toDelete = new ArrayList();
488 for (Object desc: description.getElements()){
489 if (desc instanceof Distribution){
490 Distribution distribution = (Distribution) desc;
491 if (distribution.getStatus() == null || !distribution.getStatus().isPersited()){
492 toDelete.add(distribution);
493 }
494 }
495 }
496 for (DescriptionElementBase element: toDelete){
497 description.removeElement(element);
498 }
499
500 }
501
502
503 return descriptions;
504
505 }
506
507 private void initLabels() {
508
509 int index = 1;
510 if (isShowRank){
511 index++;
512 }
513
514 loadNamedAreas();
515 for (DefinedTermBase area: areas) {
516 this.areaToColumnIndexMap.put(index++, (NamedArea)area);
517
518 //TODO: adapt to preference
519 String areaLabel = area.getLabel();
520 String property = areaLabel;
521 propertyToLabelMap.put(property, areaLabel);
522 }
523 }
524
525 private SortedSet<DefinedTermBase> loadNamedAreas() {
526 //IPreferenceStore preferenceStore = PreferencesUtil.getPreferenceStore();
527
528 String valuesAreas = PreferencesUtil.getStringValue(PreferencePredicate.AvailableDistributionAreaTerms.getKey());
529 String values = PreferencesUtil.getStringValue(PreferencePredicate.AvailableDistributionAreaVocabularies.getKey());
530 if (values != null && values != "") { //$NON-NLS-1$
531 String[] split = values.split(";"); //$NON-NLS-1$
532 List<String> listValue = Arrays.asList(split);
533 List<DefinedTermBase> termlist = new ArrayList<DefinedTermBase>();
534 Set<UUID> uuidList = new HashSet<UUID>();
535 UUID uuid;
536 for(String s : listValue){
537 uuid = UUID.fromString(s);
538 uuidList.add(uuid);
539
540 }
541 IVocabularyService service = CdmStore.getService(IVocabularyService.class);
542 List<TermVocabulary> vocs = service.find(uuidList);
543 split = valuesAreas.split(";");
544 listValue = Arrays.asList(split);
545 for (TermVocabulary voc: vocs){
546 termlist.addAll(service.getTerms(voc, null, null, null, null).getRecords());
547 }
548 List<DefinedTermBase> filteredList = new ArrayList();
549 for (DefinedTermBase area: termlist){
550 if (listValue.contains(area.getUuid().toString())) {
551 filteredList.add(area);
552 }
553
554 }
555
556 if (PreferencesUtil.isSortNamedAreaByOrderInVocabulary()){
557 areas = getTermsOrderedByVocabularyOrder(filteredList);
558 } else if (PreferencesUtil.isShowIdInVocabularyInChecklistEditor()){
559 areas = getTermsOrderedByIdInVocabulary(filteredList);
560 }else{
561 areas = getTermsOrderedByLabels(filteredList, CdmStore.getDefaultLanguage());
562 }
563 }
564 return null;
565 }
566
567 public SortedSet<DefinedTermBase> getTermsOrderedByLabels(List<DefinedTermBase> listTerm,Language language){
568 TermLanguageComparator<?> comp = new TermLanguageComparator<>();
569 comp.setCompareLanguage(language);
570 SortedSet<DefinedTermBase> result = new TreeSet(comp);
571 if(listTerm != null){
572 result.addAll(listTerm);
573 }
574 return result;
575 }
576
577 public SortedSet<DefinedTermBase> getTermsOrderedByIdInVocabulary(List<DefinedTermBase> namedAreas) {
578 TermIdInVocabularyComparator<?> comp = new TermIdInVocabularyComparator<>();
579
580 SortedSet<DefinedTermBase> result = new TreeSet(comp);
581 if(namedAreas != null){
582 result.addAll(namedAreas);
583 }
584 return result;
585 }
586
587 public SortedSet<DefinedTermBase> getTermsOrderedByVocabularyOrder(List<DefinedTermBase> listAreas){
588 HashMap<TermVocabulary<DefinedTermBase>, List<DefinedTermBase>> vocs = new HashMap<>();
589 OrderedTermComparator<?> comp = new OrderedTermComparator<>();
590 boolean allOrderedTerms = true;
591 List<TermVocabulary> alreadyOrderIndexNull = new ArrayList<>();
592 for (DefinedTermBase term: listAreas){
593 if (!(term instanceof OrderedTermBase)){
594 allOrderedTerms = false;
595 break;
596 }else if (((OrderedTermBase)term).getOrderIndex() == 0){
597 if(alreadyOrderIndexNull.contains(term.getVocabulary())) {
598 allOrderedTerms = false;
599 break;
600 }else{
601 alreadyOrderIndexNull.add(term.getVocabulary());
602 }
603
604
605 }
606 }
607 if (allOrderedTerms){
608 SortedSet<DefinedTermBase> result = new TreeSet(comp.reversed());
609 result.addAll(listAreas);
610 return result;
611 }else{
612 return getTermsOrderedByLabels(listAreas, PreferencesUtil.getGlobalLanguage());
613 }
614
615
616 }
617
618 private void registerHandlersAndListeners(AbstractLayer topMostLayer) {
619 //selection listener
620 E4SelectionListener selectionListener = new DistributionCellSelectionListener(part.getSelectionService(),
621 selectionLayer, bodyDataProvider, part);
622 selectionLayer.addLayerListener(selectionListener);
623 selectionListener.setFullySelectedRowsOnly(false);
624
625 //register handler for view configuration menu
626 // natTable.registerCommandHandler(toolbar.getDisplayPersistenceDialogCommandHandler());
627 }
628
629 /**
630 * @return
631 */
632 public IRowDataProvider<TaxonDistributionDTO> getBodyDataProvider() {
633 return bodyDataProvider;
634 }
635
636 public void setDirty() {
637 part.setDirty();
638 }
639
640 public Reference getDefaultSource(){
641 return defaultSource;
642 }
643
644
645
646 }