Project

General

Profile

Download (10.4 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.apache.commons.lang.StringUtils;
13
import org.eclipse.jface.util.PropertyChangeEvent;
14
import org.eclipse.swt.SWT;
15
import org.eclipse.swt.events.SelectionEvent;
16
import org.eclipse.swt.widgets.Listener;
17

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

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

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

    
42
	private ArrayList<T> terms;
43

    
44
	private Comparator<T> termComparator;
45

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

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

    
54
		populateTerms(termsWithoutNull);
55

    
56
	}
57

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

    
62
	private List<T> customPreferredTerms;
63

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

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

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

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

    
89
    }
90

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

    
96
    }
97

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

    
103
        this.termType = termType;
104
        this.termVocabulary = termVocabulary;
105
        this.termClass = termClass;
106
        this.addEmptyElement = addEmptyElement;
107
        this.useAbbrevLabel = useAbbrevLabel;
108
        this.termComparator = comparator;
109
        if (labelString != null) {
110
            label.setText(labelString);
111
        }
112

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

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

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

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

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

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

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

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

    
178
		combo.removeAll();
179

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

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

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

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

    
209
			}
210

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

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

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

    
226
		combo.select(index);
227

    
228
	}
229

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

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

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

    
291
		preferredTerms.add(term);
292

    
293
		populateTerms(preferredTerms);
294
	}
295

    
296
	/** {@inheritDoc} */
297
	@Override
298
    public void widgetSelected(SelectionEvent e) {
299
		selection = terms.get(combo.getSelectionIndex());
300
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
301
	}
302

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

    
314
	protected TermManager getTermManager() {
315
		return CdmStore.getTermManager();
316
	}
317

    
318
	public int getVisibleItemCount(){
319
		return combo.getVisibleItemCount();
320
	}
321

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

    
337
	public void removeEmptyElement(){
338
	    if(addEmptyElement){
339
	        if(terms.contains(emptyElement)){
340
	            terms.remove(emptyElement);
341
	        }
342
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
343
	            combo.remove(EMPTY_ELEMENT_LABEL);
344
	        }
345
	    }
346
	}
347

    
348
}
(7-7/11)