Project

General

Profile

Download (11.3 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.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.DefinedTerm;
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 <T>
49
 */
50
public class TermComboElement<T extends DefinedTermBase>
51
		extends AbstractCdmFormElement implements SelectionListener,
52
		DisposeListener, IEnableableFormElement, ISelectable {
53

    
54
	private static final int DEFAULT_VISIBLE_ITEMS = 10;
55

    
56
	private T selection;
57

    
58
	private T emptyElement;
59
	private static String EMPTY_ELEMENT_LABEL = "";
60

    
61
	protected Label label;
62
	private final Combo combo;
63

    
64
	private ArrayList<T> terms;
65

    
66
	private Comparator<T> termComparator;
67

    
68
	private final Class<T> termClass;
69

    
70
	private List<T> customPreferredTerms;
71

    
72
	private boolean addEmptyElement;
73

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

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

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

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

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

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

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

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

    
127
        combo.addSelectionListener(this);
128
        combo.addDisposeListener(this);
129
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
130

    
131
        if (selection != null) {
132
            setSelection(selection);
133
        }
134
	}
135

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

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

    
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
			return term.getLabel(CdmStore.getDefaultLanguage());
287
		}
288
	}
289

    
290
	/**
291
	 *
292
	 *
293
	 * @param term
294
	 */
295
	private void createTermNotInPreferredTerms(T term) {
296
		List<T> preferredTerms = getPreferredTerms();
297

    
298
		preferredTerms.add(term);
299

    
300
		populateTerms(preferredTerms);
301
	}
302

    
303
	/**
304
	 * <p>
305
	 * addSelectionListener
306
	 * </p>
307
	 *
308
	 * @param listener
309
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
310
	 */
311
	public void addSelectionListener(SelectionListener listener) {
312
		combo.addSelectionListener(listener);
313
	}
314

    
315
	/**
316
	 * <p>
317
	 * removeSelectionListener
318
	 * </p>
319
	 *
320
	 * @param listener
321
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
322
	 */
323
	public void removeSelectionListener(SelectionListener listener) {
324
		combo.removeSelectionListener(listener);
325
	}
326

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

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

    
358
	/** {@inheritDoc} */
359
	@Override
360
    public void setSelected(boolean selected) {
361
		setBackground(selected ? SELECTED : getPersistentBackground());
362
	}
363

    
364
	/** {@inheritDoc} */
365
	@Override
366
    public void widgetDisposed(DisposeEvent e) {
367
		PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
368
	}
369

    
370
	// not used
371
	/** {@inheritDoc} */
372
	@Override
373
    public void widgetDefaultSelected(SelectionEvent e) {
374
	}
375

    
376
	/** {@inheritDoc} */
377
	@Override
378
    public void setIrrelevant(boolean irrelevant) {
379
		String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
380
				: Resources.COLOR_COMPOSITE_BACKGROUND;
381

    
382
		Color color = StoreUtil.getColor(colorId);
383
		combo.setBackground(color);
384
	}
385

    
386
	/** {@inheritDoc} */
387
	@Override
388
	public void setBackground(Color color) {
389
		if (label != null) {
390
            label.setBackground(color);
391
        }
392
	}
393

    
394
	/**
395
	 *
396
	 */
397
	protected TermManager getTermManager() {
398
		return CdmStore.getTermManager();
399
	}
400

    
401
	/**
402
	 *
403
	 * @return
404
	 */
405
	public int getVisibleItemCount(){
406
		return combo.getVisibleItemCount();
407
	}
408

    
409
	/**
410
	 *
411
	 * @param count
412
	 */
413
	public void setVisibleItemCount(int count){
414
		combo.setVisibleItemCount(count);
415
	}
416

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

    
432
}
(2-2/3)