Project

General

Profile

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

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

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

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

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

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

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

    
86
    private final static int GRID_COLS = 4;
87

    
88
    private final static int GRID_ROWS = 20;
89

    
90
    private static final boolean HAS_BASIONYM_DEFAULT = false;
91

    
92
    private AbstractField<String> genusOrUninomialField;
93

    
94
    private AbstractField<String> infraGenericEpithetField;
95

    
96
    private AbstractField<String> specificEpithetField;
97

    
98
    private AbstractField<String> infraSpecificEpithetField;
99

    
100
    private SwitchableTextField fullTitleCacheFiled;
101

    
102
    private SwitchableTextField protectedNameCacheField;
103

    
104
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
105

    
106
    private TextField nomenclaturalReferenceDetail;
107

    
108
    private TeamOrPersonField exBasionymAuthorshipField;
109

    
110
    private TeamOrPersonField basionymAuthorshipField;
111

    
112
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
113

    
114
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
115

    
116
    private NameRelationField validationField;
117

    
118
    private NameRelationField orthographicVariantField;
119

    
120
    private ElementCollectionField<NomenclaturalStatus> 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
     *
174
     * @param editableAnotationTypes the editableAnotationTypes to set
175
     */
176
    @Override
177
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
178
        this.editableAnotationTypes = editableAnotationTypes;
179
    }
180

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

    
189
    /**
190
     * {@inheritDoc}
191
     */
192
    @Override
193
    public String getWindowCaption() {
194
        return "Name editor";
195
    }
196

    
197

    
198
    /**
199
     * {@inheritDoc}
200
     */
201
    @Override
202
    public int getWindowWidth() {
203
        return 800;
204
    }
205

    
206
    /**
207
     * {@inheritDoc}
208
     */
209
    @Override
210
    public void focusFirst() {
211
        // none
212
    }
213

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

    
221
    /**
222
     * {@inheritDoc}
223
     */
224
    @Override
225
    protected String getDefaultComponentStyles() {
226
        return "tiny";
227
    }
228

    
229
    /**
230
     * {@inheritDoc}
231
     */
232
    @Override
233
    protected void initContent() {
234

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

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

    
251
         - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
252
         - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
253

    
254
         - homotypicalGroup -> hidden
255
         - typeDesignations -> hidden
256
         - descriptions -> hidden
257
         - taxonBases -> hidden
258
         - registrations -> hidden
259

    
260
         - relationsFromThisName-> TODO implement later
261
         - relationsToThisName -> TODO implement later
262

    
263
         - genusOrUninomial -> textField
264
         - infraGenericEpithet  -> textField
265
         - specificEpithet  -> textField
266
         - infraSpecificEpithet  -> textField
267

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

    
274
         - status -> TODO field
275
         - monomHybrid -> TODO implement hybrids later
276
         - binomHybrid -> TODO implement hybrids later
277
         - trinomHybrid -> TODO implement hybrids later
278

    
279
         - hybridParentRelations -> TODO implement hybrids later
280
         - hybridChildRelations -> TODO implement hybrids later
281
         - hybridFormula -> TODO implement hybrids later
282

    
283
         ** ViralName attributes **
284
         - acronym
285

    
286
         ** BacterialName attributes **
287
         - subGenusAuthorship
288
         - nameApprobation
289
         - breed
290
         - publicationYear
291
         - originalPublicationYear
292
         - cultivarName
293
        */
294

    
295
        int row = 0;
296

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

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

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

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

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

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

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

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

    
366

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

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

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

    
382
                    @Override
383
                    public NomenclaturalStatus create() {
384
                        return NomenclaturalStatus.NewInstance(null);
385
                    }
386
                },
387
                NomenclaturalStatusRow.class
388
                ){
389

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

    
396
                    @Override
397
                    public boolean isEmpty() {
398
                        Collection value = getValue();
399
                        return value == null || value.isEmpty() ;
400
                    }
401

    
402
                    @Override
403
                    public void setComponentError(ErrorMessage componentError) {
404
                        nomStatusCollectionField.setComponentError(componentError);
405
                    }
406

    
407
        };
408

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

    
418
        Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
419
        nomStatusCollectionPanel.setCaption("Status");
420
        nomStatusCollectionPanel.setWidth(100, Unit.PERCENTAGE);
421

    
422
        bindField(nomStatusCollectionField, "status");
423
        addComponent(nomStatusCollectionPanel, 0, row, 3, row);
424

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

    
435
            Object fieldValue = e.getSource().getValue();
436
            UUID beanUuid = null;
437
            if(fieldValue != null){
438
                beanUuid = ((CdmBase)fieldValue).getUuid();
439

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

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

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

    
465
            Object fieldValue = e.getSource().getValue();
466
            UUID beanUuid = null;
467
            if(fieldValue != null){
468
                beanUuid = ((CdmBase)fieldValue).getUuid();
469

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

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

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

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

    
566
        row++;
567
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
568
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
569
        boolean isCurator = UserHelperAccess.userHelper().userIs(new RoleProber(RolesAndPermissions.ROLE_CURATION));
570
        boolean isAdmin = UserHelperAccess.userHelper().userIsAdmin();
571
        if(isCurator || isAdmin){
572
            annotationsListField.withNewButton(true);
573
        } else {
574
            annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
575
        }
576

    
577
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
578

    
579
        // -----------------------------------------------------------------------------
580

    
581
        setAdvancedModeEnabled(true);
582
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
583

    
584
        registerAdvancedModeComponents(combinationAuthorshipField);
585
        registerAdvancedModeComponents(basionymAuthorshipField);
586
        registerAdvancedModeComponents(exBasionymAuthorshipField);
587
        registerAdvancedModeComponents(exCombinationAuthorshipField);
588

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

    
594
        setAdvancedMode(false);
595

    
596
        //TODO remove below line once #7858 is fixed
597
        withDeleteButton(false);
598

    
599
    }
600

    
601
    protected TeamOrPersonBase inferBasiomynAuthors() {
602
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
603
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
604
            TaxonName basionym = basionyms.get(0);
605
            if(basionym.getCombinationAuthorship() != null){
606
                return basionym.getCombinationAuthorship();
607
            } else if(basionym.getNomenclaturalReference() != null){
608
                return basionym.getNomenclaturalReference().getAuthorship();
609
            }
610
        }
611
        return null;
612
    }
613

    
614
    protected TeamOrPersonBase inferExBasiomynAuthors() {
615
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
616
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
617
            TaxonName basionym = basionyms.get(0);
618
                return basionym.getExCombinationAuthorship();
619
        }
620
        return null;
621
    }
622

    
623
    protected TeamOrPersonBase inferCombinationAuthors() {
624
        Reference nomRef = nomReferenceCombobox.getValue();
625
        if(nomRef != null) {
626
            return nomRef.getAuthorship();
627
        }
628
        return null;
629
    }
630

    
631
    protected TeamOrPersonBase inferExCombinationAuthors() {
632
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
633

    
634
        TeamOrPersonBase inferredExAuthor = null;
635
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
636
            TaxonName validatedName = nameRelationDTO.getOtherName();
637
            if(validatedName.getCombinationAuthorship() != null) {
638
                inferredExAuthor = validatedName.getCombinationAuthorship();
639
            } else if(validatedName.getNomenclaturalReference() != null){
640
                inferredExAuthor = validatedName.getNomenclaturalReference().getAuthorship();
641
            }
642
        }
643
        TeamOrPersonBase inferredCominationAuthors = inferCombinationAuthors();
644
        if(inferredExAuthor != null && inferredCominationAuthors != null
645
                // comparing by nomTitle to detect duplicates:
646
                && inferredExAuthor.getNomenclaturalTitle().equals(inferredCominationAuthors.getNomenclaturalTitle())) {
647
            // If and only if ex author = author the ex author is not included
648
            // into the author teams due to the ICN 46.10. (see #8317)
649
            inferredExAuthor = null;
650
        }
651
        return inferredExAuthor;
652
    }
653

    
654
    @Override
655
    protected void afterItemDataSourceSet() {
656

    
657

    
658
        rankSelect.addValueChangeListener(updateFieldVisibilityListener);
659
        basionymToggle.addValueChangeListener(e -> {
660
            updateAuthorshipFields();
661
        });
662
        validationToggle.addValueChangeListener(e -> {
663
            updateAuthorshipFields();
664
            });
665
        replacedSynonymsToggle.addValueChangeListener(e -> {
666
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
667
            replacedSynonymsComboboxSelect.setVisible(enable);
668
        });
669
        orthographicVariantToggle.addValueChangeListener(e -> {
670
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
671
            orthographicVariantField.setVisible(enable);
672
        });
673

    
674
        TaxonNameDTO taxonNameDTO = getBean();
675
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
676
                || taxonNameDTO.getBasionymAuthorship() != null
677
                || taxonNameDTO.getExBasionymAuthorship() != null;
678
        basionymToggle.setValue(showBasionymSection);
679
        basionymToggle.setReadOnly(showBasionymSection);
680

    
681
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
682
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
683
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
684
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
685

    
686
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
687
        validationToggle.setValue(showValidationSection);
688
        validationToggle.setReadOnly(showValidationSection);
689

    
690
        boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
691
        orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
692
        orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
693

    
694
        if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
695
            updateAuthorshipFields();
696
        }
697
        if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
698
            nomReferenceCombobox.setDescription("Selection limited to nomenclatural reference and parts of it.");
699
        }
700
        if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
701
            nomReferenceCombobox.setRequired(true);
702
            nomReferenceCombobox.setImmediate(true);
703

    
704
            String userHint = "Please use the 'Edit' function to fix the problem in the related name.";
705
            validationField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
706
            orthographicVariantField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
707
            basionymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
708
            replacedSynonymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
709
        }
710
    }
711

    
712
    /**
713
     * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
714
     * authors from the related nomenclatural reference or taxon name.
715
     * <p>
716
     * Finally the {@link #updateFieldVisibility()} is invoked.
717
     *
718
     * @param taxonName
719
     */
720
    @Override
721
    public void updateAuthorshipFields() {
722

    
723
        TaxonNameDTO taxonName = getBean();
724

    
725
        // ------------- CombinationAuthors
726
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
727
                taxonName.getCombinationAuthorship(),
728
                inferCombinationAuthors(),
729
                combinationAuthorshipField,
730
                nomReferenceCombobox.getSelect(),
731
                isInferredCombinationAuthorship);
732

    
733

    
734
        // ------------- Basionym and ExBasionymAuthors
735
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
736

    
737
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
738
                    taxonName.getBasionymAuthorship(),
739
                    inferBasiomynAuthors(),
740
                    basionymAuthorshipField,
741
                    basionymsComboboxSelect,
742
                    isInferredBasionymAuthorship
743
                    );
744

    
745
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
746
                    taxonName.getExBasionymAuthorship(),
747
                    inferExBasiomynAuthors(),
748
                    exBasionymAuthorshipField,
749
                    basionymsComboboxSelect,
750
                    isInferredExBasionymAuthorship
751
                    );
752

    
753
        }
754

    
755
        // ------------- Validation and ExCombinationAuthors
756
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
757
                taxonName.getExCombinationAuthorship(),
758
                inferExCombinationAuthors(),
759
                exCombinationAuthorshipField,
760
                validationField.getRelatedNameComboBox(),
761
                isInferredExCombinationAuthorship
762
                );
763

    
764
        updateFieldVisibility();
765
    }
766

    
767

    
768
    /**
769
     *
770
     * @param authorship
771
     *    the value of the taxonName authorship field
772
     * @param inferredAuthors
773
     *    the value inferred from other fields which may be set as authorship to the taxon name
774
     * @param authorshipField
775
     *    the ui element to edit the taxonName authorship field
776
     * @param updateTriggerField
777
     * @param lastInferredAuthorshipState
778
     * @return
779
     */
780
    protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
781
            TeamOrPersonField authorshipField, AbstractField updateTriggerField,
782
            Boolean lastInferredAuthorshipState) {
783

    
784
        if(authorship == null){
785
            authorshipField.setValue(inferredAuthors);
786
            lastInferredAuthorshipState = true;
787
        } else {
788
            boolean authorshipMatch = authorship == inferredAuthors;
789
            if(lastInferredAuthorshipState == null){
790
                // initialization of authorshipState, this comes only into account when the editor is just being initialized
791
                lastInferredAuthorshipState = authorshipMatch;
792
            }
793
            if(!authorshipMatch && lastInferredAuthorshipState){
794
                // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
795
                authorshipField.setValue(inferredAuthors);
796
                lastInferredAuthorshipState = true;
797
            }
798
        }
799

    
800
        if(updateTriggerField != null){
801
            // IMPORTANT!
802
            // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
803
            // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
804
            // Otherwise we risk multiple representation problems in the hibernate session
805
            if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
806
                ValueChangeListener listener = e ->  {
807
                    logger.debug(" value changed #2");
808
                    updateAuthorshipFields();
809
                };
810
                updateTriggerField.addValueChangeListener(listener);
811
                authorshipUpdateListeners.put(updateTriggerField, listener);
812
            }
813
        }
814

    
815
        return lastInferredAuthorshipState;
816
    }
817

    
818
    /**
819
     * @param rank
820
     * @return
821
     */
822
    private void updateFieldVisibility() {
823

    
824
        // TODO use getField() instead and remove field references
825
        Rank rank = (Rank) rankSelect.getValue();
826

    
827
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES()) && !rank.getRankClass().equals(RankClass.Unknown);
828
        Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
829
        Boolean withValidationSection = BooleanUtils.isTrue(validationToggle.getValue());
830
        Boolean withOrthographicCorrectionSection = BooleanUtils.isTrue(orthographicVariantToggle.getValue());
831

    
832
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
833
            if(isSpeciesOrBelow) {
834
                if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
835
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
836
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
837
                            this,
838
                            new TaxonNameEditorActionStrRep(
839
                                    EditorActionType.ADD,
840
                                    e.getButton(),
841
                                    combobox,
842
                                    this)
843
                        ));
844
                    combobox.addClickListenerEditEntity(e -> {
845
                        //WeaklyRelatedEntityCombobox<TaxonName> wrcbbx = combobox;
846
                        if(combobox.getValue() != null){
847
                            getViewEventBus().publish(this,
848
                                new TaxonNameEditorActionStrRep(
849
                                        EditorActionType.EDIT,
850
                                        combobox.getIdForValue(),
851
                                        e.getButton(),
852
                                        combobox,
853
                                        this)
854
                            );
855
                        }
856
                    });
857
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
858
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
859
                }
860
            } else {
861
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
862
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new TextFieldNFix(), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
863
                    genusOrUninomialField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
864
                }
865
            }
866
        }
867

    
868
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
869
            if(rank.isInfraSpecific()) {
870
                if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
871
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
872
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
873
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
874
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
875
                            this,
876
                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
877
                        ));
878
                    combobox.addClickListenerEditEntity(e -> {
879
                        if(combobox.getValue() != null){
880
                            getViewEventBus().publish(this,
881
                                new TaxonNameEditorActionStrRep(
882
                                        EditorActionType.EDIT,
883
                                        combobox.getIdForValue(),
884
                                        e.getButton(),
885
                                        combobox,
886
                                        this)
887
                            );
888
                        }
889
                    });
890
                }
891
            } else {
892
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
893
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
894
                    specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
895
               }
896
            }
897
        }
898

    
899
        if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
900
            orthographicVariantField.setCaption("Orthographical correction");
901
            orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
902
            orthographicVariantToggle.setCaption("Orthographical correction");
903
        } else {
904
            orthographicVariantField.setCaption("Orthographical variant");
905
            orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
906
            orthographicVariantToggle.setCaption("Orthographical variant");
907
        }
908

    
909
        genusOrUninomialField.setRequired(true);
910
        specificEpithetField.setVisible(isSpeciesOrBelow);
911
        specificEpithetField.setRequired(isSpeciesOrBelow);
912
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
913
        infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
914
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
915
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
916
        infraGenericEpithetField.setRequired(rank.isInfraGeneric());
917
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
918

    
919
        basionymsComboboxSelect.setVisible(withBasionymSection);
920

    
921
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
922
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
923
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
924

    
925
        validationField.setVisible(withValidationSection);
926
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
927

    
928
        orthographicVariantField.setVisible(withOrthographicCorrectionSection);
929
        if(withOrthographicCorrectionSection){
930
            orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
931
            orthographicVariantField.addValidator(orthographicCorrectionValidator);
932
        } else {
933
            if(orthographicCorrectionValidator  != null){
934
                orthographicVariantField.removeValidator(orthographicCorrectionValidator);
935
                orthographicVariantField = null;
936
            }
937
        }
938

    
939
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
940
        specificEpithetField.setVisible(isSpeciesOrBelow);
941
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
942
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
943
    }
944

    
945

    
946
    @Override
947
    public void cancel() {
948
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
949
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
950
        super.cancel();
951
    }
952

    
953

    
954
    /**
955
     * {@inheritDoc}
956
     */
957
    @Override
958
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
959
        return nomReferenceCombobox;
960
    }
961

    
962

    
963
    /**
964
     * {@inheritDoc}
965
     */
966
    @Override
967
    public TextField getNomenclaturalReferenceDetail() {
968
        return nomenclaturalReferenceDetail;
969
    }
970

    
971
    /**
972
     * {@inheritDoc}
973
     */
974
    @Override
975
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
976
        return basionymsComboboxSelect;
977
    }
978

    
979
    /**
980
     * {@inheritDoc}
981
     */
982
    @Override
983
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
984
        return replacedSynonymsComboboxSelect;
985
    }
986

    
987
    /**
988
     * {@inheritDoc}
989
     */
990
    @Override
991
    public NativeSelect getRankSelect() {
992
        return rankSelect;
993
    }
994

    
995
    /**
996
     * {@inheritDoc}
997
     */
998
    @Override
999
    public AbstractField<String> getGenusOrUninomialField(){
1000
        return genusOrUninomialField;
1001
    }
1002

    
1003
    /**
1004
     * @return the exBasionymAuthorshipField
1005
     */
1006
    @Override
1007
    public TeamOrPersonField getExBasionymAuthorshipField() {
1008
        return exBasionymAuthorshipField;
1009
    }
1010

    
1011
    /**
1012
     * @return the basionymAuthorshipField
1013
     */
1014
    @Override
1015
    public TeamOrPersonField getBasionymAuthorshipField() {
1016
        return basionymAuthorshipField;
1017
    }
1018

    
1019
    /**
1020
     * @return the combinationAuthorshipField
1021
     */
1022
    @Override
1023
    public TeamOrPersonField getCombinationAuthorshipField() {
1024
        return combinationAuthorshipField;
1025
    }
1026

    
1027
    /**
1028
     * @return the exCombinationAuthorshipField
1029
     */
1030
    @Override
1031
    public TeamOrPersonField getExCombinationAuthorshipField() {
1032
        return exCombinationAuthorshipField;
1033
    }
1034

    
1035
    @Override
1036
    public NameRelationField getValidationField(){
1037
        return validationField;
1038
    }
1039

    
1040
    @Override
1041
    public NameRelationField getOrthographicVariantField() {
1042
        return orthographicVariantField;
1043
    }
1044

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

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

    
1056
    @Override
1057
    public void disableMode(TaxonNamePopupEditorMode mode){
1058
        modesActive.remove(mode);
1059
        updateFormOnModeChange();
1060
    }
1061

    
1062
    /**
1063
     * updates UI in turn of mode changes if needed, that is when the bean has been set
1064
     * already.
1065
     */
1066
    private void updateFormOnModeChange() {
1067
        if(getBean() != null){
1068
            // need to update the ui
1069
            afterItemDataSourceSet();
1070
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1071
                updateFieldVisibility();
1072
            }
1073
        }
1074
    }
1075

    
1076
    @Override
1077
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1078
        return modesActive;
1079
    }
1080

    
1081
    @Override
1082
    public CheckBox getBasionymToggle() {
1083
        return basionymToggle;
1084
    }
1085

    
1086
    @Override
1087
    public FilterableAnnotationsField getAnnotationsField() {
1088
        return annotationsListField;
1089
    }
1090

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

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

    
1131

    
1132
    /**
1133
     * @return the infraGenericEpithetField
1134
     */
1135
    @Override
1136
    public AbstractField<String> getInfraGenericEpithetField() {
1137
        return infraGenericEpithetField;
1138
    }
1139

    
1140
    /**
1141
     * @return the specificEpithetField
1142
     */
1143
    @Override
1144
    public AbstractField<String> getSpecificEpithetField() {
1145
        return specificEpithetField;
1146
    }
1147

    
1148
    /**
1149
     * @return the infraSpecificEpithetField
1150
     */
1151
    @Override
1152
    public AbstractField<String> getInfraSpecificEpithetField() {
1153
        return infraSpecificEpithetField;
1154
    }
1155

    
1156
    @Override
1157
    public CheckBox getOrthographicVariantToggle() {
1158
        return orthographicVariantToggle;
1159
    }
1160

    
1161
    @Override
1162
    public ElementCollectionField<NomenclaturalStatus> getNomStatusCollectionField(){
1163
        return nomStatusCollectionField;
1164
    }
1165

    
1166
}
(12-12/15)