Merge branch 'release/5.19.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / EnumComboElement.java
1 /**
2 * Copyright (C) 2007 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.taxeditor.ui.combo;
10
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Comparator;
16 import java.util.LinkedHashMap;
17 import java.util.List;
18 import java.util.Map.Entry;
19
20 import org.eclipse.swt.events.SelectionEvent;
21 import org.eclipse.swt.widgets.Combo;
22 import org.eclipse.ui.forms.widgets.TableWrapData;
23
24 import eu.etaxonomy.cdm.model.media.ExternalLinkType;
25 import eu.etaxonomy.cdm.model.name.NameRelationship;
26 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
27 import eu.etaxonomy.cdm.model.name.NomenclaturalCodeEdition;
28 import eu.etaxonomy.cdm.model.name.TaxonName;
29 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
30 import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
31 import eu.etaxonomy.cdm.model.reference.ReferenceType;
32 import eu.etaxonomy.cdm.model.taxon.TaxonNodeStatus;
33 import eu.etaxonomy.cdm.model.term.IEnumTerm;
34 import eu.etaxonomy.taxeditor.l10n.Messages;
35 import eu.etaxonomy.taxeditor.model.AbstractUtility;
36 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
37 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
38 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
39 import eu.etaxonomy.taxeditor.ui.section.name.NameRelationshipDetailElement;
40 import eu.etaxonomy.taxeditor.ui.section.name.NomenclaturalStatusElement;
41 import eu.etaxonomy.taxeditor.ui.section.name.NomenclaturalStatusSection;
42
43 /**
44 * @author n.hoffmann
45 * @created Mar 16, 2010
46 */
47 public class EnumComboElement<T extends IEnumTerm<T>>
48 extends AbstractComboElement<T> {
49
50 //TODO RL
51 public void setVisible(boolean b){
52 combo.setVisible(b);
53 }
54
55 private static CdmEnumDataHolder[] cdmEnumDataHolders = {
56 new CdmEnumDataHolder<NomenclaturalCode>(){
57
58 @Override
59 public String getName() {
60 return "Nomenclatural Code";
61 }
62
63 @Override
64 public Collection<NomenclaturalCode> getElements() {
65 Collection<NomenclaturalCode> result = new ArrayList<>(Arrays.asList(NomenclaturalCode.values()));
66 result.remove(NomenclaturalCode.ICVCN);
67 return result;
68 }
69
70 @Override
71 public Class<NomenclaturalCode> getClazz() {
72 return NomenclaturalCode.class;
73 }
74 },
75 new CdmEnumDataHolder<ReferenceType>(){
76
77 @Override
78 public String getName() {
79 return "Reference Type";
80 }
81
82 @Override
83 public Collection<ReferenceType> getElements() {
84 List<ReferenceType> list = Arrays.asList(ReferenceType.values());
85 Collections.sort(list, new Comparator<ReferenceType>() {
86 @Override
87 public int compare(ReferenceType rt1, ReferenceType rt2){
88 return rt1.getLabel().compareTo(rt2.getLabel());
89 }
90 });
91 return list;
92 }
93
94 @Override
95 public Class<ReferenceType> getClazz() {
96 return ReferenceType.class;
97 }
98
99 },
100 new CdmEnumDataHolder<SpecimenOrObservationType>(){
101
102 @Override
103 public String getName() {
104 return "Specimen / Observation Type";
105 }
106
107 @Override
108 public Collection<SpecimenOrObservationType> getElements() {
109 return Arrays.asList(SpecimenOrObservationType.values());
110 }
111
112 @Override
113 public Class<SpecimenOrObservationType> getClazz() {
114 return SpecimenOrObservationType.class;
115 }
116
117 },
118 new CdmEnumDataHolder<ExternalLinkType>(){
119
120 @Override
121 public String getName() {
122 return "Type";
123 }
124
125 @Override
126 public Collection<ExternalLinkType> getElements() {
127 return Arrays.asList(ExternalLinkType.values());
128 }
129
130 @Override
131 public Class<ExternalLinkType> getClazz() {
132 return ExternalLinkType.class;
133 }
134
135 },
136 new CdmEnumDataHolder<OriginalSourceType>(){
137
138 @Override
139 public String getName() {
140 return "Original Source Type";
141 }
142
143 @Override
144 public Collection<OriginalSourceType> getElements() {
145 return Arrays.asList(OriginalSourceType.values());
146 }
147
148 @Override
149 public Class<OriginalSourceType> getClazz() {
150 return OriginalSourceType.class;
151 }
152
153 },
154 new CdmEnumDataHolder<NomenclaturalCodeEdition>(){
155
156 @Override
157 public String getName() {
158 return "Nomenclatural Code Edition";
159 }
160
161 @Override
162 public Collection<NomenclaturalCodeEdition> getElements() {
163 return Arrays.asList(NomenclaturalCodeEdition.values());
164 }
165
166 @Override
167 public Class<NomenclaturalCodeEdition> getClazz() {
168 return NomenclaturalCodeEdition.class;
169 }
170
171 },
172 new CdmEnumDataHolder<TaxonNodeStatus>(){
173
174 @Override
175 public String getName() {
176 return "Taxon Node Status";
177 }
178
179 @Override
180 public Collection<TaxonNodeStatus> getElements() {
181 return Arrays.asList(TaxonNodeStatus.values());
182 }
183
184 @Override
185 public Class<TaxonNodeStatus> getClazz() {
186 return TaxonNodeStatus.class;
187 }
188
189 }
190 };
191
192 protected List<T> elementTypeList = new ArrayList<>();
193
194 private final Class<T> enumType;
195
196 public EnumComboElement(CdmFormFactory formFactory,
197 ICdmFormElement parentElement, Class<T> enumType, Comparator<T> comparator, int style, boolean hasNullValue) {
198 super(formFactory, parentElement, hasNullValue);
199 this.enumType = enumType;
200 label.setText(getDefaultLabelString());
201 populateTypes(comparator);
202 combo.addSelectionListener(this);
203 addContentProposalAdapter();
204 }
205
206 public void setIndent(int indent) {
207 TableWrapData layoutData = new TableWrapData();
208 layoutData.indent = indent;
209 label.setLayoutData(layoutData);
210
211 getLayoutComposite().layout();
212 }
213
214 public Combo getCombo(){
215 return combo;
216 }
217
218 private String getDefaultLabelString() {
219 if(enumType.equals(ReferenceType.class)){
220 return "Reference Type";
221 } else if (enumType.equals(NomenclaturalCode.class)){
222 return "Nomenclatural Code";
223 } else if(enumType.equals(OriginalSourceType.class)) {
224 return "Orig. Source Type";
225 } else if(enumType.equals(SpecimenOrObservationType.class)) {
226 return "Spec./Obs. Type";
227 } else if(enumType.equals(ExternalLinkType.class)) {
228 return "Type";
229 } else if(enumType.equals(NomenclaturalCodeEdition.class)) {
230 return "Code Edition";
231 }else if(enumType.equals(TaxonNodeStatus.class)) {
232 return Messages.EnumCombo_Placement_status;
233 }
234 return "No Label";
235 }
236
237 private void populateTypes(Comparator<T> comparator){
238 List<T> elementsForClass = new ArrayList<T>(getElementsForClass(enumType));
239 if(comparator!=null){
240 Collections.sort(elementsForClass, comparator);
241 }
242 int index = 0;
243 if (hasNullValue){
244 combo.add("", index);
245 index++;
246 }
247 // special hierarchical order for specimens
248 if(enumType.equals(SpecimenOrObservationType.class)){
249 LinkedHashMap<T, String> orderedTerms = AbstractUtility.orderTerms(elementsForClass);
250 for(Entry<T, String> keyLabelPair : orderedTerms.entrySet()){
251 elementTypeList.add(keyLabelPair.getKey());
252 combo.add(keyLabelPair.getValue(), index);
253 index++;
254 }
255 }else if(enumType.equals(NomenclaturalCodeEdition.class)){
256 NomenclaturalCode code = null;
257
258 ICdmFormElement parentElement = getParentElement();
259 if (parentElement instanceof NameRelationshipDetailElement){
260 NameRelationship rel = ((NameRelationshipDetailElement)parentElement).getEntity();
261 code = rel.getToName().getNameType();
262 }else if (parentElement instanceof NomenclaturalStatusElement){
263 ICdmFormElement parent = ((NomenclaturalStatusElement)parentElement).getParentElement();
264 TaxonName name = ((NomenclaturalStatusSection)parent).getEntity();
265 code = name.getNameType();
266 }
267 List<NomenclaturalCodeEdition> elements = NomenclaturalCodeEdition.forCode(code);
268 LinkedHashMap<NomenclaturalCodeEdition, String> orderedTerms = AbstractUtility.orderTerms(elements);
269 for (NomenclaturalCodeEdition codeEdition: elements){
270 elementTypeList.add((T)codeEdition);
271 combo.add(codeEdition.getLabel(), index);
272 index++;
273 }
274 }
275 // default order
276 else{
277 for(T enumElement : elementsForClass){
278 elementTypeList.add(enumElement);
279 if (enumElement instanceof IEnumTerm) {
280 combo.add(((IEnumTerm) enumElement).getLabel(), index);
281 index++;
282 }else{
283 combo.add(((Enum) enumElement).name(), index);
284 index++;
285 }
286 }
287 }
288 }
289
290 @Override
291 public void setSelection(T selection) {
292 this.selection = selection;
293 int index = elementTypeList.indexOf(selection);
294 if (hasNullValue && selection != null){
295 index++;
296 }
297 combo.select(index);
298 }
299
300 @Override
301 public void widgetSelected(SelectionEvent e) {
302
303 int index = combo.getSelectionIndex();
304 if (index == -2){
305 return;
306 }
307 if (hasNullValue ){
308 index--;
309 }
310 if (index<0){
311 selection = null;
312 }else{
313 selection = elementTypeList.get(index);
314 }
315
316 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
317 }
318
319 private Collection<T> getElementsForClass(Class<T> clazz){
320 CdmEnumDataHolder<T> dataHolder = getCdmEnumDataHolderForClass(clazz);
321 if (dataHolder != null) {
322 return dataHolder.getElements();
323 }
324 return null;
325 }
326
327 private CdmEnumDataHolder<T> getCdmEnumDataHolderForClass(Class<T> clazz){
328 for (CdmEnumDataHolder dataHolder : cdmEnumDataHolders) {
329 if (dataHolder.getClazz().equals(clazz)){
330 return dataHolder;
331 }
332 }
333 return null;
334 }
335
336 private interface CdmEnumDataHolder<T> {
337 Class<T> getClazz();
338 String getName();
339 Collection<T> getElements();
340 }
341 }