Project

General

Profile

Download (50.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.view.name;
10

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

    
18
import org.apache.commons.lang3.BooleanUtils;
19
import org.apache.logging.log4j.LogManager;
20
import org.apache.logging.log4j.Logger;
21
import org.springframework.context.annotation.Scope;
22
import org.vaadin.viritin.fields.AbstractElementCollection.Instantiator;
23
import org.vaadin.viritin.fields.ElementCollectionField;
24

    
25
import com.vaadin.data.Property;
26
import com.vaadin.data.Property.ValueChangeListener;
27
import com.vaadin.data.Validator.InvalidValueException;
28
import com.vaadin.server.FontAwesome;
29
import com.vaadin.shared.ui.MarginInfo;
30
import com.vaadin.spring.annotation.SpringComponent;
31
import com.vaadin.ui.AbstractField;
32
import com.vaadin.ui.Alignment;
33
import com.vaadin.ui.Button;
34
import com.vaadin.ui.CheckBox;
35
import com.vaadin.ui.Component;
36
import com.vaadin.ui.CssLayout;
37
import com.vaadin.ui.GridLayout;
38
import com.vaadin.ui.NativeSelect;
39
import com.vaadin.ui.Panel;
40
import com.vaadin.ui.TextField;
41
import com.vaadin.ui.themes.ValoTheme;
42

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

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

    
88
    private static final long serialVersionUID = -7037436241474466359L;
89

    
90
    private final static Logger logger = LogManager.getLogger();
91

    
92
    private final static int GRID_COLS = 4;
93

    
94
    private final static int GRID_ROWS = 21;
95

    
96
    private static final boolean HAS_BASIONYM_DEFAULT = false;
97

    
98
    private AbstractField<String> genusOrUninomialField;
99

    
100
    private AbstractField<String> infraGenericEpithetField;
101

    
102
    private AbstractField<String> specificEpithetField;
103

    
104
    private AbstractField<String> infraSpecificEpithetField;
105

    
106
    private SwitchableTextField fullTitleCacheFiled;
107

    
108
    private SwitchableTextField protectedNameCacheField;
109

    
110
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
111

    
112
    private TextField nomenclaturalReferenceDetail;
113

    
114
    private TeamOrPersonField exBasionymAuthorshipField;
115

    
116
    private TeamOrPersonField basionymAuthorshipField;
117

    
118
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
119

    
120
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
121

    
122
    private NameRelationField validationField;
123

    
124
    private NameRelationField orthographicVariantField;
125

    
126
    private CheckBox nomStatusCollectionFieldToggle;
127

    
128
    private ElementCollectionField<NomenclaturalStatusDTO> nomStatusCollectionField;
129

    
130
    private CheckBox basionymToggle;
131

    
132
    private CheckBox replacedSynonymsToggle;
133

    
134
    private CheckBox validationToggle;
135

    
136
    private CheckBox orthographicVariantToggle;
137

    
138
    private NativeSelect rankSelect;
139

    
140
    private Button rankSelectFullListToggle;
141

    
142
    private TeamOrPersonField combinationAuthorshipField;
143

    
144
    private TeamOrPersonField exCombinationAuthorshipField;
145

    
146
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
147

    
148
    private Boolean isInferredCombinationAuthorship = null;
149

    
150
    private Boolean isInferredBasionymAuthorship = null;
151

    
152
    private Boolean isInferredExBasionymAuthorship = null;
153

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

    
156
    private Boolean isInferredExCombinationAuthorship;
157

    
158
    private int specificEpithetFieldRow;
159

    
160
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
161

    
162
    private FilterableAnnotationsField annotationsListField;
163

    
164
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
165

    
166
    private int genusOrUninomialRow;
167

    
168
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
169

    
170
    private boolean isRanksFullList = false;
171

    
172
    /**
173
     * By default  AnnotationType.EDITORIAL() is enabled.
174
     *
175
     * @return the editableAnotationTypes
176
     */
177
    @Override
178
    public AnnotationType[] getEditableAnotationTypes() {
179
        return editableAnotationTypes;
180
    }
181

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

    
192
    public TaxonNamePopupEditor() {
193
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
194
    }
195

    
196
    @Override
197
    public String getWindowCaption() {
198
        return "Name editor";
199
    }
200

    
201
    @Override
202
    public int getWindowWidth() {
203
        return 800;
204
    }
205

    
206
    @Override
207
    public void focusFirst() {
208
        // none
209
    }
210

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

    
218
    @Override
219
    protected String getDefaultComponentStyles() {
220
        return "tiny";
221
    }
222

    
223
    @Override
224
    protected void initContent() {
225

    
226
        GridLayout grid = (GridLayout)getFieldLayout();
227
        grid.setSizeFull();
228
        grid.setHideEmptyRowsAndColumns(true);
229
        grid.setSpacing(true);
230
        grid.setColumnExpandRatio(0, 0.3f);
231
        grid.setColumnExpandRatio(1, 0.3f);
232
        grid.setColumnExpandRatio(2, 0.3f);
233
        grid.setColumnExpandRatio(3, 0.0f);
234

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

    
243
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
244
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
245

    
246
         - homotypicalGroup -> hidden
247
         - typeDesignations -> hidden
248
         - descriptions -> hidden
249
         - taxonBases -> hidden
250
         - registrations -> hidden
251

    
252
         - relationsFromThisName-> TODO implement later
253
         - relationsToThisName -> TODO implement later
254

    
255
         - genusOrUninomial -> textField
256
         - infraGenericEpithet  -> textField
257
         - specificEpithet  -> textField
258
         - infraSpecificEpithet  -> textField
259

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

    
266
         - status -> TODO field
267
         - monomHybrid -> TODO implement hybrids later
268
         - binomHybrid -> TODO implement hybrids later
269
         - trinomHybrid -> TODO implement hybrids later
270

    
271
         - hybridParentRelations -> TODO implement hybrids later
272
         - hybridChildRelations -> TODO implement hybrids later
273
         - hybridFormula -> TODO implement hybrids later
274

    
275
         ** ViralName attributes **
276
         - acronym
277

    
278
         ** BacterialName attributes **
279
         - subGenusAuthorship
280
         - nameApprobation
281
         - breed
282
         - publicationYear
283
         - originalPublicationYear
284
         - cultivarName
285
        */
286

    
287
        int row = 0;
288

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

    
309
        row++;
310
        basionymToggle = new CheckBox("With basionym");
311
        basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
312
        basionymToggle.setStyleName(getDefaultComponentStyles());
313
        grid.addComponent(basionymToggle, 0, row);
314
        grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
315

    
316
        replacedSynonymsToggle = new CheckBox("With replaced synonym");
317
        grid.addComponent(replacedSynonymsToggle, 1, row);
318
        grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
319

    
320
        validationToggle = new CheckBox("Validation");
321
        grid.addComponent(validationToggle, 2, row);
322
        grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
323

    
324
        orthographicVariantToggle = new CheckBox("Orthographical variant");
325
        grid.addComponent(orthographicVariantToggle, 3, row);
326
        grid.setComponentAlignment(orthographicVariantToggle, Alignment.BOTTOM_LEFT);
327

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

    
348
        row++;
349
        combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
350
        combinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
351
        addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
352

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

    
372

    
373
        // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
374
        // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
375
        nomReferenceCombobox.setWidth("100%");
376
        addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 3, row);
377

    
378
        row++;
379
        nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 0, row, 2, row);
380
        nomenclaturalReferenceDetail.setWidth(100, Unit.PERCENTAGE);
381

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

    
395
                    @Override
396
                    public NomenclaturalStatusDTO create() {
397
                        return NomenclaturalStatusDTO.newInstance();
398
                    }
399
                },
400
                NomenclaturalStatusRow.class
401
                ){
402
                    private static final long serialVersionUID = -3130918034491809593L;
403

    
404
                    @Override
405
                    public void commit() throws SourceException, InvalidValueException {
406
                        validate(); // validate always so that empty rows are recognized
407
                        super.commit();
408
                    }
409

    
410
                    @Override
411
                    public boolean isEmpty() {
412
                        Collection<?> value = getValue();
413
                        return value == null || value.isEmpty() ;
414
                    }
415

    
416
        };
417

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

    
427
        Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
428
        nomStatusCollectionPanel.setCaption("Status");
429
        nomStatusCollectionPanel.setWidth(100, Unit.PERCENTAGE);
430

    
431
        bindField(nomStatusCollectionField, "status");
432
        addComponent(nomStatusCollectionPanel, 0, row, 3, row);
433

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

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

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

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

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

    
474
            Object fieldValue = e.getSource().getValue();
475
            UUID beanUuid = null;
476
            if(fieldValue != null){
477
                beanUuid = ((CdmBase)fieldValue).getUuid();
478

    
479
            }
480
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
481
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
482
        });
483
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
484

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

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

    
570
        row++;
571
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
572
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
573
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
574

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

    
586
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
587

    
588
        // -----------------------------------------------------------------------------
589

    
590
        setAdvancedModeEnabled(true);
591
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
592

    
593
        registerAdvancedModeComponents(combinationAuthorshipField);
594
        registerAdvancedModeComponents(basionymAuthorshipField);
595
        registerAdvancedModeComponents(exBasionymAuthorshipField);
596
        registerAdvancedModeComponents(exCombinationAuthorshipField);
597

    
598
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
599
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
600
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
601
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
602

    
603
        setAdvancedMode(false);
604

    
605
        //TODO remove below line once #7858 is fixed
606
        withDeleteButton(false);
607

    
608
    }
609

    
610
    private void updateRankSelectFullListToggleButton() {
611
        if(isRanksFullList) {
612
            rankSelectFullListToggle.setIcon(FontAwesome.COMPRESS);
613
            rankSelectFullListToggle.setDescription("Show short list of ranks");
614
        } else {
615
            rankSelectFullListToggle.setIcon(FontAwesome.EXPAND);
616
            rankSelectFullListToggle.setDescription("Show full list of ranks");
617
        }
618
    }
619

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

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

    
642
    protected TeamOrPersonBase inferCombinationAuthors() {
643
        Reference nomRef = nomReferenceCombobox.getValue();
644
        if(nomRef != null) {
645
            return nomRef.getAuthorship();
646
        }
647
        return null;
648
    }
649

    
650
    protected TeamOrPersonBase inferExCombinationAuthors() {
651
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
652

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

    
673
    @Override
674
    protected void afterItemDataSourceSet() {
675

    
676

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

    
693
        TaxonNameDTO taxonNameDTO = getBean();
694
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
695
                || taxonNameDTO.getBasionymAuthorship() != null
696
                || taxonNameDTO.getExBasionymAuthorship() != null;
697
        basionymToggle.setValue(showBasionymSection);
698
        basionymToggle.setReadOnly(showBasionymSection);
699

    
700
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
701
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
702
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
703
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
704

    
705
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
706
        validationToggle.setValue(showValidationSection);
707
        validationToggle.setReadOnly(showValidationSection);
708

    
709
        boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
710
        orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
711
        orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
712

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

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

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

    
742
        TaxonNameDTO taxonName = getBean();
743

    
744
        // ------------- CombinationAuthors
745
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
746
                taxonName.getCombinationAuthorship(),
747
                inferCombinationAuthors(),
748
                combinationAuthorshipField,
749
                nomReferenceCombobox.getSelect(),
750
                isInferredCombinationAuthorship);
751

    
752

    
753
        // ------------- Basionym and ExBasionymAuthors
754
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
755

    
756
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
757
                    taxonName.getBasionymAuthorship(),
758
                    inferBasiomynAuthors(),
759
                    basionymAuthorshipField,
760
                    basionymsComboboxSelect,
761
                    isInferredBasionymAuthorship
762
                    );
763

    
764
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
765
                    taxonName.getExBasionymAuthorship(),
766
                    inferExBasiomynAuthors(),
767
                    exBasionymAuthorshipField,
768
                    basionymsComboboxSelect,
769
                    isInferredExBasionymAuthorship
770
                    );
771

    
772
        }
773

    
774
        // ------------- Validation and ExCombinationAuthors
775
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
776
                taxonName.getExCombinationAuthorship(),
777
                inferExCombinationAuthors(),
778
                exCombinationAuthorshipField,
779
                validationField.getRelatedNameComboBox(),
780
                isInferredExCombinationAuthorship
781
                );
782

    
783
        updateFieldVisibility();
784
    }
785

    
786

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

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

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

    
834
        return lastInferredAuthorshipState;
835
    }
836

    
837
    /**
838
     * @param rank
839
     * @return
840
     */
841
    private void updateFieldVisibility() {
842

    
843
        // TODO use getField() instead and remove field references
844
        Rank rank = (Rank) rankSelect.getValue();
845

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

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

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

    
919
        if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
920
            orthographicVariantField.setCaption("Orthographical correction");
921
            orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
922
            orthographicVariantToggle.setCaption("Orthographical correction");
923
        } else {
924
            orthographicVariantField.setCaption("Orthographical variant");
925
            orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
926
            orthographicVariantToggle.setCaption("Orthographical variant");
927
        }
928

    
929
        genusOrUninomialField.setRequired(true);
930
        specificEpithetField.setVisible(isSpeciesOrBelow);
931
        specificEpithetField.setRequired(isSpeciesOrBelow);
932
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
933
        infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
934
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
935
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
936
        infraGenericEpithetField.setRequired(rank.isInfraGeneric());
937
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
938

    
939
        basionymsComboboxSelect.setVisible(withBasionymSection);
940

    
941
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
942
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
943
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
944

    
945
        validationField.setVisible(withValidationSection);
946
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
947

    
948
        orthographicVariantField.setVisible(withOrthographicCorrectionSection);
949
        if(withOrthographicCorrectionSection){
950
            orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
951
            orthographicVariantField.addValidator(orthographicCorrectionValidator);
952
        } else {
953
            if(orthographicCorrectionValidator  != null){
954
                orthographicVariantField.removeValidator(orthographicCorrectionValidator);
955
                orthographicVariantField = null;
956
            }
957
        }
958

    
959
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
960
        specificEpithetField.setVisible(isSpeciesOrBelow);
961
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
962
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
963

    
964
        updateNomStatusCollectionFieldVisibility();
965

    
966
    }
967

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

    
979
    @Override
980
    public void cancel() {
981
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
982
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
983
        super.cancel();
984
    }
985

    
986
    @Override
987
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
988
        return nomReferenceCombobox;
989
    }
990

    
991
    @Override
992
    public TextField getNomenclaturalReferenceDetail() {
993
        return nomenclaturalReferenceDetail;
994
    }
995

    
996
    @Override
997
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
998
        return basionymsComboboxSelect;
999
    }
1000

    
1001
    @Override
1002
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
1003
        return replacedSynonymsComboboxSelect;
1004
    }
1005

    
1006
    @Override
1007
    public NativeSelect getRankSelect() {
1008
        return rankSelect;
1009
    }
1010

    
1011
    @Override
1012
    public Button getRankSelectFullListToggle() {
1013
        return rankSelectFullListToggle;
1014
    }
1015

    
1016
    @Override
1017
    public AbstractField<String> getGenusOrUninomialField(){
1018
        return genusOrUninomialField;
1019
    }
1020

    
1021
    @Override
1022
    public TeamOrPersonField getExBasionymAuthorshipField() {
1023
        return exBasionymAuthorshipField;
1024
    }
1025

    
1026
    @Override
1027
    public TeamOrPersonField getBasionymAuthorshipField() {
1028
        return basionymAuthorshipField;
1029
    }
1030

    
1031
    @Override
1032
    public TeamOrPersonField getCombinationAuthorshipField() {
1033
        return combinationAuthorshipField;
1034
    }
1035

    
1036
    @Override
1037
    public TeamOrPersonField getExCombinationAuthorshipField() {
1038
        return exCombinationAuthorshipField;
1039
    }
1040

    
1041
    @Override
1042
    public NameRelationField getValidationField(){
1043
        return validationField;
1044
    }
1045

    
1046
    @Override
1047
    public NameRelationField getOrthographicVariantField() {
1048
        return orthographicVariantField;
1049
    }
1050

    
1051
    @Override
1052
    public void enableMode(TaxonNamePopupEditorMode mode){
1053
            modesActive.add(mode);
1054
            updateFormOnModeChange();
1055
    }
1056

    
1057
    @Override
1058
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1059
        return modesActive.contains(mode);
1060
    }
1061

    
1062
    @Override
1063
    public boolean isRanksFullList() {
1064
        return isRanksFullList;
1065
    }
1066

    
1067
    @Override
1068
    public void disableMode(TaxonNamePopupEditorMode mode){
1069
        modesActive.remove(mode);
1070
        updateFormOnModeChange();
1071
    }
1072

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

    
1087
    @Override
1088
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1089
        return modesActive;
1090
    }
1091

    
1092
    @Override
1093
    public CheckBox getBasionymToggle() {
1094
        return basionymToggle;
1095
    }
1096

    
1097
    @Override
1098
    public FilterableAnnotationsField getAnnotationsField() {
1099
        return annotationsListField;
1100
    }
1101

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

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

    
1139
    @Override
1140
    public AbstractField<String> getInfraGenericEpithetField() {
1141
        return infraGenericEpithetField;
1142
    }
1143

    
1144
    @Override
1145
    public AbstractField<String> getSpecificEpithetField() {
1146
        return specificEpithetField;
1147
    }
1148

    
1149
    @Override
1150
    public AbstractField<String> getInfraSpecificEpithetField() {
1151
        return infraSpecificEpithetField;
1152
    }
1153

    
1154
    @Override
1155
    public CheckBox getOrthographicVariantToggle() {
1156
        return orthographicVariantToggle;
1157
    }
1158

    
1159
    @Override
1160
    public ElementCollectionField<NomenclaturalStatusDTO> getNomStatusCollectionField(){
1161
        return nomStatusCollectionField;
1162
    }
1163
}
(15-15/18)