6ee853a8c18e2dbff10c544b493f00471fc9b82c
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / VocabularyComboElement.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.api.service.IVocabularyService;
23 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
24 import eu.etaxonomy.cdm.model.common.TermVocabulary;
25 import eu.etaxonomy.taxeditor.model.MessagingUtils;
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 <VOC>
48 */
49 public class VocabularyComboElement<VOC extends TermVocabulary<DefinedTermBase>>
50 extends AbstractCdmFormElement implements SelectionListener,
51 DisposeListener, IEnableableFormElement, ISelectable {
52
53 private static final int DEFAULT_VISIBLE_ITEMS = 10;
54
55 private VOC selection;
56
57 private VOC emptyElement;
58 private static String EMPTY_ELEMENT_LABEL = "";
59
60 protected Label label;
61 private final Combo combo;
62
63 private ArrayList<VOC> terms;
64
65 private Comparator<VOC> vocComparator;
66
67 private final Class<VOC> vocClass;
68
69 public VocabularyComboElement(CdmFormFactory formFactory,
70 ICdmFormElement parentElement, Class<VOC> termClass, String labelString, VOC selection,
71 int style) {
72 super(formFactory, parentElement);
73
74 if(termClass!=null){
75 this.vocClass = termClass;
76 }
77 else{
78 this.vocClass = (Class<VOC>) TermVocabulary.class;
79 }
80
81 if (labelString != null) {
82 label = formFactory.createLabel(getLayoutComposite(), labelString);
83 addControl(label);
84 }
85
86 // create combo
87 combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY );//FIXME: removed this parameter seems break windows version: | style
88 addControl(combo);
89 combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
90 combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
91
92 if(this.vocClass!=null){
93 populateTerms(getVocabularies());
94 }
95
96 combo.addSelectionListener(this);
97 combo.addDisposeListener(this);
98 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
99
100 if (selection != null) {
101 setSelection(selection);
102 }
103 }
104
105 /**
106 * <p>
107 * Getter for the field <code>selection</code>.
108 * </p>
109 *
110 * @return a T object.
111 */
112 public VOC getSelection() {
113 return selection;
114 }
115
116 /**
117 * <p>Sets the selection of the combo to the given T object.</p>
118 * <p>Passing <code>null</code> to this method will set the selection to
119 * the empty element and effectively clear the selection</p>
120 *
121 * @param selection
122 * a T object or <code>null</code> to clear the selection
123 */
124 public void setSelection(VOC selection) {
125 this.selection = selection;
126
127 this.selection = selection;
128
129 Listener[] listeners = combo.getListeners(SWT.Selection);
130
131 for (Listener listener : listeners) {
132 combo.removeListener(SWT.Selection, listener);
133 }
134 int selectedIndex;
135 if(selection == null){
136 // set selection to the emptyElement
137 selectedIndex = 0;
138 }else{
139 selectedIndex = terms.indexOf(selection);
140 if (selectedIndex == -1) {
141 createTermNotInPreferredTerms(selection);
142 selectedIndex = terms.indexOf(selection);
143 }
144 }
145 combo.select(selectedIndex);
146
147 for (Listener listener : listeners) {
148 combo.addListener(SWT.Selection, listener);
149 }
150 }
151
152 /**
153 * Fills the combo with elements and sets up the convenience functions
154 * for selection index
155 *
156 * @param preferredTerms
157 */
158 private void populateTerms(List<VOC> preferredTerms) {
159
160 combo.removeAll();
161
162 terms = new ArrayList<VOC>();
163
164 int i = 1;
165 int index = 0;
166
167 // Add an empty element for when nothing was selected yet
168 combo.add(EMPTY_ELEMENT_LABEL);
169 terms.add(emptyElement);
170
171 if (vocComparator != null) {
172 Collections.sort(preferredTerms, vocComparator);
173 }
174 for (VOC term : preferredTerms) {
175 String label = getLabel(term);
176 if (label == null) {
177 if (term.getTitleCache() != null) {
178 label = term.getTitleCache();
179 MessagingUtils.warn(getClass(),
180 "Term does not have a default language representation: " + label
181 + ", " + term.getUuid());
182 } else {
183 label = "Unknown";
184 MessagingUtils.warn(getClass(),
185 "Representation Label and TitleCache empty for term: "
186 + term + ", " + term.getUuid());
187 }
188
189 }
190
191 combo.add(label);
192 terms.add(term);
193
194 i++;
195 if (selection != null) {
196 if (selection.equals(term)) {
197 index = i;
198 }
199 }
200 }
201
202 if (selection != null && index == 0) {
203 createTermNotInPreferredTerms(selection);
204 }
205
206 combo.select(index);
207 }
208
209 /*
210 * (non-Javadoc)
211 * @see eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
212 */
213 /** {@inheritDoc} */
214 @Override
215 public void setEnabled(boolean enabled) {
216 combo.setEnabled(enabled);
217 }
218
219 /* (non-Javadoc)
220 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
221 */
222 @Override
223 public boolean isEnabled() {
224 return combo.isEnabled();
225 }
226
227 /**
228 * <p>
229 * preferredTerms
230 * </p>
231 *
232 * @return a {@link java.util.List} object.
233 */
234 protected List<VOC> getVocabularies(){
235 return CdmStore.getService(IVocabularyService.class).list(vocClass, null, null, null, null);
236 }
237
238 /**
239 * May be overridden by derived classes if the desired label string does not
240 * reside in term.getLabel();
241 *
242 * @param term
243 * a T object.
244 * @return a {@link java.lang.String} object.
245 */
246 protected String getLabel(VOC term) {
247 if (term == null){
248 return "";
249 }else{
250 return term.getLabel(CdmStore.getDefaultLanguage());
251 }
252 }
253
254 /**
255 *
256 *
257 * @param term
258 */
259 private void createTermNotInPreferredTerms(VOC term) {
260 List<VOC> preferredTerms = getVocabularies();
261
262 preferredTerms.add(term);
263
264 populateTerms(preferredTerms);
265 }
266
267 /**
268 * <p>
269 * addSelectionListener
270 * </p>
271 *
272 * @param listener
273 * a {@link org.eclipse.swt.events.SelectionListener} object.
274 */
275 public void addSelectionListener(SelectionListener listener) {
276 combo.addSelectionListener(listener);
277 }
278
279 /**
280 * <p>
281 * removeSelectionListener
282 * </p>
283 *
284 * @param listener
285 * a {@link org.eclipse.swt.events.SelectionListener} object.
286 */
287 public void removeSelectionListener(SelectionListener listener) {
288 combo.removeSelectionListener(listener);
289 }
290
291 /*
292 * (non-Javadoc)
293 *
294 * @see
295 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
296 * .events.SelectionEvent)
297 */
298 /** {@inheritDoc} */
299 @Override
300 public void widgetSelected(SelectionEvent e) {
301 selection = terms.get(combo.getSelectionIndex());
302 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
303 }
304
305 /*
306 * (non-Javadoc)
307 *
308 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
309 * PropertyChangeEvent)
310 */
311 /** {@inheritDoc} */
312 @Override
313 public void propertyChange(PropertyChangeEvent event) {
314 super.propertyChange(event);
315 if (event != null
316 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
317 .getProperty())) {
318 populateTerms(getVocabularies());
319 }
320 }
321
322 /** {@inheritDoc} */
323 @Override
324 public void setSelected(boolean selected) {
325 setBackground(selected ? SELECTED : getPersistentBackground());
326 }
327
328 /** {@inheritDoc} */
329 @Override
330 public void widgetDisposed(DisposeEvent e) {
331 PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
332 }
333
334 // not used
335 /** {@inheritDoc} */
336 @Override
337 public void widgetDefaultSelected(SelectionEvent e) {
338 }
339
340 /** {@inheritDoc} */
341 @Override
342 public void setIrrelevant(boolean irrelevant) {
343 String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
344 : 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 */
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 }