improving layout
[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
14 import org.springframework.security.core.GrantedAuthority;
15
16 import com.vaadin.ui.Alignment;
17 import com.vaadin.ui.CheckBox;
18 import com.vaadin.ui.GridLayout;
19 import com.vaadin.ui.ListSelect;
20 import com.vaadin.ui.TextField;
21
22 import eu.etaxonomy.cdm.model.common.CdmBase;
23 import eu.etaxonomy.cdm.model.name.Rank;
24 import eu.etaxonomy.cdm.model.name.TaxonName;
25 import eu.etaxonomy.cdm.model.reference.Reference;
26 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
27 import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
28 import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
29 import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
30 import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
31 import eu.etaxonomy.cdm.vaadin.security.UserHelper;
32 import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
33 import eu.etaxonomy.vaadin.component.SwitchableTextField;
34 import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
35 import eu.etaxonomy.vaadin.component.ToOneRelatedEntityCombobox;
36 import eu.etaxonomy.vaadin.event.EditorActionType;
37 import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor;
38 import eu.etaxonomy.vaadin.permission.EditPermissionTester;
39
40 /**
41 * @author a.kohlbecker
42 * @since May 22, 2017
43 *
44 */
45 public class TaxonNamePopupEditor extends AbstractCdmPopupEditor<TaxonName, TaxonNameEditorPresenter> implements TaxonNamePopupEditorView, AccessRestrictedView {
46
47 private static final long serialVersionUID = -7037436241474466359L;
48
49 private final static int GRID_COLS = 4;
50
51 private final static int GRID_ROWS = 12;
52
53 private static final boolean HAS_BASIONYM_DEFAULT = false;
54
55 private TextField genusOrUninomialField;
56
57 private TextField infraGenericEpithetField;
58
59 private TextField specificEpithetField;
60
61 private TextField infraSpecificEpithetField;
62
63 private SwitchableTextField fullTitleCacheFiled;
64
65 private SwitchableTextField protectedNameCacheField;
66
67 private ToOneRelatedEntityCombobox<Reference> nomReferenceCombobox;
68
69 private TextField nomenclaturalReferenceDetail;
70
71 private TeamOrPersonField exBasionymAuthorshipField;
72
73 private TeamOrPersonField basionymAuthorshipField;
74
75 private ToManyRelatedEntitiesComboboxSelect<TaxonName> basionymsComboboxSelect;
76
77 private CheckBox basionymToggle;
78
79 private ListSelect rankSelect;
80
81 private TeamOrPersonField combinationAuthorshipField;
82
83 private TeamOrPersonField exCombinationAuthorshipField;
84
85 private EnumSet<TaxonNamePopupEditorMode> modesActive = EnumSet.noneOf(TaxonNamePopupEditorMode.class);
86
87 /**
88 * @param layout
89 * @param dtoType
90 */
91 public TaxonNamePopupEditor() {
92 super(new GridLayout(GRID_COLS, GRID_ROWS), TaxonName.class);
93 }
94
95 /**
96 * {@inheritDoc}
97 */
98 @Override
99 public String getWindowCaption() {
100 return "Name editor";
101 }
102
103
104
105 /**
106 * {@inheritDoc}
107 */
108 @Override
109 public int getWindowPixelWidth() {
110 return 700;
111 }
112
113 /**
114 * {@inheritDoc}
115 */
116 @Override
117 public void focusFirst() {
118 // titleField.focus();
119
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 @Override
126 protected String getDefaultComponentStyles() {
127 return "tiny";
128 }
129
130 /**
131 * {@inheritDoc}
132 */
133 @Override
134 protected void initContent() {
135
136 GridLayout grid = (GridLayout)getFieldLayout();
137 grid.setSizeFull();
138 grid.setSpacing(true);
139 grid.setColumnExpandRatio(0, 0.3f);
140 grid.setColumnExpandRatio(1, 0.3f);
141 grid.setColumnExpandRatio(2, 0.3f);
142 grid.setColumnExpandRatio(3, 0.0f);
143
144 /*
145 - nameType: preset, needs to be set in the presenter for new names
146 - appendedPhrase: -> TODO field
147 - nomenclaturalMicroReference: -> TODO field
148 - nomenclaturalReference -> field but disabled for REGISTRY
149 - rank -> SelectField which determines the visiblity of the other fields
150
151 - fullTitleCache + protectedFullTitleCache -> SwitchableTextField : ADVANCED_MODE
152 - nameCache + protectedNameCache -> SwitchableTextField : ADVANCED_MODE
153
154 - homotypicalGroup -> hidden
155 - typeDesignations -> hidden
156 - descriptions -> hidden
157 - taxonBases -> hidden
158 - registrations -> hidden
159
160 - relationsFromThisName-> TODO implement later
161 - relationsToThisName -> TODO implement later
162
163 - genusOrUninomial -> textField
164 - infraGenericEpithet -> textField
165 - specificEpithet -> textField
166 - infraSpecificEpithet -> textField
167
168 - authorshipCache + protectedAuthorshipCache -> SwitchableTextField : only ADVANCED_MODE and disabled for REGISTRY
169 - basionymAuthorship -> field but disabled for REGISTRY, basionym is set as nameRelationShip
170 - combinationAuthorship -> field but disabled for REGISTRY author team of the reference
171 - exCombinationAuthorship -> textField
172 - exBasionymAuthorship -> textField
173
174 - status -> TODO field
175 - monomHybrid -> TODO implement hybrids later
176 - binomHybrid -> TODO implement hybrids later
177 - trinomHybrid -> TODO implement hybrids later
178
179 - hybridParentRelations -> TODO implement hybrids later
180 - hybridChildRelations -> TODO implement hybrids later
181 - hybridFormula -> TODO implement hybrids later
182
183 ** ViralName attributes **
184 - acronym
185
186 ** BacterialName attributes **
187 - subGenusAuthorship
188 - nameApprobation
189 - breed
190 - publicationYear
191 - originalPublicationYear
192 - cultivarName
193 */
194
195 int row = 0;
196
197 rankSelect = new ListSelect("Rank");
198 rankSelect.setNullSelectionAllowed(false);
199 rankSelect.setRows(1);
200 rankSelect.setWidth(100, Unit.PERCENTAGE);
201 rankSelect.addValueChangeListener(e -> updateFieldVisibility((Rank)e.getProperty().getValue()));
202 addField(rankSelect, "rank", 0, row, 1, row);
203 grid.setComponentAlignment(rankSelect, Alignment.TOP_RIGHT);
204
205 basionymToggle = new CheckBox("With basionym");
206 basionymToggle.setValue(HAS_BASIONYM_DEFAULT);
207 basionymToggle.addValueChangeListener(e -> {
208 boolean enable = e.getProperty().getValue() != null && (Boolean)e.getProperty().getValue();
209 enableBasionymFields(enable);
210 });
211 basionymToggle.setStyleName(getDefaultComponentStyles());
212 grid.addComponent(basionymToggle, 2, row, 3, row);
213 grid.setComponentAlignment(basionymToggle, Alignment.BOTTOM_LEFT);
214 row++;
215 // fullTitleCache
216 fullTitleCacheFiled = addSwitchableTextField("Full title cache", "fullTitleCache", "protectedFullTitleCache", 0, row, GRID_COLS-1, row);
217 fullTitleCacheFiled.setWidth(100, Unit.PERCENTAGE);
218 row++;
219 protectedNameCacheField = addSwitchableTextField("Name cache", "nameCache", "protectedNameCache", 0, row, GRID_COLS-1, row);
220 protectedNameCacheField.setWidth(100, Unit.PERCENTAGE);
221 row++;
222 genusOrUninomialField = addTextField("Genus or uninomial", "genusOrUninomial", 0, row, 1, row);
223 genusOrUninomialField.setWidth(200, Unit.PIXELS);
224 infraGenericEpithetField = addTextField("Infrageneric epithet", "infraGenericEpithet", 2, row, 3, row);
225 infraGenericEpithetField.setWidth(200, Unit.PIXELS);
226 row++;
227 specificEpithetField = addTextField("Specific epithet", "specificEpithet", 0, row, 1, row);
228 specificEpithetField.setWidth(200, Unit.PIXELS);
229 infraSpecificEpithetField = addTextField("Infraspecific epithet", "infraSpecificEpithet", 2, row, 3, row);
230 infraSpecificEpithetField.setWidth(200, Unit.PIXELS);
231 row++;
232 combinationAuthorshipField = new TeamOrPersonField("combination author(s)");
233 combinationAuthorshipField.setWidth(100, Unit.PERCENTAGE);
234 addField(combinationAuthorshipField, "combinationAuthorship", 0, row, GRID_COLS-1, row);
235 row++;
236 exCombinationAuthorshipField = new TeamOrPersonField("Ex-combination author(s)");
237 exCombinationAuthorshipField.setWidth(100, Unit.PERCENTAGE);
238 addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
239
240 // nomenclaturalReference
241 row++;
242 nomReferenceCombobox = new ToOneRelatedEntityCombobox<Reference>("Nomenclatural reference", Reference.class);
243 nomReferenceCombobox.addClickListenerAddEntity(e -> getEventBus().publishEvent(
244 new ReferenceEditorAction(EditorActionType.ADD, null, nomReferenceCombobox, this)
245 ));
246 nomReferenceCombobox.addClickListenerEditEntity(e -> {
247 if(nomReferenceCombobox.getValue() != null){
248 getEventBus().publishEvent(
249 new ReferenceEditorAction(
250 EditorActionType.EDIT,
251 nomReferenceCombobox.getValue().getId(),
252 nomReferenceCombobox,
253 this)
254 );
255 }
256 });
257 // nomReferenceCombobox.setWidth(300, Unit.PIXELS);
258 nomReferenceCombobox.setWidth("100%");
259 addField(nomReferenceCombobox, "nomenclaturalReference", 0, row, 2, row);
260 nomenclaturalReferenceDetail = addTextField("Reference detail", "nomenclaturalMicroReference", 3, row, 3, row);
261 nomenclaturalReferenceDetail.setWidth(100, Unit.PIXELS);
262
263
264 // Basionym
265 row++;
266 basionymsComboboxSelect = new ToManyRelatedEntitiesComboboxSelect<TaxonName>(TaxonName.class, "Basionym");
267 basionymsComboboxSelect.setConverter(new SetToListConverter<TaxonName>());
268 addField(basionymsComboboxSelect, "basionyms", 0, row, 3, row);
269 basionymsComboboxSelect.setWidth(100, Unit.PERCENTAGE);
270 basionymsComboboxSelect.withEditButton(true);
271 basionymsComboboxSelect.setEditPermissionTester(new EditPermissionTester() {
272
273 @Override
274 public boolean userHasEditPermission(Object bean) {
275 return UserHelper.fromSession().userHasPermission((CdmBase)bean, CRUD.UPDATE, CRUD.DELETE);
276 }
277 });
278 basionymsComboboxSelect.setEditActionListener(e -> {
279
280 Object fieldValue = e.getSource().getValue();
281 Integer beanId = null;
282 if(fieldValue != null){
283 beanId = ((CdmBase)fieldValue).getId();
284
285 }
286 eventBus.publishEvent(new TaxonNameEditorAction(e.getAction(), beanId, e.getSource(), this));
287 });
288 grid.setComponentAlignment(basionymsComboboxSelect, Alignment.TOP_RIGHT);
289 row++;
290 basionymAuthorshipField = new TeamOrPersonField("Basionym author(s)");
291 basionymAuthorshipField.setWidth(100, Unit.PERCENTAGE);
292 addField(basionymAuthorshipField, "basionymAuthorship", 0, row, GRID_COLS-1, row);
293 row++;
294 exBasionymAuthorshipField = new TeamOrPersonField("Ex-basionym author(s)");
295 exBasionymAuthorshipField.setWidth(100, Unit.PERCENTAGE);
296 addField(exBasionymAuthorshipField, "exBasionymAuthorship", 0, row, GRID_COLS-1, row);
297
298
299
300 setAdvancedModeEnabled(true);
301 enableBasionymFields(HAS_BASIONYM_DEFAULT);
302 registerAdvancedModeComponents(fullTitleCacheFiled, protectedNameCacheField);
303 registerAdvancedModeComponents(basionymAuthorshipField.getCachFields());
304 registerAdvancedModeComponents(exBasionymAuthorshipField.getCachFields());
305 registerAdvancedModeComponents(combinationAuthorshipField.getCachFields());
306 registerAdvancedModeComponents(exCombinationAuthorshipField.getCachFields());
307 setAdvancedMode(false);
308
309 }
310
311 /**
312 * @param value
313 * @return
314 */
315 private void enableBasionymFields(boolean enable) {
316 basionymAuthorshipField.setVisible(enable);
317 exBasionymAuthorshipField.setVisible(enable);
318 basionymsComboboxSelect.setVisible(enable);
319 if(modesActive.contains(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
320 TaxonName taxonName = getBean();
321 basionymAuthorshipField.setVisible(taxonName.getBasionymAuthorship() != null);
322 }
323 }
324
325 /**
326 * @param rank
327 * @return
328 */
329 private void updateFieldVisibility(Rank rank) {
330 boolean isSpeciesOrBelow = !rank.isHigher(Rank.SPECIES());
331 // TODO use getField() instead and remove field references
332 infraSpecificEpithetField.setVisible(rank.isInfraSpecific());
333 specificEpithetField.setVisible(isSpeciesOrBelow);
334 infraGenericEpithetField.setVisible(rank.isInfraGenericButNotSpeciesGroup());
335 genusOrUninomialField.setCaption(isSpeciesOrBelow ? "Genus" : "Uninomial");
336 }
337
338 @Override
339 protected void afterItemDataSourceSet() {
340 TaxonName taxonName = getBean();
341 boolean showBasionymSection = taxonName.getBasionyms().size() > 0
342 || taxonName.getBasionymAuthorship() != null
343 || taxonName.getExBasionymAuthorship() != null;
344 basionymToggle.setValue(showBasionymSection);
345
346 if(isModeEnabled(TaxonNamePopupEditorMode.suppressReplacementAuthorshipData)){
347 combinationAuthorshipField.setVisible(taxonName.getCombinationAuthorship() != null);
348 }
349
350 }
351
352 /**
353 * {@inheritDoc}
354 */
355 @Override
356 public boolean allowAnonymousAccess() {
357 return false;
358 }
359
360 /**
361 * {@inheritDoc}
362 */
363 @Override
364 public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
365 return null;
366 }
367
368 /**
369 * {@inheritDoc}
370 */
371 @Override
372 public ToOneRelatedEntityCombobox<Reference> getNomReferenceCombobox() {
373 return nomReferenceCombobox;
374 }
375
376 /**
377 * {@inheritDoc}
378 */
379 @Override
380 public ToManyRelatedEntitiesComboboxSelect<TaxonName> getBasionymComboboxSelect() {
381 return basionymsComboboxSelect;
382 }
383
384 /**
385 * {@inheritDoc}
386 */
387 @Override
388 public ListSelect getRankSelect() {
389 return rankSelect;
390 }
391
392 /**
393 * @return the exBasionymAuthorshipField
394 */
395 @Override
396 public TeamOrPersonField getExBasionymAuthorshipField() {
397 return exBasionymAuthorshipField;
398 }
399
400 /**
401 * @return the basionymAuthorshipField
402 */
403 @Override
404 public TeamOrPersonField getBasionymAuthorshipField() {
405 return basionymAuthorshipField;
406 }
407
408 /**
409 * @return the combinationAuthorshipField
410 */
411 @Override
412 public TeamOrPersonField getCombinationAuthorshipField() {
413 return combinationAuthorshipField;
414 }
415
416 /**
417 * @return the exCombinationAuthorshipField
418 */
419 @Override
420 public TeamOrPersonField getExCombinationAuthorshipField() {
421 return exCombinationAuthorshipField;
422 }
423
424 @Override
425 public void enableMode(TaxonNamePopupEditorMode mode){
426 modesActive.add(mode);
427 }
428
429 @Override
430 public boolean isModeEnabled(TaxonNamePopupEditorMode mode){
431 return modesActive.contains(mode);
432 }
433
434 @Override
435 public void disableMode(TaxonNamePopupEditorMode mode){
436 modesActive.remove(mode);
437 }
438
439 @Override
440 public CheckBox getBasionymToggle() {
441 return basionymToggle;
442 }
443
444
445 }