Project

General

Profile

Download (14.5 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.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;
28

    
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;
46

    
47
/**
48
 * @author a.kohlbecker
49
 * @since May 15, 2017
50
 *
51
 */
52
@SpringComponent
53
@Scope("prototype")
54
public class SpecimenTypeDesignationWorkingsetPopupEditor
55
    extends AbstractPopupEditor<SpecimenTypeDesignationWorkingSetDTO, SpecimenTypeDesignationWorkingsetEditorPresenter>
56
    implements SpecimenTypeDesignationWorkingsetPopupEditorView, AccessRestrictedView, PerEntityAuthorityGrantingEditor {
57
    /**
58
     *
59
     */
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.";
61

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

    
73
    private static final long serialVersionUID = 5418275817834009509L;
74

    
75
    private ListSelect countrySelectField;
76

    
77
    private ElementCollectionField<SpecimenTypeDesignationDTO> typeDesignationsCollectionField;
78

    
79
    private EnumSet<CRUD> crud;
80

    
81
    private TeamOrPersonField collectorField;
82

    
83
    private FilterableAnnotationsField annotationsListField;
84

    
85
    private AnnotationType[] editableAnotationTypes = RegistrationUIDefaults.EDITABLE_ANOTATION_TYPES;
86

    
87
    private GeoLocationField exactLocationField;
88

    
89
    private Panel typeDesignationsScrollPanel;
90

    
91
    /**
92
     * @return the countrySelectField
93
     */
94
    @Override
95
    public ListSelect getCountrySelectField() {
96
        return countrySelectField;
97
    }
98

    
99
    /**
100
     * {@inheritDoc}
101
     */
102
    @Override
103
    protected void initContent() {
104

    
105
        GridLayout grid = (GridLayout)getFieldLayout();
106
        grid.setSpacing(true);
107
        grid.setMargin(true);
108
        grid.setColumns(3);
109
        grid.setRows(10);
110

    
111
        //TODO typifyingAuthors
112

    
113
        // FieldUnit + GatheringEvent
114

    
115
        int row = 0;
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);
122

    
123
        row++;
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
130

    
131
        row++;
132
        exactLocationField = new GeoLocationField("Geo location");
133
        addField(exactLocationField, "exactLocation", 0, row, 2, row);
134
        exactLocationField.setWidth("100%");
135

    
136
        row++;
137
        MinMaxTextField absElevationMinMax = new MinMaxTextField("Altitude", "m");
138
        absElevationMinMax.setWidth("100%");
139
        absElevationMinMax.addSubComponentsStyleName(getDefaultComponentStyles());
140
        grid.addComponent(absElevationMinMax, 0, row, 2, row);
141

    
142
        bindField(absElevationMinMax.getMinField(), "absoluteElevation");
143
        bindField(absElevationMinMax.getMaxField(), "absoluteElevationMax");
144
        bindField(absElevationMinMax.getTextField(), "absoluteElevationText");
145

    
146
        absElevationMinMax.getMaxField().setConverter(new IntegerConverter());
147
        absElevationMinMax.getMinField().setConverter(new IntegerConverter());
148

    
149
        row++;
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);
154

    
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));
162

    
163
        row++;
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);
168

    
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());
174

    
175
        row++;
176
        collectorField = new TeamOrPersonField("Collector", TeamOrPersonBaseCaptionGenerator.CacheType.COLLECTOR_TITLE);
177
        addField(collectorField, "collector", 0, row, 2, row);
178

    
179
        row++;
180

    
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);
185

    
186

    
187
        row++;
188

    
189
        // FIXME: can we use the Grid instead?
190
        typeDesignationsCollectionField = new ElementCollectionField<SpecimenTypeDesignationDTO>(
191
                SpecimenTypeDesignationDTO.class,
192
                SpecimenTypeDesignationDTORow.class
193
                ){
194

    
195
                    @Override
196
                    public void commit() throws SourceException, InvalidValueException {
197
                        validate(); // validate always so that empty rows are recognized
198
                        super.commit();
199
                    }
200

    
201
                    @Override
202
                    public boolean isEmpty() {
203
                        Collection value = getValue();
204
                        return value == null || value.isEmpty() ;
205
                    }
206

    
207
                    @Override
208
                    public void setComponentError(ErrorMessage componentError) {
209
                        typeDesignationsScrollPanel.setComponentError(componentError);
210
                    }
211

    
212
        };
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());
219

    
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));
225

    
226
        // typeDesignationsCollectionField.getLayout().setMargin(false);
227
        // typeDesignationsCollectionField.addStyleName("composite-field-wrapper");
228
        // addField(typeDesignationsCollectionField, "specimenTypeDesignationDTOs", 0, row, 2, row);
229

    
230
        typeDesignationsScrollPanel = new Panel(typeDesignationsCollectionField.getLayout());
231
        typeDesignationsScrollPanel.setCaption("Types");
232
        typeDesignationsScrollPanel.setWidth(800, Unit.PIXELS);
233

    
234
        bindField(typeDesignationsCollectionField, "specimenTypeDesignationDTOs");
235
        addComponent(typeDesignationsScrollPanel, 0, row, 2, row);
236

    
237
        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);
242

    
243
     }
244

    
245

    
246
    /**
247
     * {@inheritDoc}
248
     */
249
    @Override
250
    public String getWindowCaption() {
251
        return "Specimen typedesignations editor";
252
    }
253

    
254
    /**
255
     * {@inheritDoc}
256
     */
257
    @Override
258
    public void focusFirst() {
259
        // none
260
    }
261

    
262
    /**
263
     * {@inheritDoc}
264
     */
265
    @Override
266
    protected String getDefaultComponentStyles() {
267
        return "tiny";
268
    }
269

    
270
    /**
271
     * {@inheritDoc}
272
     */
273
    @Override
274
    public boolean allowAnonymousAccess() {
275
        return false;
276
    }
277

    
278
    /**
279
     * {@inheritDoc}
280
     */
281
    @Override
282
    public Collection<Collection<GrantedAuthority>> allowedGrantedAuthorities() {
283
        return null;
284
    }
285

    
286
    /**
287
     * {@inheritDoc}
288
     */
289
    @Override
290
    public boolean isResizable() {
291
        return true;
292
    }
293

    
294

    
295
    // ------- SpecimenTypeDesignationWorkingsetPopupEditorView methods ---- //
296
    @Override
297
    public ElementCollectionField<SpecimenTypeDesignationDTO> getTypeDesignationsCollectionField() {
298
        return typeDesignationsCollectionField;
299
    }
300

    
301
    @Override
302
    public void applyDefaultComponentStyle(Component ... components){
303
        for(int i = 0; i <components.length; i++){
304
            components[i].setStyleName(getDefaultComponentStyles());
305
        }
306
    }
307

    
308
    /**
309
     * {@inheritDoc}
310
     */
311
    @Override
312
    public void grantToCurrentUser(EnumSet<CRUD> crud) {
313
        getPresenter().setGrantsForCurrentUser(crud);
314

    
315
    }
316

    
317
    /**
318
     * {@inheritDoc}
319
     */
320
    @Override
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();
327
        }
328
        updateAllowDelete();
329
    }
330

    
331
    /**
332
     * {@inheritDoc}
333
     */
334
    @Override
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);
342
        }
343
    }
344

    
345

    
346
    /**
347
     * {@inheritDoc}
348
     */
349
    @Override
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));
355

    
356
    }
357

    
358
    /**
359
     * @return the collectorField
360
     */
361
    @Override
362
    public TeamOrPersonField getCollectorField() {
363
        return collectorField;
364
    }
365

    
366
    /**
367
     * By default  AnnotationType.EDITORIAL() is enabled.
368
     *
369
     * @return the editableAnotationTypes
370
     */
371
    @Override
372
    public AnnotationType[] getEditableAnotationTypes() {
373
        return editableAnotationTypes;
374
    }
375

    
376
    /**
377
     * By default  AnnotationType.EDITORIAL() is enabled.
378
     *
379
     *
380
     * @param editableAnotationTypes the editableAnotationTypes to set
381
     */
382
    @Override
383
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
384
        this.editableAnotationTypes = editableAnotationTypes;
385
    }
386

    
387
    /**
388
     * {@inheritDoc}
389
     */
390
    @Override
391
    public FilterableAnnotationsField getAnnotationsField() {
392
        return annotationsListField;
393
    }
394

    
395
    @Override
396
    public GeoLocationField getExactLocationField() {
397
        return exactLocationField;
398
    }
399

    
400

    
401

    
402
}
(8-8/14)