Project

General

Profile

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

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

    
83
    private static final long serialVersionUID = -7037436241474466359L;
84

    
85
    private final static int GRID_COLS = 4;
86

    
87
    private final static int GRID_ROWS = 20;
88

    
89
    private static final boolean HAS_BASIONYM_DEFAULT = false;
90

    
91
    private AbstractField<String> genusOrUninomialField;
92

    
93
    private AbstractField<String> infraGenericEpithetField;
94

    
95
    private AbstractField<String> specificEpithetField;
96

    
97
    private AbstractField<String> infraSpecificEpithetField;
98

    
99
    private SwitchableTextField fullTitleCacheFiled;
100

    
101
    private SwitchableTextField protectedNameCacheField;
102

    
103
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
104

    
105
    private TextField nomenclaturalReferenceDetail;
106

    
107
    private TeamOrPersonField exBasionymAuthorshipField;
108

    
109
    private TeamOrPersonField basionymAuthorshipField;
110

    
111
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
112

    
113
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
114

    
115
    private NameRelationField validationField;
116

    
117
    private NameRelationField orthographicVariantField;
118

    
119
    private ElementCollectionField<NomenclaturalStatus> nomStatusCollectionField;
120

    
121
    private CheckBox basionymToggle;
122

    
123
    private CheckBox replacedSynonymsToggle;
124

    
125
    private CheckBox validationToggle;
126

    
127
    private CheckBox orthographicVariantToggle;
128

    
129
    private NativeSelect rankSelect;
130

    
131
    private TeamOrPersonField combinationAuthorshipField;
132

    
133
    private TeamOrPersonField exCombinationAuthorshipField;
134

    
135
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
136

    
137
    private Boolean isInferredCombinationAuthorship = null;
138

    
139
    private Boolean isInferredBasionymAuthorship = null;
140

    
141
    private Boolean isInferredExBasionymAuthorship = null;
142

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

    
145
    private Boolean isInferredExCombinationAuthorship;
146

    
147
    private int specificEpithetFieldRow;
148

    
149
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
150

    
151
    private FilterableAnnotationsField annotationsListField;
152

    
153
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
154

    
155
    private int genusOrUninomialRow;
156

    
157
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
158

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

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

    
179
    public TaxonNamePopupEditor() {
180
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
181
    }
182

    
183
    @Override
184
    public String getWindowCaption() {
185
        return "Name editor";
186
    }
187

    
188
    @Override
189
    public int getWindowWidth() {
190
        return 800;
191
    }
192

    
193
    @Override
194
    public void focusFirst() {
195
        // none
196
    }
197

    
198
    @Override
199
    public void applyDefaultComponentStyle(Component ... components){
200
        for(int i = 0; i <components.length; i++){
201
            components[i].setStyleName(getDefaultComponentStyles());
202
        }
203
    }
204

    
205
    @Override
206
    protected String getDefaultComponentStyles() {
207
        return "tiny";
208
    }
209

    
210
    @Override
211
    protected void initContent() {
212

    
213
        GridLayout grid = (GridLayout)getFieldLayout();
214
        grid.setSizeFull();
215
        grid.setHideEmptyRowsAndColumns(true);
216
        grid.setSpacing(true);
217
        grid.setColumnExpandRatio(0, 0.3f);
218
        grid.setColumnExpandRatio(1, 0.3f);
219
        grid.setColumnExpandRatio(2, 0.3f);
220
        grid.setColumnExpandRatio(3, 0.0f);
221

    
222
        /*
223
         * TaxonName properties for reference here (NOTE: this editor operates on TaxonNameDTOs!):
224
         - nameType: preset, needs to be set in the presenter for new names
225
         - appendedPhrase: -> TODO field
226
         - nomenclaturalMicroReference:  -> TODO field
227
         - nomenclaturalSource.citation ->  field but disabled for REGISTRY
228
         - rank -> SelectField which determines the visiblity of the other fields
229

    
230
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
231
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
232

    
233
         - homotypicalGroup -> hidden
234
         - typeDesignations -> hidden
235
         - descriptions -> hidden
236
         - taxonBases -> hidden
237
         - registrations -> hidden
238

    
239
         - relationsFromThisName-> TODO implement later
240
         - relationsToThisName -> TODO implement later
241

    
242
         - genusOrUninomial -> textField
243
         - infraGenericEpithet  -> textField
244
         - specificEpithet  -> textField
245
         - infraSpecificEpithet  -> textField
246

    
247
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
248
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
249
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
250
         - exCombinationAuthorship -> textField
251
         - exBasionymAuthorship -> textField
252

    
253
         - status -> TODO field
254
         - monomHybrid -> TODO implement hybrids later
255
         - binomHybrid -> TODO implement hybrids later
256
         - trinomHybrid -> TODO implement hybrids later
257

    
258
         - hybridParentRelations -> TODO implement hybrids later
259
         - hybridChildRelations -> TODO implement hybrids later
260
         - hybridFormula -> TODO implement hybrids later
261

    
262
         ** ViralName attributes **
263
         - acronym
264

    
265
         ** BacterialName attributes **
266
         - subGenusAuthorship
267
         - nameApprobation
268
         - breed
269
         - publicationYear
270
         - originalPublicationYear
271
         - cultivarName
272
        */
273

    
274
        int row = 0;
275

    
276
        rankSelect = new NativeSelect("Rank");
277
        rankSelect.setNullSelectionAllowed(false);
278
        rankSelect.setWidth(100, Unit.PERCENTAGE);
279
        addField(rankSelect, "rank", 0, row, 1, row);
280
        grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
281

    
282
        row++;
283
        basionymToggle = new CheckBox("With basionym");
284
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
285
        basionymToggle.setStyleName(getDefaultComponentStyles());
286
        grid.addComponent(basionymToggle, 0, row);
287
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
288

    
289
        replacedSynonymsToggle = new CheckBox("With replaced synonym");
290
        grid.addComponent(replacedSynonymsToggle, 1, row);
291
        grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
292

    
293
        validationToggle = new CheckBox("Validation");
294
        grid.addComponent(validationToggle, 2, row);
295
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
296

    
297
        orthographicVariantToggle = new CheckBox("Orthographical variant");
298
        grid.addComponent(orthographicVariantToggle, 3, row);
299
        grid.setComponentAlignment(orthographicVariantToggle, Alignment.BOTTOM_LEFT);
300

    
301
        row++;
302
        // fullTitleCache
303
        fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
304
        fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
305
        row++;
306
        protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
307
        protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
308
        row++;
309
        genusOrUninomialRow = row;
310
        genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
311
        genusOrUninomialField.setWidth(200, Unit.PIXELS);
312
        infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
313
        infraGenericEpithetField.setWidth(200, Unit.PIXELS);
314
        row++;
315
        specificEpithetFieldRow = row;
316
        specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
317
        specificEpithetField.setWidth(200, Unit.PIXELS);
318
        infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
319
        infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
320

    
321
        row++;
322
        combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
323
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
324
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
325

    
326
        row++;
327
        nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
328
        nomReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
329
                this,
330
                new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
331
                ));
332
        nomReferenceCombobox.addClickListenerEditEntity(e -> {
333
            if(nomReferenceCombobox.getValue() != null){
334
                getViewEventBus().publish(this,
335
                    new ReferenceEditorAction(
336
                            EditorActionType.EDIT,
337
                            nomReferenceCombobox.getValue().getUuid(),
338
                            e.getButton(),
339
                            nomReferenceCombobox,
340
                            this)
341
                );
342
            }
343
            });
344

    
345

    
346
        // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
347
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
348
        nomReferenceCombobox.setWidth("100%");
349
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 3, row);
350

    
351
        row++;
352
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 0, row, 2, row);
353
        nomenclaturalReferenceDetail.setWidth(100, Unit.PERCENTAGE);
354

    
355
        // --------------- nom status
356
        row++;
357
        nomStatusCollectionField = new ElementCollectionField<NomenclaturalStatus>(
358
                NomenclaturalStatus.class,
359
                new Instantiator<NomenclaturalStatus>() {
360
                    private static final long serialVersionUID = -2427045940046513092L;
361

    
362
                    @Override
363
                    public NomenclaturalStatus create() {
364
                        return NomenclaturalStatus.NewInstance(null);
365
                    }
366
                },
367
                NomenclaturalStatusRow.class
368
                ){
369
                    private static final long serialVersionUID = -3130918034491809593L;
370

    
371
                    @Override
372
                    public void commit() throws SourceException, InvalidValueException {
373
                        validate(); // validate always so that empty rows are recognized
374
                        super.commit();
375
                    }
376

    
377
                    @Override
378
                    public boolean isEmpty() {
379
                        Collection<?> value = getValue();
380
                        return value == null || value.isEmpty() ;
381
                    }
382

    
383
                    @Override
384
                    public void setComponentError(ErrorMessage componentError) {
385
                        nomStatusCollectionField.setComponentError(componentError);
386
                    }
387

    
388
        };
389

    
390
        nomStatusCollectionField.getLayout().setSpacing(false);
391
        nomStatusCollectionField.setVisibleProperties(NomenclaturalStatusRow.visibleFields());
392
        nomStatusCollectionField.setPropertyHeader("type", "Status type");
393
        nomStatusCollectionField.setPropertyHeader("citation", "Reference");
394
        nomStatusCollectionField.setPropertyHeader("citationMicroReference", "Reference detail");
395
        nomStatusCollectionField.setPropertyHeader("ruleConsidered", "Rule considered");
396
        nomStatusCollectionField.addElementAddedListener( e -> nomStatusCollectionField.setComponentError(null));
397
        nomStatusCollectionField.getLayout().setMargin(new MarginInfo(false, true));
398

    
399
        Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
400
        nomStatusCollectionPanel.setCaption("Status");
401
        nomStatusCollectionPanel.setWidth(100, Unit.PERCENTAGE);
402

    
403
        bindField(nomStatusCollectionField, "status");
404
        addComponent(nomStatusCollectionPanel, 0, row, 3, row);
405

    
406
        // --------------- Basionyms
407
        row++;
408
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
409
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
410
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
411
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
412
        basionymsComboboxSelect.withEditButton(true);
413
        basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
414
        basionymsComboboxSelect.setEditActionListener(e -> {
415

    
416
            Object fieldValue = e.getSource().getValue();
417
            UUID beanUuid = null;
418
            if(fieldValue != null){
419
                beanUuid = ((CdmBase)fieldValue).getUuid();
420

    
421
            }
422
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
423
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
424
        });
425
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
426

    
427
        row++;
428
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
429
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
430
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
431
        row++;
432
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
433
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
434
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
435

    
436
        // --------------- ReplacedSynonyms
437
        row++;
438
        replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Replaced synonym");
439
        replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
440
        addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
441
        replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
442
        replacedSynonymsComboboxSelect.withEditButton(true);
443
        replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
444
        replacedSynonymsComboboxSelect.setEditActionListener(e -> {
445

    
446
            Object fieldValue = e.getSource().getValue();
447
            UUID beanUuid = null;
448
            if(fieldValue != null){
449
                beanUuid = ((CdmBase)fieldValue).getUuid();
450

    
451
            }
452
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
453
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
454
        });
455
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
456

    
457
        // --------------- Validation
458
        row++;
459
        validationField = new NameRelationField("Validation of", "Designation", Direction.relatedTo, NameRelationshipType.VALIDATED_BY_NAME());
460
        validationField.setWidth(100, Unit.PERCENTAGE);
461
        ToOneRelatedEntityCombobox<TaxonName> validatedNameComboBox = validationField.getRelatedNameComboBox();
462
        validatedNameComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
463
                this,
464
                new TaxonNameEditorAction(EditorActionType.ADD, null, validatedNameComboBox, this)
465
                ));
466
        validatedNameComboBox.addClickListenerEditEntity(e -> {
467
            if(validatedNameComboBox.getValue() != null){
468
                getViewEventBus().publish(this,
469
                    new TaxonNameEditorAction(
470
                            EditorActionType.EDIT,
471
                            validatedNameComboBox.getValue().getUuid(),
472
                            e.getButton(),
473
                            validatedNameComboBox,
474
                            this)
475
                );
476
            }
477
        });
478
        ToOneRelatedEntityCombobox<Reference> validationCitatonComboBox = validationField.getCitatonComboBox();
479
        validationCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
480
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
481
                this,
482
                new ReferenceEditorAction(EditorActionType.ADD, null, validationCitatonComboBox, this)
483
                ));
484
        validationCitatonComboBox.addClickListenerEditEntity(e -> {
485
            if(validationCitatonComboBox.getValue() != null){
486
                getViewEventBus().publish(this,
487
                    new ReferenceEditorAction(
488
                            EditorActionType.EDIT,
489
                            validationCitatonComboBox.getValue().getUuid(),
490
                            e.getButton(),
491
                            validationCitatonComboBox,
492
                            this)
493
                );
494
            }
495
        });
496
        addField(validationField, "validationFor", 0, row, 3, row);
497
        grid.setComponentAlignment(validationField, Alignment.TOP_RIGHT);
498

    
499
        // ------- Orthographic Variant (Correction)
500
        row++;
501
        orthographicVariantField = new NameRelationField("Orthographical variant", "Name variant", Direction.relatedTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT());
502
        orthographicVariantField.setWidth(100, Unit.PERCENTAGE);
503
        // corrected name must have same
504
        ToOneRelatedEntityCombobox<TaxonName> orthographicVariantCombobox = orthographicVariantField.getRelatedNameComboBox();
505
        orthographicVariantCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
506
                this,
507
                new TaxonNameEditorAction(EditorActionType.ADD, null, orthographicVariantCombobox, this)
508
                ));
509
        orthographicVariantCombobox.addClickListenerEditEntity(e -> {
510
            if(orthographicVariantCombobox.getValue() != null){
511
                getViewEventBus().publish(this,
512
                    new TaxonNameEditorAction(
513
                            EditorActionType.EDIT,
514
                            orthographicVariantCombobox.getValue().getUuid(),
515
                            e.getButton(),
516
                            orthographicVariantCombobox,
517
                            this)
518
                );
519
            }
520
        });
521
        ToOneRelatedEntityCombobox<Reference> orthographicCorrectionCitatonComboBox = orthographicVariantField.getCitatonComboBox();
522
        orthographicCorrectionCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
523
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
524
                this,
525
                new ReferenceEditorAction(EditorActionType.ADD, null, orthographicCorrectionCitatonComboBox, this)
526
                ));
527
        orthographicCorrectionCitatonComboBox.addClickListenerEditEntity(e -> {
528
            if(orthographicCorrectionCitatonComboBox.getValue() != null){
529
                getViewEventBus().publish(this,
530
                    new ReferenceEditorAction(
531
                            EditorActionType.EDIT,
532
                            orthographicCorrectionCitatonComboBox.getValue().getUuid(),
533
                            e.getButton(),
534
                            orthographicCorrectionCitatonComboBox,
535
                            this)
536
                );
537
            }
538
        });
539
        addField(orthographicVariantField, "orthographicVariant", 0, row, 3, row);
540
        grid.setComponentAlignment(orthographicVariantField, Alignment.TOP_RIGHT);
541

    
542
        row++;
543
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
544
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
545
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
546

    
547
        row++;
548
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
549
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
550
        boolean isCurator = UserHelperAccess.userHelper().userIs(new RoleProber(RolesAndPermissions.ROLE_CURATION));
551
        boolean isAdmin = UserHelperAccess.userHelper().userIsAdmin();
552
        if(isCurator || isAdmin){
553
            annotationsListField.withNewButton(true);
554
        } else {
555
            annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
556
        }
557

    
558
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
559

    
560
        // -----------------------------------------------------------------------------
561

    
562
        setAdvancedModeEnabled(true);
563
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
564

    
565
        registerAdvancedModeComponents(combinationAuthorshipField);
566
        registerAdvancedModeComponents(basionymAuthorshipField);
567
        registerAdvancedModeComponents(exBasionymAuthorshipField);
568
        registerAdvancedModeComponents(exCombinationAuthorshipField);
569

    
570
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
571
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
572
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
573
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
574

    
575
        setAdvancedMode(false);
576

    
577
        //TODO remove below line once #7858 is fixed
578
        withDeleteButton(false);
579

    
580
    }
581

    
582
    protected TeamOrPersonBase inferBasiomynAuthors() {
583
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
584
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
585
            TaxonName basionym = basionyms.get(0);
586
            if(basionym.getCombinationAuthorship() != null){
587
                return basionym.getCombinationAuthorship();
588
            } else if(basionym.getNomenclaturalReference() != null){
589
                return basionym.getNomenclaturalReference().getAuthorship();
590
            }
591
        }
592
        return null;
593
    }
594

    
595
    protected TeamOrPersonBase inferExBasiomynAuthors() {
596
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
597
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
598
            TaxonName basionym = basionyms.get(0);
599
                return basionym.getExCombinationAuthorship();
600
        }
601
        return null;
602
    }
603

    
604
    protected TeamOrPersonBase inferCombinationAuthors() {
605
        Reference nomRef = nomReferenceCombobox.getValue();
606
        if(nomRef != null) {
607
            return nomRef.getAuthorship();
608
        }
609
        return null;
610
    }
611

    
612
    protected TeamOrPersonBase inferExCombinationAuthors() {
613
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
614

    
615
        TeamOrPersonBase inferredExAuthor = null;
616
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
617
            TaxonName validatedName = nameRelationDTO.getOtherName();
618
            if(validatedName.getCombinationAuthorship() != null) {
619
                inferredExAuthor = validatedName.getCombinationAuthorship();
620
            } else if(validatedName.getNomenclaturalReference() != null){
621
                inferredExAuthor = validatedName.getNomenclaturalReference().getAuthorship();
622
            }
623
        }
624
        TeamOrPersonBase inferredCominationAuthors = inferCombinationAuthors();
625
        if(inferredExAuthor != null && inferredCominationAuthors != null
626
                // comparing by nomTitle to detect duplicates:
627
                && inferredExAuthor.getNomenclaturalTitle().equals(inferredCominationAuthors.getNomenclaturalTitle())) {
628
            // If and only if ex author = author the ex author is not included
629
            // into the author teams due to the ICN 46.10. (see #8317)
630
            inferredExAuthor = null;
631
        }
632
        return inferredExAuthor;
633
    }
634

    
635
    @Override
636
    protected void afterItemDataSourceSet() {
637

    
638

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

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

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

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

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

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

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

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

    
704
        TaxonNameDTO taxonName = getBean();
705

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

    
714

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

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

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

    
734
        }
735

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

    
745
        updateFieldVisibility();
746
    }
747

    
748

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

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

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

    
796
        return lastInferredAuthorshipState;
797
    }
798

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

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

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

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

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

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

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

    
900
        basionymsComboboxSelect.setVisible(withBasionymSection);
901

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

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

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

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

    
926

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

    
934
    @Override
935
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
936
        return nomReferenceCombobox;
937
    }
938

    
939
    @Override
940
    public TextField getNomenclaturalReferenceDetail() {
941
        return nomenclaturalReferenceDetail;
942
    }
943

    
944
    @Override
945
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
946
        return basionymsComboboxSelect;
947
    }
948

    
949
    @Override
950
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
951
        return replacedSynonymsComboboxSelect;
952
    }
953

    
954
    @Override
955
    public NativeSelect getRankSelect() {
956
        return rankSelect;
957
    }
958

    
959
    @Override
960
    public AbstractField<String> getGenusOrUninomialField(){
961
        return genusOrUninomialField;
962
    }
963

    
964
    @Override
965
    public TeamOrPersonField getExBasionymAuthorshipField() {
966
        return exBasionymAuthorshipField;
967
    }
968

    
969
    @Override
970
    public TeamOrPersonField getBasionymAuthorshipField() {
971
        return basionymAuthorshipField;
972
    }
973

    
974
    @Override
975
    public TeamOrPersonField getCombinationAuthorshipField() {
976
        return combinationAuthorshipField;
977
    }
978

    
979
    @Override
980
    public TeamOrPersonField getExCombinationAuthorshipField() {
981
        return exCombinationAuthorshipField;
982
    }
983

    
984
    @Override
985
    public NameRelationField getValidationField(){
986
        return validationField;
987
    }
988

    
989
    @Override
990
    public NameRelationField getOrthographicVariantField() {
991
        return orthographicVariantField;
992
    }
993

    
994
    @Override
995
    public void enableMode(TaxonNamePopupEditorMode mode){
996
            modesActive.add(mode);
997
            updateFormOnModeChange();
998
    }
999

    
1000
    @Override
1001
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1002
        return modesActive.contains(mode);
1003
    }
1004

    
1005
    @Override
1006
    public void disableMode(TaxonNamePopupEditorMode mode){
1007
        modesActive.remove(mode);
1008
        updateFormOnModeChange();
1009
    }
1010

    
1011
    /**
1012
     * updates UI in turn of mode changes if needed, that is when the bean has been set
1013
     * already.
1014
     */
1015
    private void updateFormOnModeChange() {
1016
        if(getBean() != null){
1017
            // need to update the ui
1018
            afterItemDataSourceSet();
1019
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1020
                updateFieldVisibility();
1021
            }
1022
        }
1023
    }
1024

    
1025
    @Override
1026
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1027
        return modesActive;
1028
    }
1029

    
1030
    @Override
1031
    public CheckBox getBasionymToggle() {
1032
        return basionymToggle;
1033
    }
1034

    
1035
    @Override
1036
    public FilterableAnnotationsField getAnnotationsField() {
1037
        return annotationsListField;
1038
    }
1039

    
1040
    @Override
1041
    public void setReadOnly(boolean readOnly) {
1042
        super.setReadOnly(readOnly);
1043
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1044
        boolean validationToggleReadonly = validationToggle.isReadOnly();
1045
        combinationAuthorshipField.setEditorReadOnly(readOnly);
1046
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1047
        basionymAuthorshipField.setEditorReadOnly(readOnly);
1048
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1049
        // preserve old readonly states if they were true
1050
        if(basionymToggleReadonly){
1051
            basionymToggle.setReadOnly(true);
1052
        }
1053
        if(validationToggleReadonly){
1054
            validationToggle.setReadOnly(true);
1055
        }
1056
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1057
    }
1058

    
1059
    /**
1060
     * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1061
     *
1062
     * @param readOnly
1063
     */
1064
    public void setAllFieldsReadOnly(boolean readOnly) {
1065
        recursiveReadonly(readOnly, getMainLayout());
1066
        // NOTE:We are uUsing the enabled state instead of read only since
1067
        // setting read only will not affect the members editor.
1068
        // this seems to be a bug in TeamOrPersonField or in
1069
        // ToManyRelatedEntitiesListSelect
1070
        combinationAuthorshipField.setEnabled(!readOnly);
1071
        exCombinationAuthorshipField.setEnabled(!readOnly);
1072
        basionymAuthorshipField.setEnabled(!readOnly);
1073
        exBasionymAuthorshipField.setEnabled(!readOnly);
1074
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1075
    }
1076

    
1077
    @Override
1078
    public AbstractField<String> getInfraGenericEpithetField() {
1079
        return infraGenericEpithetField;
1080
    }
1081

    
1082
    @Override
1083
    public AbstractField<String> getSpecificEpithetField() {
1084
        return specificEpithetField;
1085
    }
1086

    
1087
    @Override
1088
    public AbstractField<String> getInfraSpecificEpithetField() {
1089
        return infraSpecificEpithetField;
1090
    }
1091

    
1092
    @Override
1093
    public CheckBox getOrthographicVariantToggle() {
1094
        return orthographicVariantToggle;
1095
    }
1096

    
1097
    @Override
1098
    public ElementCollectionField<NomenclaturalStatus> getNomStatusCollectionField(){
1099
        return nomStatusCollectionField;
1100
    }
1101
}
(12-12/15)