cleanup
[cdm-vaadin.git] / src / main / java / eu / etaxonomy / cdm / vaadin / view / name / TaxonNamePopupEditor.java
1 /**
2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.vaadin.view.name;
10
11 import java.util.Collection;
12 import java.util.EnumSet;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.UUID;
17
18 import org.apache.commons.lang3.BooleanUtils;
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.Logger;
21 import org.springframework.context.annotation.Scope;
22 import org.vaadin.viritin.fields.AbstractElementCollection.Instantiator;
23 import org.vaadin.viritin.fields.ElementCollectionField;
24
25 import com.vaadin.data.Property;
26 import com.vaadin.data.Property.ValueChangeListener;
27 import com.vaadin.data.Validator.InvalidValueException;
28 import com.vaadin.server.FontAwesome;
29 import com.vaadin.shared.ui.MarginInfo;
30 import com.vaadin.spring.annotation.SpringComponent;
31 import com.vaadin.ui.AbstractField;
32 import com.vaadin.ui.Alignment;
33 import com.vaadin.ui.Button;
34 import com.vaadin.ui.CheckBox;
35 import com.vaadin.ui.Component;
36 import com.vaadin.ui.CssLayout;
37 import com.vaadin.ui.GridLayout;
38 import com.vaadin.ui.NativeSelect;
39 import com.vaadin.ui.Panel;
40 import com.vaadin.ui.TextField;
41 import com.vaadin.ui.themes.ValoTheme;
42
43 import eu.etaxonomy.cdm.api.util.RoleProberImpl;
44 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
45 import eu.etaxonomy.cdm.model.common.AnnotationType;
46 import eu.etaxonomy.cdm.model.common.CdmBase;
47 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
48 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
49 import eu.etaxonomy.cdm.model.name.Rank;
50 import eu.etaxonomy.cdm.model.name.RankClass;
51 import eu.etaxonomy.cdm.model.name.TaxonName;
52 import eu.etaxonomy.cdm.model.reference.Reference;
53 import eu.etaxonomy.cdm.service.UserHelperAccess;
54 import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
55 import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
56 import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
57 import eu.etaxonomy.cdm.vaadin.data.validator.NomenclaturalReferenceExistsValidator;
58 import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
59 import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
60 import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorActionStrRep;
61 import eu.etaxonomy.cdm.vaadin.model.name.NameRelationshipDTO;
62 import eu.etaxonomy.cdm.vaadin.model.name.NomenclaturalStatusDTO;
63 import eu.etaxonomy.cdm.vaadin.model.name.TaxonNameDTO;
64 import eu.etaxonomy.cdm.vaadin.permission.CdmEditDeletePermissionTester;
65 import eu.etaxonomy.cdm.vaadin.permission.RolesAndPermissions;
66 import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
67 import eu.etaxonomy.cdm.vaadin.ui.UIMessages;
68 import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
69 import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
70 import eu.etaxonomy.vaadin.component.NameRelationField;
71 import eu.etaxonomy.vaadin.component.ReloadableLazyComboBox;
72 import eu.etaxonomy.vaadin.component.SwitchableTextField;
73 import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
74 import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
75 import eu.etaxonomy.vaadin.component.WeaklyRelatedEntityCombobox;
76 import eu.etaxonomy.vaadin.event.EditorActionType;
77 import eu.etaxonomy.vaadin.mvp.AbstractCdmDTOPopupEditor;
78
79 /**
80 * @author a.kohlbecker
81 * @since May 22, 2017
82 */
83 @SpringComponent
84 @Scope("prototype")
85 public class TaxonNamePopupEditor
86 extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter>
87 implements TaxonNamePopupEditorView{
88
89 private static final long serialVersionUID = -7037436241474466359L;
90 private static final Logger logger = LogManager.getLogger();
91
92 private final static int GRID_COLS = 4;
93
94 private final static int GRID_ROWS = 21;
95
96 private static final boolean HAS_BASIONYM_DEFAULT = false;
97
98 private AbstractField<String> genusOrUninomialField;
99
100 private AbstractField<String> infraGenericEpithetField;
101
102 private AbstractField<String> specificEpithetField;
103
104 private AbstractField<String> infraSpecificEpithetField;
105
106 private SwitchableTextField fullTitleCacheFiled;
107
108 private SwitchableTextField protectedNameCacheField;
109
110 private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
111
112 private TextField nomenclaturalReferenceDetail;
113
114 private TeamOrPersonField exBasionymAuthorshipField;
115
116 private TeamOrPersonField basionymAuthorshipField;
117
118 private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
119
120 private ToManyRelatedEntitiesComboboxSelect<TaxonName> replacedSynonymsComboboxSelect;
121
122 private NameRelationField validationField;
123
124 private NameRelationField orthographicVariantField;
125
126 private CheckBox nomStatusCollectionFieldToggle;
127
128 private ElementCollectionField<NomenclaturalStatusDTO> nomStatusCollectionField;
129
130 private CheckBox basionymToggle;
131
132 private CheckBox replacedSynonymsToggle;
133
134 private CheckBox validationToggle;
135
136 private CheckBox orthographicVariantToggle;
137
138 private NativeSelect rankSelect;
139
140 private Button rankSelectFullListToggle;
141
142 private TeamOrPersonField combinationAuthorshipField;
143
144 private TeamOrPersonField exCombinationAuthorshipField;
145
146 private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
147
148 private Boolean isInferredCombinationAuthorship = null;
149
150 private Boolean isInferredBasionymAuthorship = null;
151
152 private Boolean isInferredExBasionymAuthorship = null;
153
154 private Map<AbstractField, Property.ValueChangeListener> authorshipUpdateListeners = new HashMap<>();
155
156 private Boolean isInferredExCombinationAuthorship;
157
158 private int specificEpithetFieldRow;
159
160 private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
161
162 private FilterableAnnotationsField annotationsListField;
163
164 private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
165
166 private int genusOrUninomialRow;
167
168 private OrthographicCorrectionReferenceValidator orthographicCorrectionValidator;
169
170 private boolean isRanksFullList = false;
171
172 /**
173 * By default AnnotationType.EDITORIAL() is enabled.
174 *
175 * @return the editableAnotationTypes
176 */
177 @Override
178 public AnnotationType[] getEditableAnotationTypes() {
179 return editableAnotationTypes;
180 }
181
182 /**
183 * By default AnnotationType.EDITORIAL() is enabled.
184 *
185 * @param editableAnotationTypes the editableAnotationTypes to set
186 */
187 @Override
188 public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
189 this.editableAnotationTypes = editableAnotationTypes;
190 }
191
192 public TaxonNamePopupEditor() {
193 super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonNameDTO.class);
194 }
195
196 @Override
197 public String getWindowCaption() {
198 return "Name editor";
199 }
200
201 @Override
202 public int getWindowWidth() {
203 return 800;
204 }
205
206 @Override
207 public void focusFirst() {
208 // none
209 }
210
211 @Override
212 public void applyDefaultComponentStyle(Component ... components){
213 for(int i = 0; i <components.length; i++){
214 components[i].setStyleName(getDefaultComponentStyles());
215 }
216 }
217
218 @Override
219 protected String getDefaultComponentStyles() {
220 return "tiny";
221 }
222
223 @Override
224 protected void initContent() {
225
226 GridLayout grid = (GridLayout)getFieldLayout();
227 grid.setSizeFull();
228 grid.setHideEmptyRowsAndColumns(true);
229 grid.setSpacing(true);
230 grid.setColumnExpandRatio(0, 0.3f);
231 grid.setColumnExpandRatio(1, 0.3f);
232 grid.setColumnExpandRatio(2, 0.3f);
233 grid.setColumnExpandRatio(3, 0.0f);
234
235 /*
236 * TaxonName properties for reference here (NOTE: this editor operates on TaxonNameDTOs!):
237 - nameType: preset, needs to be set in the presenter for new names
238 - appendedPhrase: -> TODO field
239 - nomenclaturalMicroReference: -> TODO field
240 - nomenclaturalSource.citation -> field but disabled for REGISTRY
241 - rank -> SelectField which determines the visiblity of the other fields
242
243 - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
244 - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
245
246 - homotypicalGroup -> hidden
247 - typeDesignations -> hidden
248 - descriptions -> hidden
249 - taxonBases -> hidden
250 - registrations -> hidden
251
252 - relationsFromThisName-> TODO implement later
253 - relationsToThisName -> TODO implement later
254
255 - genusOrUninomial -> textField
256 - infraGenericEpithet -> textField
257 - specificEpithet -> textField
258 - infraSpecificEpithet -> textField
259
260 - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
261 - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
262 - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
263 - exCombinationAuthorship -> textField
264 - exBasionymAuthorship -> textField
265
266 - status -> TODO field
267 - monomHybrid -> TODO implement hybrids later
268 - binomHybrid -> TODO implement hybrids later
269 - trinomHybrid -> TODO implement hybrids later
270
271 - hybridParentRelations -> TODO implement hybrids later
272 - hybridChildRelations -> TODO implement hybrids later
273 - hybridFormula -> TODO implement hybrids later
274
275 ** ViralName attributes **
276 - acronym
277
278 ** BacterialName attributes **
279 - subGenusAuthorship
280 - nameApprobation
281 - breed
282 - publicationYear
283 - originalPublicationYear
284 - cultivarName
285 */
286
287 int row = 0;
288
289 rankSelect = new NativeSelect("Rank");
290 rankSelect.setNullSelectionAllowed(false);
291 rankSelect.setWidth(100, Unit.PERCENTAGE);
292 rankSelectFullListToggle = new Button();
293 updateRankSelectFullListToggleButton();
294 rankSelectFullListToggle.addClickListener(e -> {
295 isRanksFullList = !isRanksFullList;
296 updateRankSelectFullListToggleButton();
297 });
298 CssLayout rankSelectGroup = new CssLayout();
299 rankSelectGroup.setWidth(100, Unit.PERCENTAGE);
300 rankSelectGroup.addComponents(rankSelect, rankSelectFullListToggle);
301 bindField(rankSelect, "rank");
302 applyDefaultComponentStyles(rankSelect);
303 applyDefaultComponentStyles(rankSelectFullListToggle);
304 applyDefaultComponentStyle(rankSelectGroup);
305 addComponent(rankSelectGroup, 0, row, 1, row);
306 rankSelectGroup.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
307 grid.setComponentAlignment(rankSelectGroup, Alignment.TOP_RIGHT);
308
309 row++;
310 basionymToggle = new CheckBox("With basionym");
311 basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
312 basionymToggle.setStyleName(getDefaultComponentStyles());
313 grid.addComponent(basionymToggle, 0, row);
314 grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
315
316 replacedSynonymsToggle = new CheckBox("With replaced synonym");
317 grid.addComponent(replacedSynonymsToggle, 1, row);
318 grid.setComponentAlignment(replacedSynonymsToggle, Alignment.BOTTOM_LEFT);
319
320 validationToggle = new CheckBox("Validation");
321 grid.addComponent(validationToggle, 2, row);
322 grid.setComponentAlignment(validationToggle, Alignment.BOTTOM_LEFT);
323
324 orthographicVariantToggle = new CheckBox("Orthographical variant");
325 grid.addComponent(orthographicVariantToggle, 3, row);
326 grid.setComponentAlignment(orthographicVariantToggle, Alignment.BOTTOM_LEFT);
327
328 row++;
329 // fullTitleCache
330 fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
331 fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
332 row++;
333 protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
334 protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
335 row++;
336 genusOrUninomialRow = row;
337 genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
338 genusOrUninomialField.setWidth(200, Unit.PIXELS);
339 infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
340 infraGenericEpithetField.setWidth(200, Unit.PIXELS);
341 row++;
342 specificEpithetFieldRow = row;
343 specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
344 specificEpithetField.setWidth(200, Unit.PIXELS);
345 infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
346 infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
347
348 row++;
349 combinationAuthorshipField = new TeamOrPersonField("Combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
350 combinationAuthorshipField.setWidth(100, Unit.PERCENTAGE);
351 addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
352
353 row++;
354 nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
355 nomReferenceCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
356 this,
357 new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
358 ));
359 nomReferenceCombobox.addClickListenerEditEntity(e -> {
360 if(nomReferenceCombobox.getValue() != null){
361 getViewEventBus().publish(this,
362 new ReferenceEditorAction(
363 EditorActionType.EDIT,
364 nomReferenceCombobox.getValue().getUuid(),
365 e.getButton(),
366 nomReferenceCombobox,
367 this)
368 );
369 }
370 });
371
372
373 // nomReferenceCombobox.getSelect().addValueChangeListener(e -> logger.debug("nomReferenceCombobox value changed #1"));
374 // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
375 nomReferenceCombobox.setWidth("100%");
376 addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 3, row);
377
378 row++;
379 nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 0, row, 2, row);
380 nomenclaturalReferenceDetail.setWidth(100, Unit.PERCENTAGE);
381
382 // --------------- nom status
383 row++;
384 nomStatusCollectionFieldToggle = new CheckBox("Invalid, illegitimate, or other status");
385 nomStatusCollectionFieldToggle.addValueChangeListener(e -> {
386 nomStatusCollectionField.getLayout().getParent().setVisible(nomStatusCollectionFieldToggle.getValue());
387 });
388 addComponent(nomStatusCollectionFieldToggle, 0, row, 0, row);
389 row++;
390 nomStatusCollectionField = new ElementCollectionField<NomenclaturalStatusDTO>(
391 NomenclaturalStatusDTO.class,
392 new Instantiator<NomenclaturalStatusDTO>() {
393 private static final long serialVersionUID = -2427045940046513092L;
394
395 @Override
396 public NomenclaturalStatusDTO create() {
397 return NomenclaturalStatusDTO.newInstance();
398 }
399 },
400 NomenclaturalStatusRow.class
401 ){
402 private static final long serialVersionUID = -3130918034491809593L;
403
404 @Override
405 public void commit() throws SourceException, InvalidValueException {
406 validate(); // validate always so that empty rows are recognized
407 super.commit();
408 }
409
410 @Override
411 public boolean isEmpty() {
412 Collection<?> value = getValue();
413 return value == null || value.isEmpty() ;
414 }
415
416 };
417
418 nomStatusCollectionField.getLayout().setSpacing(false);
419 nomStatusCollectionField.setVisibleProperties(NomenclaturalStatusRow.visibleFields());
420 nomStatusCollectionField.setPropertyHeader("type", "Status type");
421 nomStatusCollectionField.setPropertyHeader("citation", "Reference");
422 nomStatusCollectionField.setPropertyHeader("citationMicroReference", "Reference detail");
423 nomStatusCollectionField.setPropertyHeader("ruleConsidered", "Rule considered");
424 nomStatusCollectionField.addElementAddedListener( e -> nomStatusCollectionField.setComponentError(null));
425 nomStatusCollectionField.getLayout().setMargin(new MarginInfo(false, true));
426
427 Panel nomStatusCollectionPanel = new Panel(nomStatusCollectionField.getLayout());
428 nomStatusCollectionPanel.setCaption("Status");
429 nomStatusCollectionPanel.setWidth(100, Unit.PERCENTAGE);
430
431 bindField(nomStatusCollectionField, "status");
432 addComponent(nomStatusCollectionPanel, 0, row, 3, row);
433
434 // --------------- Basionyms
435 row++;
436 basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
437 basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
438 addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
439 basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
440 basionymsComboboxSelect.withEditButton(true);
441 basionymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
442 basionymsComboboxSelect.setEditActionListener(e -> {
443
444 Object fieldValue = e.getSource().getValue();
445 UUID beanUuid = null;
446 if(fieldValue != null){
447 beanUuid = ((CdmBase)fieldValue).getUuid();
448
449 }
450 ReloadableLazyComboBox<TaxonName> lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
451 getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
452 });
453 grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
454
455 row++;
456 basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
457 basionymAuthorshipField.setWidth(100, Unit.PERCENTAGE);
458 addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
459 row++;
460 exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
461 exBasionymAuthorshipField.setWidth(100, Unit.PERCENTAGE);
462 addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
463
464 // --------------- ReplacedSynonyms
465 row++;
466 replacedSynonymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<>(TaxonName.class, "Replaced synonym");
467 replacedSynonymsComboboxSelect.setConverter(new SetToListConverter<>());
468 addField(replacedSynonymsComboboxSelect, "replacedSynonyms", 0, row, 3, row);
469 replacedSynonymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
470 replacedSynonymsComboboxSelect.withEditButton(true);
471 replacedSynonymsComboboxSelect.setEditPermissionTester(new CdmEditDeletePermissionTester());
472 replacedSynonymsComboboxSelect.setEditActionListener(e -> {
473
474 Object fieldValue = e.getSource().getValue();
475 UUID beanUuid = null;
476 if(fieldValue != null){
477 beanUuid = ((CdmBase)fieldValue).getUuid();
478
479 }
480 ReloadableLazyComboBox<TaxonName> lazyCombobox = (ReloadableLazyComboBox<TaxonName>) e.getSource();
481 getViewEventBus().publish(this, new TaxonNameEditorAction(e.getAction(), beanUuid, null, lazyCombobox, this));
482 });
483 grid.setComponentAlignment(replacedSynonymsComboboxSelect, Alignment.TOP_RIGHT);
484
485 // --------------- Validation
486 row++;
487 validationField = new NameRelationField("Validation of", "Designation", Direction.relatedTo, NameRelationshipType.VALIDATED_BY_NAME());
488 validationField.setWidth(100, Unit.PERCENTAGE);
489 ToOneRelatedEntityCombobox<TaxonName> validatedNameComboBox = validationField.getRelatedNameComboBox();
490 validatedNameComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
491 this,
492 new TaxonNameEditorAction(EditorActionType.ADD, null, validatedNameComboBox, this)
493 ));
494 validatedNameComboBox.addClickListenerEditEntity(e -> {
495 if(validatedNameComboBox.getValue() != null){
496 getViewEventBus().publish(this,
497 new TaxonNameEditorAction(
498 EditorActionType.EDIT,
499 validatedNameComboBox.getValue().getUuid(),
500 e.getButton(),
501 validatedNameComboBox,
502 this)
503 );
504 }
505 });
506 ToOneRelatedEntityCombobox<Reference> validationCitatonComboBox = validationField.getCitatonComboBox();
507 validationCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
508 // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
509 this,
510 new ReferenceEditorAction(EditorActionType.ADD, null, validationCitatonComboBox, this)
511 ));
512 validationCitatonComboBox.addClickListenerEditEntity(e -> {
513 if(validationCitatonComboBox.getValue() != null){
514 getViewEventBus().publish(this,
515 new ReferenceEditorAction(
516 EditorActionType.EDIT,
517 validationCitatonComboBox.getValue().getUuid(),
518 e.getButton(),
519 validationCitatonComboBox,
520 this)
521 );
522 }
523 });
524 addField(validationField, "validationFor", 0, row, 3, row);
525 grid.setComponentAlignment(validationField, Alignment.TOP_RIGHT);
526
527 // ------- Orthographic Variant (Correction)
528 row++;
529 orthographicVariantField = new NameRelationField("Orthographical variant", "Name variant", Direction.relatedTo, NameRelationshipType.ORTHOGRAPHIC_VARIANT());
530 orthographicVariantField.setWidth(100, Unit.PERCENTAGE);
531 // corrected name must have same
532 ToOneRelatedEntityCombobox<TaxonName> orthographicVariantCombobox = orthographicVariantField.getRelatedNameComboBox();
533 orthographicVariantCombobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
534 this,
535 new TaxonNameEditorAction(EditorActionType.ADD, null, orthographicVariantCombobox, this)
536 ));
537 orthographicVariantCombobox.addClickListenerEditEntity(e -> {
538 if(orthographicVariantCombobox.getValue() != null){
539 getViewEventBus().publish(this,
540 new TaxonNameEditorAction(
541 EditorActionType.EDIT,
542 orthographicVariantCombobox.getValue().getUuid(),
543 e.getButton(),
544 orthographicVariantCombobox,
545 this)
546 );
547 }
548 });
549 ToOneRelatedEntityCombobox<Reference> orthographicCorrectionCitatonComboBox = orthographicVariantField.getCitatonComboBox();
550 orthographicCorrectionCitatonComboBox.addClickListenerAddEntity(e -> getViewEventBus().publish(
551 // NOTE: adding new references is currently not allowed for name relations, see NameRelationField!!
552 this,
553 new ReferenceEditorAction(EditorActionType.ADD, null, orthographicCorrectionCitatonComboBox, this)
554 ));
555 orthographicCorrectionCitatonComboBox.addClickListenerEditEntity(e -> {
556 if(orthographicCorrectionCitatonComboBox.getValue() != null){
557 getViewEventBus().publish(this,
558 new ReferenceEditorAction(
559 EditorActionType.EDIT,
560 orthographicCorrectionCitatonComboBox.getValue().getUuid(),
561 e.getButton(),
562 orthographicCorrectionCitatonComboBox,
563 this)
564 );
565 }
566 });
567 addField(orthographicVariantField, "orthographicVariant", 0, row, 3, row);
568 grid.setComponentAlignment(orthographicVariantField, Alignment.TOP_RIGHT);
569
570 row++;
571 exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)", TeamOrPersonBaseCaptionGenerator.CacheType.NOMENCLATURAL_TITLE);
572 exCombinationAuthorshipField.setWidth(100, Unit.PERCENTAGE);
573 addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
574
575 row++;
576 annotationsListField = new FilterableAnnotationsField("Editorial notes");
577 annotationsListField.setWidth(100, Unit.PERCENTAGE);
578 boolean isCurator = UserHelperAccess.userHelper().userIs(new RoleProberImpl(RolesAndPermissions.ROLE_CURATION));
579 boolean isAdmin = UserHelperAccess.userHelper().userIsAdmin();
580 if(isCurator || isAdmin){
581 annotationsListField.withNewButton(true);
582 } else {
583 annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
584 }
585
586 addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
587
588 // -----------------------------------------------------------------------------
589
590 setAdvancedModeEnabled(true);
591 registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
592
593 registerAdvancedModeComponents(combinationAuthorshipField);
594 registerAdvancedModeComponents(basionymAuthorshipField);
595 registerAdvancedModeComponents(exBasionymAuthorshipField);
596 registerAdvancedModeComponents(exCombinationAuthorshipField);
597
598 registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
599 registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
600 registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
601 registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
602
603 setAdvancedMode(false);
604
605 //TODO remove below line once #7858 is fixed
606 withDeleteButton(false);
607
608 }
609
610 private void updateRankSelectFullListToggleButton() {
611 if(isRanksFullList) {
612 rankSelectFullListToggle.setIcon(FontAwesome.COMPRESS);
613 rankSelectFullListToggle.setDescription("Show short list of ranks");
614 } else {
615 rankSelectFullListToggle.setIcon(FontAwesome.EXPAND);
616 rankSelectFullListToggle.setDescription("Show full list of ranks");
617 }
618 }
619
620 protected TeamOrPersonBase inferBasiomynAuthors() {
621 List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
622 if(!basionyms.isEmpty() && basionyms.get(0) != null){
623 TaxonName basionym = basionyms.get(0);
624 if(basionym.getCombinationAuthorship() != null){
625 return basionym.getCombinationAuthorship();
626 } else if(basionym.getNomenclaturalReference() != null){
627 return basionym.getNomenclaturalReference().getAuthorship();
628 }
629 }
630 return null;
631 }
632
633 protected TeamOrPersonBase inferExBasiomynAuthors() {
634 List<TaxonName> basionyms = basionymsComboboxSelect.getValue();
635 if(!basionyms.isEmpty() && basionyms.get(0) != null){
636 TaxonName basionym = basionyms.get(0);
637 return basionym.getExCombinationAuthorship();
638 }
639 return null;
640 }
641
642 protected TeamOrPersonBase inferCombinationAuthors() {
643 Reference nomRef = nomReferenceCombobox.getValue();
644 if(nomRef != null) {
645 return nomRef.getAuthorship();
646 }
647 return null;
648 }
649
650 protected TeamOrPersonBase inferExCombinationAuthors() {
651 NameRelationshipDTO nameRelationDTO = validationField.getValue();
652
653 TeamOrPersonBase inferredExAuthor = null;
654 if(nameRelationDTO != null && nameRelationDTO.getOtherName() != null){
655 TaxonName validatedName = nameRelationDTO.getOtherName();
656 if(validatedName.getCombinationAuthorship() != null) {
657 inferredExAuthor = validatedName.getCombinationAuthorship();
658 } else if(validatedName.getNomenclaturalReference() != null){
659 inferredExAuthor = validatedName.getNomenclaturalReference().getAuthorship();
660 }
661 }
662 TeamOrPersonBase<?> inferredCominationAuthors = inferCombinationAuthors();
663 if(inferredExAuthor != null && inferredCominationAuthors != null
664 // comparing by nomTitle to detect duplicates:
665 && inferredExAuthor.getNomenclaturalTitleCache().equals(inferredCominationAuthors.getNomenclaturalTitleCache())) {
666 // If and only if ex author = author the ex author is not included
667 // into the author teams due to the ICN 46.10. (see #8317)
668 inferredExAuthor = null;
669 }
670 return inferredExAuthor;
671 }
672
673 @Override
674 protected void afterItemDataSourceSet() {
675
676
677 rankSelect.addValueChangeListener(updateFieldVisibilityListener);
678 basionymToggle.addValueChangeListener(e -> {
679 updateAuthorshipFields();
680 });
681 validationToggle.addValueChangeListener(e -> {
682 updateAuthorshipFields();
683 });
684 replacedSynonymsToggle.addValueChangeListener(e -> {
685 boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
686 replacedSynonymsComboboxSelect.setVisible(enable);
687 });
688 orthographicVariantToggle.addValueChangeListener(e -> {
689 boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
690 orthographicVariantField.setVisible(enable);
691 });
692
693 TaxonNameDTO taxonNameDTO = getBean();
694 boolean showBasionymSection = taxonNameDTO.getBasionyms().size() > 0
695 || taxonNameDTO.getBasionymAuthorship() != null
696 || taxonNameDTO.getExBasionymAuthorship() != null;
697 basionymToggle.setValue(showBasionymSection);
698 basionymToggle.setReadOnly(showBasionymSection);
699
700 boolean showReplacedSynonyms = taxonNameDTO.getReplacedSynonyms().size() > 0;
701 replacedSynonymsToggle.setValue(showReplacedSynonyms);
702 replacedSynonymsToggle.setReadOnly(showReplacedSynonyms);
703 replacedSynonymsComboboxSelect.setVisible(showReplacedSynonyms);
704
705 boolean showValidationSection = taxonNameDTO.getValidationFor() != null || taxonNameDTO.getExCombinationAuthorship() != null;
706 validationToggle.setValue(showValidationSection);
707 validationToggle.setReadOnly(showValidationSection);
708
709 boolean showOrthographicCorrectionSection = taxonNameDTO.getOrthographicVariant() != null;
710 orthographicVariantToggle.setValue(showOrthographicCorrectionSection);
711 orthographicVariantToggle.setReadOnly(showOrthographicCorrectionSection);
712
713 if(isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
714 updateAuthorshipFields();
715 }
716 if(isModeEnabled(TaxonNamePopupEditorMode.NOMENCLATURALREFERENCE_SECTION_EDITING_ONLY) && getBean().getNomenclaturalReference() != null) {
717 nomReferenceCombobox.setDescription("Selection limited to nomenclatural reference and parts of it.");
718 }
719 if(isModeEnabled(TaxonNamePopupEditorMode.REQUIRE_NOMENCLATURALREFERENCE)) {
720 nomReferenceCombobox.setRequired(true);
721 nomReferenceCombobox.setImmediate(true);
722
723 String userHint = "Please use the 'Edit' function to fix the problem in the related name.";
724 validationField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
725 orthographicVariantField.getRelatedNameComboBox().getSelect().addValidator(new NomenclaturalReferenceExistsValidator(userHint));
726 basionymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
727 replacedSynonymsComboboxSelect.addFieldValidator(new NomenclaturalReferenceExistsValidator(userHint));
728 }
729 }
730
731 /**
732 * Updates all authorship fields if the an authorship field is empty this method attempts to infer the
733 * authors from the related nomenclatural reference or taxon name.
734 * <p>
735 * Finally the {@link #updateFieldVisibility()} is invoked.
736 *
737 * @param taxonName
738 */
739 @Override
740 public void updateAuthorshipFields() {
741
742 TaxonNameDTO taxonName = getBean();
743
744 // ------------- CombinationAuthors
745 isInferredCombinationAuthorship = updateAuthorshipFieldData(
746 taxonName.getCombinationAuthorship(),
747 inferCombinationAuthors(),
748 combinationAuthorshipField,
749 nomReferenceCombobox.getSelect(),
750 isInferredCombinationAuthorship);
751
752
753 // ------------- Basionym and ExBasionymAuthors
754 if(BooleanUtils.isTrue(basionymToggle.getValue())){
755
756 isInferredBasionymAuthorship = updateAuthorshipFieldData(
757 taxonName.getBasionymAuthorship(),
758 inferBasiomynAuthors(),
759 basionymAuthorshipField,
760 basionymsComboboxSelect,
761 isInferredBasionymAuthorship
762 );
763
764 isInferredExBasionymAuthorship = updateAuthorshipFieldData(
765 taxonName.getExBasionymAuthorship(),
766 inferExBasiomynAuthors(),
767 exBasionymAuthorshipField,
768 basionymsComboboxSelect,
769 isInferredExBasionymAuthorship
770 );
771
772 }
773
774 // ------------- Validation and ExCombinationAuthors
775 isInferredExCombinationAuthorship = updateAuthorshipFieldData(
776 taxonName.getExCombinationAuthorship(),
777 inferExCombinationAuthors(),
778 exCombinationAuthorshipField,
779 validationField.getRelatedNameComboBox(),
780 isInferredExCombinationAuthorship
781 );
782
783 updateFieldVisibility();
784 }
785
786
787 /**
788 *
789 * @param authorship
790 * the value of the taxonName authorship field
791 * @param inferredAuthors
792 * the value inferred from other fields which may be set as authorship to the taxon name
793 * @param authorshipField
794 * the ui element to edit the taxonName authorship field
795 * @param updateTriggerField
796 * @param lastInferredAuthorshipState
797 * @return
798 */
799 protected Boolean updateAuthorshipFieldData(TeamOrPersonBase<?> authorship, TeamOrPersonBase inferredAuthors,
800 TeamOrPersonField authorshipField, AbstractField updateTriggerField,
801 Boolean lastInferredAuthorshipState) {
802
803 if(authorship == null){
804 authorshipField.setValue(inferredAuthors);
805 lastInferredAuthorshipState = true;
806 } else {
807 boolean authorshipMatch = authorship == inferredAuthors;
808 if(lastInferredAuthorshipState == null){
809 // initialization of authorshipState, this comes only into account when the editor is just being initialized
810 lastInferredAuthorshipState = authorshipMatch;
811 }
812 if(!authorshipMatch && lastInferredAuthorshipState){
813 // update the combinationAuthorshipField to follow changes of the nomenclatural reference in case it was autofilled before
814 authorshipField.setValue(inferredAuthors);
815 lastInferredAuthorshipState = true;
816 }
817 }
818
819 if(updateTriggerField != null){
820 // IMPORTANT!
821 // this ChangeListener must be added at this very late point in the editor lifecycle so that it is called after
822 // the ToOneRelatedEntityReloader which may have been added to the updateTriggerField in the presenters handleViewEntered() method.
823 // Otherwise we risk multiple representation problems in the hibernate session
824 if(!authorshipUpdateListeners.containsKey(updateTriggerField)){
825 ValueChangeListener listener = e -> {
826 logger.debug(" value changed #2");
827 updateAuthorshipFields();
828 };
829 updateTriggerField.addValueChangeListener(listener);
830 authorshipUpdateListeners.put(updateTriggerField, listener);
831 }
832 }
833
834 return lastInferredAuthorshipState;
835 }
836
837 private void updateFieldVisibility() {
838
839 // TODO use getField() instead and remove field references
840 Rank rank = (Rank) rankSelect.getValue();
841
842 @SuppressWarnings("deprecation")
843 boolean isSpeciesOrBelow = rank.isLowerOrEqualTo(RankClass.Species);
844 Boolean withBasionymSection = BooleanUtils.isTrue(basionymToggle.getValue());
845 Boolean withValidationSection = BooleanUtils.isTrue(validationToggle.getValue());
846 Boolean withOrthographicCorrectionSection = BooleanUtils.isTrue(orthographicVariantToggle.getValue());
847
848 if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
849 if(isSpeciesOrBelow) {
850 if(TextField.class.isAssignableFrom(genusOrUninomialField.getClass())){
851 WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
852 combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
853 this,
854 new TaxonNameEditorActionStrRep(
855 EditorActionType.ADD,
856 e.getButton(),
857 combobox,
858 this)
859 ));
860 combobox.addClickListenerEditEntity(e -> {
861 //WeaklyRelatedEntityCombobox<TaxonName> wrcbbx = combobox;
862 if(combobox.getValue() != null){
863 getViewEventBus().publish(this,
864 new TaxonNameEditorActionStrRep(
865 EditorActionType.EDIT,
866 combobox.getIdForValue(),
867 e.getButton(),
868 combobox,
869 this)
870 );
871 }
872 });
873 combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
874 genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, combobox, 0, genusOrUninomialRow, 1, genusOrUninomialRow);
875 }
876 } else {
877 if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(genusOrUninomialField.getClass())) {
878 genusOrUninomialField = replaceComponent("genusOrUninomial", genusOrUninomialField, new TextFieldNFix(), 0, genusOrUninomialRow, 1, genusOrUninomialRow);
879 genusOrUninomialField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
880 }
881 }
882 }
883
884 if(isModeEnabled(TaxonNamePopupEditorMode.VALIDATE_AGAINST_HIGHER_NAME_PART)){
885 if(rank.isInfraSpecific()) {
886 if(TextField.class.isAssignableFrom(specificEpithetField.getClass())) {
887 WeaklyRelatedEntityCombobox<TaxonName> combobox = new WeaklyRelatedEntityCombobox<TaxonName>("-> this caption will be replaced <-", TaxonName.class);
888 specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, combobox, 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
889 combobox.getSelect().setRequiredError(UIMessages.REQUIRED_SELECT_MISSING);
890 combobox.addClickListenerAddEntity(e -> getViewEventBus().publish(
891 this,
892 new TaxonNameEditorActionStrRep(EditorActionType.ADD, e.getButton(), combobox, this)
893 ));
894 combobox.addClickListenerEditEntity(e -> {
895 if(combobox.getValue() != null){
896 getViewEventBus().publish(this,
897 new TaxonNameEditorActionStrRep(
898 EditorActionType.EDIT,
899 combobox.getIdForValue(),
900 e.getButton(),
901 combobox,
902 this)
903 );
904 }
905 });
906 }
907 } else {
908 if(WeaklyRelatedEntityCombobox.class.isAssignableFrom(specificEpithetField.getClass())) {
909 specificEpithetField = replaceComponent("specificEpithet", specificEpithetField, new TextFieldNFix(), 0, specificEpithetFieldRow, 1, specificEpithetFieldRow);
910 specificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
911 }
912 }
913 }
914
915 if(isModeEnabled(TaxonNamePopupEditorMode.ORTHOGRAPHIC_CORRECTION)){
916 orthographicVariantField.setCaption("Orthographical correction");
917 orthographicVariantField.getRelatedNameComboBox().setCaption("Incorrect name");
918 orthographicVariantToggle.setCaption("Orthographical correction");
919 } else {
920 orthographicVariantField.setCaption("Orthographical variant");
921 orthographicVariantField.getRelatedNameComboBox().setCaption("Name variant");
922 orthographicVariantToggle.setCaption("Orthographical variant");
923 }
924
925 genusOrUninomialField.setRequired(true);
926 specificEpithetField.setVisible(isSpeciesOrBelow);
927 specificEpithetField.setRequired(isSpeciesOrBelow);
928 infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
929 infraSpecificEpithetField.setRequired(rank.isInfraSpecific());
930 infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
931 infraGenericEpithetField.setVisible(rank.isInfraGeneric());
932 infraGenericEpithetField.setRequired(rank.isInfraGeneric());
933 infraSpecificEpithetField.setRequiredError(UIMessages.REQUIRED_TEXT_MISSING);
934
935 basionymsComboboxSelect.setVisible(withBasionymSection);
936
937 combinationAuthorshipField.setVisible(isInferredCombinationAuthorship != null && !isInferredCombinationAuthorship);
938 basionymAuthorshipField.setVisible(withBasionymSection && isInferredBasionymAuthorship != null && !isInferredBasionymAuthorship);
939 exBasionymAuthorshipField.setVisible(withBasionymSection && isInferredExBasionymAuthorship != null && !isInferredExBasionymAuthorship);
940
941 validationField.setVisible(withValidationSection);
942 exCombinationAuthorshipField.setVisible(withValidationSection && isInferredExCombinationAuthorship != null && !isInferredExCombinationAuthorship);
943
944 orthographicVariantField.setVisible(withOrthographicCorrectionSection);
945 if(withOrthographicCorrectionSection){
946 orthographicCorrectionValidator = new OrthographicCorrectionReferenceValidator(nomReferenceCombobox);
947 orthographicVariantField.addValidator(orthographicCorrectionValidator);
948 } else {
949 if(orthographicCorrectionValidator != null){
950 orthographicVariantField.removeValidator(orthographicCorrectionValidator);
951 orthographicVariantField = null;
952 }
953 }
954
955 infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
956 specificEpithetField.setVisible(isSpeciesOrBelow);
957 infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
958 genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
959
960 updateNomStatusCollectionFieldVisibility();
961
962 }
963
964 public void updateNomStatusCollectionFieldVisibility() {
965 boolean nameHasStatus = false;
966 if(nomStatusCollectionField.getLayout().getRows() > 1) {
967 // fist row holds the lables
968 NativeSelect fistStatusSelect = (NativeSelect)nomStatusCollectionField.getLayout().getComponent(0, 1);
969 nameHasStatus = fistStatusSelect.getValue() != null;
970 }
971 nomStatusCollectionField.getLayout().getParent().setVisible(nameHasStatus);
972 nomStatusCollectionFieldToggle.setValue(Boolean.valueOf(nameHasStatus));
973 }
974
975 @Override
976 public void cancel() {
977 authorshipUpdateListeners.keySet().forEach(field -> field.removeValueChangeListener(authorshipUpdateListeners.get(field)));
978 rankSelect.removeValueChangeListener(updateFieldVisibilityListener);
979 super.cancel();
980 }
981
982 @Override
983 public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
984 return nomReferenceCombobox;
985 }
986
987 @Override
988 public TextField getNomenclaturalReferenceDetail() {
989 return nomenclaturalReferenceDetail;
990 }
991
992 @Override
993 public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
994 return basionymsComboboxSelect;
995 }
996
997 @Override
998 public ToManyRelatedEntitiesComboboxSelect<TaxonName> getReplacedSynonymsComboboxSelect() {
999 return replacedSynonymsComboboxSelect;
1000 }
1001
1002 @Override
1003 public NativeSelect getRankSelect() {
1004 return rankSelect;
1005 }
1006
1007 @Override
1008 public Button getRankSelectFullListToggle() {
1009 return rankSelectFullListToggle;
1010 }
1011
1012 @Override
1013 public AbstractField<String> getGenusOrUninomialField(){
1014 return genusOrUninomialField;
1015 }
1016
1017 @Override
1018 public TeamOrPersonField getExBasionymAuthorshipField() {
1019 return exBasionymAuthorshipField;
1020 }
1021
1022 @Override
1023 public TeamOrPersonField getBasionymAuthorshipField() {
1024 return basionymAuthorshipField;
1025 }
1026
1027 @Override
1028 public TeamOrPersonField getCombinationAuthorshipField() {
1029 return combinationAuthorshipField;
1030 }
1031
1032 @Override
1033 public TeamOrPersonField getExCombinationAuthorshipField() {
1034 return exCombinationAuthorshipField;
1035 }
1036
1037 @Override
1038 public NameRelationField getValidationField(){
1039 return validationField;
1040 }
1041
1042 @Override
1043 public NameRelationField getOrthographicVariantField() {
1044 return orthographicVariantField;
1045 }
1046
1047 @Override
1048 public void enableMode(TaxonNamePopupEditorMode mode){
1049 modesActive.add(mode);
1050 updateFormOnModeChange();
1051 }
1052
1053 @Override
1054 public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
1055 return modesActive.contains(mode);
1056 }
1057
1058 @Override
1059 public boolean isRanksFullList() {
1060 return isRanksFullList;
1061 }
1062
1063 @Override
1064 public void disableMode(TaxonNamePopupEditorMode mode){
1065 modesActive.remove(mode);
1066 updateFormOnModeChange();
1067 }
1068
1069 /**
1070 * updates UI in turn of mode changes if needed, that is when the bean has been set
1071 * already.
1072 */
1073 private void updateFormOnModeChange() {
1074 if(getBean() != null){
1075 // need to update the ui
1076 afterItemDataSourceSet();
1077 if(!isModeEnabled(TaxonNamePopupEditorMode.AUTOFILL_AUTHORSHIP_DATA)){
1078 updateFieldVisibility();
1079 }
1080 }
1081 }
1082
1083 @Override
1084 public EnumSet<TaxonNamePopupEditorMode> getModesActive(){
1085 return modesActive;
1086 }
1087
1088 @Override
1089 public CheckBox getBasionymToggle() {
1090 return basionymToggle;
1091 }
1092
1093 @Override
1094 public FilterableAnnotationsField getAnnotationsField() {
1095 return annotationsListField;
1096 }
1097
1098 @Override
1099 public void setReadOnly(boolean readOnly) {
1100 super.setReadOnly(readOnly);
1101 boolean basionymToggleReadonly = basionymToggle.isReadOnly();
1102 boolean validationToggleReadonly = validationToggle.isReadOnly();
1103 combinationAuthorshipField.setEditorReadOnly(readOnly);
1104 exCombinationAuthorshipField.setEditorReadOnly(readOnly);
1105 basionymAuthorshipField.setEditorReadOnly(readOnly);
1106 exBasionymAuthorshipField.setEditorReadOnly(readOnly);
1107 // preserve old readonly states if they were true
1108 if(basionymToggleReadonly){
1109 basionymToggle.setReadOnly(true);
1110 }
1111 if(validationToggleReadonly){
1112 validationToggle.setReadOnly(true);
1113 }
1114 nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1115 }
1116
1117 /**
1118 * Sets the readonly state of all fields in this editor, but leaving the editor itself untouched.
1119 *
1120 * @param readOnly
1121 */
1122 public void setAllFieldsReadOnly(boolean readOnly) {
1123 logger.error("Set all fields to readonly");
1124
1125 recursiveReadonly(readOnly, getMainLayout());
1126 // NOTE:We are using the enabled state instead of read only since
1127 // setting read only will not affect the members editor.
1128 // this seems to be a bug in TeamOrPersonField or in
1129 // ToManyRelatedEntitiesListSelect
1130 combinationAuthorshipField.setEnabled(!readOnly);
1131 exCombinationAuthorshipField.setEnabled(!readOnly);
1132 basionymAuthorshipField.setEnabled(!readOnly);
1133 exBasionymAuthorshipField.setEnabled(!readOnly);
1134 nomStatusCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
1135 }
1136
1137 @Override
1138 public AbstractField<String> getInfraGenericEpithetField() {
1139 return infraGenericEpithetField;
1140 }
1141
1142 @Override
1143 public AbstractField<String> getSpecificEpithetField() {
1144 return specificEpithetField;
1145 }
1146
1147 @Override
1148 public AbstractField<String> getInfraSpecificEpithetField() {
1149 return infraSpecificEpithetField;
1150 }
1151
1152 @Override
1153 public CheckBox getOrthographicVariantToggle() {
1154 return orthographicVariantToggle;
1155 }
1156
1157 @Override
1158 public ElementCollectionField<NomenclaturalStatusDTO> getNomStatusCollectionField(){
1159 return nomStatusCollectionField;
1160 }
1161 }