Project

General

Profile

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

    
53
	private static final int DEFAULT_VISIBLE_ITEMS = 10;
54

    
55
	private T selection;
56

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

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

    
63
	private ArrayList<T> terms;
64

    
65
	private Comparator<T> termComparator;
66

    
67
	private final Class<T> termClass;
68

    
69
	private List<T> customPreferredTerms;
70

    
71
	public TermComboElement(CdmFormFactory formFactory,
72
			ICdmFormElement parentElement, TermType termType, String labelString, T selection,
73
			int style) {
74
		this(formFactory, parentElement, null, termType, null, labelString, selection, style);
75
	}
76

    
77
	public TermComboElement(CdmFormFactory formFactory,
78
	        ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection,
79
	        int style) {
80
	    this(formFactory, parentElement, null, null, termVocabulary, labelString, selection, style);
81
	}
82

    
83
    public TermComboElement(CdmFormFactory formFactory,
84
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection,
85
            int style) {
86
        this(formFactory, parentElement, termClass, null, null, labelString, selection, style);
87
    }
88

    
89
	private TermComboElement(CdmFormFactory formFactory,
90
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection,
91
	        int style) {
92
        super(formFactory, parentElement);
93

    
94
        if(termClass!=null){
95
            this.termClass = termClass;
96
        }
97
        else{
98
            this.termClass =  (Class<T>) DefinedTerm.class;
99
        }
100

    
101
        if (labelString != null) {
102
            label = formFactory.createLabel(getLayoutComposite(), labelString);
103
            addControl(label);
104
        }
105

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

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

    
123
        combo.addSelectionListener(this);
124
        combo.addDisposeListener(this);
125
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
126

    
127
        if (selection != null) {
128
            setSelection(selection);
129
        }
130
	}
131

    
132
	/**
133
	 * <p>
134
	 * Getter for the field <code>selection</code>.
135
	 * </p>
136
	 *
137
	 * @return a T object.
138
	 */
139
	public T getSelection() {
140
		return selection;
141
	}
142

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

    
154
		this.selection = selection;
155

    
156
		Listener[] listeners = combo.getListeners(SWT.Selection);
157

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

    
174
		for (Listener listener : listeners) {
175
			combo.addListener(SWT.Selection, listener);
176
		}
177
	}
178

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

    
187
		combo.removeAll();
188

    
189
		terms = new ArrayList<T>();
190

    
191
		int i = 1;
192
		int index = 0;
193

    
194
		// Add an empty element for when nothing was selected yet
195
		combo.add(EMPTY_ELEMENT_LABEL);
196
		terms.add(emptyElement);
197

    
198
		if (termComparator != null) {
199
			Collections.sort(preferredTerms, termComparator);
200
		}
201
		for (T term : preferredTerms) {
202
			String label = getLabel(term);
203
			if (label == null) {
204
				if (term.getTitleCache() != null) {
205
					label = term.getTitleCache();
206
					StoreUtil.warn(getClass(),
207
							"Term does not have a default language representation: " + label
208
									+ ", " + term.getUuid());
209
				} else {
210
					label = "Unknown";
211
					StoreUtil.warn(getClass(),
212
							"Representation Label and TitleCache empty for term: "
213
									+ term + ", " + term.getUuid());
214
				}
215

    
216
			}
217

    
218
			combo.add(label);
219
			terms.add(term);
220

    
221
			i++;
222
			if (selection != null) {
223
				if (selection.equals(term)) {
224
					index = i;
225
				}
226
			}
227
		}
228

    
229
		if (selection != null && index == 0) {
230
			createTermNotInPreferredTerms(selection);
231
		}
232

    
233
		combo.select(index);
234
	}
235

    
236
	/*
237
	 * (non-Javadoc)
238
	 * @see eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
239
	 */
240
	/** {@inheritDoc} */
241
	@Override
242
    public void setEnabled(boolean enabled) {
243
		combo.setEnabled(enabled);
244
	}
245

    
246
	/* (non-Javadoc)
247
	 * @see eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement#isEnabled()
248
	 */
249
	@Override
250
	public boolean isEnabled() {
251
	    return combo.isEnabled();
252
	}
253

    
254
	/**
255
	 * <p>
256
	 * preferredTerms
257
	 * </p>
258
	 *
259
	 * @return a {@link java.util.List} object.
260
	 */
261
	protected List<T> getPreferredTerms(){
262
		if (customPreferredTerms != null){
263
			return customPreferredTerms;
264
		}
265
		return getTermManager().getPreferredTerms(termClass);
266
	}
267

    
268
	/**
269
	 * May be overridden by derived classes if the desired label string does not
270
	 * reside in term.getLabel();
271
	 *
272
	 * @param term
273
	 *            a T object.
274
	 * @return a {@link java.lang.String} object.
275
	 */
276
	protected String getLabel(T term) {
277
		if (term == null){
278
			return "";
279
		}else{
280
			return term.getLabel(CdmStore.getDefaultLanguage());
281
		}
282
	}
283

    
284
	/**
285
	 *
286
	 *
287
	 * @param term
288
	 */
289
	private void createTermNotInPreferredTerms(T term) {
290
		List<T> preferredTerms = getPreferredTerms();
291

    
292
		preferredTerms.add(term);
293

    
294
		populateTerms(preferredTerms);
295
	}
296

    
297
	/**
298
	 * <p>
299
	 * addSelectionListener
300
	 * </p>
301
	 *
302
	 * @param listener
303
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
304
	 */
305
	public void addSelectionListener(SelectionListener listener) {
306
		combo.addSelectionListener(listener);
307
	}
308

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

    
321
	/*
322
	 * (non-Javadoc)
323
	 *
324
	 * @see
325
	 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
326
	 * .events.SelectionEvent)
327
	 */
328
	/** {@inheritDoc} */
329
	@Override
330
    public void widgetSelected(SelectionEvent e) {
331
		selection = terms.get(combo.getSelectionIndex());
332
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
333
	}
334

    
335
	/*
336
	 * (non-Javadoc)
337
	 *
338
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
339
	 * PropertyChangeEvent)
340
	 */
341
	/** {@inheritDoc} */
342
	@Override
343
    public void propertyChange(PropertyChangeEvent event) {
344
		super.propertyChange(event);
345
		if (event != null
346
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
347
						.getProperty())) {
348
			populateTerms(getPreferredTerms());
349
		}
350
	}
351

    
352
	/** {@inheritDoc} */
353
	@Override
354
    public void setSelected(boolean selected) {
355
		setBackground(selected ? SELECTED : getPersistentBackground());
356
	}
357

    
358
	/** {@inheritDoc} */
359
	@Override
360
    public void widgetDisposed(DisposeEvent e) {
361
		PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
362
	}
363

    
364
	// not used
365
	/** {@inheritDoc} */
366
	@Override
367
    public void widgetDefaultSelected(SelectionEvent e) {
368
	}
369

    
370
	/** {@inheritDoc} */
371
	@Override
372
    public void setIrrelevant(boolean irrelevant) {
373
		String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
374
				: Resources.COLOR_COMPOSITE_BACKGROUND;
375

    
376
		Color color = StoreUtil.getColor(colorId);
377
		combo.setBackground(color);
378
	}
379

    
380
	/** {@inheritDoc} */
381
	@Override
382
	public void setBackground(Color color) {
383
		if (label != null) {
384
            label.setBackground(color);
385
        }
386
	}
387

    
388
	/**
389
	 *
390
	 */
391
	protected TermManager getTermManager() {
392
		return CdmStore.getTermManager();
393
	}
394

    
395
	/**
396
	 *
397
	 * @return
398
	 */
399
	public int getVisibleItemCount(){
400
		return combo.getVisibleItemCount();
401
	}
402

    
403
	/**
404
	 *
405
	 * @param count
406
	 */
407
	public void setVisibleItemCount(int count){
408
		combo.setVisibleItemCount(count);
409
	}
410

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

    
426
}
(2-2/2)