Project

General

Profile

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

    
11
import java.util.Collection;
12
import java.util.EnumSet;
13

    
14
import org.springframework.context.annotation.Scope;
15
import org.springframework.security.core.GrantedAuthority;
16
import org.vaadin.viritin.fields.ElementCollectionField;
17

    
18
import com.vaadin.data.Validator.InvalidValueException;
19
import com.vaadin.data.validator.DoubleRangeValidator;
20
import com.vaadin.server.ErrorMessage;
21
import com.vaadin.shared.ui.MarginInfo;
22
import com.vaadin.spring.annotation.SpringComponent;
23
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
24
import com.vaadin.ui.Component;
25
import com.vaadin.ui.GridLayout;
26
import com.vaadin.ui.NativeSelect;
27
import com.vaadin.ui.Panel;
28
import com.vaadin.ui.TextArea;
29

    
30
import eu.etaxonomy.cdm.model.common.AnnotationType;
31
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
32
import eu.etaxonomy.cdm.vaadin.component.CollectionRowRepresentative;
33
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
34
import eu.etaxonomy.cdm.vaadin.component.common.GeoLocationField;
35
import eu.etaxonomy.cdm.vaadin.component.common.MinMaxTextField;
36
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
37
import eu.etaxonomy.cdm.vaadin.component.common.TimePeriodField;
38
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO;
39
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO;
40
import eu.etaxonomy.cdm.vaadin.permission.AccessRestrictedView;
41
import eu.etaxonomy.cdm.vaadin.ui.RegistrationUIDefaults;
42
import eu.etaxonomy.cdm.vaadin.util.TeamOrPersonBaseCaptionGenerator;
43
import eu.etaxonomy.cdm.vaadin.util.converter.DoubleConverter;
44
import eu.etaxonomy.cdm.vaadin.util.converter.IntegerConverter;
45
import eu.etaxonomy.cdm.vaadin.view.PerEntityAuthorityGrantingEditor;
46
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
47

    
48
/**
49
 * @author a.kohlbecker
50
 * @since May 15, 2017
51
 *
52
 * TODO as subclass of AbstractCdmPopupEditor?
53
 *
54
 */
55
@SpringComponent
56
@Scope("prototype")
57
public class SpecimenTypeDesignationWorkingsetPopupEditor
58
    extends AbstractPopupEditor<SpecimenTypeDesignationWorkingSetDTO, SpecimenTypeDesignationWorkingsetEditorPresenter>
59
    implements SpecimenTypeDesignationWorkingsetPopupEditorView, AccessRestrictedView, PerEntityAuthorityGrantingEditor {
60
    /**
61
     *
62
     */
63
    private static final String CAN_T_SAVE_AS_LONG_AS_TYPE_DESIGNATIONS_ARE_MISSING = "Can't save as long as type designations are missing.";
64

    
65
    /**
66
     * @param layout
67
     * @param dtoType
68
     */
69
    public SpecimenTypeDesignationWorkingsetPopupEditor() {
70
        super(new GridLayout(), SpecimenTypeDesignationWorkingSetDTO.class);
71
        GridLayout grid = (GridLayout) getFieldLayout();
72
        grid.setMargin(true);
73
        grid.setSpacing(true);
74
    }
75

    
76
    private static final long serialVersionUID = 5418275817834009509L;
77

    
78
    private NativeSelect countrySelectField;
79

    
80
    private ElementCollectionField<SpecimenTypeDesignationDTO> typeDesignationsCollectionField;
81

    
82
    private EnumSet<CRUD> crud;
83

    
84
    private TeamOrPersonField collectorField;
85

    
86
    private FilterableAnnotationsField annotationsListField;
87

    
88
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
89

    
90
    private GeoLocationField exactLocationField;
91

    
92
    private Panel typeDesignationsScrollPanel;
93

    
94
    private String accessDeniedMessage;
95

    
96
    /**
97
     * @return the countrySelectField
98
     */
99
    @Override
100
    public NativeSelect getCountrySelectField() {
101
        return countrySelectField;
102
    }
103

    
104
    /**
105
     * {@inheritDoc}
106
     */
107
    @Override
108
    protected void initContent() {
109

    
110
        GridLayout grid = (GridLayout)getFieldLayout();
111
        grid.setSpacing(true);
112
        grid.setMargin(true);
113
        grid.setColumns(3);
114
        grid.setRows(10);
115

    
116
        //TODO typifyingAuthors
117

    
118
        // FieldUnit + GatheringEvent
119

    
120
        int row = 0;
121
        countrySelectField = new NativeSelect("Country");
122
        addField(countrySelectField, "country", 1, row , 2, row);
123
        countrySelectField.setWidth("100%");
124
        countrySelectField.setItemCaptionMode(ItemCaptionMode.PROPERTY);
125
        countrySelectField.setItemCaptionPropertyId("label");
126

    
127
        row++;
128
        TextArea localityField = new TextArea("Locality");
129
        localityField.setNullRepresentation("");
130
        addField(localityField, "locality", 0, row , 2, row);
131
        localityField.setWidth("100%");
132
        // NOTE: setRows and SetCold breaks he width setting,
133
        //        see https://github.com/vaadin/framework/issues/3617
134

    
135
        row++;
136
        exactLocationField = new GeoLocationField("Geo location");
137
        addField(exactLocationField, "exactLocation", 0, row, 2, row);
138
        exactLocationField.setWidth("100%");
139

    
140
        row++;
141
        MinMaxTextField absElevationMinMax = new MinMaxTextField("Altitude", "m");
142
        absElevationMinMax.setWidth("100%");
143
        absElevationMinMax.addSubComponentsStyleName(getDefaultComponentStyles());
144
        grid.addComponent(absElevationMinMax, 0, row, 2, row);
145

    
146
        bindField(absElevationMinMax.getMinField(), "absoluteElevation");
147
        bindField(absElevationMinMax.getMaxField(), "absoluteElevationMax");
148
        bindField(absElevationMinMax.getTextField(), "absoluteElevationText");
149

    
150
        absElevationMinMax.getMaxField().setConverter(new IntegerConverter());
151
        absElevationMinMax.getMinField().setConverter(new IntegerConverter());
152

    
153
        row++;
154
        MinMaxTextField distanceToWaterSurfaceMinMax = new MinMaxTextField("Distance to water surface", "m");
155
        distanceToWaterSurfaceMinMax.setWidth("100%");
156
        distanceToWaterSurfaceMinMax.addSubComponentsStyleName(getDefaultComponentStyles());
157
        grid.addComponent(distanceToWaterSurfaceMinMax, 0, row, 2, row);
158

    
159
        bindField(distanceToWaterSurfaceMinMax.getMinField(), "distanceToWaterSurface");
160
        bindField(distanceToWaterSurfaceMinMax.getMaxField(), "distanceToWaterSurfaceMax");
161
        bindField(distanceToWaterSurfaceMinMax.getTextField(), "distanceToWaterSurfaceText");
162
        distanceToWaterSurfaceMinMax.getMaxField().setConverter(new DoubleConverter());
163
        distanceToWaterSurfaceMinMax.getMinField().setConverter(new DoubleConverter());
164
        distanceToWaterSurfaceMinMax.getMaxField().addValidator(new DoubleRangeValidator("Negative values are not allowed here.", 0.0, Double.MAX_VALUE));
165
        distanceToWaterSurfaceMinMax.getMinField().addValidator(new DoubleRangeValidator("Negative values are not allowed here.", 0.0, Double.MAX_VALUE));
166

    
167
        row++;
168
        MinMaxTextField distanceToGroundMinMax = new MinMaxTextField("Distance to substrate", "m");
169
        distanceToGroundMinMax.setWidth("100%");
170
        distanceToGroundMinMax.addSubComponentsStyleName(getDefaultComponentStyles());
171
        grid.addComponent(distanceToGroundMinMax, 0, row, 2, row);
172

    
173
        bindField(distanceToGroundMinMax.getMinField(), "distanceToGround");
174
        bindField(distanceToGroundMinMax.getMaxField(), "distanceToGroundMax");
175
        bindField(distanceToGroundMinMax.getTextField(), "distanceToGroundText");
176
        distanceToGroundMinMax.getMaxField().setConverter(new DoubleConverter());
177
        distanceToGroundMinMax.getMinField().setConverter(new DoubleConverter());
178

    
179
        row++;
180
        collectorField = new TeamOrPersonField("Collector", TeamOrPersonBaseCaptionGenerator.CacheType.COLLECTOR_TITLE);
181
        addField(collectorField, "collector", 0, row, 2, row);
182

    
183
        row++;
184

    
185
        TimePeriodField collectionDateField = new TimePeriodField("Collection date");
186
        // collectionDateField.setInputPrompt("dd.mm.yyyy");
187
        addField(collectionDateField, "gatheringDate", 0, row, 1, row);
188
        addTextField("Field number", "fieldNumber", 2, row);
189

    
190

    
191
        row++;
192

    
193
        // FIXME: can we use the Grid instead?
194
        typeDesignationsCollectionField = new ElementCollectionField<SpecimenTypeDesignationDTO>(
195
                SpecimenTypeDesignationDTO.class,
196
                SpecimenTypeDesignationDTORow.class
197
                ){
198

    
199
                    @Override
200
                    public void commit() throws SourceException, InvalidValueException {
201
                        validate(); // validate always so that empty rows are recognized
202
                        super.commit();
203
                    }
204

    
205
                    @Override
206
                    public boolean isEmpty() {
207
                        Collection value = getValue();
208
                        return value == null || value.isEmpty() ;
209
                    }
210

    
211
                    @Override
212
                    public void setComponentError(ErrorMessage componentError) {
213
                        typeDesignationsScrollPanel.setComponentError(componentError);
214
                    }
215

    
216
        };
217
        typeDesignationsCollectionField.withCaption("Types");
218
        typeDesignationsCollectionField.getLayout().setSpacing(false);
219
        typeDesignationsCollectionField.getLayout().setColumns(3);
220
        typeDesignationsCollectionField.setRequired(true); // only works with the above overwritten commit()
221
        typeDesignationsCollectionField.setRequiredError(CAN_T_SAVE_AS_LONG_AS_TYPE_DESIGNATIONS_ARE_MISSING);
222
        typeDesignationsCollectionField.setVisibleProperties(SpecimenTypeDesignationDTORow.visibleFields());
223

    
224
        typeDesignationsCollectionField.setPropertyHeader("accessionNumber", "Access. num.");
225
        typeDesignationsCollectionField.setPropertyHeader("preferredStableUri", "Stable URI");
226
        typeDesignationsCollectionField.setPropertyHeader("mediaSpecimenReference", "Image reference");
227
        typeDesignationsCollectionField.setPropertyHeader("mediaSpecimenReferenceDetail", "Reference detail");
228
        typeDesignationsCollectionField.addElementAddedListener( e -> typeDesignationsCollectionField.setComponentError(null));
229
        typeDesignationsCollectionField.getLayout().setMargin(new MarginInfo(false, true));
230

    
231
        // typeDesignationsCollectionField.getLayout().setMargin(false);
232
        // typeDesignationsCollectionField.addStyleName("composite-field-wrapper");
233
        // addField(typeDesignationsCollectionField, "specimenTypeDesignationDTOs", 0, row, 2, row);
234

    
235
        typeDesignationsScrollPanel = new Panel(typeDesignationsCollectionField.getLayout());
236
        typeDesignationsScrollPanel.setCaption("Types");
237
        typeDesignationsScrollPanel.setWidth(800, Unit.PIXELS);
238

    
239
        bindField(typeDesignationsCollectionField, "specimenTypeDesignationDTOs");
240
        addComponent(typeDesignationsScrollPanel, 0, row, 2, row);
241

    
242
        row++;
243
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
244
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
245
        annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
246
        addField(annotationsListField, "annotations", 0, row, 2, row);
247

    
248
     }
249

    
250

    
251
    /**
252
     * {@inheritDoc}
253
     */
254
    @Override
255
    public String getWindowCaption() {
256
        return "Specimen typedesignations editor";
257
    }
258

    
259
    /**
260
     * {@inheritDoc}
261
     */
262
    @Override
263
    public void focusFirst() {
264
        // none
265
    }
266

    
267
    /**
268
     * {@inheritDoc}
269
     */
270
    @Override
271
    protected String getDefaultComponentStyles() {
272
        return "tiny";
273
    }
274

    
275
    @Override
276
    public boolean allowAnonymousAccess() {
277
        return false;
278
    }
279

    
280
    @Override
281
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
282
        return null;
283
    }
284

    
285
    @Override
286
    public String getAccessDeniedMessage() {
287
        return accessDeniedMessage;
288
    }
289

    
290
    @Override
291
    public void setAccessDeniedMessage(String accessDeniedMessage) {
292
        this.accessDeniedMessage = accessDeniedMessage;
293
    }
294

    
295
    /**
296
     * {@inheritDoc}
297
     */
298
    @Override
299
    public boolean isResizable() {
300
        return true;
301
    }
302

    
303

    
304
    // ------- SpecimenTypeDesignationWorkingsetPopupEditorView methods ---- //
305
    @Override
306
    public ElementCollectionField<SpecimenTypeDesignationDTO> getTypeDesignationsCollectionField() {
307
        return typeDesignationsCollectionField;
308
    }
309

    
310
    @Override
311
    public void applyDefaultComponentStyle(Component ... components){
312
        for(int i = 0; i <components.length; i++){
313
            components[i].setStyleName(getDefaultComponentStyles());
314
        }
315
    }
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
321
    public void grantToCurrentUser(EnumSet<CRUD> crud) {
322
        getPresenter().setGrantsForCurrentUser(crud);
323

    
324
    }
325

    
326
    /**
327
     * {@inheritDoc}
328
     */
329
    @Override
330
    protected void afterItemDataSourceSet() {
331
        super.afterItemDataSourceSet();
332
        GridLayout gridLayout = this.typeDesignationsCollectionField.getLayout();
333
        for(int rowIndex = 1; rowIndex < gridLayout.getRows(); rowIndex++){ // first row is header
334
            Component item = gridLayout.getComponent(SpecimenTypeDesignationDTORow.rowListSelectColumn(), rowIndex);
335
            ((CollectionRowRepresentative)item).updateRowItemsEnabledStates();
336
        }
337
        updateAllowDeleteTypeDesignation();
338
    }
339

    
340
    /**
341
     * {@inheritDoc}
342
     */
343
    @Override
344
    public void updateAllowDeleteTypeDesignation(){
345
        // disable the delete button if there is only one typeDesignation
346
        // if this typeDesignation is deleted the fieldUnit would become orphan in the
347
        // TypeDesignationWorkingSet
348
        GridLayout gridLayout = this.typeDesignationsCollectionField.getLayout();
349
        if(gridLayout.getRows() == 3){ // first row is header, last row is next new item
350
            gridLayout.getComponent(gridLayout.getColumns() - 1, 1).setEnabled(false);
351
        }
352
    }
353

    
354

    
355
    /**
356
     * {@inheritDoc}
357
     */
358
    @Override
359
    public void setReadOnly(boolean readOnly) {
360
        super.setReadOnly(readOnly);
361
        getFieldLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
362
        collectorField.setEditorReadOnly(readOnly);
363
        typeDesignationsCollectionField.getLayout().iterator().forEachRemaining(c -> c.setReadOnly(readOnly));
364

    
365
    }
366

    
367
    /**
368
     * @return the collectorField
369
     */
370
    @Override
371
    public TeamOrPersonField getCollectorField() {
372
        return collectorField;
373
    }
374

    
375
    /**
376
     * By default  AnnotationType.EDITORIAL() is enabled.
377
     *
378
     * @return the editableAnotationTypes
379
     */
380
    @Override
381
    public AnnotationType[] getEditableAnotationTypes() {
382
        return editableAnotationTypes;
383
    }
384

    
385
    /**
386
     * By default  AnnotationType.EDITORIAL() is enabled.
387
     *
388
     *
389
     * @param editableAnotationTypes the editableAnotationTypes to set
390
     */
391
    @Override
392
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
393
        this.editableAnotationTypes = editableAnotationTypes;
394
    }
395

    
396
    /**
397
     * {@inheritDoc}
398
     */
399
    @Override
400
    public FilterableAnnotationsField getAnnotationsField() {
401
        return annotationsListField;
402
    }
403

    
404
    @Override
405
    public GeoLocationField getExactLocationField() {
406
        return exactLocationField;
407
    }
408

    
409

    
410

    
411
}
(9-9/15)