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