Merging changes from snapshot_3.0.9 to fix bug #2235
[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
67 /**
68 * <p>
69 * Constructor for AbstractTermComboElement.
70 * </p>
71 *
72 * @param parentElement
73 * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
74 * object.
75 * @param style
76 * a int.
77 * @param formFactory
78 * a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
79 * object.
80 * @param labelString
81 * a {@link java.lang.String} object.
82 * @param selection
83 * a T object.
84 * @param visibleItems
85 * a int.
86 * @param <T>
87 * a T object.
88 */
89 public TermComboElement(CdmFormFactory formFactory,
90 ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection,
91 int style) {
92 super(formFactory, parentElement);
93
94 this.termClass = termClass;
95
96 if (labelString != null) {
97 label = formFactory.createLabel(getLayoutComposite(), labelString);
98 addControl(label);
99 }
100
101 // create combo
102 combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY);
103 addControl(combo);
104 combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
105 combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
106
107 populateTerms(getPreferredTerms());
108
109 combo.addSelectionListener(this);
110 combo.addDisposeListener(this);
111 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
112
113 if (selection != null) {
114 setSelection(selection);
115 }
116 }
117
118 /**
119 * <p>
120 * Getter for the field <code>selection</code>.
121 * </p>
122 *
123 * @return a T object.
124 */
125 public T getSelection() {
126 return selection;
127 }
128
129 /**
130 * <p>Sets the selection of the combo to the given T object.</p>
131 * <p>Passing <code>null</code> to this method will set the selection to
132 * the empty element and effectively clear the selection</p>
133 *
134 * @param selection
135 * a T object or <code>null</code> to clear the selection
136 */
137 public void setSelection(T selection) {
138 Listener[] listeners = combo.getListeners(SWT.Selection);
139
140 for (Listener listener : listeners) {
141 combo.removeListener(SWT.Selection, listener);
142 }
143 int index;
144 if(selection == null){
145 index = 0;
146 }else{
147 index = terms.indexOf(selection);
148 if (index == -1) {
149 createTermNotInPreferredTerms(selection);
150 index = terms.indexOf(selection);
151 }
152 }
153 combo.select(index);
154
155 for (Listener listener : listeners) {
156 combo.addListener(SWT.Selection, listener);
157 }
158 }
159
160 private void populateTerms(List<T> preferredTerms) {
161
162 combo.removeAll();
163
164 terms = new ArrayList<T>();
165
166 int i = 1;
167 int index = 0;
168
169 // Add an empty element for when nothing was selected yet
170 combo.add(EMPTY_ELEMENT_LABEL);
171 terms.add(emptyElement);
172
173 if (termComparator != null) {
174 Collections.sort(preferredTerms, termComparator);
175 }
176 for (T term : preferredTerms) {
177 String label = getLabel(term);
178 if (label == null) {
179 if (term.getTitleCache() != null) {
180 label = term.getTitleCache();
181 StoreUtil.error(getClass(),
182 "Term does not have a representation: " + term
183 + ", " + term.getUuid(), null);
184 } else {
185 label = "Unknown";
186 StoreUtil.error(getClass(),
187 "Representation Label and TitleCache empty for term: "
188 + term + ", " + term.getUuid(), null);
189 }
190
191 }
192
193 combo.add(label);
194 terms.add(term);
195
196 i++;
197 if (selection != null) {
198 if (selection.equals(term)) {
199 index = i;
200 }
201 }
202 }
203
204 if (selection != null && index == 0) {
205 createTermNotInPreferredTerms(selection);
206 }
207
208 combo.select(index);
209 }
210
211 /*
212 * (non-Javadoc)
213 *
214 * @see
215 * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
216 */
217 /** {@inheritDoc} */
218 public void setEnabled(boolean enabled) {
219 combo.setEnabled(enabled);
220 }
221
222 /**
223 * <p>
224 * preferredTerms
225 * </p>
226 *
227 * @return a {@link java.util.List} object.
228 */
229 protected List<T> getPreferredTerms(){
230 return getTermManager().getPreferredTerms(termClass);
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(T term) {
242 return term.getLabel(CdmStore.getDefaultLanguage());
243 }
244
245 private void createTermNotInPreferredTerms(T term) {
246 List<T> preferredTerms = getPreferredTerms();
247
248 preferredTerms.add(term);
249
250 populateTerms(preferredTerms);
251 }
252
253 /**
254 * <p>
255 * addSelectionListener
256 * </p>
257 *
258 * @param listener
259 * a {@link org.eclipse.swt.events.SelectionListener} object.
260 */
261 public void addSelectionListener(SelectionListener listener) {
262 combo.addSelectionListener(listener);
263 }
264
265 /**
266 * <p>
267 * removeSelectionListener
268 * </p>
269 *
270 * @param listener
271 * a {@link org.eclipse.swt.events.SelectionListener} object.
272 */
273 public void removeSelectionListener(SelectionListener listener) {
274 combo.removeSelectionListener(listener);
275 }
276
277 /*
278 * (non-Javadoc)
279 *
280 * @see
281 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
282 * .events.SelectionEvent)
283 */
284 /** {@inheritDoc} */
285 public void widgetSelected(SelectionEvent e) {
286 selection = terms.get(combo.getSelectionIndex());
287 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
288 }
289
290 /*
291 * (non-Javadoc)
292 *
293 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
294 * PropertyChangeEvent)
295 */
296 /** {@inheritDoc} */
297 public void propertyChange(PropertyChangeEvent event) {
298 super.propertyChange(event);
299 if (event != null
300 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
301 .getProperty())) {
302 populateTerms(getPreferredTerms());
303 }
304 }
305
306 /** {@inheritDoc} */
307 public void setSelected(boolean selected) {
308 setBackground(selected ? SELECTED : getPersistentBackground());
309 }
310
311 /** {@inheritDoc} */
312 public void widgetDisposed(DisposeEvent e) {
313 PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
314 }
315
316 // not used
317 /** {@inheritDoc} */
318 public void widgetDefaultSelected(SelectionEvent e) {
319 }
320
321 /** {@inheritDoc} */
322 public void setIrrelevant(boolean irrelevant) {
323 String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
324 : Resources.COLOR_COMPOSITE_BACKGROUND;
325
326 Color color = StoreUtil.getColor(colorId);
327 combo.setBackground(color);
328 }
329
330 /** {@inheritDoc} */
331 @Override
332 public void setBackground(Color color) {
333 if (label != null)
334 label.setBackground(color);
335 }
336
337 /**
338 *
339 */
340 protected TermManager getTermManager() {
341 return CdmStore.getTermManager();
342 }
343
344 public int getVisibleItemCount(){
345 return combo.getVisibleItemCount();
346 }
347
348 public void setVisibleItemCount(int count){
349 combo.setVisibleItemCount(count);
350 }
351
352 public void setTerms(List<T> terms) {
353 populateTerms(terms);
354 }
355 }