extract string constant
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / TermComboElement.java
1 /**
2 *
3 */
4 package eu.etaxonomy.taxeditor.ui.combo;
5
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.Collections;
9 import java.util.Comparator;
10 import java.util.List;
11
12 import org.apache.commons.lang.StringUtils;
13 import org.eclipse.jface.util.PropertyChangeEvent;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.widgets.Listener;
17
18 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
19 import eu.etaxonomy.cdm.model.term.TermType;
20 import eu.etaxonomy.cdm.model.term.TermVocabulary;
21 import eu.etaxonomy.taxeditor.model.MessagingUtils;
22 import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
23 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
24 import eu.etaxonomy.taxeditor.store.CdmStore;
25 import eu.etaxonomy.taxeditor.store.TermManager;
26 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
27 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
28 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
29
30 /**
31 * @author n.hoffmann
32 * @created Nov 5, 2009
33 * @version 1.0
34 * @param <T>
35 */
36 public class TermComboElement<T extends DefinedTermBase>
37 extends AbstractComboElement<T> {
38
39 private T emptyElement;
40 private static String EMPTY_ELEMENT_LABEL = "";
41
42 private ArrayList<T> terms;
43
44 private Comparator<T> termComparator;
45
46 public Comparator<T> getTermComparator() {
47 return termComparator;
48 }
49
50 public void setTermComparator(Comparator<T> termComparator) {
51 this.termComparator = termComparator;
52 List<T> termsWithoutNull = terms.subList(1, terms.size());
53
54 populateTerms(termsWithoutNull);
55
56 }
57
58 private final TermType termType;
59 private final TermVocabulary termVocabulary;
60 private final Class<T> termClass;
61
62 private List<T> customPreferredTerms;
63
64 private boolean useAbbrevLabel = false;
65 private boolean addEmptyElement;
66
67 public TermComboElement(CdmFormFactory formFactory,
68 ICdmFormElement parentElement, TermType termType, String labelString, T selection, boolean addEmptyElement,
69 int style, boolean useAbbrevLabel, Comparator<T> comparator) {
70 this(formFactory, parentElement, null, termType, null, null, labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
71 }
72
73 public TermComboElement(CdmFormFactory formFactory,
74 ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
75 int style, boolean useAbbrevLabel, Comparator<T> comparator) {
76 this(formFactory, parentElement, null, null, termVocabulary, null,labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
77 }
78
79 public TermComboElement(CdmFormFactory formFactory,
80 ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
81 int style) {
82 this(formFactory, parentElement, termClass, null, null, null, labelString, selection, addEmptyElement, style, false, null);
83 }
84 public TermComboElement(CdmFormFactory formFactory,
85 ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
86 int style, boolean useAbbrevLabel) {
87 this(formFactory, parentElement, termClass, null, null, null,labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
88
89 }
90
91 public TermComboElement(CdmFormFactory formFactory,
92 ICdmFormElement parentElement, List<T> terms, String labelString, T selection, boolean addEmptyElement,
93 int style, boolean useAbbrevLabel) {
94 this(formFactory, parentElement, null, null, null, terms,labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
95
96 }
97
98 private TermComboElement(CdmFormFactory formFactory,
99 ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, List<T> terms,String labelString, T selection, boolean addEmptyElement,
100 int style, boolean useAbbrevLabel, Comparator<T> comparator) {
101 super(formFactory, parentElement);
102
103 this.termType = termType;
104 this.termVocabulary = termVocabulary;
105 this.termClass = termClass;
106 this.addEmptyElement = addEmptyElement;
107 this.useAbbrevLabel = useAbbrevLabel;
108 this.termComparator = comparator;
109 if (labelString != null) {
110 label.setText(labelString);
111 }
112 this.selection = selection;
113
114 if(termType!=null){
115 //TODO try to remove generic T and avoid classes to be used
116 populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
117 }
118 else if(termVocabulary!=null){
119 populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
120 }
121 else if(this.termClass!=null){
122 populateTerms(getPreferredTerms());
123 }else if (terms != null){
124 populateTerms(terms);
125 }
126
127 combo.addSelectionListener(this);
128 combo.addDisposeListener(this);
129 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
130
131 if (selection != null) {
132 setSelection(selection);
133 }
134 }
135
136 /**
137 * <p>Sets the selection of the combo to the given T object.</p>
138 * <p>Passing <code>null</code> to this method will set the selection to
139 * the empty element and effectively clear the selection</p>
140 *
141 * @param selection
142 * a T object or <code>null</code> to clear the selection
143 */
144 @Override
145 public void setSelection(T selection) {
146 this.selection = selection;
147
148 Listener[] listeners = combo.getListeners(SWT.Selection);
149
150 for (Listener listener : listeners) {
151 combo.removeListener(SWT.Selection, listener);
152 }
153 int selectedIndex;
154 if(selection == null){
155 // set selection to the emptyElement
156 selectedIndex = 0;
157 }else{
158 selectedIndex = terms.indexOf(selection);
159 if (selectedIndex == -1) {
160 createTermNotInPreferredTerms(selection, this.terms);
161 selectedIndex = terms.indexOf(selection);
162 }
163 }
164 combo.select(selectedIndex);
165
166 for (Listener listener : listeners) {
167 combo.addListener(SWT.Selection, listener);
168 }
169 }
170
171 /**
172 * Fills the combo with elements and sets up the convenience functions
173 * for selection index
174 *
175 * @param preferredTerms
176 */
177 protected void populateTerms(List<T> preferredTerms) {
178
179 combo.removeAll();
180
181 terms = new ArrayList<T>();
182
183 int i = 1;
184 int index = 0;
185
186 if(addEmptyElement){
187 // Add an empty element for when nothing was selected yet
188 combo.add(EMPTY_ELEMENT_LABEL);
189 terms.add(emptyElement);
190 }
191
192 if (termComparator != null) {
193 Collections.sort(preferredTerms, termComparator);
194 }
195 for (T term : preferredTerms) {
196 String label = getLabel(term);
197 if (label == null) {
198 if (term.getTitleCache() != null) {
199 label = term.getTitleCache();
200 MessagingUtils.warn(getClass(),
201 "Term does not have a default language representation: " + label
202 + ", " + term.getUuid());
203 } else {
204 label = "Unknown";
205 MessagingUtils.warn(getClass(),
206 "Representation Label and TitleCache empty for term: "
207 + term + ", " + term.getUuid());
208 }
209
210 }
211
212 combo.add(label);
213 terms.add(term);
214
215 i++;
216 if (selection != null) {
217 if (selection.equals(term)) {
218 index = i;
219 }
220 }
221 }
222
223 if (selection != null && index == 0) {
224 createTermNotInPreferredTerms(selection, preferredTerms);
225 }
226
227 combo.select(index);
228
229 }
230
231 protected List<T> getPreferredTerms(){
232 List<T> preferredTerms = new ArrayList<T>();
233 if (customPreferredTerms != null){
234 return customPreferredTerms;
235 }
236 else if(termType!=null){
237 preferredTerms = getTermManager().getPreferredTerms(termType);
238 }
239 else if(termVocabulary!=null){
240 preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
241 }
242 if(termClass!=null){
243 preferredTerms = getTermManager().getPreferredTerms(termClass);
244 }
245 return preferredTerms;
246 }
247
248 /**
249 * May be overridden by derived classes if the desired label string does not
250 * reside in term.getLabel();
251 *
252 * @param term
253 * a T object.
254 * @return a {@link java.lang.String} object.
255 */
256 protected String getLabel(T term) {
257 if (term == null){
258 return "";
259 }else{
260 String termLabel = null;
261 if (useAbbrevLabel){
262 if (!StringUtils.isBlank(term.getIdInVocabulary())){
263 termLabel = term.getIdInVocabulary();
264 }
265 }
266 if (termLabel == null){
267 termLabel = term.getLabel(CdmStore.getDefaultLanguage());
268 }
269 if (termLabel == null){
270 termLabel = term.getLabel();
271 }
272 if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
273 && term.getVocabulary()!=null){
274 String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
275 if (vocLabel == null){
276 vocLabel = term.getVocabulary().getLabel();
277 }
278 termLabel += " ["+vocLabel+"]";
279 }
280 return termLabel;
281 }
282 }
283
284 /**
285 *
286 *
287 * @param term
288 */
289 private void createTermNotInPreferredTerms(T term, List<T> preferredTerms) {
290 //List<T> preferredTerms = getPreferredTerms();
291
292 preferredTerms.add(term);
293
294 populateTerms(preferredTerms);
295 }
296
297 /** {@inheritDoc} */
298 @Override
299 public void widgetSelected(SelectionEvent e) {
300 selection = terms.get(combo.getSelectionIndex());
301 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
302 }
303
304 /** {@inheritDoc} */
305 @Override
306 public void propertyChange(PropertyChangeEvent event) {
307 super.propertyChange(event);
308 T selection = this.selection;
309 if (event != null
310 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
311 .getProperty())) {
312 populateTerms(getPreferredTerms());
313 }
314 this.setSelection(selection);
315 }
316
317 protected TermManager getTermManager() {
318 return CdmStore.getTermManager();
319 }
320
321 public int getVisibleItemCount(){
322 return combo.getVisibleItemCount();
323 }
324
325 /**
326 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
327 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
328 * given terms. Also, any previous selection will be reseted.</p>
329 *
330 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
331 *
332 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
333 */
334 public void setTerms(List<T> terms) {
335 setSelection(null);
336 customPreferredTerms = terms;
337 populateTerms(customPreferredTerms);
338 }
339
340 public void removeEmptyElement(){
341 if(addEmptyElement){
342 if(terms.contains(emptyElement)){
343 terms.remove(emptyElement);
344 }
345 if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
346 combo.remove(EMPTY_ELEMENT_LABEL);
347 }
348 }
349 }
350
351 }