2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.vaadin
.view
.name
;
11 import java
.util
.Collection
;
12 import java
.util
.EnumSet
;
14 import org
.springframework
.context
.annotation
.Scope
;
15 import org
.springframework
.security
.core
.GrantedAuthority
;
16 import org
.vaadin
.viritin
.fields
.ElementCollectionField
;
18 import com
.vaadin
.data
.Validator
.InvalidValueException
;
19 import com
.vaadin
.data
.validator
.DoubleRangeValidator
;
20 import com
.vaadin
.server
.ErrorMessage
;
21 import com
.vaadin
.spring
.annotation
.SpringComponent
;
22 import com
.vaadin
.ui
.AbstractSelect
.ItemCaptionMode
;
23 import com
.vaadin
.ui
.Component
;
24 import com
.vaadin
.ui
.GridLayout
;
25 import com
.vaadin
.ui
.ListSelect
;
26 import com
.vaadin
.ui
.Panel
;
27 import com
.vaadin
.ui
.TextArea
;
29 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
30 import eu
.etaxonomy
.cdm
.persistence
.hibernate
.permission
.CRUD
;
31 import eu
.etaxonomy
.cdm
.vaadin
.component
.CollectionRowRepresentative
;
32 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.FilterableAnnotationsField
;
33 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.GeoLocationField
;
34 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.MinMaxTextField
;
35 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.TeamOrPersonField
;
36 import eu
.etaxonomy
.cdm
.vaadin
.component
.common
.TimePeriodField
;
37 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationDTO
;
38 import eu
.etaxonomy
.cdm
.vaadin
.model
.registration
.SpecimenTypeDesignationWorkingSetDTO
;
39 import eu
.etaxonomy
.cdm
.vaadin
.permission
.AccessRestrictedView
;
40 import eu
.etaxonomy
.cdm
.vaadin
.ui
.RegistrationUIDefaults
;
41 import eu
.etaxonomy
.cdm
.vaadin
.util
.TeamOrPersonBaseCaptionGenerator
;
42 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.DoubleConverter
;
43 import eu
.etaxonomy
.cdm
.vaadin
.util
.converter
.IntegerConverter
;
44 import eu
.etaxonomy
.cdm
.vaadin
.view
.PerEntityAuthorityGrantingEditor
;
45 import eu
.etaxonomy
.vaadin
.mvp
.AbstractPopupEditor
;
48 * @author a.kohlbecker
54 public class SpecimenTypeDesignationWorkingsetPopupEditor
55 extends AbstractPopupEditor
<SpecimenTypeDesignationWorkingSetDTO
, SpecimenTypeDesignationWorkingsetEditorPresenter
>
56 implements SpecimenTypeDesignationWorkingsetPopupEditorView
, AccessRestrictedView
, PerEntityAuthorityGrantingEditor
{
60 private static final String CAN_T_SAVE_AS_LONG_AS_TYPE_DESIGNATIONS_ARE_MISSING
= "Can't save as long as type designations are missing.";
66 public SpecimenTypeDesignationWorkingsetPopupEditor() {
67 super(new GridLayout(), SpecimenTypeDesignationWorkingSetDTO
.class);
68 GridLayout grid
= (GridLayout
) getFieldLayout();
70 grid
.setSpacing(true);
73 private static final long serialVersionUID
= 5418275817834009509L;
75 private ListSelect countrySelectField
;
77 private ElementCollectionField
<SpecimenTypeDesignationDTO
> typeDesignationsCollectionField
;
79 private EnumSet
<CRUD
> crud
;
81 private TeamOrPersonField collectorField
;
83 private FilterableAnnotationsField annotationsListField
;
85 private AnnotationType
[] editableAnotationTypes
= RegistrationUIDefaults
.EDITABLE_ANOTATION_TYPES
;
87 private GeoLocationField exactLocationField
;
89 private Panel typeDesignationsScrollPanel
;
92 * @return the countrySelectField
95 public ListSelect
getCountrySelectField() {
96 return countrySelectField
;
103 protected void initContent() {
105 GridLayout grid
= (GridLayout
)getFieldLayout();
106 grid
.setSpacing(true);
107 grid
.setMargin(true);
111 //TODO typifyingAuthors
113 // FieldUnit + GatheringEvent
116 countrySelectField
= new ListSelect("Country");
117 addField(countrySelectField
, "country", 1, row
, 2, row
);
118 countrySelectField
.setWidth("100%");
119 countrySelectField
.setItemCaptionMode(ItemCaptionMode
.PROPERTY
);
120 countrySelectField
.setItemCaptionPropertyId("label");
121 countrySelectField
.setRows(1);
124 TextArea localityField
= new TextArea("Locality");
125 localityField
.setNullRepresentation("");
126 addField(localityField
, "locality", 0, row
, 2, row
);
127 localityField
.setWidth("100%");
128 // NOTE: setRows and SetCold breaks he width setting,
129 // see https://github.com/vaadin/framework/issues/3617
132 exactLocationField
= new GeoLocationField("Geo location");
133 addField(exactLocationField
, "exactLocation", 0, row
, 2, row
);
134 exactLocationField
.setWidth("100%");
137 MinMaxTextField absElevationMinMax
= new MinMaxTextField("Altitude", "m");
138 absElevationMinMax
.setWidth("100%");
139 absElevationMinMax
.addSubComponentsStyleName(getDefaultComponentStyles());
140 grid
.addComponent(absElevationMinMax
, 0, row
, 2, row
);
142 bindField(absElevationMinMax
.getMinField(), "absoluteElevation");
143 bindField(absElevationMinMax
.getMaxField(), "absoluteElevationMax");
144 bindField(absElevationMinMax
.getTextField(), "absoluteElevationText");
146 absElevationMinMax
.getMaxField().setConverter(new IntegerConverter());
147 absElevationMinMax
.getMinField().setConverter(new IntegerConverter());
150 MinMaxTextField distanceToWaterSurfaceMinMax
= new MinMaxTextField("Distance to water surface", "m");
151 distanceToWaterSurfaceMinMax
.setWidth("100%");
152 distanceToWaterSurfaceMinMax
.addSubComponentsStyleName(getDefaultComponentStyles());
153 grid
.addComponent(distanceToWaterSurfaceMinMax
, 0, row
, 2, row
);
155 bindField(distanceToWaterSurfaceMinMax
.getMinField(), "distanceToWaterSurface");
156 bindField(distanceToWaterSurfaceMinMax
.getMaxField(), "distanceToWaterSurfaceMax");
157 bindField(distanceToWaterSurfaceMinMax
.getTextField(), "distanceToWaterSurfaceText");
158 distanceToWaterSurfaceMinMax
.getMaxField().setConverter(new DoubleConverter());
159 distanceToWaterSurfaceMinMax
.getMinField().setConverter(new DoubleConverter());
160 distanceToWaterSurfaceMinMax
.getMaxField().addValidator(new DoubleRangeValidator("Negative values are not allowed here.", 0.0, Double
.MAX_VALUE
));
161 distanceToWaterSurfaceMinMax
.getMinField().addValidator(new DoubleRangeValidator("Negative values are not allowed here.", 0.0, Double
.MAX_VALUE
));
164 MinMaxTextField distanceToGroundMinMax
= new MinMaxTextField("Distance to substrate", "m");
165 distanceToGroundMinMax
.setWidth("100%");
166 distanceToGroundMinMax
.addSubComponentsStyleName(getDefaultComponentStyles());
167 grid
.addComponent(distanceToGroundMinMax
, 0, row
, 2, row
);
169 bindField(distanceToGroundMinMax
.getMinField(), "distanceToGround");
170 bindField(distanceToGroundMinMax
.getMaxField(), "distanceToGroundMax");
171 bindField(distanceToGroundMinMax
.getTextField(), "distanceToGroundText");
172 distanceToGroundMinMax
.getMaxField().setConverter(new DoubleConverter());
173 distanceToGroundMinMax
.getMinField().setConverter(new DoubleConverter());
176 collectorField
= new TeamOrPersonField("Collector", TeamOrPersonBaseCaptionGenerator
.CacheType
.COLLECTOR_TITLE
);
177 addField(collectorField
, "collector", 0, row
, 2, row
);
181 TimePeriodField collectionDateField
= new TimePeriodField("Collection date");
182 // collectionDateField.setInputPrompt("dd.mm.yyyy");
183 addField(collectionDateField
, "gatheringDate", 0, row
, 1, row
);
184 addTextField("Field number", "fieldNumber", 2, row
);
189 // FIXME: can we use the Grid instead?
190 typeDesignationsCollectionField
= new ElementCollectionField
<SpecimenTypeDesignationDTO
>(
191 SpecimenTypeDesignationDTO
.class,
192 SpecimenTypeDesignationDTORow
.class
196 public void commit() throws SourceException
, InvalidValueException
{
197 validate(); // validate always so that empty rows are recognized
202 public boolean isEmpty() {
203 Collection value
= getValue();
204 return value
== null || value
.isEmpty() ;
208 public void setComponentError(ErrorMessage componentError
) {
209 typeDesignationsScrollPanel
.setComponentError(componentError
);
213 typeDesignationsCollectionField
.withCaption("Types");
214 typeDesignationsCollectionField
.getLayout().setSpacing(false);
215 typeDesignationsCollectionField
.getLayout().setColumns(3);
216 typeDesignationsCollectionField
.setRequired(true); // only works with the above overwritten commit()
217 typeDesignationsCollectionField
.setRequiredError(CAN_T_SAVE_AS_LONG_AS_TYPE_DESIGNATIONS_ARE_MISSING
);
218 typeDesignationsCollectionField
.setVisibleProperties(SpecimenTypeDesignationDTORow
.visibleFields());
220 typeDesignationsCollectionField
.setPropertyHeader("accessionNumber", "Access. num.");
221 typeDesignationsCollectionField
.setPropertyHeader("preferredStableUri", "Stable URI");
222 typeDesignationsCollectionField
.setPropertyHeader("mediaSpecimenReference", "Image reference");
223 typeDesignationsCollectionField
.setPropertyHeader("mediaSpecimenReferenceDetail", "Reference detail");
224 typeDesignationsCollectionField
.addElementAddedListener( e
-> typeDesignationsCollectionField
.setComponentError(null));
226 // typeDesignationsCollectionField.getLayout().setMargin(false);
227 // typeDesignationsCollectionField.addStyleName("composite-field-wrapper");
228 // addField(typeDesignationsCollectionField, "specimenTypeDesignationDTOs", 0, row, 2, row);
230 typeDesignationsScrollPanel
= new Panel(typeDesignationsCollectionField
.getLayout());
231 typeDesignationsScrollPanel
.setCaption("Types");
232 typeDesignationsScrollPanel
.setWidth(800, Unit
.PIXELS
);
234 bindField(typeDesignationsCollectionField
, "specimenTypeDesignationDTOs");
235 addComponent(typeDesignationsScrollPanel
, 0, row
, 2, row
);
238 annotationsListField
= new FilterableAnnotationsField("Editorial notes");
239 annotationsListField
.setWidth(100, Unit
.PERCENTAGE
);
240 annotationsListField
.setAnnotationTypesVisible(editableAnotationTypes
);
241 addField(annotationsListField
, "annotations", 0, row
, 2, row
);
250 public String
getWindowCaption() {
251 return "Specimen typedesignations editor";
258 public void focusFirst() {
266 protected String
getDefaultComponentStyles() {
274 public boolean allowAnonymousAccess() {
282 public Collection
<Collection
<GrantedAuthority
>> allowedGrantedAuthorities() {
290 public boolean isResizable() {
295 // ------- SpecimenTypeDesignationWorkingsetPopupEditorView methods ---- //
297 public ElementCollectionField
<SpecimenTypeDesignationDTO
> getTypeDesignationsCollectionField() {
298 return typeDesignationsCollectionField
;
302 public void applyDefaultComponentStyle(Component
... components
){
303 for(int i
= 0; i
<components
.length
; i
++){
304 components
[i
].setStyleName(getDefaultComponentStyles());
312 public void grantToCurrentUser(EnumSet
<CRUD
> crud
) {
313 getPresenter().setGrantsForCurrentUser(crud
);
321 protected void afterItemDataSourceSet() {
322 super.afterItemDataSourceSet();
323 GridLayout gridLayout
= this.typeDesignationsCollectionField
.getLayout();
324 for(int rowIndex
= 1; rowIndex
< gridLayout
.getRows(); rowIndex
++){ // first row is header
325 Component item
= gridLayout
.getComponent(SpecimenTypeDesignationDTORow
.rowListSelectColumn(), rowIndex
);
326 ((CollectionRowRepresentative
)item
).updateRowItemsEnabledStates();
335 public void updateAllowDelete(){
336 // disable the delete button if there is only one typeDesignation
337 // if this typeDesignation is deleted the fieldUnit would become orphan in the
338 // TypeDesignationWorkingSet
339 GridLayout gridLayout
= this.typeDesignationsCollectionField
.getLayout();
340 if(gridLayout
.getRows() == 3){ // first row is header, last row is next new item
341 gridLayout
.getComponent(gridLayout
.getColumns() - 1, 1).setEnabled(false);
350 public void setReadOnly(boolean readOnly
) {
351 super.setReadOnly(readOnly
);
352 getFieldLayout().iterator().forEachRemaining(c
-> c
.setReadOnly(readOnly
));
353 collectorField
.setEditorReadOnly(readOnly
);
354 typeDesignationsCollectionField
.getLayout().iterator().forEachRemaining(c
-> c
.setReadOnly(readOnly
));
359 * @return the collectorField
362 public TeamOrPersonField
getCollectorField() {
363 return collectorField
;
367 * By default AnnotationType.EDITORIAL() is enabled.
369 * @return the editableAnotationTypes
372 public AnnotationType
[] getEditableAnotationTypes() {
373 return editableAnotationTypes
;
377 * By default AnnotationType.EDITORIAL() is enabled.
380 * @param editableAnotationTypes the editableAnotationTypes to set
383 public void setEditableAnotationTypes(AnnotationType
... editableAnotationTypes
) {
384 this.editableAnotationTypes
= editableAnotationTypes
;
391 public FilterableAnnotationsField
getAnnotationsField() {
392 return annotationsListField
;
396 public GeoLocationField
getExactLocationField() {
397 return exactLocationField
;