removed style parameter for combobox. Quick fix for ticket #4289. Needs to be reviewed.
[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.Collections;
8 import java.util.Comparator;
9 import java.util.List;
10
11 import org.eclipse.jface.util.PropertyChangeEvent;
12 import org.eclipse.swt.SWT;
13 import org.eclipse.swt.events.DisposeEvent;
14 import org.eclipse.swt.events.DisposeListener;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.events.SelectionListener;
17 import org.eclipse.swt.graphics.Color;
18 import org.eclipse.swt.widgets.Combo;
19 import org.eclipse.swt.widgets.Label;
20 import org.eclipse.swt.widgets.Listener;
21
22 import eu.etaxonomy.cdm.model.common.DefinedTerm;
23 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
24 import eu.etaxonomy.cdm.model.common.TermType;
25 import eu.etaxonomy.cdm.model.common.TermVocabulary;
26 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
27 import eu.etaxonomy.taxeditor.preference.Resources;
28 import eu.etaxonomy.taxeditor.store.CdmStore;
29 import eu.etaxonomy.taxeditor.store.StoreUtil;
30 import eu.etaxonomy.taxeditor.store.TermManager;
31 import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
32 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
33 import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
34 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
35 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
36 import eu.etaxonomy.taxeditor.ui.element.ISelectable;
37 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
38
39 /**
40 * <p>
41 * Abstract AbstractTermComboElement class.
42 * </p>
43 *
44 * @author n.hoffmann
45 * @created Nov 5, 2009
46 * @version 1.0
47 * @param <T>
48 */
49 public class TermComboElement<T extends DefinedTermBase>
50 extends AbstractCdmFormElement implements SelectionListener,
51 DisposeListener, IEnableableFormElement, ISelectable {
52
53 private static final int DEFAULT_VISIBLE_ITEMS = 10;
54
55 private T selection;
56
57 private T emptyElement;
58 private static String EMPTY_ELEMENT_LABEL = "";
59
60 protected Label label;
61 private final Combo combo;
62
63 private ArrayList<T> terms;
64
65 private Comparator<T> termComparator;
66
67 private final Class<T> termClass;
68
69 private List<T> customPreferredTerms;
70
71 public TermComboElement(CdmFormFactory formFactory,
72 ICdmFormElement parentElement, TermType termType, String labelString, T selection,
73 int style) {
74 this(formFactory, parentElement, null, termType, null, labelString, selection, style);
75 }
76
77 public TermComboElement(CdmFormFactory formFactory,
78 ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection,
79 int style) {
80 this(formFactory, parentElement, null, null, termVocabulary, labelString, selection, style);
81 }
82
83 public TermComboElement(CdmFormFactory formFactory,
84 ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection,
85 int style) {
86 this(formFactory, parentElement, termClass, null, null, labelString, selection, style);
87 }
88
89 private TermComboElement(CdmFormFactory formFactory,
90 ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection,
91 int style) {
92 super(formFactory, parentElement);
93
94 if(termClass!=null){
95 this.termClass = termClass;
96 }
97 else{
98 this.termClass = (Class<T>) DefinedTerm.class;
99 }
100
101 if (labelString != null) {
102 label = formFactory.createLabel(getLayoutComposite(), labelString);
103 addControl(label);
104 }
105
106 // create combo
107 combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY );//FIXME: removed this parameter seems break windows version: | style
108 addControl(combo);
109 combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
110 combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
111
112 if(termType!=null){
113 //TODO try to remove generic T and avoid classes to be used
114 populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
115 }
116 else if(termVocabulary!=null){
117 populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
118 }
119 else if(this.termClass!=null){
120 populateTerms(getPreferredTerms());
121 }
122
123 combo.addSelectionListener(this);
124 combo.addDisposeListener(this);
125 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
126
127 if (selection != null) {
128 setSelection(selection);
129 }
130 }
131
132 /**
133 * <p>
134 * Getter for the field <code>selection</code>.
135 * </p>
136 *
137 * @return a T object.
138 */
139 public T getSelection() {
140 return selection;
141 }
142
143 /**
144 * <p>Sets the selection of the combo to the given T object.</p>
145 * <p>Passing <code>null</code> to this method will set the selection to
146 * the empty element and effectively clear the selection</p>
147 *
148 * @param selection
149 * a T object or <code>null</code> to clear the selection
150 */
151 public void setSelection(T selection) {
152 this.selection = selection;
153
154 this.selection = selection;
155
156 Listener[] listeners = combo.getListeners(SWT.Selection);
157
158 for (Listener listener : listeners) {
159 combo.removeListener(SWT.Selection, listener);
160 }
161 int selectedIndex;
162 if(selection == null){
163 // set selection to the emptyElement
164 selectedIndex = 0;
165 }else{
166 selectedIndex = terms.indexOf(selection);
167 if (selectedIndex == -1) {
168 createTermNotInPreferredTerms(selection);
169 selectedIndex = terms.indexOf(selection);
170 }
171 }
172 combo.select(selectedIndex);
173
174 for (Listener listener : listeners) {
175 combo.addListener(SWT.Selection, listener);
176 }
177 }
178
179 /**
180 * Fills the combo with elements and sets up the convenience functions
181 * for selection index
182 *
183 * @param preferredTerms
184 */
185 private void populateTerms(List<T> preferredTerms) {
186
187 combo.removeAll();
188
189 terms = new ArrayList<T>();
190
191 int i = 1;
192 int index = 0;
193
194 // Add an empty element for when nothing was selected yet
195 combo.add(EMPTY_ELEMENT_LABEL);
196 terms.add(emptyElement);
197
198 if (termComparator != null) {
199 Collections.sort(preferredTerms, termComparator);
200 }
201 for (T term : preferredTerms) {
202 String label = getLabel(term);
203 if (label == null) {
204 if (term.getTitleCache() != null) {
205 label = term.getTitleCache();
206 StoreUtil.warn(getClass(),
207 "Term does not have a default language representation: " + label
208 + ", " + term.getUuid());
209 } else {
210 label = "Unknown";
211 StoreUtil.warn(getClass(),
212 "Representation Label and TitleCache empty for term: "
213 + term + ", " + term.getUuid());
214 }
215
216 }
217
218 combo.add(label);
219 terms.add(term);
220
221 i++;
222 if (selection != null) {
223 if (selection.equals(term)) {
224 index = i;
225 }
226 }
227 }
228
229 if (selection != null && index == 0) {
230 createTermNotInPreferredTerms(selection);
231 }
232
233 combo.select(index);
234 }
235
236 /*
237 * (non-Javadoc)
238 * @see eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
239 */
240 /** {@inheritDoc} */
241 @Override
242 public void setEnabled(boolean enabled) {
243 combo.setEnabled(enabled);
244 }
245
246 /* (non-Javadoc)
247 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
248 */
249 @Override
250 public boolean isEnabled() {
251 return combo.isEnabled();
252 }
253
254 /**
255 * <p>
256 * preferredTerms
257 * </p>
258 *
259 * @return a {@link java.util.List} object.
260 */
261 protected List<T> getPreferredTerms(){
262 if (customPreferredTerms != null){
263 return customPreferredTerms;
264 }
265 return getTermManager().getPreferredTerms(termClass);
266 }
267
268 /**
269 * May be overridden by derived classes if the desired label string does not
270 * reside in term.getLabel();
271 *
272 * @param term
273 * a T object.
274 * @return a {@link java.lang.String} object.
275 */
276 protected String getLabel(T term) {
277 if (term == null){
278 return "";
279 }else{
280 return term.getLabel(CdmStore.getDefaultLanguage());
281 }
282 }
283
284 /**
285 *
286 *
287 * @param term
288 */
289 private void createTermNotInPreferredTerms(T term) {
290 List<T> preferredTerms = getPreferredTerms();
291
292 preferredTerms.add(term);
293
294 populateTerms(preferredTerms);
295 }
296
297 /**
298 * <p>
299 * addSelectionListener
300 * </p>
301 *
302 * @param listener
303 * a {@link org.eclipse.swt.events.SelectionListener} object.
304 */
305 public void addSelectionListener(SelectionListener listener) {
306 combo.addSelectionListener(listener);
307 }
308
309 /**
310 * <p>
311 * removeSelectionListener
312 * </p>
313 *
314 * @param listener
315 * a {@link org.eclipse.swt.events.SelectionListener} object.
316 */
317 public void removeSelectionListener(SelectionListener listener) {
318 combo.removeSelectionListener(listener);
319 }
320
321 /*
322 * (non-Javadoc)
323 *
324 * @see
325 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
326 * .events.SelectionEvent)
327 */
328 /** {@inheritDoc} */
329 @Override
330 public void widgetSelected(SelectionEvent e) {
331 selection = terms.get(combo.getSelectionIndex());
332 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
333 }
334
335 /*
336 * (non-Javadoc)
337 *
338 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
339 * PropertyChangeEvent)
340 */
341 /** {@inheritDoc} */
342 @Override
343 public void propertyChange(PropertyChangeEvent event) {
344 super.propertyChange(event);
345 if (event != null
346 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
347 .getProperty())) {
348 populateTerms(getPreferredTerms());
349 }
350 }
351
352 /** {@inheritDoc} */
353 @Override
354 public void setSelected(boolean selected) {
355 setBackground(selected ? SELECTED : getPersistentBackground());
356 }
357
358 /** {@inheritDoc} */
359 @Override
360 public void widgetDisposed(DisposeEvent e) {
361 PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
362 }
363
364 // not used
365 /** {@inheritDoc} */
366 @Override
367 public void widgetDefaultSelected(SelectionEvent e) {
368 }
369
370 /** {@inheritDoc} */
371 @Override
372 public void setIrrelevant(boolean irrelevant) {
373 String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
374 : Resources.COLOR_COMPOSITE_BACKGROUND;
375
376 Color color = StoreUtil.getColor(colorId);
377 combo.setBackground(color);
378 }
379
380 /** {@inheritDoc} */
381 @Override
382 public void setBackground(Color color) {
383 if (label != null) {
384 label.setBackground(color);
385 }
386 }
387
388 /**
389 *
390 */
391 protected TermManager getTermManager() {
392 return CdmStore.getTermManager();
393 }
394
395 /**
396 *
397 * @return
398 */
399 public int getVisibleItemCount(){
400 return combo.getVisibleItemCount();
401 }
402
403 /**
404 *
405 * @param count
406 */
407 public void setVisibleItemCount(int count){
408 combo.setVisibleItemCount(count);
409 }
410
411 /**
412 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
413 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
414 * given terms. Also, any previous selection will be reseted.</p>
415 *
416 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
417 *
418 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
419 */
420 public void setTerms(List<T> terms) {
421 setSelection(null);
422 customPreferredTerms = terms;
423 populateTerms(customPreferredTerms);
424 }
425
426 }