Project

General

Profile

Download (10.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.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.SelectionEvent;
15
import org.eclipse.swt.widgets.Listener;
16

    
17
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
18
import eu.etaxonomy.cdm.model.term.TermType;
19
import eu.etaxonomy.cdm.model.term.TermVocabulary;
20
import eu.etaxonomy.taxeditor.model.MessagingUtils;
21
import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
22
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
23
import eu.etaxonomy.taxeditor.store.CdmStore;
24
import eu.etaxonomy.taxeditor.store.TermManager;
25
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
26
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
27
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
28

    
29
/**
30
 * @author n.hoffmann
31
 * @created Nov 5, 2009
32
 * @version 1.0
33
 * @param <T>
34
 */
35
public class TermComboElement<T extends DefinedTermBase>
36
		extends AbstractComboElement<T> {
37

    
38
	private T emptyElement;
39
	private static String EMPTY_ELEMENT_LABEL = "";
40

    
41
	private ArrayList<T> terms;
42

    
43
	private Comparator<T> termComparator;
44

    
45
	public Comparator<T> getTermComparator() {
46
		return termComparator;
47
	}
48

    
49
	public void setTermComparator(Comparator<T> termComparator) {
50
		this.termComparator = termComparator;
51
		List<T> termsWithoutNull = terms.subList(1, terms.size());
52

    
53
		populateTerms(termsWithoutNull);
54

    
55
	}
56

    
57
	private final TermType termType;
58
	private final TermVocabulary termVocabulary;
59
	private final Class<T> termClass;
60

    
61
	private List<T> customPreferredTerms;
62

    
63
	private boolean useAbbrevLabel = false;
64
	private boolean addEmptyElement;
65

    
66
	public TermComboElement(CdmFormFactory formFactory,
67
			ICdmFormElement parentElement, TermType termType, String labelString, T selection, boolean addEmptyElement,
68
			int style, boolean useAbbrevLabel, Comparator<T> comparator) {
69
		this(formFactory, parentElement, null, termType, null, null, labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
70
	}
71

    
72
	public TermComboElement(CdmFormFactory formFactory,
73
	        ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
74
	        int style, boolean useAbbrevLabel, Comparator<T> comparator) {
75
	    this(formFactory, parentElement, null, null, termVocabulary, null,labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
76
	}
77

    
78
    public TermComboElement(CdmFormFactory formFactory,
79
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
80
            int style) {
81
        this(formFactory, parentElement, termClass, null, null, null, labelString, selection, addEmptyElement, style, false, null);
82
    }
83
    public TermComboElement(CdmFormFactory formFactory,
84
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
85
            int style, boolean useAbbrevLabel) {
86
        this(formFactory, parentElement, termClass, null, null, null,labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
87

    
88
    }
89

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

    
95
    }
96

    
97
	private TermComboElement(CdmFormFactory formFactory,
98
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, List<T> terms,String labelString, T selection, boolean addEmptyElement,
99
	        int style, boolean useAbbrevLabel, Comparator<T> comparator) {
100
        super(formFactory, parentElement);
101

    
102
        this.termType = termType;
103
        this.termVocabulary = termVocabulary;
104
        this.termClass = termClass;
105
        this.addEmptyElement = addEmptyElement;
106
        this.useAbbrevLabel = useAbbrevLabel;
107
        this.termComparator = comparator;
108
        if (labelString != null) {
109
            label.setText(labelString);
110
        }
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
        }else if (terms != null){
122
            populateTerms(terms);
123
        }
124

    
125
        combo.addSelectionListener(this);
126
        combo.addDisposeListener(this);
127
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
128

    
129
        if (selection != null) {
130
            setSelection(selection);
131
        }
132
	}
133

    
134
	/**
135
	 * <p>Sets the selection of the combo to the given T object.</p>
136
	 * <p>Passing <code>null</code> to this method will set the selection to
137
	 * the empty element and effectively clear the selection</p>
138
	 *
139
	 * @param selection
140
	 *            a T object or <code>null</code> to clear the selection
141
	 */
142
	@Override
143
    public void setSelection(T selection) {
144
		this.selection = selection;
145

    
146
		Listener[] listeners = combo.getListeners(SWT.Selection);
147

    
148
		for (Listener listener : listeners) {
149
			combo.removeListener(SWT.Selection, listener);
150
		}
151
		int selectedIndex;
152
		if(selection == null){
153
			// set selection to the emptyElement
154
			selectedIndex = 0;
155
		}else{
156
			selectedIndex = terms.indexOf(selection);
157
			if (selectedIndex == -1) {
158
				createTermNotInPreferredTerms(selection);
159
				selectedIndex = terms.indexOf(selection);
160
			}
161
		}
162
		combo.select(selectedIndex);
163

    
164
		for (Listener listener : listeners) {
165
			combo.addListener(SWT.Selection, listener);
166
		}
167
	}
168

    
169
	/**
170
	 * Fills the combo with elements and sets up the convenience functions
171
	 * for selection index
172
	 *
173
	 * @param preferredTerms
174
	 */
175
	protected void populateTerms(List<T> preferredTerms) {
176

    
177
		combo.removeAll();
178

    
179
		terms = new ArrayList<T>();
180

    
181
		int i = 1;
182
		int index = 0;
183

    
184
		if(addEmptyElement){
185
		    // Add an empty element for when nothing was selected yet
186
		    combo.add(EMPTY_ELEMENT_LABEL);
187
		    terms.add(emptyElement);
188
		}
189

    
190
		if (termComparator != null) {
191
			Collections.sort(preferredTerms, termComparator);
192
		}
193
		for (T term : preferredTerms) {
194
			String label = getLabel(term);
195
			if (label == null) {
196
				if (term.getTitleCache() != null) {
197
					label = term.getTitleCache();
198
					MessagingUtils.warn(getClass(),
199
							"Term does not have a default language representation: " + label
200
									+ ", " + term.getUuid());
201
				} else {
202
					label = "Unknown";
203
					MessagingUtils.warn(getClass(),
204
							"Representation Label and TitleCache empty for term: "
205
									+ term + ", " + term.getUuid());
206
				}
207

    
208
			}
209

    
210
			combo.add(label);
211
			terms.add(term);
212

    
213
			i++;
214
			if (selection != null) {
215
				if (selection.equals(term)) {
216
					index = i;
217
				}
218
			}
219
		}
220

    
221
        if (selection != null && index == 0) {
222
			createTermNotInPreferredTerms(selection);
223
		}
224

    
225
		combo.select(index);
226

    
227
	}
228

    
229
	protected List<T> getPreferredTerms(){
230
	    List<T> preferredTerms = new ArrayList<T>();
231
		if (customPreferredTerms != null){
232
			return customPreferredTerms;
233
		}
234
		else if(termType!=null){
235
		    preferredTerms = getTermManager().getPreferredTerms(termType);
236
		}
237
		else if(termVocabulary!=null){
238
		    preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
239
		}
240
		if(termClass!=null){
241
		    preferredTerms = getTermManager().getPreferredTerms(termClass);
242
		}
243
		return preferredTerms;
244
	}
245

    
246
	/**
247
	 * May be overridden by derived classes if the desired label string does not
248
	 * reside in term.getLabel();
249
	 *
250
	 * @param term
251
	 *            a T object.
252
	 * @return a {@link java.lang.String} object.
253
	 */
254
	protected String getLabel(T term) {
255
		if (term == null){
256
			return "";
257
		}else{
258
			String termLabel = null;
259
			if (useAbbrevLabel){
260
				termLabel = term.getIdInVocabulary();
261
			}else{
262
				termLabel = term.getLabel(CdmStore.getDefaultLanguage());
263
			}
264
			if (termLabel == null){
265
			    termLabel = term.getLabel();
266
			}
267
			if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
268
			    && term.getVocabulary()!=null){
269
			    String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
270
			    if (vocLabel == null){
271
			        vocLabel = term.getVocabulary().getLabel();
272
			    }
273
			    termLabel += " ["+vocLabel+"]";
274
			}
275
            return termLabel;
276
		}
277
	}
278

    
279
	/**
280
	 *
281
	 *
282
	 * @param term
283
	 */
284
	private void createTermNotInPreferredTerms(T term) {
285
		List<T> preferredTerms = getPreferredTerms();
286

    
287
		preferredTerms.add(term);
288

    
289
		populateTerms(preferredTerms);
290
	}
291

    
292
	/** {@inheritDoc} */
293
	@Override
294
    public void widgetSelected(SelectionEvent e) {
295
		selection = terms.get(combo.getSelectionIndex());
296
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
297
	}
298

    
299
	/** {@inheritDoc} */
300
	@Override
301
    public void propertyChange(PropertyChangeEvent event) {
302
		super.propertyChange(event);
303
		if (event != null
304
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
305
						.getProperty())) {
306
			populateTerms(getPreferredTerms());
307
		}
308
	}
309

    
310
	protected TermManager getTermManager() {
311
		return CdmStore.getTermManager();
312
	}
313

    
314
	public int getVisibleItemCount(){
315
		return combo.getVisibleItemCount();
316
	}
317

    
318
	/**
319
	 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
320
	 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
321
	 * given terms. Also, any previous selection will be reseted.</p>
322
	 *
323
	 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
324
	 *
325
	 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
326
	 */
327
	public void setTerms(List<T> terms) {
328
		setSelection(null);
329
		customPreferredTerms = terms;
330
		populateTerms(customPreferredTerms);
331
	}
332

    
333
	public void removeEmptyElement(){
334
	    if(addEmptyElement){
335
	        if(terms.contains(emptyElement)){
336
	            terms.remove(emptyElement);
337
	        }
338
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
339
	            combo.remove(EMPTY_ELEMENT_LABEL);
340
	        }
341
	    }
342
	}
343

    
344
}
(7-7/11)