Project

General

Profile

Download (48.5 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.shared.ui.MarginInfo;
27
import com.vaadin.spring.annotation.SpringComponent;
28
import com.vaadin.ui.AbstractField;
29
import com.vaadin.ui.Alignment;
30
import com.vaadin.ui.CheckBox;
31
import com.vaadin.ui.Component;
32
import com.vaadin.ui.GridLayout;
33
import com.vaadin.ui.NativeSelect;
34
import com.vaadin.ui.Panel;
35
import com.vaadin.ui.TextField;
36

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

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

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

    
84
    private final static int GRID_COLS = 4;
85

    
86
    private final static int GRID_ROWS = 21;
87

    
88
    private static final boolean HAS_BASIONYM_DEFAULT = false;
89

    
90
    private AbstractField<String> genusOrUninomialField;
91

    
92
    private AbstractField<String> infraGenericEpithetField;
93

    
94
    private AbstractField<String> specificEpithetField;
95

    
96
    private AbstractField<String> infraSpecificEpithetField;
97

    
98
    private SwitchableTextField fullTitleCacheFiled;
99

    
100
    private SwitchableTextField protectedNameCacheField;
101

    
102
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
103

    
104
    private TextField nomenclaturalReferenceDetail;
105

    
106
    private TeamOrPersonField exBasionymAuthorshipField;
107

    
108
    private TeamOrPersonField basionymAuthorshipField;
109

    
110
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
111

    
112
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
113

    
114
    private NameRelationField validationField;
115

    
116
    private NameRelationField orthographicVariantField;
117

    
118
    private CheckBox nomStatusCollectionFieldToggle;
119

    
120
    private ElementCollectionField<NomenclaturalStatusDTO> nomStatusCollectionField;
121

    
122
    private CheckBox basionymToggle;
123

    
124
    private CheckBox replacedSynonymsToggle;
125

    
126
    private CheckBox validationToggle;
127

    
128
    private CheckBox orthographicVariantToggle;
129

    
130
    private NativeSelect rankSelect;
131

    
132
    private TeamOrPersonField combinationAuthorshipField;
133

    
134
    private TeamOrPersonField exCombinationAuthorshipField;
135

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

    
138
    private Boolean isInferredCombinationAuthorship = null;
139

    
140
    private Boolean isInferredBasionymAuthorship = null;
141

    
142
    private Boolean isInferredExBasionymAuthorship = null;
143

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

    
146
    private Boolean isInferredExCombinationAuthorship;
147

    
148
    private int specificEpithetFieldRow;
149

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

    
152
    private FilterableAnnotationsField annotationsListField;
153

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

    
156
    private int genusOrUninomialRow;
157

    
158
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
159

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

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

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

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

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

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

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

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

    
211
    @Override
212
    protected void initContent() {
213

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

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

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

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

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

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

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

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

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

    
263
         ** ViralName attributes **
264
         - acronym
265

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

    
275
        int row = 0;
276

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

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

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

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

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

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

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

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

    
346

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

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

    
356
        // --------------- nom status
357
        row++;
358
        nomStatusCollectionFieldToggle = new CheckBox("Invalid, illegitimate, or other status");
359
        nomStatusCollectionFieldToggle.addValueChangeListener(e -> {
360
            nomStatusCollectionField.getLayout().getParent().setVisible(nomStatusCollectionFieldToggle.getValue());
361
        });
362
        addComponent(nomStatusCollectionFieldToggle, 0, row, 0, row);
363
        row++;
364
        nomStatusCollectionField = new ElementCollectionField<NomenclaturalStatusDTO>(
365
                NomenclaturalStatusDTO.class,
366
                new Instantiator<NomenclaturalStatusDTO>() {
367
                    private static final long serialVersionUID = -2427045940046513092L;
368

    
369
                    @Override
370
                    public NomenclaturalStatusDTO create() {
371
                        return NomenclaturalStatusDTO.newInstance();
372
                    }
373
                },
374
                NomenclaturalStatusRow.class
375
                ){
376
                    private static final long serialVersionUID = -3130918034491809593L;
377

    
378
                    @Override
379
                    public void commit() throws SourceException, InvalidValueException {
380
                        validate(); // validate always so that empty rows are recognized
381
                        super.commit();
382
                    }
383

    
384
                    @Override
385
                    public boolean isEmpty() {
386
                        Collection<?> value = getValue();
387
                        return value == null || value.isEmpty() ;
388
                    }
389

    
390
        };
391

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

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

    
405
        bindField(nomStatusCollectionField, "status");
406
        addComponent(nomStatusCollectionPanel, 0, row, 3, row);
407

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

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

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

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

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

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

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

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

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

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

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

    
560
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
561

    
562
        // -----------------------------------------------------------------------------
563

    
564
        setAdvancedModeEnabled(true);
565
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
566

    
567
        registerAdvancedModeComponents(combinationAuthorshipField);
568
        registerAdvancedModeComponents(basionymAuthorshipField);
569
        registerAdvancedModeComponents(exBasionymAuthorshipField);
570
        registerAdvancedModeComponents(exCombinationAuthorshipField);
571

    
572
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
573
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
574
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
575
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
576

    
577
        setAdvancedMode(false);
578

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

    
582
    }
583

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

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

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

    
614
    protected TeamOrPersonBase inferExCombinationAuthors() {
615
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
616

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

    
637
    @Override
638
    protected void afterItemDataSourceSet() {
639

    
640

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

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

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

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

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

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

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

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

    
706
        TaxonNameDTO taxonName = getBean();
707

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

    
716

    
717
        // ------------- Basionym and ExBasionymAuthors
718
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
719

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

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

    
736
        }
737

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

    
747
        updateFieldVisibility();
748
    }
749

    
750

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

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

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

    
798
        return lastInferredAuthorshipState;
799
    }
800

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

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

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

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

    
851
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
852
            if(rank.isInfraSpecific()) {
853
                if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
854
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
855
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
856
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
857
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
858
                            this,
859
                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
860
                        ));
861
                    combobox.addClickListenerEditEntity(e -> {
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
                }
874
            } else {
875
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
876
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
877
                    specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
878
               }
879
            }
880
        }
881

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

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

    
902
        basionymsComboboxSelect.setVisible(withBasionymSection);
903

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

    
908
        validationField.setVisible(withValidationSection);
909
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
910

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

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

    
927
        updateNomStatusCollectionFieldVisibility();
928

    
929
    }
930

    
931
    public void updateNomStatusCollectionFieldVisibility() {
932
        boolean nameHasStatus = false;
933
        if(nomStatusCollectionField.getLayout().getRows() > 1) {
934
            // fist row holds the lables
935
            NativeSelect fistStatusSelect = (NativeSelect)nomStatusCollectionField.getLayout().getComponent(0, 1);
936
            nameHasStatus = fistStatusSelect.getValue() != null;
937
        }
938
        nomStatusCollectionField.getLayout().getParent().setVisible(nameHasStatus);
939
        nomStatusCollectionFieldToggle.setValue(Boolean.valueOf(nameHasStatus));
940
    }
941

    
942
    @Override
943
    public void cancel() {
944
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
945
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
946
        super.cancel();
947
    }
948

    
949
    @Override
950
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
951
        return nomReferenceCombobox;
952
    }
953

    
954
    @Override
955
    public TextField getNomenclaturalReferenceDetail() {
956
        return nomenclaturalReferenceDetail;
957
    }
958

    
959
    @Override
960
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
961
        return basionymsComboboxSelect;
962
    }
963

    
964
    @Override
965
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
966
        return replacedSynonymsComboboxSelect;
967
    }
968

    
969
    @Override
970
    public NativeSelect getRankSelect() {
971
        return rankSelect;
972
    }
973

    
974
    @Override
975
    public AbstractField<String> getGenusOrUninomialField(){
976
        return genusOrUninomialField;
977
    }
978

    
979
    @Override
980
    public TeamOrPersonField getExBasionymAuthorshipField() {
981
        return exBasionymAuthorshipField;
982
    }
983

    
984
    @Override
985
    public TeamOrPersonField getBasionymAuthorshipField() {
986
        return basionymAuthorshipField;
987
    }
988

    
989
    @Override
990
    public TeamOrPersonField getCombinationAuthorshipField() {
991
        return combinationAuthorshipField;
992
    }
993

    
994
    @Override
995
    public TeamOrPersonField getExCombinationAuthorshipField() {
996
        return exCombinationAuthorshipField;
997
    }
998

    
999
    @Override
1000
    public NameRelationField getValidationField(){
1001
        return validationField;
1002
    }
1003

    
1004
    @Override
1005
    public NameRelationField getOrthographicVariantField() {
1006
        return orthographicVariantField;
1007
    }
1008

    
1009
    @Override
1010
    public void enableMode(TaxonNamePopupEditorMode mode){
1011
            modesActive.add(mode);
1012
            updateFormOnModeChange();
1013
    }
1014

    
1015
    @Override
1016
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1017
        return modesActive.contains(mode);
1018
    }
1019

    
1020
    @Override
1021
    public void disableMode(TaxonNamePopupEditorMode mode){
1022
        modesActive.remove(mode);
1023
        updateFormOnModeChange();
1024
    }
1025

    
1026
    /**
1027
     * updates UI in turn of mode changes if needed, that is when the bean has been set
1028
     * already.
1029
     */
1030
    private void updateFormOnModeChange() {
1031
        if(getBean() != null){
1032
            // need to update the ui
1033
            afterItemDataSourceSet();
1034
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1035
                updateFieldVisibility();
1036
            }
1037
        }
1038
    }
1039

    
1040
    @Override
1041
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1042
        return modesActive;
1043
    }
1044

    
1045
    @Override
1046
    public CheckBox getBasionymToggle() {
1047
        return basionymToggle;
1048
    }
1049

    
1050
    @Override
1051
    public FilterableAnnotationsField getAnnotationsField() {
1052
        return annotationsListField;
1053
    }
1054

    
1055
    @Override
1056
    public void setReadOnly(boolean readOnly) {
1057
        super.setReadOnly(readOnly);
1058
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1059
        boolean validationToggleReadonly = validationToggle.isReadOnly();
1060
        combinationAuthorshipField.setEditorReadOnly(readOnly);
1061
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1062
        basionymAuthorshipField.setEditorReadOnly(readOnly);
1063
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1064
        // preserve old readonly states if they were true
1065
        if(basionymToggleReadonly){
1066
            basionymToggle.setReadOnly(true);
1067
        }
1068
        if(validationToggleReadonly){
1069
            validationToggle.setReadOnly(true);
1070
        }
1071
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1072
    }
1073

    
1074
    /**
1075
     * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1076
     *
1077
     * @param readOnly
1078
     */
1079
    public void setAllFieldsReadOnly(boolean readOnly) {
1080
        recursiveReadonly(readOnly, getMainLayout());
1081
        // NOTE:We are uUsing the enabled state instead of read only since
1082
        // setting read only will not affect the members editor.
1083
        // this seems to be a bug in TeamOrPersonField or in
1084
        // ToManyRelatedEntitiesListSelect
1085
        combinationAuthorshipField.setEnabled(!readOnly);
1086
        exCombinationAuthorshipField.setEnabled(!readOnly);
1087
        basionymAuthorshipField.setEnabled(!readOnly);
1088
        exBasionymAuthorshipField.setEnabled(!readOnly);
1089
        nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1090
    }
1091

    
1092
    @Override
1093
    public AbstractField<String> getInfraGenericEpithetField() {
1094
        return infraGenericEpithetField;
1095
    }
1096

    
1097
    @Override
1098
    public AbstractField<String> getSpecificEpithetField() {
1099
        return specificEpithetField;
1100
    }
1101

    
1102
    @Override
1103
    public AbstractField<String> getInfraSpecificEpithetField() {
1104
        return infraSpecificEpithetField;
1105
    }
1106

    
1107
    @Override
1108
    public CheckBox getOrthographicVariantToggle() {
1109
        return orthographicVariantToggle;
1110
    }
1111

    
1112
    @Override
1113
    public ElementCollectionField<NomenclaturalStatusDTO> getNomStatusCollectionField(){
1114
        return nomStatusCollectionField;
1115
    }
1116
}
(15-15/18)