Merge branch 'release/5.19.0'
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / VocabularyComboElement.java
1 /**
2 * Copyright (C) 2016 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.Collections;
13 import java.util.Comparator;
14 import java.util.List;
15
16 import org.eclipse.jface.util.PropertyChangeEvent;
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.events.SelectionEvent;
19 import org.eclipse.swt.widgets.Listener;
20
21 import eu.etaxonomy.cdm.api.service.IVocabularyService;
22 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
23 import eu.etaxonomy.cdm.model.term.TermType;
24 import eu.etaxonomy.cdm.model.term.TermVocabulary;
25 import eu.etaxonomy.cdm.persistence.dto.TermVocabularyDto;
26 import eu.etaxonomy.taxeditor.model.MessagingUtils;
27 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
28 import eu.etaxonomy.taxeditor.store.CdmStore;
29 import eu.etaxonomy.taxeditor.store.TermManager;
30 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
31 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
32 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
33
34 /**
35 * @author n.hoffmann
36 * @created Nov 5, 2009
37 */
38 public class VocabularyComboElement<TERM extends DefinedTermBase<TERM>, VOC extends TermVocabulary<TERM>>
39 extends AbstractComboElement<VOC> {
40
41 private VOC emptyElement;
42 private static String EMPTY_ELEMENT_LABEL = "";
43
44 private ArrayList<VOC> terms;
45
46 private Comparator<VOC> vocComparator;
47
48 private final TermType termType;
49
50 public VocabularyComboElement(CdmFormFactory formFactory,
51 ICdmFormElement parentElement, TermType termType, String labelString,
52 VOC selection, int style) {
53 super(formFactory, parentElement);
54
55 this.termType = termType;
56
57 populateTerms(getVocabularies());
58
59 combo.addSelectionListener(this);
60 combo.addDisposeListener(this);
61 addContentProposalAdapter();
62
63 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
64
65 if (selection != null) {
66 setSelection(selection);
67 }
68 }
69
70 public VocabularyComboElement(CdmFormFactory formFactory,
71 ICdmFormElement parentElement, TermType termType, String labelString,
72 TermVocabularyDto selection, int style) {
73 super(formFactory, parentElement);
74
75 this.termType = termType;
76
77 populateTerms(getVocabularies());
78
79 combo.addSelectionListener(this);
80 combo.addDisposeListener(this);
81 addContentProposalAdapter();
82
83 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
84
85 if (selection != null) {
86 setSelectionDto(selection);
87 }
88 }
89
90 /**
91 * <p>Sets the selection of the combo to the given T object.</p>
92 * <p>Passing <code>null</code> to this method will set the selection to
93 * the empty element and effectively clear the selection</p>
94 *
95 * @param selection
96 * a T object or <code>null</code> to clear the selection
97 */
98 @Override
99 public void setSelection(VOC selection) {
100 this.selection = selection;
101
102 Listener[] listeners = combo.getListeners(SWT.Selection);
103
104 // for (Listener listener : listeners) {
105 // combo.removeListener(SWT.Selection, listener);
106 // }
107 int selectedIndex;
108 if(selection == null){
109 // set selection to the emptyElement
110 selectedIndex = 0;
111 }else{
112 selectedIndex = terms.indexOf(selection);
113 if (selectedIndex == -1) {
114 createTermNotInPreferredTerms(selection);
115 selectedIndex = terms.indexOf(selection);
116 }
117 }
118 combo.select(selectedIndex);
119
120 // for (Listener listener : listeners) {
121 // combo.addListener(SWT.Selection, listener);
122 // }
123 }
124
125 public void setSelectionDto(TermVocabularyDto selection) {
126 Listener[] listeners = combo.getListeners(SWT.Selection);
127
128 // for (Listener listener : listeners) {
129 // combo.removeListener(SWT.Selection, listener);
130 // }
131 int selectedIndex = 0;
132 if(selection == null){
133 // set selection to the emptyElement
134 selectedIndex = 0;
135 }else{
136 for (VOC voc: terms){
137
138 if (voc != null && voc.getUuid().equals(selection.getUuid())){
139 selectedIndex = terms.indexOf(voc);
140 }
141 }
142
143 // if (selectedIndex == -1) {
144 // createTermNotInPreferredTerms(selection);
145 // selectedIndex = terms.indexOf(selection);
146 // }
147 }
148 if (selectedIndex > -1) {
149 combo.select(selectedIndex);
150 }
151
152 // for (Listener listener : listeners) {
153 // combo.addListener(SWT.Selection, listener);
154 // }
155 }
156
157 /**
158 * Fills the combo with elements and sets up the convenience functions
159 * for selection index
160 *
161 * @param preferredTerms
162 */
163 private void populateTerms(List<VOC> preferredTerms) {
164
165 combo.removeAll();
166
167 terms = new ArrayList<VOC>();
168
169 int i = 1;
170 int index = 0;
171
172 // Add an empty element for when nothing was selected yet
173 combo.add(EMPTY_ELEMENT_LABEL);
174 terms.add(emptyElement);
175
176 if (vocComparator != null) {
177 Collections.sort(preferredTerms, vocComparator);
178 }else{
179 Collections.sort(preferredTerms, new Comparator<VOC>() {
180
181 @Override
182 public int compare(VOC o1, VOC o2) {
183 if (o1.equals(o2)){
184 return 0;
185 }
186 int result = ((TermVocabulary) o1).getTitleCache().toLowerCase().compareTo(((TermVocabulary)o2).getTitleCache().toLowerCase());
187
188 return result;
189 }
190 });
191 }
192 for (VOC term : preferredTerms) {
193 String label = getLabel(term);
194 if (label == null) {
195 if (term.getTitleCache() != null) {
196 label = term.getTitleCache();
197 MessagingUtils.warn(getClass(),
198 "Term does not have a default language representation: " + label
199 + ", " + term.getUuid());
200 } else {
201 label = "Unknown";
202 MessagingUtils.warn(getClass(),
203 "Representation Label and TitleCache empty for term: "
204 + term + ", " + term.getUuid());
205 }
206
207 }
208
209 combo.add(label);
210 combo.setData(label, term);
211 terms.add(term);
212
213 i++;
214 if (selection != null) {
215 if (selection.equals(term)) {
216 index = i;
217 }
218 }
219 }
220
221 if (selection != null && index == 0) {
222 createTermNotInPreferredTerms(selection);
223 }
224
225 combo.select(index);
226 }
227
228 protected List<VOC> getVocabularies(){
229 List<TermVocabulary<TERM>> list = CdmStore.getService(IVocabularyService.class).<TERM>findByTermType(termType, null);
230 return (List<VOC>) list;
231 }
232
233 /**
234 * May be overridden by derived classes if the desired label string does not
235 * reside in term.getLabel();
236 *
237 * @param term
238 * a T object.
239 * @return a {@link java.lang.String} object.
240 */
241 protected String getLabel(VOC term) {
242 if (term == null){
243 return "";
244 }else{
245 return term.getLabel(CdmStore.getDefaultLanguage());
246 }
247 }
248
249 private void createTermNotInPreferredTerms(VOC term) {
250 List<VOC> preferredTerms = getVocabularies();
251
252 preferredTerms.add(term);
253
254 populateTerms(preferredTerms);
255 }
256
257 @Override
258 public void widgetSelected(SelectionEvent e) {
259 int i = combo.getSelectionIndex();
260 if (i > -1){
261 selection = terms.get(i);
262 }else{
263 selection = null;
264 }
265 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
266 }
267
268 @Override
269 public void propertyChange(PropertyChangeEvent event) {
270 super.propertyChange(event);
271 if (event != null
272 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
273 .getProperty())) {
274 populateTerms(getVocabularies());
275 }
276 }
277
278 protected TermManager getTermManager() {
279 return CdmStore.getTermManager();
280 }
281
282 public int getVisibleItemCount(){
283 return combo.getVisibleItemCount();
284 }
285
286 public void removeEmptyElement(){
287 terms.remove(emptyElement);
288 combo.remove(EMPTY_ELEMENT_LABEL);
289 }
290 }