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