Project

General

Profile

Download (14.8 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
 * TODO as subclass of AbstractCdmPopupEditor?
52
 *
53
 */
54
@SpringComponent
55
@Scope("prototype")
56
public class SpecimenTypeDesignationWorkingsetPopupEditor
57
    extends AbstractPopupEditor<SpecimenTypeDesignationWorkingSetDTO, SpecimenTypeDesignationWorkingsetEditorPresenter>
58
    implements SpecimenTypeDesignationWorkingsetPopupEditorView, AccessRestrictedView, PerEntityAuthorityGrantingEditor {
59
    /**
60
     *
61
     */
62
    private static final String CAN_T_SAVE_AS_LONG_AS_TYPE_DESIGNATIONS_ARE_MISSING = "Can't save as long as type designations are missing.";
63

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

    
75
    private static final long serialVersionUID = 5418275817834009509L;
76

    
77
    private ListSelect countrySelectField;
78

    
79
    private ElementCollectionField<SpecimenTypeDesignationDTO> typeDesignationsCollectionField;
80

    
81
    private EnumSet<CRUD> crud;
82

    
83
    private TeamOrPersonField collectorField;
84

    
85
    private FilterableAnnotationsField annotationsListField;
86

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

    
89
    private GeoLocationField exactLocationField;
90

    
91
    private Panel typeDesignationsScrollPanel;
92

    
93
    private String accessDeniedMessage;
94

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

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

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

    
115
        //TODO typifyingAuthors
116

    
117
        // FieldUnit + GatheringEvent
118

    
119
        int row = 0;
120
        countrySelectField = new ListSelect("Country");
121
        addField(countrySelectField, "country", 1, row , 2, row);
122
        countrySelectField.setWidth("100%");
123
        countrySelectField.setItemCaptionMode(ItemCaptionMode.PROPERTY);
124
        countrySelectField.setItemCaptionPropertyId("label");
125
        countrySelectField.setRows(1);
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

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

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

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

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

    
247
     }
248

    
249

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

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

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

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

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

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

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

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

    
302

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

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

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

    
323
    }
324

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

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

    
353

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

    
364
    }
365

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

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

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

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

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

    
408

    
409

    
410
}
(8-8/14)