Project

General

Profile

Download (44 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.EnumSet;
12
import java.util.HashMap;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.UUID;
16

    
17
import org.apache.commons.lang3.BooleanUtils;
18
import org.springframework.context.annotation.Scope;
19

    
20
import com.vaadin.data.Property;
21
import com.vaadin.data.Property.ValueChangeListener;
22
import com.vaadin.spring.annotation.SpringComponent;
23
import com.vaadin.ui.AbstractField;
24
import com.vaadin.ui.Alignment;
25
import com.vaadin.ui.CheckBox;
26
import com.vaadin.ui.GridLayout;
27
import com.vaadin.ui.NativeSelect;
28
import com.vaadin.ui.TextField;
29

    
30
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
31
import eu.etaxonomy.cdm.model.common.AnnotationType;
32
import eu.etaxonomy.cdm.model.common.CdmBase;
33
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
34
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
35
import eu.etaxonomy.cdm.model.name.Rank;
36
import eu.etaxonomy.cdm.model.name.RankClass;
37
import eu.etaxonomy.cdm.model.name.TaxonName;
38
import eu.etaxonomy.cdm.model.reference.Reference;
39
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
40
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
41
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
42
import eu.etaxonomy.cdm.vaadin.data.validator.NomenclaturalReferenceExistsValidator;
43
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
44
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
45
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
46
import eu.etaxonomy.cdm.vaadin.model.name.NameRelationshipDTO;
47
import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
48
import eu.etaxonomy.cdm.vaadin.permission.CdmEditDeletePermissionTester;
49
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
50
import eu.etaxonomy.cdm.vaadin.ui.UIMessages;
51
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
52
import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
53
import eu.etaxonomy.vaadin.component.NameRelationField;
54
import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
55
import eu.etaxonomy.vaadin.component.SwitchableTextField;
56
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
57
import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
58
import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
59
import eu.etaxonomy.vaadin.event.EditorActionType;
60
import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOPopupEditor;
61

    
62
/**
63
 * @author a.kohlbecker
64
 * @since May 22, 2017
65
 *
66
 */
67
@SpringComponent
68
@Scope("prototype")
69
public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter>
70
    implements TaxonNamePopupEditorView{
71

    
72
    private static final long serialVersionUID = -7037436241474466359L;
73

    
74
    private final static int GRID_COLS = 4;
75

    
76
    private final static int GRID_ROWS = 19;
77

    
78
    private static final boolean HAS_BASIONYM_DEFAULT = false;
79

    
80
    private AbstractField<String> genusOrUninomialField;
81

    
82
    private AbstractField<String> infraGenericEpithetField;
83

    
84
    private AbstractField<String> specificEpithetField;
85

    
86
    private AbstractField<String> infraSpecificEpithetField;
87

    
88
    private SwitchableTextField fullTitleCacheFiled;
89

    
90
    private SwitchableTextField protectedNameCacheField;
91

    
92
    private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
93

    
94
    private TextField nomenclaturalReferenceDetail;
95

    
96
    private TeamOrPersonField exBasionymAuthorshipField;
97

    
98
    private TeamOrPersonField basionymAuthorshipField;
99

    
100
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
101

    
102
    private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
103

    
104
    private NameRelationField validationField;
105

    
106
    private NameRelationField orthographicVariantField;
107

    
108
    private CheckBox basionymToggle;
109

    
110
    private CheckBox replacedSynonymsToggle;
111

    
112
    private CheckBox validationToggle;
113

    
114
    private CheckBox orthographicVariantToggle;
115

    
116
    private NativeSelect rankSelect;
117

    
118
    private TeamOrPersonField combinationAuthorshipField;
119

    
120
    private TeamOrPersonField exCombinationAuthorshipField;
121

    
122
    private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
123

    
124
    private Boolean isInferredCombinationAuthorship = null;
125

    
126
    private Boolean isInferredBasionymAuthorship = null;
127

    
128
    private Boolean isInferredExBasionymAuthorship = null;
129

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

    
132
    private Boolean isInferredExCombinationAuthorship;
133

    
134
    private int specificEpithetFieldRow;
135

    
136
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
137

    
138
    private FilterableAnnotationsField annotationsListField;
139

    
140
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
141

    
142
    private int genusOrUninomialRow;
143

    
144
    private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
145

    
146
    /**
147
     * By default  AnnotationType.EDITORIAL() is enabled.
148
     *
149
     * @return the editableAnotationTypes
150
     */
151
    @Override
152
    public AnnotationType[] getEditableAnotationTypes() {
153
        return editableAnotationTypes;
154
    }
155

    
156
    /**
157
     * By default  AnnotationType.EDITORIAL() is enabled.
158
     *
159
     *
160
     * @param editableAnotationTypes the editableAnotationTypes to set
161
     */
162
    @Override
163
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
164
        this.editableAnotationTypes = editableAnotationTypes;
165
    }
166

    
167
    /**
168
     * @param layout
169
     * @param dtoType
170
     */
171
    public TaxonNamePopupEditor() {
172
        super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
173
    }
174

    
175
    /**
176
     * {@inheritDoc}
177
     */
178
    @Override
179
    public String getWindowCaption() {
180
        return "Name editor";
181
    }
182

    
183

    
184
    /**
185
     * {@inheritDoc}
186
     */
187
    @Override
188
    public int getWindowWidth() {
189
        return 800;
190
    }
191

    
192
    /**
193
     * {@inheritDoc}
194
     */
195
    @Override
196
    public void focusFirst() {
197
        // titleField.focus();
198

    
199
    }
200

    
201
    /**
202
     * {@inheritDoc}
203
     */
204
    @Override
205
    protected String getDefaultComponentStyles() {
206
        return "tiny";
207
    }
208

    
209
    /**
210
     * {@inheritDoc}
211
     */
212
    @Override
213
    protected void initContent() {
214

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

    
224
        /*
225
         - nameType: preset, needs to be set in the presenter for new names
226
         - appendedPhrase: -> TODO field
227
         - nomenclaturalMicroReference:  -> TODO field
228
         - nomenclaturalReference ->  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
        // --------------- Basionyms
357
        row++;
358
        basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
359
        basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
360
        addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
361
        basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
362
        basionymsComboboxSelect.withEditButton(true);
363
        basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
364
        basionymsComboboxSelect.setEditActionListener(e -> {
365

    
366
            Object fieldValue = e.getSource().getValue();
367
            UUID beanUuid = null;
368
            if(fieldValue != null){
369
                beanUuid = ((CdmBase)fieldValue).getUuid();
370

    
371
            }
372
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
373
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
374
        });
375
        grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
376

    
377
        row++;
378
        basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
379
        basionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
380
        addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
381
        row++;
382
        exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
383
        exBasionymAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
384
        addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
385

    
386
        // --------------- ReplacedSynonyms
387
        row++;
388
        replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Replaced synonyms");
389
        replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
390
        addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
391
        replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
392
        replacedSynonymsComboboxSelect.withEditButton(true);
393
        replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
394
        replacedSynonymsComboboxSelect.setEditActionListener(e -> {
395

    
396
            Object fieldValue = e.getSource().getValue();
397
            UUID beanUuid = null;
398
            if(fieldValue != null){
399
                beanUuid = ((CdmBase)fieldValue).getUuid();
400

    
401
            }
402
            ReloadableLazyComboBox<TaxonName>  lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
403
            getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
404
        });
405
        grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
406

    
407
        // --------------- Validation
408
        row++;
409
        validationField = new NameRelationField("Validation", "Validated name", Direction.relatedTo, NameRelationshipType.VALIDATED_BY_NAME());
410
        validationField.setWidth(100, Unit.PERCENTAGE);
411
        ToOneRelatedEntityCombobox<TaxonName> validatedNameComboBox = validationField.getRelatedNameComboBox();
412
        validatedNameComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
413
                this,
414
                new TaxonNameEditorAction(EditorActionType.ADD, null, validatedNameComboBox, this)
415
                ));
416
        validatedNameComboBox.addClickListenerEditEntity(e -> {
417
            if(validatedNameComboBox.getValue() != null){
418
                getViewEventBus().publish(this,
419
                    new TaxonNameEditorAction(
420
                            EditorActionType.EDIT,
421
                            validatedNameComboBox.getValue().getUuid(),
422
                            e.getButton(),
423
                            validatedNameComboBox,
424
                            this)
425
                );
426
            }
427
        });
428
        ToOneRelatedEntityCombobox<Reference> validationCitatonComboBox = validationField.getCitatonComboBox();
429
        validationCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
430
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
431
                this,
432
                new ReferenceEditorAction(EditorActionType.ADD, null, validationCitatonComboBox, this)
433
                ));
434
        validationCitatonComboBox.addClickListenerEditEntity(e -> {
435
            if(validationCitatonComboBox.getValue() != null){
436
                getViewEventBus().publish(this,
437
                    new ReferenceEditorAction(
438
                            EditorActionType.EDIT,
439
                            validationCitatonComboBox.getValue().getUuid(),
440
                            e.getButton(),
441
                            validationCitatonComboBox,
442
                            this)
443
                );
444
            }
445
        });
446
        addField(validationField, "validationFor", 0, row, 3, row);
447
        grid.setComponentAlignment(validationField, Alignment.TOP_RIGHT);
448

    
449
        // ------- Orthographic Variant (Correction)
450
        row++;
451
        orthographicVariantField = new NameRelationField("Orthographical variant", "Name variant", Direction.relatedTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT());
452
        orthographicVariantField.setWidth(100, Unit.PERCENTAGE);
453
        // corrected name must have same
454
        ToOneRelatedEntityCombobox<TaxonName> orthographicVariantCombobox = orthographicVariantField.getRelatedNameComboBox();
455
        orthographicVariantCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
456
                this,
457
                new TaxonNameEditorAction(EditorActionType.ADD, null, orthographicVariantCombobox, this)
458
                ));
459
        orthographicVariantCombobox.addClickListenerEditEntity(e -> {
460
            if(orthographicVariantCombobox.getValue() != null){
461
                getViewEventBus().publish(this,
462
                    new TaxonNameEditorAction(
463
                            EditorActionType.EDIT,
464
                            orthographicVariantCombobox.getValue().getUuid(),
465
                            e.getButton(),
466
                            orthographicVariantCombobox,
467
                            this)
468
                );
469
            }
470
        });
471
        ToOneRelatedEntityCombobox<Reference> orthographicCorrectionCitatonComboBox = orthographicVariantField.getCitatonComboBox();
472
        orthographicCorrectionCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
473
                // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
474
                this,
475
                new ReferenceEditorAction(EditorActionType.ADD, null, orthographicCorrectionCitatonComboBox, this)
476
                ));
477
        orthographicCorrectionCitatonComboBox.addClickListenerEditEntity(e -> {
478
            if(orthographicCorrectionCitatonComboBox.getValue() != null){
479
                getViewEventBus().publish(this,
480
                    new ReferenceEditorAction(
481
                            EditorActionType.EDIT,
482
                            orthographicCorrectionCitatonComboBox.getValue().getUuid(),
483
                            e.getButton(),
484
                            orthographicCorrectionCitatonComboBox,
485
                            this)
486
                );
487
            }
488
        });
489
        addField(orthographicVariantField, "orthographicVariant", 0, row, 3, row);
490
        grid.setComponentAlignment(orthographicVariantField, Alignment.TOP_RIGHT);
491

    
492
        row++;
493
        exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
494
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
495
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
496

    
497
        row++;
498
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
499
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
500
        annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
501
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
502

    
503
        // -----------------------------------------------------------------------------
504

    
505
        setAdvancedModeEnabled(true);
506
        registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
507

    
508
        registerAdvancedModeComponents(combinationAuthorshipField);
509
        registerAdvancedModeComponents(basionymAuthorshipField);
510
        registerAdvancedModeComponents(exBasionymAuthorshipField);
511
        registerAdvancedModeComponents(exCombinationAuthorshipField);
512

    
513
        registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
514
        registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
515
        registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
516
        registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
517

    
518
        setAdvancedMode(false);
519

    
520
        //TODO remove below line once #7858 is fixed
521
        withDeleteButton(false);
522

    
523
    }
524

    
525
    protected TeamOrPersonBase inferBasiomynAuthors() {
526
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
527
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
528
            TaxonName basionym = basionyms.get(0);
529
            if(basionym.getCombinationAuthorship() != null){
530
                return basionym.getCombinationAuthorship();
531
            } else if(basionym.getNomenclaturalReference() != null){
532
                return basionym.getNomenclaturalReference().getAuthorship();
533
            }
534
        }
535
        return null;
536
    }
537

    
538
    protected TeamOrPersonBase inferExBasiomynAuthors() {
539
        List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
540
        if(!basionyms.isEmpty() && basionyms.get(0) != null){
541
            TaxonName basionym = basionyms.get(0);
542
                return basionym.getExCombinationAuthorship();
543
        }
544
        return null;
545
    }
546

    
547
    protected TeamOrPersonBase inferCombinationAuthors() {
548
        Reference nomRef = nomReferenceCombobox.getValue();
549
        if(nomRef != null) {
550
            return nomRef.getAuthorship();
551
        }
552
        return null;
553
    }
554

    
555
    protected TeamOrPersonBase inferExCombinationAuthors() {
556
        NameRelationshipDTO nameRelationDTO = validationField.getValue();
557
        if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
558
            TaxonName validatedName = nameRelationDTO.getOtherName();
559
            if(validatedName.getCombinationAuthorship() != null) {
560
                return validatedName.getCombinationAuthorship();
561
            } else if(validatedName.getNomenclaturalReference() != null){
562
                return validatedName.getNomenclaturalReference().getAuthorship();
563
            }
564
        }
565
        return null;
566
    }
567

    
568
    @Override
569
    protected void afterItemDataSourceSet() {
570

    
571

    
572
        rankSelect.addValueChangeListener(updateFieldVisibilityListener);
573
        basionymToggle.addValueChangeListener(e -> {
574
            updateAuthorshipFields();
575
        });
576
        validationToggle.addValueChangeListener(e -> {
577
            updateAuthorshipFields();
578
            });
579
        replacedSynonymsToggle.addValueChangeListener(e -> {
580
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
581
            replacedSynonymsComboboxSelect.setVisible(enable);
582
        });
583
        orthographicVariantToggle.addValueChangeListener(e -> {
584
            boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
585
            orthographicVariantField.setVisible(enable);
586
        });
587

    
588
        TaxonNameDTO taxonNameDTO = getBean();
589
        boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
590
                || taxonNameDTO.getBasionymAuthorship() != null
591
                || taxonNameDTO.getExBasionymAuthorship() != null;
592
        basionymToggle.setValue(showBasionymSection);
593
        basionymToggle.setReadOnly(showBasionymSection);
594

    
595
        boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
596
        replacedSynonymsToggle.setValue(showReplacedSynonyms);
597
        replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
598
        replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
599

    
600
        boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
601
        validationToggle.setValue(showValidationSection);
602
        validationToggle.setReadOnly(showValidationSection);
603

    
604
        boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
605
        orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
606
        orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
607

    
608
        if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
609
            updateAuthorshipFields();
610
        }
611
        if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
612
            nomReferenceCombobox.setDescription("Selection limited to nomenclatural reference and parts of it.");
613
        }
614
        if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
615
            nomReferenceCombobox.setRequired(true);
616
            nomReferenceCombobox.setImmediate(true);
617

    
618
            String userHint = "Please use the 'Edit' function to fix the problem in the related name.";
619
            validationField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
620
            orthographicVariantField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
621
            basionymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
622
            replacedSynonymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
623
        }
624
    }
625

    
626
    /**
627
     * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
628
     * authors from the related nomenclatural reference or taxon name.
629
     * <p>
630
     * Finally the {@link #updateFieldVisibility()} is invoked.
631
     *
632
     * @param taxonName
633
     */
634
    @Override
635
    public void updateAuthorshipFields() {
636

    
637
        TaxonNameDTO taxonName = getBean();
638

    
639
        // ------------- CombinationAuthors
640
        isInferredCombinationAuthorship = updateAuthorshipFieldData(
641
                taxonName.getCombinationAuthorship(),
642
                inferCombinationAuthors(),
643
                combinationAuthorshipField,
644
                nomReferenceCombobox.getSelect(),
645
                isInferredCombinationAuthorship);
646

    
647

    
648
        // ------------- Basionym and ExBasionymAuthors
649
        if(BooleanUtils.isTrue(basionymToggle.getValue())){
650

    
651
            isInferredBasionymAuthorship = updateAuthorshipFieldData(
652
                    taxonName.getBasionymAuthorship(),
653
                    inferBasiomynAuthors(),
654
                    basionymAuthorshipField,
655
                    basionymsComboboxSelect,
656
                    isInferredBasionymAuthorship
657
                    );
658

    
659
            isInferredExBasionymAuthorship = updateAuthorshipFieldData(
660
                    taxonName.getExBasionymAuthorship(),
661
                    inferExBasiomynAuthors(),
662
                    exBasionymAuthorshipField,
663
                    basionymsComboboxSelect,
664
                    isInferredExBasionymAuthorship
665
                    );
666

    
667
        }
668

    
669
        // ------------- Validation and ExCombinationAuthors
670
        isInferredExCombinationAuthorship = updateAuthorshipFieldData(
671
                taxonName.getExCombinationAuthorship(),
672
                inferExCombinationAuthors(),
673
                exCombinationAuthorshipField,
674
                validationField.getRelatedNameComboBox(),
675
                isInferredExCombinationAuthorship
676
                );
677

    
678
        updateFieldVisibility();
679
    }
680

    
681

    
682
    /**
683
     *
684
     * @param authorship
685
     *    the value of the taxonName authorship field
686
     * @param inferredAuthors
687
     *    the value inferred from other fields which may be set as authorship to the taxon name
688
     * @param authorshipField
689
     *    the ui element to edit the taxonName authorship field
690
     * @param updateTriggerField
691
     * @param lastInferredAuthorshipState
692
     * @return
693
     */
694
    protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
695
            TeamOrPersonField authorshipField, AbstractField updateTriggerField,
696
            Boolean lastInferredAuthorshipState) {
697

    
698
        if(authorship == null){
699
            authorshipField.setValue(inferredAuthors);
700
            lastInferredAuthorshipState = true;
701
        } else {
702
            boolean authorshipMatch = authorship == inferredAuthors;
703
            if(lastInferredAuthorshipState == null){
704
                // initialization of authorshipState, this comes only into account when the editor is just being initialized
705
                lastInferredAuthorshipState = authorshipMatch;
706
            }
707
            if(!authorshipMatch && lastInferredAuthorshipState){
708
                // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
709
                authorshipField.setValue(inferredAuthors);
710
                lastInferredAuthorshipState = true;
711
            }
712
        }
713

    
714
        if(updateTriggerField != null){
715
            // IMPORTANT!
716
            // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
717
            // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
718
            // Otherwise we risk multiple representation problems in the hibernate session
719
            if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
720
                ValueChangeListener listener = e ->  {
721
                    logger.debug(" value changed #2");
722
                    updateAuthorshipFields();
723
                };
724
                updateTriggerField.addValueChangeListener(listener);
725
                authorshipUpdateListeners.put(updateTriggerField, listener);
726
            }
727
        }
728

    
729
        return lastInferredAuthorshipState;
730
    }
731

    
732
    /**
733
     * @param rank
734
     * @return
735
     */
736
    private void updateFieldVisibility() {
737

    
738
        // TODO use getField() instead and remove field references
739
        Rank rank = (Rank) rankSelect.getValue();
740

    
741
        boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES()) && !rank.getRankClass().equals(RankClass.Unknown);
742
        Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
743
        Boolean withValidationSection = BooleanUtils.isTrue(validationToggle.getValue());
744
        Boolean withOrthographicCorrectionSection = BooleanUtils.isTrue(orthographicVariantToggle.getValue());
745

    
746
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
747
            if(isSpeciesOrBelow) {
748
                if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
749
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
750
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
751
                            this,
752
                            new TaxonNameEditorActionStrRep(
753
                                    EditorActionType.ADD,
754
                                    e.getButton(),
755
                                    combobox,
756
                                    this)
757
                        ));
758
                    combobox.addClickListenerEditEntity(e -> {
759
                        //WeaklyRelatedEntityCombobox<TaxonName> wrcbbx = combobox;
760
                        if(combobox.getValue() != null){
761
                            getViewEventBus().publish(this,
762
                                new TaxonNameEditorActionStrRep(
763
                                        EditorActionType.EDIT,
764
                                        combobox.getIdForValue(),
765
                                        e.getButton(),
766
                                        combobox,
767
                                        this)
768
                            );
769
                        }
770
                    });
771
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
772
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
773
                }
774
            } else {
775
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
776
                    genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new TextFieldNFix(), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
777
                    genusOrUninomialField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
778
                }
779
            }
780
        }
781

    
782
        if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
783
            if(rank.isInfraSpecific()) {
784
                if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
785
                    WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
786
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
787
                    combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
788
                    combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
789
                            this,
790
                            new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
791
                        ));
792
                    combobox.addClickListenerEditEntity(e -> {
793
                        if(combobox.getValue() != null){
794
                            getViewEventBus().publish(this,
795
                                new TaxonNameEditorActionStrRep(
796
                                        EditorActionType.EDIT,
797
                                        combobox.getIdForValue(),
798
                                        e.getButton(),
799
                                        combobox,
800
                                        this)
801
                            );
802
                        }
803
                    });
804
                }
805
            } else {
806
                if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
807
                    specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
808
                    specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
809
               }
810
            }
811
        }
812

    
813
        if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
814
            orthographicVariantField.setCaption("Orthographical correction");
815
            orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
816
            orthographicVariantToggle.setCaption("Orthographical correction");
817
        } else {
818
            orthographicVariantField.setCaption("Orthographical variant");
819
            orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
820
            orthographicVariantToggle.setCaption("Orthographical variant");
821
        }
822

    
823
        genusOrUninomialField.setRequired(true);
824
        specificEpithetField.setVisible(isSpeciesOrBelow);
825
        specificEpithetField.setRequired(isSpeciesOrBelow);
826
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
827
        infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
828
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
829
        infraGenericEpithetField.setVisible(rank.isInfraGeneric());
830
        infraGenericEpithetField.setRequired(rank.isInfraGeneric());
831
        infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
832

    
833
        basionymsComboboxSelect.setVisible(withBasionymSection);
834

    
835
        combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
836
        basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
837
        exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
838

    
839
        validationField.setVisible(withValidationSection);
840
        exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
841

    
842
        orthographicVariantField.setVisible(withOrthographicCorrectionSection);
843
        if(withOrthographicCorrectionSection){
844
            orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
845
            orthographicVariantField.addValidator(orthographicCorrectionValidator);
846
        } else {
847
            if(orthographicCorrectionValidator  != null){
848
                orthographicVariantField.removeValidator(orthographicCorrectionValidator);
849
                orthographicVariantField = null;
850
            }
851
        }
852

    
853
        infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
854
        specificEpithetField.setVisible(isSpeciesOrBelow);
855
        infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
856
        genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
857
    }
858

    
859

    
860
    @Override
861
    public void cancel() {
862
        authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
863
        rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
864
        super.cancel();
865
    }
866

    
867

    
868
    /**
869
     * {@inheritDoc}
870
     */
871
    @Override
872
    public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
873
        return nomReferenceCombobox;
874
    }
875

    
876

    
877
    /**
878
     * {@inheritDoc}
879
     */
880
    @Override
881
    public TextField getNomenclaturalReferenceDetail() {
882
        return nomenclaturalReferenceDetail;
883
    }
884

    
885
    /**
886
     * {@inheritDoc}
887
     */
888
    @Override
889
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
890
        return basionymsComboboxSelect;
891
    }
892

    
893
    /**
894
     * {@inheritDoc}
895
     */
896
    @Override
897
    public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
898
        return replacedSynonymsComboboxSelect;
899
    }
900

    
901
    /**
902
     * {@inheritDoc}
903
     */
904
    @Override
905
    public NativeSelect getRankSelect() {
906
        return rankSelect;
907
    }
908

    
909
    /**
910
     * {@inheritDoc}
911
     */
912
    @Override
913
    public AbstractField<String> getGenusOrUninomialField(){
914
        return genusOrUninomialField;
915
    }
916

    
917
    /**
918
     * @return the exBasionymAuthorshipField
919
     */
920
    @Override
921
    public TeamOrPersonField getExBasionymAuthorshipField() {
922
        return exBasionymAuthorshipField;
923
    }
924

    
925
    /**
926
     * @return the basionymAuthorshipField
927
     */
928
    @Override
929
    public TeamOrPersonField getBasionymAuthorshipField() {
930
        return basionymAuthorshipField;
931
    }
932

    
933
    /**
934
     * @return the combinationAuthorshipField
935
     */
936
    @Override
937
    public TeamOrPersonField getCombinationAuthorshipField() {
938
        return combinationAuthorshipField;
939
    }
940

    
941
    /**
942
     * @return the exCombinationAuthorshipField
943
     */
944
    @Override
945
    public TeamOrPersonField getExCombinationAuthorshipField() {
946
        return exCombinationAuthorshipField;
947
    }
948

    
949
    @Override
950
    public NameRelationField getValidationField(){
951
        return validationField;
952
    }
953

    
954
    @Override
955
    public NameRelationField getOrthographicVariantField() {
956
        return orthographicVariantField;
957
    }
958

    
959
    @Override
960
    public void enableMode(TaxonNamePopupEditorMode mode){
961
            modesActive.add(mode);
962
            updateFormOnModeChange();
963
    }
964

    
965
    @Override
966
    public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
967
        return modesActive.contains(mode);
968
    }
969

    
970
    @Override
971
    public void disableMode(TaxonNamePopupEditorMode mode){
972
        modesActive.remove(mode);
973
        updateFormOnModeChange();
974
    }
975

    
976
    /**
977
     * updates UI in turn of mode changes if needed, that is when the bean has been set
978
     * already.
979
     */
980
    private void updateFormOnModeChange() {
981
        if(getBean() != null){
982
            // need to update the ui
983
            afterItemDataSourceSet();
984
            if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
985
                updateFieldVisibility();
986
            }
987
        }
988
    }
989

    
990
    @Override
991
    public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
992
        return modesActive;
993
    }
994

    
995
    @Override
996
    public CheckBox getBasionymToggle() {
997
        return basionymToggle;
998
    }
999

    
1000
    @Override
1001
    public FilterableAnnotationsField getAnnotationsField() {
1002
        return annotationsListField;
1003
    }
1004

    
1005
    /**
1006
     * {@inheritDoc}
1007
     */
1008
    @Override
1009
    public void setReadOnly(boolean readOnly) {
1010
        super.setReadOnly(readOnly);
1011
        boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1012
        boolean validationToggleReadonly = validationToggle.isReadOnly();
1013
        combinationAuthorshipField.setEditorReadOnly(readOnly);
1014
        exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1015
        basionymAuthorshipField.setEditorReadOnly(readOnly);
1016
        exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1017
        // preserve old readonly states if they were true
1018
        if(basionymToggleReadonly){
1019
            basionymToggle.setReadOnly(true);
1020
        }
1021
        if(validationToggleReadonly){
1022
            validationToggle.setReadOnly(true);
1023
        }
1024
    }
1025

    
1026
    /**
1027
     * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1028
     *
1029
     * @param readOnly
1030
     */
1031
    public void setAllFieldsReadOnly(boolean readOnly) {
1032
        recursiveReadonly(readOnly, getMainLayout());
1033
        // NOTE:We are uUsing the enabled state instead of read only since
1034
        // setting read only will not affect the members editor.
1035
        // this seems to be a bug in TeamOrPersonField or in
1036
        // ToManyRelatedEntitiesListSelect
1037
        combinationAuthorshipField.setEnabled(!readOnly);
1038
        exCombinationAuthorshipField.setEnabled(!readOnly);
1039
        basionymAuthorshipField.setEnabled(!readOnly);
1040
        exBasionymAuthorshipField.setEnabled(!readOnly);
1041
    }
1042

    
1043

    
1044

    
1045
    /**
1046
     * @return the infraGenericEpithetField
1047
     */
1048
    @Override
1049
    public AbstractField<String> getInfraGenericEpithetField() {
1050
        return infraGenericEpithetField;
1051
    }
1052

    
1053
    /**
1054
     * @return the specificEpithetField
1055
     */
1056
    @Override
1057
    public AbstractField<String> getSpecificEpithetField() {
1058
        return specificEpithetField;
1059
    }
1060

    
1061
    /**
1062
     * @return the infraSpecificEpithetField
1063
     */
1064
    @Override
1065
    public AbstractField<String> getInfraSpecificEpithetField() {
1066
        return infraSpecificEpithetField;
1067
    }
1068

    
1069
    @Override
1070
    public CheckBox getOrthographicVariantToggle() {
1071
        return orthographicVariantToggle;
1072
    }
1073

    
1074

    
1075
}
(11-11/14)