Project

General

Profile

« Previous | Next » 

Revision a2415b9f

Added by Andreas Kohlbecker almost 6 years ago

ref #7458 initial implementation of a note field at the example of the TaxonNameEditor

View differences:

src/main/java/eu/etaxonomy/cdm/vaadin/component/common/FilterableAnnotationsField.java
1
/**
2
* Copyright (C) 2018 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.component.common;
10

  
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.Collection;
14
import java.util.List;
15

  
16
import org.vaadin.viritin.FilterableListContainer;
17

  
18
import com.vaadin.data.Container;
19
import com.vaadin.data.Container.Filter;
20
import com.vaadin.data.Item;
21
import com.vaadin.data.Validator.InvalidValueException;
22
import com.vaadin.data.fieldgroup.FieldGroup;
23
import com.vaadin.data.util.BeanItemContainer;
24
import com.vaadin.ui.Component;
25
import com.vaadin.ui.CssLayout;
26
import com.vaadin.ui.DefaultFieldFactory;
27
import com.vaadin.ui.Field;
28
import com.vaadin.ui.ListSelect;
29
import com.vaadin.ui.Table;
30
import com.vaadin.ui.Table.ColumnHeaderMode;
31
import com.vaadin.ui.TextArea;
32

  
33
import eu.etaxonomy.cdm.model.common.Annotation;
34
import eu.etaxonomy.cdm.model.common.AnnotationType;
35
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
36
import eu.etaxonomy.cdm.model.common.Language;
37
import eu.etaxonomy.cdm.vaadin.util.converter.SetToListConverter;
38
import eu.etaxonomy.cdm.vaadin.util.filter.CdmTermFilter;
39
import eu.etaxonomy.vaadin.component.CompositeCustomField;
40

  
41
/**
42
 * @author a.kohlbecker
43
 * @since Jun 20, 2018
44
 *
45
 */
46
public class FilterableAnnotationsField extends CompositeCustomField<List<Annotation>> {
47

  
48
    private static final long serialVersionUID = -8258550787601028813L;
49

  
50
    Class<List<Annotation>> type = (Class<List<Annotation>>)new ArrayList<Annotation>().getClass();
51

  
52
    private CssLayout root = new CssLayout();
53

  
54
    private Table table = new Table();
55

  
56
    private List<AnnotationType> typesFilter = null;
57

  
58
    private Annotation emptyDefaultAnnotation = Annotation.NewInstance(null, Language.DEFAULT());
59

  
60
    private BeanItemContainer<DefinedTermBase> typeSelectItemContainer;
61

  
62
    private FilterableListContainer<Annotation> container;
63

  
64
    public FilterableAnnotationsField() {
65
        this(null);
66
    }
67

  
68
    public FilterableAnnotationsField(String caption) {
69

  
70
        setCaption(caption);
71
        // annotations are always sets
72
        setConverter(new SetToListConverter<Annotation>());
73

  
74
        root.setWidth(100, Unit.PERCENTAGE);
75

  
76
        // setup table
77
        table.setPageLength(1);
78
        table.setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
79
        table.setWidth(100,  Unit.PERCENTAGE);
80
        table.setTableFieldFactory(new DefaultFieldFactory() {
81

  
82
            private static final long serialVersionUID = 5437750882205859178L;
83

  
84
            @Override
85
            public Field<?> createField(Item item, Object propertyId, Component uiContext) {
86

  
87
                Field<?> field = createField(propertyId);
88
                if(field == null) {
89
                    field = super.createField(item, propertyId, uiContext);
90
                }
91
                return field;
92

  
93
            }
94

  
95
            @Override
96
            public Field<?> createField(Container container, Object itemId, Object propertyId, Component uiContext) {
97

  
98
                Field<?> field = createField(propertyId);
99

  
100
                if(field == null) {
101
                    field = super.createField(container, itemId, propertyId, uiContext);
102
                }
103
                return field;
104
            }
105

  
106
            protected Field<?> createField(Object propertyId) {
107
                Field<?> field = null;
108
                if(propertyId.equals("text")){
109
                    TextArea ta = new TextArea();
110
                    ta.setNullRepresentation("");
111
                    ta.setWidth(100,  Unit.PERCENTAGE);
112
                    field = ta;
113
                } else if(propertyId.equals("annotationType")) {
114
                    ListSelect select = new ListSelect();
115
                    select.setContainerDataSource(typeSelectItemContainer);
116
                    select.setWidth(100, Unit.PIXELS);
117
                    select.setRows(1);
118
                    field = select;
119
                }
120
                field.setStyleName(table.getStyleName());
121
                return field;
122
            }
123
        });
124

  
125
        addStyledComponent(table);
126

  
127
    }
128

  
129
    public void setAnnotationTypesVisible(AnnotationType ... types){
130
        typesFilter = Arrays.asList(types);
131
    }
132

  
133
    /**
134
     * {@inheritDoc}
135
     */
136
    @Override
137
    protected void addDefaultStyles() {
138
        // no default styles here
139
    }
140

  
141
    /**
142
     * {@inheritDoc}
143
     */
144
    @Override
145
    public FieldGroup getFieldGroup() {
146
        // holds a Container instead // TODO can this cause a NPE?
147
        return null;
148
    }
149

  
150
    @Override
151
    public void commit() throws SourceException, InvalidValueException {
152
        table.commit();
153
        Collection<Filter> filters = container.getContainerFilters();
154
        super.commit();
155
        for(Filter filter : filters){
156
            container.addContainerFilter(filter);
157
        }
158
        System.err.println(container.size());
159
    }
160

  
161

  
162

  
163
    /**
164
     * {@inheritDoc}
165
     */
166
    @Override
167
    protected List<Annotation> getInternalValue() {
168
        if(container == null || container.getItemIds() == null){
169
            return null;
170
        }
171
        return new ArrayList<>(container.getItemIds());
172
    }
173

  
174

  
175
    @Override
176
    protected void setInternalValue(List<Annotation> newValue) {
177
        boolean hasIncludeFilter = typesFilter != null && !typesFilter.isEmpty();
178
        boolean onlyOneType = hasIncludeFilter && typesFilter.size() == 1;
179

  
180
        if(newValue.isEmpty()){
181
            newValue.add(emptyDefaultAnnotation);
182
            if(onlyOneType){
183
                emptyDefaultAnnotation.setAnnotationType(typesFilter.get(0));
184
            }
185
        }
186
        container = new FilterableListContainer<Annotation>(newValue);
187
        if(hasIncludeFilter){
188
            container.addContainerFilter(new CdmTermFilter<AnnotationType>("annotationType", typesFilter));
189
        }
190
        table.setContainerDataSource(container);
191
        if(onlyOneType){
192
            table.setVisibleColumns("text");
193
        } else {
194
            table.setVisibleColumns("text", "annotationType");
195
        }
196
        table.setEditable(true);
197
    }
198

  
199
    /**
200
     * {@inheritDoc}
201
     */
202
    @Override
203
    protected Component initContent() {
204
        root.addComponent(table);
205
        return root;
206
    }
207

  
208

  
209
    /**
210
     * {@inheritDoc}
211
     */
212
    @Override
213
    public Class<List<Annotation>> getType() {
214
        return type;
215
    }
216

  
217
    /**
218
     * @param buildTermItemContainer
219
     */
220
    public void setAnnotationTypeItemContainer(BeanItemContainer<DefinedTermBase> typeSelectItemContainer) {
221
        this.typeSelectItemContainer = typeSelectItemContainer;
222
    }
223

  
224

  
225
}
src/main/java/eu/etaxonomy/cdm/vaadin/model/name/TaxonNameDTO.java
8 8
*/
9 9
package eu.etaxonomy.cdm.vaadin.model.name;
10 10

  
11
import java.util.ArrayList;
11 12
import java.util.HashSet;
12 13
import java.util.List;
13 14
import java.util.Set;
......
65 66
        return name.getAnnotations();
66 67
    }
67 68

  
69
    public void setAnnotations(Set<Annotation> annotations) {
70
        List<Annotation> currentAnnotations = new ArrayList<>(name.getAnnotations());
71
        List<Annotation> annotationsSeen = new ArrayList<>();
72
        for(Annotation a : annotations){
73
            if(a == null){
74
                continue;
75
            }
76
            if(!currentAnnotations.contains(a)){
77
                name.addAnnotation(a);
78
            }
79
            annotationsSeen.add(a);
80
        }
81
        for(Annotation a : currentAnnotations){
82
            if(!annotationsSeen.contains(a)){
83
                name.removeAnnotation(a);
84
            }
85
        }
86
    }
87

  
68 88
    public String getAppendedPhrase() {
69 89
        return name.getAppendedPhrase();
70 90
    }
src/main/java/eu/etaxonomy/cdm/vaadin/util/filter/CdmTermFilter.java
1
/**
2
* Copyright (C) 2018 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.util.filter;
10

  
11
import java.util.List;
12

  
13
import com.vaadin.data.Container.Filter;
14
import com.vaadin.data.Item;
15
import com.vaadin.data.Property;
16

  
17
import eu.etaxonomy.cdm.model.common.TermBase;
18

  
19
/**
20
 * @author a.kohlbecker
21
 * @since Jun 21, 2018
22
 *
23
 */
24
public class CdmTermFilter<T extends TermBase> implements Filter {
25

  
26
    private static final long serialVersionUID = -613582375956129270L;
27

  
28
    private List<T> includeFilter;
29
    private Object propertyId;
30

  
31
    /**
32
     *
33
     * @param propertyId
34
     * @param includeFilter
35
     * @param includeNullValues true by default
36
     */
37
    public CdmTermFilter(Object propertyId, List<T> includeFilter){
38
        this.propertyId = propertyId;
39
        this.includeFilter = includeFilter;
40
    }
41

  
42
    /**
43
     * {@inheritDoc}
44
     */
45
    @Override
46
    public boolean passesFilter(Object itemId, Item item) throws UnsupportedOperationException {
47
        Property property = item.getItemProperty(propertyId);
48
        Object value = property.getValue();
49
        if(includeFilter.contains(value)){
50
            return true;
51
        }
52
        return false;
53
    }
54

  
55
    @Override
56
    public boolean appliesToProperty(Object propertyId) {
57
        return this.propertyId.equals(propertyId);
58
    }
59

  
60
}
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
27 27
import eu.etaxonomy.cdm.model.agent.AgentBase;
28 28
import eu.etaxonomy.cdm.model.agent.Person;
29 29
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
30
import eu.etaxonomy.cdm.model.common.AnnotationType;
30 31
import eu.etaxonomy.cdm.model.common.CdmBase;
31 32
import eu.etaxonomy.cdm.model.common.TermType;
32 33
import eu.etaxonomy.cdm.model.name.Rank;
......
175 176
        getView().getValidationField().getCitatonComboBox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
176 177
        getView().getValidationField().getCitatonComboBox().loadFrom(icbnCodesPagingProvider, icbnCodesPagingProvider, icbnCodesPagingProvider.getPageSize());
177 178
        getView().getValidationField().getCitatonComboBox().getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<>(getView().getValidationField().getCitatonComboBox(), this));
179

  
180
        getView().getAnnotationsField().setAnnotationTypeItemContainer(selectFieldFactory.buildTermItemContainer(
181
                AnnotationType.EDITORIAL().getUuid(), AnnotationType.TECHNICAL().getUuid()));
178 182
    }
179 183

  
180 184
    /**
......
183 187
    @Override
184 188
    protected TaxonName loadCdmEntity(UUID identifier) {
185 189

  
186
        List<String> initStrategy = Arrays.asList(new String []{
187

  
190
        List<String> initStrategy = Arrays.asList(
188 191
                "$",
192
                "annotations.type",
193
                "annotations.*", // needed as log as we are using a table in FilterableAnnotationsField
189 194
                "rank.vocabulary", // needed for comparing ranks
190 195

  
191 196
                "nomenclaturalReference.authorship",
......
214 219

  
215 220
                "relationsFromThisName",
216 221
                "homotypicalGroup.typifiedNames"
217

  
218
                }
219 222
        );
220 223

  
221 224
        TaxonName taxonName;
......
255 258

  
256 259
            }
257 260
        }
258

  
259 261
        return taxonName;
260 262
    }
261 263

  
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditor.java
34 34
import com.vaadin.ui.TextField;
35 35

  
36 36
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
37
import eu.etaxonomy.cdm.model.common.AnnotationType;
37 38
import eu.etaxonomy.cdm.model.common.CdmBase;
38 39
import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
39 40
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
......
41 42
import eu.etaxonomy.cdm.model.name.TaxonName;
42 43
import eu.etaxonomy.cdm.model.reference.Reference;
43 44
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
45
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
44 46
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
45 47
import eu.etaxonomy.cdm.vaadin.event.ReferenceEditorAction;
46 48
import eu.etaxonomy.cdm.vaadin.event.TaxonNameEditorAction;
......
65 67
 */
66 68
@SpringComponent
67 69
@Scope("prototype")
68
public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter> implements TaxonNamePopupEditorView, AccessRestrictedView {
70
public class TaxonNamePopupEditor extends AbstractCdmDTOPopupEditor<TaxonNameDTO, TaxonName, TaxonNameEditorPresenter>
71
    implements TaxonNamePopupEditorView, AccessRestrictedView {
69 72

  
70 73
    private static final long serialVersionUID = -7037436241474466359L;
71 74

  
72 75
    private final static int GRID_COLS = 4;
73 76

  
74
    private final static int GRID_ROWS = 16;
77
    private final static int GRID_ROWS = 17;
75 78

  
76 79
    private static final boolean HAS_BASIONYM_DEFAULT = false;
77 80

  
......
129 132

  
130 133
    private ValueChangeListener updateFieldVisibilityListener = e -> updateFieldVisibility();
131 134

  
135
    private FilterableAnnotationsField annotationsListField;
136

  
137
    private AnnotationType[] editableAnotationTypes = new AnnotationType[]{AnnotationType.EDITORIAL()};
138

  
139

  
140
    /**
141
     * By default  AnnotationType.EDITORIAL() is enabled.
142
     *
143
     * @return the editableAnotationTypes
144
     */
145
    public AnnotationType[] getEditableAnotationTypes() {
146
        return editableAnotationTypes;
147
    }
148

  
149
    /**
150
     * By default  AnnotationType.EDITORIAL() is enabled.
151
     *
152
     *
153
     * @param editableAnotationTypes the editableAnotationTypes to set
154
     */
155
    public void setEditableAnotationTypes(AnnotationType ... editableAnotationTypes) {
156
        this.editableAnotationTypes = editableAnotationTypes;
157
    }
158

  
132 159
    /**
133 160
     * @param layout
134 161
     * @param dtoType
......
146 173
    }
147 174

  
148 175

  
149

  
150 176
    /**
151 177
     * {@inheritDoc}
152 178
     */
......
420 446
        exCombinationAuthorshipField.setWidth(100,  Unit.PERCENTAGE);
421 447
        addField(exCombinationAuthorshipField, "exCombinationAuthorship", 0, row, GRID_COLS-1, row);
422 448

  
449
        row++;
450
        annotationsListField = new FilterableAnnotationsField("Editorial notes");
451
        annotationsListField.setWidth(100, Unit.PERCENTAGE);
452
        annotationsListField.setAnnotationTypesVisible(editableAnotationTypes);
453
        addField(annotationsListField, "annotations", 0, row, GRID_COLS-1, row);
454

  
423 455
        // -----------------------------------------------------------------------------
424 456

  
425 457
        setAdvancedModeEnabled(true);
......
831 863
        return basionymToggle;
832 864
    }
833 865

  
866
    @Override
867
    public FilterableAnnotationsField getAnnotationsField() {
868
        return annotationsListField;
869
    }
870

  
834 871
    /**
835 872
     * {@inheritDoc}
836 873
     */
......
852 889
        }
853 890
    }
854 891

  
892

  
893

  
855 894
    /**
856 895
     * @return the infraGenericEpithetField
857 896
     */
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNamePopupEditorView.java
16 16

  
17 17
import eu.etaxonomy.cdm.model.name.TaxonName;
18 18
import eu.etaxonomy.cdm.model.reference.Reference;
19
import eu.etaxonomy.cdm.vaadin.component.common.FilterableAnnotationsField;
19 20
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
20 21
import eu.etaxonomy.vaadin.component.NameRelationField;
21 22
import eu.etaxonomy.vaadin.component.ToManyRelatedEntitiesComboboxSelect;
......
115 116
     */
116 117
    public AbstractField<String> getInfraSpecificEpithetField();
117 118

  
119
    /**
120
     * @return
121
     */
122
    FilterableAnnotationsField getAnnotationsField();
123

  
118 124
}
src/main/java/eu/etaxonomy/vaadin/component/CompositeCustomField.java
29 29
/**
30 30
 * TODO implement height methods for full component size support
31 31
 *
32
 * Implementations need to override {@link  AbstractField#setInternalValue(TeamOrPersonBase<?> newValue)} in order to
33
 * to set the item datasource of the fieldGroup for example:
34
 * <pre>
35
 * @Override
36
   protected void setInternalValue(TeamOrPersonBase<?> newValue) {
37
     ...
38
     fieldGroup.setItemDataSource(new BeanItem<Team>((Team)newValue));
39
     ...
40
   }
41
 * </pre>
42
 *
32 43
 * @author a.kohlbecker
33 44
 * @since May 12, 2017
34 45
 *
src/main/java/eu/etaxonomy/vaadin/component/NestedFieldGroup.java
20 20
    /**
21 21
     * Implementations return the local fieldGroup
22 22
     *
23
     * @return
23
     * @return the FieldGroup, may be <code>null</code>.
24 24
     */
25 25
    public abstract FieldGroup getFieldGroup();
26 26

  

Also available in: Unified diff