Project

General

Profile

Download (12.2 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.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.IPreferenceKeys;
28
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
29
import eu.etaxonomy.taxeditor.preference.Resources;
30
import eu.etaxonomy.taxeditor.store.CdmStore;
31
import eu.etaxonomy.taxeditor.store.StoreUtil;
32
import eu.etaxonomy.taxeditor.store.TermManager;
33
import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
34
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
35
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
36
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
37
import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
38
import eu.etaxonomy.taxeditor.ui.element.ISelectable;
39
import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
40

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

    
55
	private static final int DEFAULT_VISIBLE_ITEMS = 10;
56

    
57
	private T selection;
58

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

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

    
65
	private ArrayList<T> terms;
66

    
67
	private Comparator<T> termComparator;
68

    
69
	private final TermType termType;
70
	private final TermVocabulary termVocabulary;
71
	private final Class<T> termClass;
72

    
73
	private List<T> customPreferredTerms;
74

    
75
	private boolean addEmptyElement;
76

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

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

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

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

    
100
        this.termType = termType;
101
        this.termVocabulary = termVocabulary;
102
        this.termClass = termClass;
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
		Listener[] listeners = combo.getListeners(SWT.Selection);
159

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

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

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

    
189
		combo.removeAll();
190

    
191
		terms = new ArrayList<T>();
192

    
193
		int i = 1;
194
		int index = 0;
195

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

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

    
220
			}
221

    
222
			combo.add(label);
223
			terms.add(term);
224

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

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

    
237
		combo.select(index);
238
	}
239

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

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

    
258
	/**
259
	 * <p>
260
	 * preferredTerms
261
	 * </p>
262
	 *
263
	 * @return a {@link java.util.List} object.
264
	 */
265
	protected List<T> getPreferredTerms(){
266
	    List<T> preferredTerms = new ArrayList<T>();
267
		if (customPreferredTerms != null){
268
			return customPreferredTerms;
269
		}
270
		else if(termType!=null){
271
		    preferredTerms = getTermManager().getPreferredTerms(termType);
272
		}
273
		else if(termVocabulary!=null){
274
		    preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
275
		}
276
		if(termClass!=null){
277
		    preferredTerms = getTermManager().getPreferredTerms(termClass);
278
		}
279
		return preferredTerms;
280
	}
281

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

    
303
	/**
304
	 *
305
	 *
306
	 * @param term
307
	 */
308
	private void createTermNotInPreferredTerms(T term) {
309
		List<T> preferredTerms = getPreferredTerms();
310

    
311
		preferredTerms.add(term);
312

    
313
		populateTerms(preferredTerms);
314
	}
315

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

    
328
	/**
329
	 * <p>
330
	 * removeSelectionListener
331
	 * </p>
332
	 *
333
	 * @param listener
334
	 *            a {@link org.eclipse.swt.events.SelectionListener} object.
335
	 */
336
	public void removeSelectionListener(SelectionListener listener) {
337
		combo.removeSelectionListener(listener);
338
	}
339

    
340
	/*
341
	 * (non-Javadoc)
342
	 *
343
	 * @see
344
	 * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
345
	 * .events.SelectionEvent)
346
	 */
347
	/** {@inheritDoc} */
348
	@Override
349
    public void widgetSelected(SelectionEvent e) {
350
		selection = terms.get(combo.getSelectionIndex());
351
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
352
	}
353

    
354
	/*
355
	 * (non-Javadoc)
356
	 *
357
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
358
	 * PropertyChangeEvent)
359
	 */
360
	/** {@inheritDoc} */
361
	@Override
362
    public void propertyChange(PropertyChangeEvent event) {
363
		super.propertyChange(event);
364
		if (event != null
365
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
366
						.getProperty())) {
367
			populateTerms(getPreferredTerms());
368
		}
369
	}
370

    
371
	/** {@inheritDoc} */
372
	@Override
373
    public void setSelected(boolean selected) {
374
		setBackground(selected ? SELECTED : getPersistentBackground());
375
	}
376

    
377
	/** {@inheritDoc} */
378
	@Override
379
    public void widgetDisposed(DisposeEvent e) {
380
		PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
381
	}
382

    
383
	// not used
384
	/** {@inheritDoc} */
385
	@Override
386
    public void widgetDefaultSelected(SelectionEvent e) {
387
	}
388

    
389
	/** {@inheritDoc} */
390
	@Override
391
    public void setIrrelevant(boolean irrelevant) {
392
		String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
393
				: Resources.COLOR_COMPOSITE_BACKGROUND;
394

    
395
		Color color = StoreUtil.getColor(colorId);
396
		combo.setBackground(color);
397
	}
398

    
399
	/** {@inheritDoc} */
400
	@Override
401
	public void setBackground(Color color) {
402
		if (label != null) {
403
            label.setBackground(color);
404
        }
405
	}
406

    
407
	/**
408
	 *
409
	 */
410
	protected TermManager getTermManager() {
411
		return CdmStore.getTermManager();
412
	}
413

    
414
	/**
415
	 *
416
	 * @return
417
	 */
418
	public int getVisibleItemCount(){
419
		return combo.getVisibleItemCount();
420
	}
421

    
422
	/**
423
	 *
424
	 * @param count
425
	 */
426
	public void setVisibleItemCount(int count){
427
		combo.setVisibleItemCount(count);
428
	}
429

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

    
445
	public void removeEmptyElement(){
446
	    if(addEmptyElement){
447
	        if(terms.contains(emptyElement)){
448
	            terms.remove(emptyElement);
449
	        }
450
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
451
	            combo.remove(EMPTY_ELEMENT_LABEL);
452
	        }
453
	    }
454
	}
455
}
(2-2/3)