Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 *
3
 */
4
package eu.etaxonomy.taxeditor.ui.combo;
5

    
6
import java.util.ArrayList;
7
import java.util.Arrays;
8
import java.util.Collections;
9
import java.util.Comparator;
10
import java.util.List;
11

    
12
import org.eclipse.jface.util.PropertyChangeEvent;
13
import org.eclipse.swt.SWT;
14
import org.eclipse.swt.events.DisposeEvent;
15
import org.eclipse.swt.events.DisposeListener;
16
import org.eclipse.swt.events.SelectionEvent;
17
import org.eclipse.swt.events.SelectionListener;
18
import org.eclipse.swt.graphics.Color;
19
import org.eclipse.swt.widgets.Combo;
20
import org.eclipse.swt.widgets.Label;
21
import org.eclipse.swt.widgets.Listener;
22

    
23
import eu.etaxonomy.cdm.model.common.DefinedTerm;
24
import eu.etaxonomy.cdm.model.common.DefinedTermBase;
25
import eu.etaxonomy.cdm.model.common.TermType;
26
import eu.etaxonomy.cdm.model.common.TermVocabulary;
27
import eu.etaxonomy.taxeditor.model.MessagingUtils;
28
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
29
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
30
import eu.etaxonomy.taxeditor.preference.Resources;
31
import eu.etaxonomy.taxeditor.store.CdmStore;
32
import eu.etaxonomy.taxeditor.store.StoreUtil;
33
import eu.etaxonomy.taxeditor.store.TermManager;
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.ICdmFormElement;
38
import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
39
import eu.etaxonomy.taxeditor.ui.element.ISelectable;
40
import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
41

    
42
/**
43
 * <p>
44
 * Abstract AbstractTermComboElement class.
45
 * </p>
46
 *
47
 * @author n.hoffmann
48
 * @created Nov 5, 2009
49
 * @version 1.0
50
 * @param <T>
51
 */
52
public class TermComboElement<T extends DefinedTermBase>
53
		extends AbstractCdmFormElement implements SelectionListener,
54
		DisposeListener, IEnableableFormElement, ISelectable {
55

    
56
	private static final int DEFAULT_VISIBLE_ITEMS = 10;
57

    
58
	private T selection;
59

    
60
	private T emptyElement;
61
	private static String EMPTY_ELEMENT_LABEL = "";
62

    
63
	protected Label label;
64
	private final Combo combo;
65

    
66
	private ArrayList<T> terms;
67

    
68
	private Comparator<T> termComparator;
69

    
70
	private final Class<T> termClass;
71

    
72
	private List<T> customPreferredTerms;
73

    
74
	private boolean addEmptyElement;
75

    
76
	public TermComboElement(CdmFormFactory formFactory,
77
			ICdmFormElement parentElement, TermType termType, String labelString, T selection, boolean addEmptyElement,
78
			int style) {
79
		this(formFactory, parentElement, null, termType, null, labelString, selection, addEmptyElement, style);
80
	}
81

    
82
	public TermComboElement(CdmFormFactory formFactory,
83
	        ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
84
	        int style) {
85
	    this(formFactory, parentElement, null, null, termVocabulary, labelString, selection, addEmptyElement, style);
86
	}
87

    
88
    public TermComboElement(CdmFormFactory formFactory,
89
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
90
            int style) {
91
        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style);
92
    }
93

    
94
	private TermComboElement(CdmFormFactory formFactory,
95
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
96
	        int style) {
97
        super(formFactory, parentElement);
98

    
99
        if(termClass!=null){
100
            this.termClass = termClass;
101
        }
102
        else{
103
            this.termClass =  (Class<T>) DefinedTerm.class;
104
        }
105
        this.addEmptyElement = addEmptyElement;
106

    
107
        if (labelString != null) {
108
            label = formFactory.createLabel(getLayoutComposite(), labelString);
109
            addControl(label);
110
        }
111

    
112
        // create combo
113
        combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY );//FIXME: removed this parameter seems break windows version: | style
114
        addControl(combo);
115
        combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
116
        combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
117

    
118
        if(termType!=null){
119
            //TODO try to remove generic T and avoid classes to be used
120
            populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
121
        }
122
        else if(termVocabulary!=null){
123
            populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
124
        }
125
        else if(this.termClass!=null){
126
            populateTerms(getPreferredTerms());
127
        }
128

    
129
        combo.addSelectionListener(this);
130
        combo.addDisposeListener(this);
131
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
132

    
133
        if (selection != null) {
134
            setSelection(selection);
135
        }
136
	}
137

    
138
	/**
139
	 * <p>
140
	 * Getter for the field <code>selection</code>.
141
	 * </p>
142
	 *
143
	 * @return a T object.
144
	 */
145
	public T getSelection() {
146
		return selection;
147
	}
148

    
149
	/**
150
	 * <p>Sets the selection of the combo to the given T object.</p>
151
	 * <p>Passing <code>null</code> to this method will set the selection to
152
	 * the empty element and effectively clear the selection</p>
153
	 *
154
	 * @param selection
155
	 *            a T object or <code>null</code> to clear the selection
156
	 */
157
	public void setSelection(T selection) {
158
		this.selection = selection;
159

    
160
		Listener[] listeners = combo.getListeners(SWT.Selection);
161

    
162
		for (Listener listener : listeners) {
163
			combo.removeListener(SWT.Selection, listener);
164
		}
165
		int selectedIndex;
166
		if(selection == null){
167
			// set selection to the emptyElement
168
			selectedIndex = 0;
169
		}else{
170
			selectedIndex = terms.indexOf(selection);
171
			if (selectedIndex == -1) {
172
				createTermNotInPreferredTerms(selection);
173
				selectedIndex = terms.indexOf(selection);
174
			}
175
		}
176
		combo.select(selectedIndex);
177

    
178
		for (Listener listener : listeners) {
179
			combo.addListener(SWT.Selection, listener);
180
		}
181
	}
182

    
183
	/**
184
	 * Fills the combo with elements and sets up the convenience functions
185
	 * for selection index
186
	 *
187
	 * @param preferredTerms
188
	 */
189
	private void populateTerms(List<T> preferredTerms) {
190

    
191
		combo.removeAll();
192

    
193
		terms = new ArrayList<T>();
194

    
195
		int i = 1;
196
		int index = 0;
197

    
198
		if(addEmptyElement){
199
		    // Add an empty element for when nothing was selected yet
200
		    combo.add(EMPTY_ELEMENT_LABEL);
201
		    terms.add(emptyElement);
202
		}
203

    
204
		if (termComparator != null) {
205
			Collections.sort(preferredTerms, termComparator);
206
		}
207
		for (T term : preferredTerms) {
208
			String label = getLabel(term);
209
			if (label == null) {
210
				if (term.getTitleCache() != null) {
211
					label = term.getTitleCache();
212
					MessagingUtils.warn(getClass(),
213
							"Term does not have a default language representation: " + label
214
									+ ", " + term.getUuid());
215
				} else {
216
					label = "Unknown";
217
					MessagingUtils.warn(getClass(),
218
							"Representation Label and TitleCache empty for term: "
219
									+ term + ", " + term.getUuid());
220
				}
221

    
222
			}
223

    
224
			combo.add(label);
225
			terms.add(term);
226

    
227
			i++;
228
			if (selection != null) {
229
				if (selection.equals(term)) {
230
					index = i;
231
				}
232
			}
233
		}
234

    
235
		if (selection != null && index == 0) {
236
			createTermNotInPreferredTerms(selection);
237
		}
238

    
239
		combo.select(index);
240
	}
241

    
242
	/*
243
	 * (non-Javadoc)
244
	 * @see eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
245
	 */
246
	/** {@inheritDoc} */
247
	@Override
248
    public void setEnabled(boolean enabled) {
249
		combo.setEnabled(enabled);
250
	}
251

    
252
	/* (non-Javadoc)
253
	 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
254
	 */
255
	@Override
256
	public boolean isEnabled() {
257
	    return combo.isEnabled();
258
	}
259

    
260
	/**
261
	 * <p>
262
	 * preferredTerms
263
	 * </p>
264
	 *
265
	 * @return a {@link java.util.List} object.
266
	 */
267
	protected List<T> getPreferredTerms(){
268
		if (customPreferredTerms != null){
269
			return customPreferredTerms;
270
		}
271
		return getTermManager().getPreferredTerms(termClass);
272
	}
273

    
274
	/**
275
	 * May be overridden by derived classes if the desired label string does not
276
	 * reside in term.getLabel();
277
	 *
278
	 * @param term
279
	 *            a T object.
280
	 * @return a {@link java.lang.String} object.
281
	 */
282
	protected String getLabel(T term) {
283
		if (term == null){
284
			return "";
285
		}else{
286
			String termLabel = term.getLabel(CdmStore.getDefaultLanguage());
287
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
288
			    && term.getVocabulary()!=null){
289
			    termLabel += " ["+term.getVocabulary().getLabel(CdmStore.getDefaultLanguage())+"]";
290
			}
291
            return termLabel;
292
		}
293
	}
294

    
295
	/**
296
	 *
297
	 *
298
	 * @param term
299
	 */
300
	private void createTermNotInPreferredTerms(T term) {
301
		List<T> preferredTerms = getPreferredTerms();
302

    
303
		preferredTerms.add(term);
304

    
305
		populateTerms(preferredTerms);
306
	}
307

    
308
	/**
309
	 * <p>
310
	 * addSelectionListener
311
	 * </p>
312
	 *
313
	 * @param listener
314
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
315
	 */
316
	public void addSelectionListener(SelectionListener listener) {
317
		combo.addSelectionListener(listener);
318
	}
319

    
320
	/**
321
	 * <p>
322
	 * removeSelectionListener
323
	 * </p>
324
	 *
325
	 * @param listener
326
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
327
	 */
328
	public void removeSelectionListener(SelectionListener listener) {
329
		combo.removeSelectionListener(listener);
330
	}
331

    
332
	/*
333
	 * (non-Javadoc)
334
	 *
335
	 * @see
336
	 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
337
	 * .events.SelectionEvent)
338
	 */
339
	/** {@inheritDoc} */
340
	@Override
341
    public void widgetSelected(SelectionEvent e) {
342
		selection = terms.get(combo.getSelectionIndex());
343
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
344
	}
345

    
346
	/*
347
	 * (non-Javadoc)
348
	 *
349
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
350
	 * PropertyChangeEvent)
351
	 */
352
	/** {@inheritDoc} */
353
	@Override
354
    public void propertyChange(PropertyChangeEvent event) {
355
		super.propertyChange(event);
356
		if (event != null
357
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
358
						.getProperty())) {
359
			populateTerms(getPreferredTerms());
360
		}
361
	}
362

    
363
	/** {@inheritDoc} */
364
	@Override
365
    public void setSelected(boolean selected) {
366
		setBackground(selected ? SELECTED : getPersistentBackground());
367
	}
368

    
369
	/** {@inheritDoc} */
370
	@Override
371
    public void widgetDisposed(DisposeEvent e) {
372
		PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
373
	}
374

    
375
	// not used
376
	/** {@inheritDoc} */
377
	@Override
378
    public void widgetDefaultSelected(SelectionEvent e) {
379
	}
380

    
381
	/** {@inheritDoc} */
382
	@Override
383
    public void setIrrelevant(boolean irrelevant) {
384
		String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
385
				: Resources.COLOR_COMPOSITE_BACKGROUND;
386

    
387
		Color color = StoreUtil.getColor(colorId);
388
		combo.setBackground(color);
389
	}
390

    
391
	/** {@inheritDoc} */
392
	@Override
393
	public void setBackground(Color color) {
394
		if (label != null) {
395
            label.setBackground(color);
396
        }
397
	}
398

    
399
	/**
400
	 *
401
	 */
402
	protected TermManager getTermManager() {
403
		return CdmStore.getTermManager();
404
	}
405

    
406
	/**
407
	 *
408
	 * @return
409
	 */
410
	public int getVisibleItemCount(){
411
		return combo.getVisibleItemCount();
412
	}
413

    
414
	/**
415
	 *
416
	 * @param count
417
	 */
418
	public void setVisibleItemCount(int count){
419
		combo.setVisibleItemCount(count);
420
	}
421

    
422
	/**
423
	 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
424
	 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
425
	 * given terms. Also, any previous selection will be reseted.</p>
426
	 *
427
	 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
428
	 *
429
	 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
430
	 */
431
	public void setTerms(List<T> terms) {
432
		setSelection(null);
433
		customPreferredTerms = terms;
434
		populateTerms(customPreferredTerms);
435
	}
436

    
437
	public void removeEmptyElement(){
438
	    if(addEmptyElement){
439
	        if(terms.contains(emptyElement)){
440
	            terms.remove(emptyElement);
441
	        }
442
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
443
	            combo.remove(EMPTY_ELEMENT_LABEL);
444
	        }
445
	    }
446
	}
447
}
(2-2/3)