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