Project

General

Profile

Download (50.1 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.FontAwesome;
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.Button;
32
import com.vaadin.ui.CheckBox;
33
import com.vaadin.ui.Component;
34
import com.vaadin.ui.CssLayout;
35
import com.vaadin.ui.GridLayout;
36
import com.vaadin.ui.NativeSelect;
37
import com.vaadin.ui.Panel;
38
import com.vaadin.ui.TextField;
39
import com.vaadin.ui.themes.ValoTheme;
40

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

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

    
86
    private static final long serialVersionUID = -7037436241474466359L;
87

    
88
    private final static int GRID_COLS = 4;
89

    
90
    private final static int GRID_ROWS = 21;
91

    
92
    private static final boolean HAS_BASIONYM_DEFAULT = false;
93

    
94
    private AbstractField<String> genusOrUninomialField;
95

    
96
    private AbstractField<String> infraGenericEpithetField;
97

    
98
    private AbstractField<String> specificEpithetField;
99

    
100
    private AbstractField<String> infraSpecificEpithetField;
101

    
102
    private SwitchableTextField fullTitleCacheFiled;
103

    
104
    private SwitchableTextField protectedNameCacheField;
105

    
106
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
107

    
108
    private TextField nomenclaturalReferenceDetail;
109

    
110
    private TeamOrPersonField exBasionymAuthorshipField;
111

    
112
    private TeamOrPersonField basionymAuthorshipField;
113

    
114
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
115

    
116
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
117

    
118
    private NameRelationField validationField;
119

    
120
    private NameRelationField orthographicVariantField;
121

    
122
    private CheckBox nomStatusCollectionFieldToggle;
123

    
124
    private ElementCollectionField<NomenclaturalStatusDTO> nomStatusCollectionField;
125

    
126
    private CheckBox basionymToggle;
127

    
128
    private CheckBox replacedSynonymsToggle;
129

    
130
    private CheckBox validationToggle;
131

    
132
    private CheckBox orthographicVariantToggle;
133

    
134
    private NativeSelect rankSelect;
135

    
136
    private Button rankSelectFullListToggle;
137

    
138
    private TeamOrPersonField combinationAuthorshipField;
139

    
140
    private TeamOrPersonField exCombinationAuthorshipField;
141

    
142
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
143

    
144
    private Boolean isInferredCombinationAuthorship = null;
145

    
146
    private Boolean isInferredBasionymAuthorship = null;
147

    
148
    private Boolean isInferredExBasionymAuthorship = null;
149

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

    
152
    private Boolean isInferredExCombinationAuthorship;
153

    
154
    private int specificEpithetFieldRow;
155

    
156
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
157

    
158
    private FilterableAnnotationsField annotationsListField;
159

    
160
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
161

    
162
    private int genusOrUninomialRow;
163

    
164
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
165

    
166
    private boolean isRanksFullList = false;
167

    
168
    /**
169
     * By default  AnnotationType.EDITORIAL() is enabled.
170
     *
171
     * @return the editableAnotationTypes
172
     */
173
    @Override
174
    public AnnotationType[] getEditableAnotationTypes() {
175
        return editableAnotationTypes;
176
    }
177

    
178
    /**
179
     * By default  AnnotationType.EDITORIAL() is enabled.
180
     *
181
     * @param editableAnotationTypes the editableAnotationTypes to set
182
     */
183
    @Override
184
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
185
        this.editableAnotationTypes = editableAnotationTypes;
186
    }
187

    
188
    public TaxonNamePopupEditor() {
189
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
190
    }
191

    
192
    @Override
193
    public String getWindowCaption() {
194
        return "Name editor";
195
    }
196

    
197
    @Override
198
    public int getWindowWidth() {
199
        return 800;
200
    }
201

    
202
    @Override
203
    public void focusFirst() {
204
        // none
205
    }
206

    
207
    @Override
208
    public void applyDefaultComponentStyle(Component ... components){
209
        for(int i = 0; i <components.length; i++){
210
            components[i].setStyleName(getDefaultComponentStyles());
211
        }
212
    }
213

    
214
    @Override
215
    protected String getDefaultComponentStyles() {
216
        return "tiny";
217
    }
218

    
219
    @Override
220
    protected void initContent() {
221

    
222
        GridLayout grid = (GridLayout)getFieldLayout();
223
        grid.setSizeFull();
224
        grid.setHideEmptyRowsAndColumns(true);
225
        grid.setSpacing(true);
226
        grid.setColumnExpandRatio(0, 0.3f);
227
        grid.setColumnExpandRatio(1, 0.3f);
228
        grid.setColumnExpandRatio(2, 0.3f);
229
        grid.setColumnExpandRatio(3, 0.0f);
230

    
231
        /*
232
         * TaxonName properties for reference here (NOTE: this editor operates on TaxonNameDTOs!):
233
         - nameType: preset, needs to be set in the presenter for new names
234
         - appendedPhrase: -> TODO field
235
         - nomenclaturalMicroReference:  -> TODO field
236
         - nomenclaturalSource.citation ->  field but disabled for REGISTRY
237
         - rank -> SelectField which determines the visiblity of the other fields
238

    
239
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
240
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
241

    
242
         - homotypicalGroup -> hidden
243
         - typeDesignations -> hidden
244
         - descriptions -> hidden
245
         - taxonBases -> hidden
246
         - registrations -> hidden
247

    
248
         - relationsFromThisName-> TODO implement later
249
         - relationsToThisName -> TODO implement later
250

    
251
         - genusOrUninomial -> textField
252
         - infraGenericEpithet  -> textField
253
         - specificEpithet  -> textField
254
         - infraSpecificEpithet  -> textField
255

    
256
         - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
257
         - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
258
         - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
259
         - exCombinationAuthorship -> textField
260
         - exBasionymAuthorship -> textField
261

    
262
         - status -> TODO field
263
         - monomHybrid -> TODO implement hybrids later
264
         - binomHybrid -> TODO implement hybrids later
265
         - trinomHybrid -> TODO implement hybrids later
266

    
267
         - hybridParentRelations -> TODO implement hybrids later
268
         - hybridChildRelations -> TODO implement hybrids later
269
         - hybridFormula -> TODO implement hybrids later
270

    
271
         ** ViralName attributes **
272
         - acronym
273

    
274
         ** BacterialName attributes **
275
         - subGenusAuthorship
276
         - nameApprobation
277
         - breed
278
         - publicationYear
279
         - originalPublicationYear
280
         - cultivarName
281
        */
282

    
283
        int row = 0;
284

    
285
        rankSelect = new NativeSelect("Rank");
286
        rankSelect.setNullSelectionAllowed(false);
287
        rankSelect.setWidth(100, Unit.PERCENTAGE);
288
        rankSelectFullListToggle = new Button();
289
        updateRankSelectFullListToggleButton();
290
        rankSelectFullListToggle.addClickListener(e -> {
291
            isRanksFullList = !isRanksFullList;
292
            updateRankSelectFullListToggleButton();
293
        });
294
        CssLayout rankSelectGroup = new CssLayout();
295
        rankSelectGroup.setWidth(100,  Unit.PERCENTAGE);
296
        rankSelectGroup.addComponents(rankSelect, rankSelectFullListToggle);
297
        bindField(rankSelect, "rank");
298
        applyDefaultComponentStyles(rankSelect);
299
        applyDefaultComponentStyles(rankSelectFullListToggle);
300
        applyDefaultComponentStyle(rankSelectGroup);
301
        addComponent(rankSelectGroup, 0, row, 1, row);
302
        rankSelectGroup.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
303
        grid.setComponentAlignment(rankSelectGroup, Alignment.TOP_RIGHT);
304

    
305
        row++;
306
        basionymToggle = new CheckBox("With basionym");
307
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
308
        basionymToggle.setStyleName(getDefaultComponentStyles());
309
        grid.addComponent(basionymToggle, 0, row);
310
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
311

    
312
        replacedSynonymsToggle = new CheckBox("With replaced synonym");
313
        grid.addComponent(replacedSynonymsToggle, 1, row);
314
        grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
315

    
316
        validationToggle = new CheckBox("Validation");
317
        grid.addComponent(validationToggle, 2, row);
318
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
319

    
320
        orthographicVariantToggle = new CheckBox("Orthographical variant");
321
        grid.addComponent(orthographicVariantToggle, 3, row);
322
        grid.setComponentAlignment(orthographicVariantToggle, Alignment.BOTTOM_LEFT);
323

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

    
344
        row++;
345
        combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
346
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
347
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
348

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

    
368

    
369
        // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
370
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
371
        nomReferenceCombobox.setWidth("100%");
372
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 3, row);
373

    
374
        row++;
375
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 0, row, 2, row);
376
        nomenclaturalReferenceDetail.setWidth(100, Unit.PERCENTAGE);
377

    
378
        // --------------- nom status
379
        row++;
380
        nomStatusCollectionFieldToggle = new CheckBox("Invalid, illegitimate, or other status");
381
        nomStatusCollectionFieldToggle.addValueChangeListener(e -> {
382
            nomStatusCollectionField.getLayout().getParent().setVisible(nomStatusCollectionFieldToggle.getValue());
383
        });
384
        addComponent(nomStatusCollectionFieldToggle, 0, row, 0, row);
385
        row++;
386
        nomStatusCollectionField = new ElementCollectionField<NomenclaturalStatusDTO>(
387
                NomenclaturalStatusDTO.class,
388
                new Instantiator<NomenclaturalStatusDTO>() {
389
                    private static final long serialVersionUID = -2427045940046513092L;
390

    
391
                    @Override
392
                    public NomenclaturalStatusDTO create() {
393
                        return NomenclaturalStatusDTO.newInstance();
394
                    }
395
                },
396
                NomenclaturalStatusRow.class
397
                ){
398
                    private static final long serialVersionUID = -3130918034491809593L;
399

    
400
                    @Override
401
                    public void commit() throws SourceException, InvalidValueException {
402
                        validate(); // validate always so that empty rows are recognized
403
                        super.commit();
404
                    }
405

    
406
                    @Override
407
                    public boolean isEmpty() {
408
                        Collection<?> value = getValue();
409
                        return value == null || value.isEmpty() ;
410
                    }
411

    
412
        };
413

    
414
        nomStatusCollectionField.getLayout().setSpacing(false);
415
        nomStatusCollectionField.setVisibleProperties(NomenclaturalStatusRow.visibleFields());
416
        nomStatusCollectionField.setPropertyHeader("type", "Status type");
417
        nomStatusCollectionField.setPropertyHeader("citation", "Reference");
418
        nomStatusCollectionField.setPropertyHeader("citationMicroReference", "Reference detail");
419
        nomStatusCollectionField.setPropertyHeader("ruleConsidered", "Rule considered");
420
        nomStatusCollectionField.addElementAddedListener( e -> nomStatusCollectionField.setComponentError(null));
421
        nomStatusCollectionField.getLayout().setMargin(new MarginInfo(false, true));
422

    
423
        Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
424
        nomStatusCollectionPanel.setCaption("Status");
425
        nomStatusCollectionPanel.setWidth(100, Unit.PERCENTAGE);
426

    
427
        bindField(nomStatusCollectionField, "status");
428
        addComponent(nomStatusCollectionPanel, 0, row, 3, row);
429

    
430
        // --------------- Basionyms
431
        row++;
432
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
433
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
434
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
435
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
436
        basionymsComboboxSelect.withEditButton(true);
437
        basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
438
        basionymsComboboxSelect.setEditActionListener(e -> {
439

    
440
            Object fieldValue = e.getSource().getValue();
441
            UUID beanUuid = null;
442
            if(fieldValue != null){
443
                beanUuid = ((CdmBase)fieldValue).getUuid();
444

    
445
            }
446
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
447
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
448
        });
449
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
450

    
451
        row++;
452
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
453
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
454
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
455
        row++;
456
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
457
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
458
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
459

    
460
        // --------------- ReplacedSynonyms
461
        row++;
462
        replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Replaced synonym");
463
        replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
464
        addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
465
        replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
466
        replacedSynonymsComboboxSelect.withEditButton(true);
467
        replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
468
        replacedSynonymsComboboxSelect.setEditActionListener(e -> {
469

    
470
            Object fieldValue = e.getSource().getValue();
471
            UUID beanUuid = null;
472
            if(fieldValue != null){
473
                beanUuid = ((CdmBase)fieldValue).getUuid();
474

    
475
            }
476
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
477
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
478
        });
479
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
480

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

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

    
566
        row++;
567
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
568
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
569
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
570

    
571
        row++;
572
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
573
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
574
        boolean isCurator = UserHelperAccess.userHelper().userIs(new RoleProberImpl(RolesAndPermissions.ROLE_CURATION));
575
        boolean isAdmin = UserHelperAccess.userHelper().userIsAdmin();
576
        if(isCurator || isAdmin){
577
            annotationsListField.withNewButton(true);
578
        } else {
579
            annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
580
        }
581

    
582
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
583

    
584
        // -----------------------------------------------------------------------------
585

    
586
        setAdvancedModeEnabled(true);
587
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
588

    
589
        registerAdvancedModeComponents(combinationAuthorshipField);
590
        registerAdvancedModeComponents(basionymAuthorshipField);
591
        registerAdvancedModeComponents(exBasionymAuthorshipField);
592
        registerAdvancedModeComponents(exCombinationAuthorshipField);
593

    
594
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
595
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
596
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
597
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
598

    
599
        setAdvancedMode(false);
600

    
601
        //TODO remove below line once #7858 is fixed
602
        withDeleteButton(false);
603

    
604
    }
605

    
606
    private void updateRankSelectFullListToggleButton() {
607
        if(isRanksFullList) {
608
            rankSelectFullListToggle.setIcon(FontAwesome.COMPRESS);
609
            rankSelectFullListToggle.setDescription("Show short list of ranks");
610
        } else {
611
            rankSelectFullListToggle.setIcon(FontAwesome.EXPAND);
612
            rankSelectFullListToggle.setDescription("Show full list of ranks");
613
        }
614
    }
615

    
616
    protected TeamOrPersonBase inferBasiomynAuthors() {
617
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
618
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
619
            TaxonName basionym = basionyms.get(0);
620
            if(basionym.getCombinationAuthorship() != null){
621
                return basionym.getCombinationAuthorship();
622
            } else if(basionym.getNomenclaturalReference() != null){
623
                return basionym.getNomenclaturalReference().getAuthorship();
624
            }
625
        }
626
        return null;
627
    }
628

    
629
    protected TeamOrPersonBase inferExBasiomynAuthors() {
630
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
631
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
632
            TaxonName basionym = basionyms.get(0);
633
                return basionym.getExCombinationAuthorship();
634
        }
635
        return null;
636
    }
637

    
638
    protected TeamOrPersonBase inferCombinationAuthors() {
639
        Reference nomRef = nomReferenceCombobox.getValue();
640
        if(nomRef != null) {
641
            return nomRef.getAuthorship();
642
        }
643
        return null;
644
    }
645

    
646
    protected TeamOrPersonBase inferExCombinationAuthors() {
647
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
648

    
649
        TeamOrPersonBase inferredExAuthor = null;
650
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
651
            TaxonName validatedName = nameRelationDTO.getOtherName();
652
            if(validatedName.getCombinationAuthorship() != null) {
653
                inferredExAuthor = validatedName.getCombinationAuthorship();
654
            } else if(validatedName.getNomenclaturalReference() != null){
655
                inferredExAuthor = validatedName.getNomenclaturalReference().getAuthorship();
656
            }
657
        }
658
        TeamOrPersonBase<?> inferredCominationAuthors = inferCombinationAuthors();
659
        if(inferredExAuthor != null && inferredCominationAuthors != null
660
                // comparing by nomTitle to detect duplicates:
661
                && inferredExAuthor.getNomenclaturalTitleCache().equals(inferredCominationAuthors.getNomenclaturalTitleCache())) {
662
            // If and only if ex author = author the ex author is not included
663
            // into the author teams due to the ICN 46.10. (see #8317)
664
            inferredExAuthor = null;
665
        }
666
        return inferredExAuthor;
667
    }
668

    
669
    @Override
670
    protected void afterItemDataSourceSet() {
671

    
672

    
673
        rankSelect.addValueChangeListener(updateFieldVisibilityListener);
674
        basionymToggle.addValueChangeListener(e -> {
675
            updateAuthorshipFields();
676
        });
677
        validationToggle.addValueChangeListener(e -> {
678
            updateAuthorshipFields();
679
            });
680
        replacedSynonymsToggle.addValueChangeListener(e -> {
681
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
682
            replacedSynonymsComboboxSelect.setVisible(enable);
683
        });
684
        orthographicVariantToggle.addValueChangeListener(e -> {
685
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
686
            orthographicVariantField.setVisible(enable);
687
        });
688

    
689
        TaxonNameDTO taxonNameDTO = getBean();
690
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
691
                || taxonNameDTO.getBasionymAuthorship() != null
692
                || taxonNameDTO.getExBasionymAuthorship() != null;
693
        basionymToggle.setValue(showBasionymSection);
694
        basionymToggle.setReadOnly(showBasionymSection);
695

    
696
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
697
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
698
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
699
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
700

    
701
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
702
        validationToggle.setValue(showValidationSection);
703
        validationToggle.setReadOnly(showValidationSection);
704

    
705
        boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
706
        orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
707
        orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
708

    
709
        if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
710
            updateAuthorshipFields();
711
        }
712
        if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
713
            nomReferenceCombobox.setDescription("Selection limited to nomenclatural reference and parts of it.");
714
        }
715
        if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
716
            nomReferenceCombobox.setRequired(true);
717
            nomReferenceCombobox.setImmediate(true);
718

    
719
            String userHint = "Please use the 'Edit' function to fix the problem in the related name.";
720
            validationField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
721
            orthographicVariantField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
722
            basionymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
723
            replacedSynonymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
724
        }
725
    }
726

    
727
    /**
728
     * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
729
     * authors from the related nomenclatural reference or taxon name.
730
     * <p>
731
     * Finally the {@link #updateFieldVisibility()} is invoked.
732
     *
733
     * @param taxonName
734
     */
735
    @Override
736
    public void updateAuthorshipFields() {
737

    
738
        TaxonNameDTO taxonName = getBean();
739

    
740
        // ------------- CombinationAuthors
741
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
742
                taxonName.getCombinationAuthorship(),
743
                inferCombinationAuthors(),
744
                combinationAuthorshipField,
745
                nomReferenceCombobox.getSelect(),
746
                isInferredCombinationAuthorship);
747

    
748

    
749
        // ------------- Basionym and ExBasionymAuthors
750
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
751

    
752
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
753
                    taxonName.getBasionymAuthorship(),
754
                    inferBasiomynAuthors(),
755
                    basionymAuthorshipField,
756
                    basionymsComboboxSelect,
757
                    isInferredBasionymAuthorship
758
                    );
759

    
760
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
761
                    taxonName.getExBasionymAuthorship(),
762
                    inferExBasiomynAuthors(),
763
                    exBasionymAuthorshipField,
764
                    basionymsComboboxSelect,
765
                    isInferredExBasionymAuthorship
766
                    );
767

    
768
        }
769

    
770
        // ------------- Validation and ExCombinationAuthors
771
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
772
                taxonName.getExCombinationAuthorship(),
773
                inferExCombinationAuthors(),
774
                exCombinationAuthorshipField,
775
                validationField.getRelatedNameComboBox(),
776
                isInferredExCombinationAuthorship
777
                );
778

    
779
        updateFieldVisibility();
780
    }
781

    
782

    
783
    /**
784
     *
785
     * @param authorship
786
     *    the value of the taxonName authorship field
787
     * @param inferredAuthors
788
     *    the value inferred from other fields which may be set as authorship to the taxon name
789
     * @param authorshipField
790
     *    the ui element to edit the taxonName authorship field
791
     * @param updateTriggerField
792
     * @param lastInferredAuthorshipState
793
     * @return
794
     */
795
    protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
796
            TeamOrPersonField authorshipField, AbstractField updateTriggerField,
797
            Boolean lastInferredAuthorshipState) {
798

    
799
        if(authorship == null){
800
            authorshipField.setValue(inferredAuthors);
801
            lastInferredAuthorshipState = true;
802
        } else {
803
            boolean authorshipMatch = authorship == inferredAuthors;
804
            if(lastInferredAuthorshipState == null){
805
                // initialization of authorshipState, this comes only into account when the editor is just being initialized
806
                lastInferredAuthorshipState = authorshipMatch;
807
            }
808
            if(!authorshipMatch && lastInferredAuthorshipState){
809
                // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
810
                authorshipField.setValue(inferredAuthors);
811
                lastInferredAuthorshipState = true;
812
            }
813
        }
814

    
815
        if(updateTriggerField != null){
816
            // IMPORTANT!
817
            // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
818
            // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
819
            // Otherwise we risk multiple representation problems in the hibernate session
820
            if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
821
                ValueChangeListener listener = e ->  {
822
                    logger.debug(" value changed #2");
823
                    updateAuthorshipFields();
824
                };
825
                updateTriggerField.addValueChangeListener(listener);
826
                authorshipUpdateListeners.put(updateTriggerField, listener);
827
            }
828
        }
829

    
830
        return lastInferredAuthorshipState;
831
    }
832

    
833
    /**
834
     * @param rank
835
     * @return
836
     */
837
    private void updateFieldVisibility() {
838

    
839
        // TODO use getField() instead and remove field references
840
        Rank rank = (Rank) rankSelect.getValue();
841

    
842
        @SuppressWarnings("deprecation")
843
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES()) && !rank.getRankClass().equals(RankClass.Unknown);
844
        Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
845
        Boolean withValidationSection = BooleanUtils.isTrue(validationToggle.getValue());
846
        Boolean withOrthographicCorrectionSection = BooleanUtils.isTrue(orthographicVariantToggle.getValue());
847

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

    
884
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
885
            if(rank.isInfraSpecific()) {
886
                if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
887
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
888
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
889
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
890
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
891
                            this,
892
                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
893
                        ));
894
                    combobox.addClickListenerEditEntity(e -> {
895
                        if(combobox.getValue() != null){
896
                            getViewEventBus().publish(this,
897
                                new TaxonNameEditorActionStrRep(
898
                                        EditorActionType.EDIT,
899
                                        combobox.getIdForValue(),
900
                                        e.getButton(),
901
                                        combobox,
902
                                        this)
903
                            );
904
                        }
905
                    });
906
                }
907
            } else {
908
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
909
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
910
                    specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
911
               }
912
            }
913
        }
914

    
915
        if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
916
            orthographicVariantField.setCaption("Orthographical correction");
917
            orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
918
            orthographicVariantToggle.setCaption("Orthographical correction");
919
        } else {
920
            orthographicVariantField.setCaption("Orthographical variant");
921
            orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
922
            orthographicVariantToggle.setCaption("Orthographical variant");
923
        }
924

    
925
        genusOrUninomialField.setRequired(true);
926
        specificEpithetField.setVisible(isSpeciesOrBelow);
927
        specificEpithetField.setRequired(isSpeciesOrBelow);
928
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
929
        infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
930
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
931
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
932
        infraGenericEpithetField.setRequired(rank.isInfraGeneric());
933
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
934

    
935
        basionymsComboboxSelect.setVisible(withBasionymSection);
936

    
937
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
938
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
939
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
940

    
941
        validationField.setVisible(withValidationSection);
942
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
943

    
944
        orthographicVariantField.setVisible(withOrthographicCorrectionSection);
945
        if(withOrthographicCorrectionSection){
946
            orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
947
            orthographicVariantField.addValidator(orthographicCorrectionValidator);
948
        } else {
949
            if(orthographicCorrectionValidator  != null){
950
                orthographicVariantField.removeValidator(orthographicCorrectionValidator);
951
                orthographicVariantField = null;
952
            }
953
        }
954

    
955
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
956
        specificEpithetField.setVisible(isSpeciesOrBelow);
957
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
958
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
959

    
960
        updateNomStatusCollectionFieldVisibility();
961

    
962
    }
963

    
964
    public void updateNomStatusCollectionFieldVisibility() {
965
        boolean nameHasStatus = false;
966
        if(nomStatusCollectionField.getLayout().getRows() > 1) {
967
            // fist row holds the lables
968
            NativeSelect fistStatusSelect = (NativeSelect)nomStatusCollectionField.getLayout().getComponent(0, 1);
969
            nameHasStatus = fistStatusSelect.getValue() != null;
970
        }
971
        nomStatusCollectionField.getLayout().getParent().setVisible(nameHasStatus);
972
        nomStatusCollectionFieldToggle.setValue(Boolean.valueOf(nameHasStatus));
973
    }
974

    
975
    @Override
976
    public void cancel() {
977
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
978
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
979
        super.cancel();
980
    }
981

    
982
    @Override
983
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
984
        return nomReferenceCombobox;
985
    }
986

    
987
    @Override
988
    public TextField getNomenclaturalReferenceDetail() {
989
        return nomenclaturalReferenceDetail;
990
    }
991

    
992
    @Override
993
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
994
        return basionymsComboboxSelect;
995
    }
996

    
997
    @Override
998
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
999
        return replacedSynonymsComboboxSelect;
1000
    }
1001

    
1002
    @Override
1003
    public NativeSelect getRankSelect() {
1004
        return rankSelect;
1005
    }
1006

    
1007
    @Override
1008
    public Button getRankSelectFullListToggle() {
1009
        return rankSelectFullListToggle;
1010
    }
1011

    
1012
    @Override
1013
    public AbstractField<String> getGenusOrUninomialField(){
1014
        return genusOrUninomialField;
1015
    }
1016

    
1017
    @Override
1018
    public TeamOrPersonField getExBasionymAuthorshipField() {
1019
        return exBasionymAuthorshipField;
1020
    }
1021

    
1022
    @Override
1023
    public TeamOrPersonField getBasionymAuthorshipField() {
1024
        return basionymAuthorshipField;
1025
    }
1026

    
1027
    @Override
1028
    public TeamOrPersonField getCombinationAuthorshipField() {
1029
        return combinationAuthorshipField;
1030
    }
1031

    
1032
    @Override
1033
    public TeamOrPersonField getExCombinationAuthorshipField() {
1034
        return exCombinationAuthorshipField;
1035
    }
1036

    
1037
    @Override
1038
    public NameRelationField getValidationField(){
1039
        return validationField;
1040
    }
1041

    
1042
    @Override
1043
    public NameRelationField getOrthographicVariantField() {
1044
        return orthographicVariantField;
1045
    }
1046

    
1047
    @Override
1048
    public void enableMode(TaxonNamePopupEditorMode mode){
1049
            modesActive.add(mode);
1050
            updateFormOnModeChange();
1051
    }
1052

    
1053
    @Override
1054
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1055
        return modesActive.contains(mode);
1056
    }
1057

    
1058
    @Override
1059
    public boolean isRanksFullList() {
1060
        return isRanksFullList;
1061
    }
1062

    
1063
    @Override
1064
    public void disableMode(TaxonNamePopupEditorMode mode){
1065
        modesActive.remove(mode);
1066
        updateFormOnModeChange();
1067
    }
1068

    
1069
    /**
1070
     * updates UI in turn of mode changes if needed, that is when the bean has been set
1071
     * already.
1072
     */
1073
    private void updateFormOnModeChange() {
1074
        if(getBean() != null){
1075
            // need to update the ui
1076
            afterItemDataSourceSet();
1077
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1078
                updateFieldVisibility();
1079
            }
1080
        }
1081
    }
1082

    
1083
    @Override
1084
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1085
        return modesActive;
1086
    }
1087

    
1088
    @Override
1089
    public CheckBox getBasionymToggle() {
1090
        return basionymToggle;
1091
    }
1092

    
1093
    @Override
1094
    public FilterableAnnotationsField getAnnotationsField() {
1095
        return annotationsListField;
1096
    }
1097

    
1098
    @Override
1099
    public void setReadOnly(boolean readOnly) {
1100
        super.setReadOnly(readOnly);
1101
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1102
        boolean validationToggleReadonly = validationToggle.isReadOnly();
1103
        combinationAuthorshipField.setEditorReadOnly(readOnly);
1104
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1105
        basionymAuthorshipField.setEditorReadOnly(readOnly);
1106
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1107
        // preserve old readonly states if they were true
1108
        if(basionymToggleReadonly){
1109
            basionymToggle.setReadOnly(true);
1110
        }
1111
        if(validationToggleReadonly){
1112
            validationToggle.setReadOnly(true);
1113
        }
1114
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1115
    }
1116

    
1117
    /**
1118
     * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1119
     *
1120
     * @param readOnly
1121
     */
1122
    public void setAllFieldsReadOnly(boolean readOnly) {
1123
        recursiveReadonly(readOnly, getMainLayout());
1124
        // NOTE:We are uUsing the enabled state instead of read only since
1125
        // setting read only will not affect the members editor.
1126
        // this seems to be a bug in TeamOrPersonField or in
1127
        // ToManyRelatedEntitiesListSelect
1128
        combinationAuthorshipField.setEnabled(!readOnly);
1129
        exCombinationAuthorshipField.setEnabled(!readOnly);
1130
        basionymAuthorshipField.setEnabled(!readOnly);
1131
        exBasionymAuthorshipField.setEnabled(!readOnly);
1132
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1133
    }
1134

    
1135
    @Override
1136
    public AbstractField<String> getInfraGenericEpithetField() {
1137
        return infraGenericEpithetField;
1138
    }
1139

    
1140
    @Override
1141
    public AbstractField<String> getSpecificEpithetField() {
1142
        return specificEpithetField;
1143
    }
1144

    
1145
    @Override
1146
    public AbstractField<String> getInfraSpecificEpithetField() {
1147
        return infraSpecificEpithetField;
1148
    }
1149

    
1150
    @Override
1151
    public CheckBox getOrthographicVariantToggle() {
1152
        return orthographicVariantToggle;
1153
    }
1154

    
1155
    @Override
1156
    public ElementCollectionField<NomenclaturalStatusDTO> getNomStatusCollectionField(){
1157
        return nomStatusCollectionField;
1158
    }
1159
}
(15-15/18)