Project

General

Profile

Download (10.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 *
3
 */
4
package eu.etaxonomy.taxeditor.ui.combo.term;
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.combo.AbstractComboElement;
27
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
28
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
29
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
30

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

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

    
43
	private ArrayList<T> terms;
44

    
45
	public ArrayList<T> getTerms() {
46
        return terms;
47
    }
48

    
49
    private Comparator<T> termComparator;
50

    
51
	public Comparator<T> getTermComparator() {
52
		return termComparator;
53
	}
54

    
55
	public void setTermComparator(Comparator<T> termComparator) {
56
		this.termComparator = termComparator;
57
		List<T> termsWithoutNull = terms.subList(1, terms.size());
58

    
59
		populateTerms(termsWithoutNull);
60

    
61
	}
62

    
63
	private final TermType termType;
64
	private final TermVocabulary termVocabulary;
65
	private final Class<T> termClass;
66

    
67
	private List<T> customPreferredTerms;
68

    
69
	private boolean useAbbrevLabel = false;
70
	private boolean addEmptyElement;
71

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

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

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

    
94
    }
95

    
96
    public TermComboElement(CdmFormFactory formFactory,
97
            ICdmFormElement parentElement, List<T> terms, String labelString, T selection, boolean addEmptyElement,
98
            int style, boolean useAbbrevLabel) {
99
        this(formFactory, parentElement, null, null, null, terms,labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
100

    
101
    }
102

    
103
	private TermComboElement(CdmFormFactory formFactory,
104
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, List<T> terms,String labelString, T selection, boolean addEmptyElement,
105
	        int style, boolean useAbbrevLabel, Comparator<T> comparator) {
106
        super(formFactory, parentElement);
107

    
108
        this.termType = termType;
109
        this.termVocabulary = termVocabulary;
110
        this.termClass = termClass;
111
        this.addEmptyElement = addEmptyElement;
112
        this.useAbbrevLabel = useAbbrevLabel;
113
        this.termComparator = comparator;
114
        if (labelString != null) {
115
            label.setText(labelString);
116
        }
117
        this.selection = selection;
118

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

    
132

    
133
        addContentProposalAdapter();
134
        combo.addSelectionListener(this);
135
        combo.addDisposeListener(this);
136

    
137
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
138

    
139
        if (selection != null) {
140
            setSelection(selection);
141
        }
142
	}
143

    
144
	/**
145
	 * <p>Sets the selection of the combo to the given T object.</p>
146
	 * <p>Passing <code>null</code> to this method will set the selection to
147
	 * the empty element and effectively clear the selection</p>
148
	 *
149
	 * @param selection
150
	 *            a T object or <code>null</code> to clear the selection
151
	 */
152
	@Override
153
    public void setSelection(T selection) {
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, this.terms);
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
	protected 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
		if(addEmptyElement){
195
		    // Add an empty element for when nothing was selected yet
196
		    combo.add(EMPTY_ELEMENT_LABEL);
197
		    terms.add(emptyElement);
198
		}
199

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

    
218
			}
219

    
220
			combo.add(label);
221
			combo.setData(label, term);
222
			terms.add(term);
223

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

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

    
236
		combo.select(index);
237

    
238
	}
239

    
240
	protected List<T> getPreferredTerms(){
241
	    List<T> preferredTerms = new ArrayList<T>();
242
		if (customPreferredTerms != null){
243
			return customPreferredTerms;
244
		}
245
		else if(termType!=null){
246
		    preferredTerms = getTermManager().getPreferredTerms(termType);
247
		}
248
		else if(termVocabulary!=null){
249
		    preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
250
		}
251
		if(termClass!=null){
252
		    preferredTerms = getTermManager().getPreferredTerms(termClass);
253
		}
254
		return preferredTerms;
255
	}
256

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

    
293
	/**
294
	 *
295
	 *
296
	 * @param term
297
	 */
298
	private void createTermNotInPreferredTerms(T term, List<T> preferredTerms) {
299
		//List<T> preferredTerms = getPreferredTerms();
300

    
301
		preferredTerms.add(term);
302

    
303
		populateTerms(preferredTerms);
304
	}
305

    
306
	/** {@inheritDoc} */
307
	@Override
308
    public void widgetSelected(SelectionEvent e) {
309
	    if (e.getSource().equals(combo) && combo.getSelectionIndex() >= 0){
310
	        selection = terms.get(combo.getSelectionIndex());
311
	    }
312
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
313
	}
314

    
315
	/** {@inheritDoc} */
316
	@Override
317
    public void propertyChange(PropertyChangeEvent event) {
318
		super.propertyChange(event);
319
		T selection = this.selection;
320
		if (event != null
321
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
322
						.getProperty())) {
323
			populateTerms(getPreferredTerms());
324
		}
325
		this.setSelection(selection);
326
	}
327

    
328
	protected TermManager getTermManager() {
329
		return CdmStore.getTermManager();
330
	}
331

    
332
	public int getVisibleItemCount(){
333
		return combo.getVisibleItemCount();
334
	}
335

    
336
	/**
337
	 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
338
	 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
339
	 * given terms. Also, any previous selection will be reseted.</p>
340
	 *
341
	 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
342
	 *
343
	 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
344
	 */
345
	public void setTerms(List<T> terms) {
346
		setSelection(null);
347
		customPreferredTerms = terms;
348
		populateTerms(customPreferredTerms);
349
	}
350

    
351
	public void removeEmptyElement(){
352
	    if(addEmptyElement){
353
	        if(terms.contains(emptyElement)){
354
	            terms.remove(emptyElement);
355
	        }
356
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
357
	            combo.remove(EMPTY_ELEMENT_LABEL);
358
	        }
359
	    }
360
	}
361

    
362
}
(1-1/4)