Project

General

Profile

Download (47.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 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.cdm.vaadin.view.name;
10

    
11
import java.util.Collection;
12
import java.util.EnumSet;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Map;
16
import java.util.UUID;
17

    
18
import org.apache.commons.lang3.BooleanUtils;
19
import org.springframework.context.annotation.Scope;
20
import org.vaadin.viritin.fields.AbstractElementCollection.Instantiator;
21
import org.vaadin.viritin.fields.ElementCollectionField;
22

    
23
import com.vaadin.data.Property;
24
import com.vaadin.data.Property.ValueChangeListener;
25
import com.vaadin.data.Validator.InvalidValueException;
26
import com.vaadin.server.ErrorMessage;
27
import com.vaadin.shared.ui.MarginInfo;
28
import com.vaadin.spring.annotation.SpringComponent;
29
import com.vaadin.ui.AbstractField;
30
import com.vaadin.ui.Alignment;
31
import com.vaadin.ui.CheckBox;
32
import com.vaadin.ui.Component;
33
import com.vaadin.ui.GridLayout;
34
import com.vaadin.ui.NativeSelect;
35
import com.vaadin.ui.Panel;
36
import com.vaadin.ui.TextField;
37

    
38
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
39
import eu.etaxonomy.cdm.model.common.AnnotationType;
40
import eu.etaxonomy.cdm.model.common.CdmBase;
41
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
42
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
43
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
44
import eu.etaxonomy.cdm.model.name.Rank;
45
import eu.etaxonomy.cdm.model.name.RankClass;
46
import eu.etaxonomy.cdm.model.name.TaxonName;
47
import eu.etaxonomy.cdm.model.reference.Reference;
48
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
49
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
50
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
51
import eu.etaxonomy.cdm.vaadin.data.validator.NomenclaturalReferenceExistsValidator;
52
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
53
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
54
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
55
import eu.etaxonomy.cdm.vaadin.model.name.NameRelationshipDTO;
56
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
57
import eu.etaxonomy.cdm.vaadin.permission.CdmEditDeletePermissionTester;
58
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
59
import eu.etaxonomy.cdm.vaadin.ui.UIMessages;
60
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
61
import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
62
import eu.etaxonomy.vaadin.component.NameRelationField;
63
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
64
import eu.etaxonomy.vaadin.component.SwitchableTextField;
65
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
66
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
67
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
68
import eu.etaxonomy.vaadin.event.EditorActionType;
69
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOPopupEditor;
70

    
71
/**
72
 * @author a.kohlbecker
73
 * @since May 22, 2017
74
 *
75
 */
76
@SpringComponent
77
@Scope("prototype")
78
public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter>
79
    implements TaxonNamePopupEditorView{
80

    
81
    private static final long serialVersionUID = -7037436241474466359L;
82

    
83
    private final static int GRID_COLS = 4;
84

    
85
    private final static int GRID_ROWS = 20;
86

    
87
    private static final boolean HAS_BASIONYM_DEFAULT = false;
88

    
89
    private AbstractField<String> genusOrUninomialField;
90

    
91
    private AbstractField<String> infraGenericEpithetField;
92

    
93
    private AbstractField<String> specificEpithetField;
94

    
95
    private AbstractField<String> infraSpecificEpithetField;
96

    
97
    private SwitchableTextField fullTitleCacheFiled;
98

    
99
    private SwitchableTextField protectedNameCacheField;
100

    
101
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
102

    
103
    private TextField nomenclaturalReferenceDetail;
104

    
105
    private TeamOrPersonField exBasionymAuthorshipField;
106

    
107
    private TeamOrPersonField basionymAuthorshipField;
108

    
109
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
110

    
111
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
112

    
113
    private NameRelationField validationField;
114

    
115
    private NameRelationField orthographicVariantField;
116

    
117
    private ElementCollectionField<NomenclaturalStatus> nomStatusCollectionField;
118

    
119
    private CheckBox basionymToggle;
120

    
121
    private CheckBox replacedSynonymsToggle;
122

    
123
    private CheckBox validationToggle;
124

    
125
    private CheckBox orthographicVariantToggle;
126

    
127
    private NativeSelect rankSelect;
128

    
129
    private TeamOrPersonField combinationAuthorshipField;
130

    
131
    private TeamOrPersonField exCombinationAuthorshipField;
132

    
133
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
134

    
135
    private Boolean isInferredCombinationAuthorship = null;
136

    
137
    private Boolean isInferredBasionymAuthorship = null;
138

    
139
    private Boolean isInferredExBasionymAuthorship = null;
140

    
141
    private Map<AbstractField, Property.ValueChangeListener> authorshipUpdateListeners = new HashMap<>();
142

    
143
    private Boolean isInferredExCombinationAuthorship;
144

    
145
    private int specificEpithetFieldRow;
146

    
147
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
148

    
149
    private FilterableAnnotationsField annotationsListField;
150

    
151
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
152

    
153
    private int genusOrUninomialRow;
154

    
155
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
156

    
157
    /**
158
     * By default  AnnotationType.EDITORIAL() is enabled.
159
     *
160
     * @return the editableAnotationTypes
161
     */
162
    @Override
163
    public AnnotationType[] getEditableAnotationTypes() {
164
        return editableAnotationTypes;
165
    }
166

    
167
    /**
168
     * By default  AnnotationType.EDITORIAL() is enabled.
169
     *
170
     *
171
     * @param editableAnotationTypes the editableAnotationTypes to set
172
     */
173
    @Override
174
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
175
        this.editableAnotationTypes = editableAnotationTypes;
176
    }
177

    
178
    /**
179
     * @param layout
180
     * @param dtoType
181
     */
182
    public TaxonNamePopupEditor() {
183
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
184
    }
185

    
186
    /**
187
     * {@inheritDoc}
188
     */
189
    @Override
190
    public String getWindowCaption() {
191
        return "Name editor";
192
    }
193

    
194

    
195
    /**
196
     * {@inheritDoc}
197
     */
198
    @Override
199
    public int getWindowWidth() {
200
        return 800;
201
    }
202

    
203
    /**
204
     * {@inheritDoc}
205
     */
206
    @Override
207
    public void focusFirst() {
208
        // none
209
    }
210

    
211
    @Override
212
    public void applyDefaultComponentStyle(Component ... components){
213
        for(int i = 0; i <components.length; i++){
214
            components[i].setStyleName(getDefaultComponentStyles());
215
        }
216
    }
217

    
218
    /**
219
     * {@inheritDoc}
220
     */
221
    @Override
222
    protected String getDefaultComponentStyles() {
223
        return "tiny";
224
    }
225

    
226
    /**
227
     * {@inheritDoc}
228
     */
229
    @Override
230
    protected void initContent() {
231

    
232
        GridLayout grid = (GridLayout)getFieldLayout();
233
        grid.setSizeFull();
234
        grid.setHideEmptyRowsAndColumns(true);
235
        grid.setSpacing(true);
236
        grid.setColumnExpandRatio(0, 0.3f);
237
        grid.setColumnExpandRatio(1, 0.3f);
238
        grid.setColumnExpandRatio(2, 0.3f);
239
        grid.setColumnExpandRatio(3, 0.0f);
240

    
241
        /*
242
         - nameType: preset, needs to be set in the presenter for new names
243
         - appendedPhrase: -> TODO field
244
         - nomenclaturalMicroReference:  -> TODO field
245
         - nomenclaturalReference ->  field but disabled for REGISTRY
246
         - rank -> SelectField which determines the visiblity of the other fields
247

    
248
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
249
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
250

    
251
         - homotypicalGroup -> hidden
252
         - typeDesignations -> hidden
253
         - descriptions -> hidden
254
         - taxonBases -> hidden
255
         - registrations -> hidden
256

    
257
         - relationsFromThisName-> TODO implement later
258
         - relationsToThisName -> TODO implement later
259

    
260
         - genusOrUninomial -> textField
261
         - infraGenericEpithet  -> textField
262
         - specificEpithet  -> textField
263
         - infraSpecificEpithet  -> textField
264

    
265
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
266
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
267
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
268
         - exCombinationAuthorship -> textField
269
         - exBasionymAuthorship -> textField
270

    
271
         - status -> TODO field
272
         - monomHybrid -> TODO implement hybrids later
273
         - binomHybrid -> TODO implement hybrids later
274
         - trinomHybrid -> TODO implement hybrids later
275

    
276
         - hybridParentRelations -> TODO implement hybrids later
277
         - hybridChildRelations -> TODO implement hybrids later
278
         - hybridFormula -> TODO implement hybrids later
279

    
280
         ** ViralName attributes **
281
         - acronym
282

    
283
         ** BacterialName attributes **
284
         - subGenusAuthorship
285
         - nameApprobation
286
         - breed
287
         - publicationYear
288
         - originalPublicationYear
289
         - cultivarName
290
        */
291

    
292
        int row = 0;
293

    
294
        rankSelect = new NativeSelect("Rank");
295
        rankSelect.setNullSelectionAllowed(false);
296
        rankSelect.setWidth(100, Unit.PERCENTAGE);
297
        addField(rankSelect, "rank", 0, row, 1, row);
298
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
299

    
300
        row++;
301
        basionymToggle = new CheckBox("With basionym");
302
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
303
        basionymToggle.setStyleName(getDefaultComponentStyles());
304
        grid.addComponent(basionymToggle, 0, row);
305
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
306

    
307
        replacedSynonymsToggle = new CheckBox("With replaced synonym");
308
        grid.addComponent(replacedSynonymsToggle, 1, row);
309
        grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
310

    
311
        validationToggle = new CheckBox("Validation");
312
        grid.addComponent(validationToggle, 2, row);
313
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
314

    
315
        orthographicVariantToggle = new CheckBox("Orthographical variant");
316
        grid.addComponent(orthographicVariantToggle, 3, row);
317
        grid.setComponentAlignment(orthographicVariantToggle, Alignment.BOTTOM_LEFT);
318

    
319
        row++;
320
        // fullTitleCache
321
        fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
322
        fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
323
        row++;
324
        protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
325
        protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
326
        row++;
327
        genusOrUninomialRow = row;
328
        genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
329
        genusOrUninomialField.setWidth(200, Unit.PIXELS);
330
        infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
331
        infraGenericEpithetField.setWidth(200, Unit.PIXELS);
332
        row++;
333
        specificEpithetFieldRow = row;
334
        specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
335
        specificEpithetField.setWidth(200, Unit.PIXELS);
336
        infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
337
        infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
338

    
339
        row++;
340
        combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
341
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
342
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
343

    
344
        row++;
345
        nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
346
        nomReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
347
                this,
348
                new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
349
                ));
350
        nomReferenceCombobox.addClickListenerEditEntity(e -> {
351
            if(nomReferenceCombobox.getValue() != null){
352
                getViewEventBus().publish(this,
353
                    new ReferenceEditorAction(
354
                            EditorActionType.EDIT,
355
                            nomReferenceCombobox.getValue().getUuid(),
356
                            e.getButton(),
357
                            nomReferenceCombobox,
358
                            this)
359
                );
360
            }
361
            });
362

    
363

    
364
        // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
365
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
366
        nomReferenceCombobox.setWidth("100%");
367
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 3, row);
368

    
369
        row++;
370
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 0, row, 2, row);
371
        nomenclaturalReferenceDetail.setWidth(100, Unit.PERCENTAGE);
372

    
373
        // --------------- nom status
374
        row++;
375
        nomStatusCollectionField = new ElementCollectionField<NomenclaturalStatus>(
376
                NomenclaturalStatus.class,
377
                new Instantiator<NomenclaturalStatus>() {
378

    
379
                    @Override
380
                    public NomenclaturalStatus create() {
381
                        return NomenclaturalStatus.NewInstance(null);
382
                    }
383
                },
384
                NomenclaturalStatusRow.class
385
                ){
386

    
387
                    @Override
388
                    public void commit() throws SourceException, InvalidValueException {
389
                        validate(); // validate always so that empty rows are recognized
390
                        super.commit();
391
                    }
392

    
393
                    @Override
394
                    public boolean isEmpty() {
395
                        Collection value = getValue();
396
                        return value == null || value.isEmpty() ;
397
                    }
398

    
399
                    @Override
400
                    public void setComponentError(ErrorMessage componentError) {
401
                        nomStatusCollectionField.setComponentError(componentError);
402
                    }
403

    
404
        };
405

    
406
        nomStatusCollectionField.getLayout().setSpacing(false);
407
        nomStatusCollectionField.setVisibleProperties(NomenclaturalStatusRow.visibleFields());
408
        nomStatusCollectionField.setPropertyHeader("type", "Status type");
409
        nomStatusCollectionField.setPropertyHeader("citation", "Reference");
410
        nomStatusCollectionField.setPropertyHeader("citationMicroReference", "Reference detail");
411
        nomStatusCollectionField.setPropertyHeader("ruleConsidered", "Rule considered");
412
        nomStatusCollectionField.addElementAddedListener( e -> nomStatusCollectionField.setComponentError(null));
413
        nomStatusCollectionField.getLayout().setMargin(new MarginInfo(false, true));
414

    
415
        Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
416
        nomStatusCollectionPanel.setCaption("Status");
417
        nomStatusCollectionPanel.setWidth(800, Unit.PIXELS);
418

    
419
        bindField(nomStatusCollectionField, "status");
420
        addComponent(nomStatusCollectionPanel, 0, row, 2, row);
421

    
422
        // --------------- Basionyms
423
        row++;
424
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
425
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
426
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
427
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
428
        basionymsComboboxSelect.withEditButton(true);
429
        basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
430
        basionymsComboboxSelect.setEditActionListener(e -> {
431

    
432
            Object fieldValue = e.getSource().getValue();
433
            UUID beanUuid = null;
434
            if(fieldValue != null){
435
                beanUuid = ((CdmBase)fieldValue).getUuid();
436

    
437
            }
438
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
439
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
440
        });
441
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
442

    
443
        row++;
444
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
445
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
446
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
447
        row++;
448
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
449
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
450
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
451

    
452
        // --------------- ReplacedSynonyms
453
        row++;
454
        replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Replaced synonyms");
455
        replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
456
        addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
457
        replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
458
        replacedSynonymsComboboxSelect.withEditButton(true);
459
        replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
460
        replacedSynonymsComboboxSelect.setEditActionListener(e -> {
461

    
462
            Object fieldValue = e.getSource().getValue();
463
            UUID beanUuid = null;
464
            if(fieldValue != null){
465
                beanUuid = ((CdmBase)fieldValue).getUuid();
466

    
467
            }
468
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
469
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
470
        });
471
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
472

    
473
        // --------------- Validation
474
        row++;
475
        validationField = new NameRelationField("Validation", "Validated name", Direction.relatedTo, NameRelationshipType.VALIDATED_BY_NAME());
476
        validationField.setWidth(100, Unit.PERCENTAGE);
477
        ToOneRelatedEntityCombobox<TaxonName> validatedNameComboBox = validationField.getRelatedNameComboBox();
478
        validatedNameComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
479
                this,
480
                new TaxonNameEditorAction(EditorActionType.ADD, null, validatedNameComboBox, this)
481
                ));
482
        validatedNameComboBox.addClickListenerEditEntity(e -> {
483
            if(validatedNameComboBox.getValue() != null){
484
                getViewEventBus().publish(this,
485
                    new TaxonNameEditorAction(
486
                            EditorActionType.EDIT,
487
                            validatedNameComboBox.getValue().getUuid(),
488
                            e.getButton(),
489
                            validatedNameComboBox,
490
                            this)
491
                );
492
            }
493
        });
494
        ToOneRelatedEntityCombobox<Reference> validationCitatonComboBox = validationField.getCitatonComboBox();
495
        validationCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
496
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
497
                this,
498
                new ReferenceEditorAction(EditorActionType.ADD, null, validationCitatonComboBox, this)
499
                ));
500
        validationCitatonComboBox.addClickListenerEditEntity(e -> {
501
            if(validationCitatonComboBox.getValue() != null){
502
                getViewEventBus().publish(this,
503
                    new ReferenceEditorAction(
504
                            EditorActionType.EDIT,
505
                            validationCitatonComboBox.getValue().getUuid(),
506
                            e.getButton(),
507
                            validationCitatonComboBox,
508
                            this)
509
                );
510
            }
511
        });
512
        addField(validationField, "validationFor", 0, row, 3, row);
513
        grid.setComponentAlignment(validationField, Alignment.TOP_RIGHT);
514

    
515
        // ------- Orthographic Variant (Correction)
516
        row++;
517
        orthographicVariantField = new NameRelationField("Orthographical variant", "Name variant", Direction.relatedTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT());
518
        orthographicVariantField.setWidth(100, Unit.PERCENTAGE);
519
        // corrected name must have same
520
        ToOneRelatedEntityCombobox<TaxonName> orthographicVariantCombobox = orthographicVariantField.getRelatedNameComboBox();
521
        orthographicVariantCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
522
                this,
523
                new TaxonNameEditorAction(EditorActionType.ADD, null, orthographicVariantCombobox, this)
524
                ));
525
        orthographicVariantCombobox.addClickListenerEditEntity(e -> {
526
            if(orthographicVariantCombobox.getValue() != null){
527
                getViewEventBus().publish(this,
528
                    new TaxonNameEditorAction(
529
                            EditorActionType.EDIT,
530
                            orthographicVariantCombobox.getValue().getUuid(),
531
                            e.getButton(),
532
                            orthographicVariantCombobox,
533
                            this)
534
                );
535
            }
536
        });
537
        ToOneRelatedEntityCombobox<Reference> orthographicCorrectionCitatonComboBox = orthographicVariantField.getCitatonComboBox();
538
        orthographicCorrectionCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
539
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
540
                this,
541
                new ReferenceEditorAction(EditorActionType.ADD, null, orthographicCorrectionCitatonComboBox, this)
542
                ));
543
        orthographicCorrectionCitatonComboBox.addClickListenerEditEntity(e -> {
544
            if(orthographicCorrectionCitatonComboBox.getValue() != null){
545
                getViewEventBus().publish(this,
546
                    new ReferenceEditorAction(
547
                            EditorActionType.EDIT,
548
                            orthographicCorrectionCitatonComboBox.getValue().getUuid(),
549
                            e.getButton(),
550
                            orthographicCorrectionCitatonComboBox,
551
                            this)
552
                );
553
            }
554
        });
555
        addField(orthographicVariantField, "orthographicVariant", 0, row, 3, row);
556
        grid.setComponentAlignment(orthographicVariantField, Alignment.TOP_RIGHT);
557

    
558
        row++;
559
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
560
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
561
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
562

    
563
        row++;
564
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
565
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
566
        annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
567
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
568

    
569
        // -----------------------------------------------------------------------------
570

    
571
        setAdvancedModeEnabled(true);
572
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
573

    
574
        registerAdvancedModeComponents(combinationAuthorshipField);
575
        registerAdvancedModeComponents(basionymAuthorshipField);
576
        registerAdvancedModeComponents(exBasionymAuthorshipField);
577
        registerAdvancedModeComponents(exCombinationAuthorshipField);
578

    
579
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
580
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
581
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
582
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
583

    
584
        setAdvancedMode(false);
585

    
586
        //TODO remove below line once #7858 is fixed
587
        withDeleteButton(false);
588

    
589
    }
590

    
591
    protected TeamOrPersonBase inferBasiomynAuthors() {
592
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
593
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
594
            TaxonName basionym = basionyms.get(0);
595
            if(basionym.getCombinationAuthorship() != null){
596
                return basionym.getCombinationAuthorship();
597
            } else if(basionym.getNomenclaturalReference() != null){
598
                return basionym.getNomenclaturalReference().getAuthorship();
599
            }
600
        }
601
        return null;
602
    }
603

    
604
    protected TeamOrPersonBase inferExBasiomynAuthors() {
605
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
606
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
607
            TaxonName basionym = basionyms.get(0);
608
                return basionym.getExCombinationAuthorship();
609
        }
610
        return null;
611
    }
612

    
613
    protected TeamOrPersonBase inferCombinationAuthors() {
614
        Reference nomRef = nomReferenceCombobox.getValue();
615
        if(nomRef != null) {
616
            return nomRef.getAuthorship();
617
        }
618
        return null;
619
    }
620

    
621
    protected TeamOrPersonBase inferExCombinationAuthors() {
622
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
623
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
624
            TaxonName validatedName = nameRelationDTO.getOtherName();
625
            if(validatedName.getCombinationAuthorship() != null) {
626
                return validatedName.getCombinationAuthorship();
627
            } else if(validatedName.getNomenclaturalReference() != null){
628
                return validatedName.getNomenclaturalReference().getAuthorship();
629
            }
630
        }
631
        return null;
632
    }
633

    
634
    @Override
635
    protected void afterItemDataSourceSet() {
636

    
637

    
638
        rankSelect.addValueChangeListener(updateFieldVisibilityListener);
639
        basionymToggle.addValueChangeListener(e -> {
640
            updateAuthorshipFields();
641
        });
642
        validationToggle.addValueChangeListener(e -> {
643
            updateAuthorshipFields();
644
            });
645
        replacedSynonymsToggle.addValueChangeListener(e -> {
646
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
647
            replacedSynonymsComboboxSelect.setVisible(enable);
648
        });
649
        orthographicVariantToggle.addValueChangeListener(e -> {
650
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
651
            orthographicVariantField.setVisible(enable);
652
        });
653

    
654
        TaxonNameDTO taxonNameDTO = getBean();
655
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
656
                || taxonNameDTO.getBasionymAuthorship() != null
657
                || taxonNameDTO.getExBasionymAuthorship() != null;
658
        basionymToggle.setValue(showBasionymSection);
659
        basionymToggle.setReadOnly(showBasionymSection);
660

    
661
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
662
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
663
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
664
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
665

    
666
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
667
        validationToggle.setValue(showValidationSection);
668
        validationToggle.setReadOnly(showValidationSection);
669

    
670
        boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
671
        orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
672
        orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
673

    
674
        if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
675
            updateAuthorshipFields();
676
        }
677
        if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
678
            nomReferenceCombobox.setDescription("Selection limited to nomenclatural reference and parts of it.");
679
        }
680
        if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
681
            nomReferenceCombobox.setRequired(true);
682
            nomReferenceCombobox.setImmediate(true);
683

    
684
            String userHint = "Please use the 'Edit' function to fix the problem in the related name.";
685
            validationField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
686
            orthographicVariantField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
687
            basionymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
688
            replacedSynonymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
689
        }
690
    }
691

    
692
    /**
693
     * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
694
     * authors from the related nomenclatural reference or taxon name.
695
     * <p>
696
     * Finally the {@link #updateFieldVisibility()} is invoked.
697
     *
698
     * @param taxonName
699
     */
700
    @Override
701
    public void updateAuthorshipFields() {
702

    
703
        TaxonNameDTO taxonName = getBean();
704

    
705
        // ------------- CombinationAuthors
706
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
707
                taxonName.getCombinationAuthorship(),
708
                inferCombinationAuthors(),
709
                combinationAuthorshipField,
710
                nomReferenceCombobox.getSelect(),
711
                isInferredCombinationAuthorship);
712

    
713

    
714
        // ------------- Basionym and ExBasionymAuthors
715
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
716

    
717
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
718
                    taxonName.getBasionymAuthorship(),
719
                    inferBasiomynAuthors(),
720
                    basionymAuthorshipField,
721
                    basionymsComboboxSelect,
722
                    isInferredBasionymAuthorship
723
                    );
724

    
725
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
726
                    taxonName.getExBasionymAuthorship(),
727
                    inferExBasiomynAuthors(),
728
                    exBasionymAuthorshipField,
729
                    basionymsComboboxSelect,
730
                    isInferredExBasionymAuthorship
731
                    );
732

    
733
        }
734

    
735
        // ------------- Validation and ExCombinationAuthors
736
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
737
                taxonName.getExCombinationAuthorship(),
738
                inferExCombinationAuthors(),
739
                exCombinationAuthorshipField,
740
                validationField.getRelatedNameComboBox(),
741
                isInferredExCombinationAuthorship
742
                );
743

    
744
        updateFieldVisibility();
745
    }
746

    
747

    
748
    /**
749
     *
750
     * @param authorship
751
     *    the value of the taxonName authorship field
752
     * @param inferredAuthors
753
     *    the value inferred from other fields which may be set as authorship to the taxon name
754
     * @param authorshipField
755
     *    the ui element to edit the taxonName authorship field
756
     * @param updateTriggerField
757
     * @param lastInferredAuthorshipState
758
     * @return
759
     */
760
    protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
761
            TeamOrPersonField authorshipField, AbstractField updateTriggerField,
762
            Boolean lastInferredAuthorshipState) {
763

    
764
        if(authorship == null){
765
            authorshipField.setValue(inferredAuthors);
766
            lastInferredAuthorshipState = true;
767
        } else {
768
            boolean authorshipMatch = authorship == inferredAuthors;
769
            if(lastInferredAuthorshipState == null){
770
                // initialization of authorshipState, this comes only into account when the editor is just being initialized
771
                lastInferredAuthorshipState = authorshipMatch;
772
            }
773
            if(!authorshipMatch && lastInferredAuthorshipState){
774
                // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
775
                authorshipField.setValue(inferredAuthors);
776
                lastInferredAuthorshipState = true;
777
            }
778
        }
779

    
780
        if(updateTriggerField != null){
781
            // IMPORTANT!
782
            // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
783
            // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
784
            // Otherwise we risk multiple representation problems in the hibernate session
785
            if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
786
                ValueChangeListener listener = e ->  {
787
                    logger.debug(" value changed #2");
788
                    updateAuthorshipFields();
789
                };
790
                updateTriggerField.addValueChangeListener(listener);
791
                authorshipUpdateListeners.put(updateTriggerField, listener);
792
            }
793
        }
794

    
795
        return lastInferredAuthorshipState;
796
    }
797

    
798
    /**
799
     * @param rank
800
     * @return
801
     */
802
    private void updateFieldVisibility() {
803

    
804
        // TODO use getField() instead and remove field references
805
        Rank rank = (Rank) rankSelect.getValue();
806

    
807
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES()) && !rank.getRankClass().equals(RankClass.Unknown);
808
        Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
809
        Boolean withValidationSection = BooleanUtils.isTrue(validationToggle.getValue());
810
        Boolean withOrthographicCorrectionSection = BooleanUtils.isTrue(orthographicVariantToggle.getValue());
811

    
812
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
813
            if(isSpeciesOrBelow) {
814
                if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
815
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
816
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
817
                            this,
818
                            new TaxonNameEditorActionStrRep(
819
                                    EditorActionType.ADD,
820
                                    e.getButton(),
821
                                    combobox,
822
                                    this)
823
                        ));
824
                    combobox.addClickListenerEditEntity(e -> {
825
                        //WeaklyRelatedEntityCombobox<TaxonName> wrcbbx = combobox;
826
                        if(combobox.getValue() != null){
827
                            getViewEventBus().publish(this,
828
                                new TaxonNameEditorActionStrRep(
829
                                        EditorActionType.EDIT,
830
                                        combobox.getIdForValue(),
831
                                        e.getButton(),
832
                                        combobox,
833
                                        this)
834
                            );
835
                        }
836
                    });
837
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
838
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
839
                }
840
            } else {
841
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
842
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new TextFieldNFix(), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
843
                    genusOrUninomialField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
844
                }
845
            }
846
        }
847

    
848
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
849
            if(rank.isInfraSpecific()) {
850
                if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
851
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
852
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
853
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
854
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
855
                            this,
856
                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
857
                        ));
858
                    combobox.addClickListenerEditEntity(e -> {
859
                        if(combobox.getValue() != null){
860
                            getViewEventBus().publish(this,
861
                                new TaxonNameEditorActionStrRep(
862
                                        EditorActionType.EDIT,
863
                                        combobox.getIdForValue(),
864
                                        e.getButton(),
865
                                        combobox,
866
                                        this)
867
                            );
868
                        }
869
                    });
870
                }
871
            } else {
872
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
873
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
874
                    specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
875
               }
876
            }
877
        }
878

    
879
        if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
880
            orthographicVariantField.setCaption("Orthographical correction");
881
            orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
882
            orthographicVariantToggle.setCaption("Orthographical correction");
883
        } else {
884
            orthographicVariantField.setCaption("Orthographical variant");
885
            orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
886
            orthographicVariantToggle.setCaption("Orthographical variant");
887
        }
888

    
889
        genusOrUninomialField.setRequired(true);
890
        specificEpithetField.setVisible(isSpeciesOrBelow);
891
        specificEpithetField.setRequired(isSpeciesOrBelow);
892
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
893
        infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
894
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
895
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
896
        infraGenericEpithetField.setRequired(rank.isInfraGeneric());
897
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
898

    
899
        basionymsComboboxSelect.setVisible(withBasionymSection);
900

    
901
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
902
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
903
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
904

    
905
        validationField.setVisible(withValidationSection);
906
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
907

    
908
        orthographicVariantField.setVisible(withOrthographicCorrectionSection);
909
        if(withOrthographicCorrectionSection){
910
            orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
911
            orthographicVariantField.addValidator(orthographicCorrectionValidator);
912
        } else {
913
            if(orthographicCorrectionValidator  != null){
914
                orthographicVariantField.removeValidator(orthographicCorrectionValidator);
915
                orthographicVariantField = null;
916
            }
917
        }
918

    
919
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
920
        specificEpithetField.setVisible(isSpeciesOrBelow);
921
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
922
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
923
    }
924

    
925

    
926
    @Override
927
    public void cancel() {
928
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
929
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
930
        super.cancel();
931
    }
932

    
933

    
934
    /**
935
     * {@inheritDoc}
936
     */
937
    @Override
938
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
939
        return nomReferenceCombobox;
940
    }
941

    
942

    
943
    /**
944
     * {@inheritDoc}
945
     */
946
    @Override
947
    public TextField getNomenclaturalReferenceDetail() {
948
        return nomenclaturalReferenceDetail;
949
    }
950

    
951
    /**
952
     * {@inheritDoc}
953
     */
954
    @Override
955
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
956
        return basionymsComboboxSelect;
957
    }
958

    
959
    /**
960
     * {@inheritDoc}
961
     */
962
    @Override
963
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
964
        return replacedSynonymsComboboxSelect;
965
    }
966

    
967
    /**
968
     * {@inheritDoc}
969
     */
970
    @Override
971
    public NativeSelect getRankSelect() {
972
        return rankSelect;
973
    }
974

    
975
    /**
976
     * {@inheritDoc}
977
     */
978
    @Override
979
    public AbstractField<String> getGenusOrUninomialField(){
980
        return genusOrUninomialField;
981
    }
982

    
983
    /**
984
     * @return the exBasionymAuthorshipField
985
     */
986
    @Override
987
    public TeamOrPersonField getExBasionymAuthorshipField() {
988
        return exBasionymAuthorshipField;
989
    }
990

    
991
    /**
992
     * @return the basionymAuthorshipField
993
     */
994
    @Override
995
    public TeamOrPersonField getBasionymAuthorshipField() {
996
        return basionymAuthorshipField;
997
    }
998

    
999
    /**
1000
     * @return the combinationAuthorshipField
1001
     */
1002
    @Override
1003
    public TeamOrPersonField getCombinationAuthorshipField() {
1004
        return combinationAuthorshipField;
1005
    }
1006

    
1007
    /**
1008
     * @return the exCombinationAuthorshipField
1009
     */
1010
    @Override
1011
    public TeamOrPersonField getExCombinationAuthorshipField() {
1012
        return exCombinationAuthorshipField;
1013
    }
1014

    
1015
    @Override
1016
    public NameRelationField getValidationField(){
1017
        return validationField;
1018
    }
1019

    
1020
    @Override
1021
    public NameRelationField getOrthographicVariantField() {
1022
        return orthographicVariantField;
1023
    }
1024

    
1025
    @Override
1026
    public void enableMode(TaxonNamePopupEditorMode mode){
1027
            modesActive.add(mode);
1028
            updateFormOnModeChange();
1029
    }
1030

    
1031
    @Override
1032
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1033
        return modesActive.contains(mode);
1034
    }
1035

    
1036
    @Override
1037
    public void disableMode(TaxonNamePopupEditorMode mode){
1038
        modesActive.remove(mode);
1039
        updateFormOnModeChange();
1040
    }
1041

    
1042
    /**
1043
     * updates UI in turn of mode changes if needed, that is when the bean has been set
1044
     * already.
1045
     */
1046
    private void updateFormOnModeChange() {
1047
        if(getBean() != null){
1048
            // need to update the ui
1049
            afterItemDataSourceSet();
1050
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1051
                updateFieldVisibility();
1052
            }
1053
        }
1054
    }
1055

    
1056
    @Override
1057
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1058
        return modesActive;
1059
    }
1060

    
1061
    @Override
1062
    public CheckBox getBasionymToggle() {
1063
        return basionymToggle;
1064
    }
1065

    
1066
    @Override
1067
    public FilterableAnnotationsField getAnnotationsField() {
1068
        return annotationsListField;
1069
    }
1070

    
1071
    /**
1072
     * {@inheritDoc}
1073
     */
1074
    @Override
1075
    public void setReadOnly(boolean readOnly) {
1076
        super.setReadOnly(readOnly);
1077
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1078
        boolean validationToggleReadonly = validationToggle.isReadOnly();
1079
        combinationAuthorshipField.setEditorReadOnly(readOnly);
1080
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1081
        basionymAuthorshipField.setEditorReadOnly(readOnly);
1082
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1083
        // preserve old readonly states if they were true
1084
        if(basionymToggleReadonly){
1085
            basionymToggle.setReadOnly(true);
1086
        }
1087
        if(validationToggleReadonly){
1088
            validationToggle.setReadOnly(true);
1089
        }
1090
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1091
    }
1092

    
1093
    /**
1094
     * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1095
     *
1096
     * @param readOnly
1097
     */
1098
    public void setAllFieldsReadOnly(boolean readOnly) {
1099
        recursiveReadonly(readOnly, getMainLayout());
1100
        // NOTE:We are uUsing the enabled state instead of read only since
1101
        // setting read only will not affect the members editor.
1102
        // this seems to be a bug in TeamOrPersonField or in
1103
        // ToManyRelatedEntitiesListSelect
1104
        combinationAuthorshipField.setEnabled(!readOnly);
1105
        exCombinationAuthorshipField.setEnabled(!readOnly);
1106
        basionymAuthorshipField.setEnabled(!readOnly);
1107
        exBasionymAuthorshipField.setEnabled(!readOnly);
1108
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1109
    }
1110

    
1111

    
1112
    /**
1113
     * @return the infraGenericEpithetField
1114
     */
1115
    @Override
1116
    public AbstractField<String> getInfraGenericEpithetField() {
1117
        return infraGenericEpithetField;
1118
    }
1119

    
1120
    /**
1121
     * @return the specificEpithetField
1122
     */
1123
    @Override
1124
    public AbstractField<String> getSpecificEpithetField() {
1125
        return specificEpithetField;
1126
    }
1127

    
1128
    /**
1129
     * @return the infraSpecificEpithetField
1130
     */
1131
    @Override
1132
    public AbstractField<String> getInfraSpecificEpithetField() {
1133
        return infraSpecificEpithetField;
1134
    }
1135

    
1136
    @Override
1137
    public CheckBox getOrthographicVariantToggle() {
1138
        return orthographicVariantToggle;
1139
    }
1140

    
1141
    @Override
1142
    public ElementCollectionField<NomenclaturalStatus> getNomStatusCollectionField(){
1143
        return nomStatusCollectionField;
1144
    }
1145

    
1146
}
(12-12/15)