Project

General

Profile

Download (9.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.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.common.DefinedTermBase;
18
import eu.etaxonomy.cdm.model.common.TermType;
19
import eu.etaxonomy.cdm.model.common.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
	private final TermType termType;
46
	private final TermVocabulary termVocabulary;
47
	private final Class<T> termClass;
48

    
49
	private List<T> customPreferredTerms;
50

    
51
	private boolean useAbbrevLabel = false;
52
	private boolean addEmptyElement;
53

    
54
	public TermComboElement(CdmFormFactory formFactory,
55
			ICdmFormElement parentElement, TermType termType, String labelString, T selection, boolean addEmptyElement,
56
			int style, boolean useAbbrevLabel) {
57
		this(formFactory, parentElement, null, termType, null, labelString, selection, addEmptyElement, style, useAbbrevLabel);
58
	}
59

    
60
	public TermComboElement(CdmFormFactory formFactory,
61
	        ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
62
	        int style) {
63
	    this(formFactory, parentElement, null, null, termVocabulary, labelString, selection, addEmptyElement, style, false);
64
	}
65

    
66
    public TermComboElement(CdmFormFactory formFactory,
67
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
68
            int style) {
69
        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style, false);
70
    }
71
    public TermComboElement(CdmFormFactory formFactory,
72
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
73
            int style, boolean useAbbrevLabel) {
74
        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style, useAbbrevLabel);
75
       
76
    }
77

    
78
	private TermComboElement(CdmFormFactory formFactory,
79
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
80
	        int style, boolean useAbbrevLabel) {
81
        super(formFactory, parentElement);
82

    
83
        this.termType = termType;
84
        this.termVocabulary = termVocabulary;
85
        this.termClass = termClass;
86
        this.addEmptyElement = addEmptyElement;
87
        this.useAbbrevLabel = useAbbrevLabel;
88
        if (labelString != null) {
89
            label.setText(labelString);
90
        }
91

    
92
        if(termType!=null){
93
            //TODO try to remove generic T and avoid classes to be used
94
            populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
95
        }
96
        else if(termVocabulary!=null){
97
            populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
98
        }
99
        else if(this.termClass!=null){
100
            populateTerms(getPreferredTerms());
101
        }
102

    
103
        combo.addSelectionListener(this);
104
        combo.addDisposeListener(this);
105
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
106

    
107
        if (selection != null) {
108
            setSelection(selection);
109
        }
110
	}
111

    
112
	/**
113
	 * <p>Sets the selection of the combo to the given T object.</p>
114
	 * <p>Passing <code>null</code> to this method will set the selection to
115
	 * the empty element and effectively clear the selection</p>
116
	 *
117
	 * @param selection
118
	 *            a T object or <code>null</code> to clear the selection
119
	 */
120
	@Override
121
    public void setSelection(T selection) {
122
		this.selection = selection;
123

    
124
		Listener[] listeners = combo.getListeners(SWT.Selection);
125

    
126
		for (Listener listener : listeners) {
127
			combo.removeListener(SWT.Selection, listener);
128
		}
129
		int selectedIndex;
130
		if(selection == null){
131
			// set selection to the emptyElement
132
			selectedIndex = 0;
133
		}else{
134
			selectedIndex = terms.indexOf(selection);
135
			if (selectedIndex == -1) {
136
				createTermNotInPreferredTerms(selection);
137
				selectedIndex = terms.indexOf(selection);
138
			}
139
		}
140
		combo.select(selectedIndex);
141

    
142
		for (Listener listener : listeners) {
143
			combo.addListener(SWT.Selection, listener);
144
		}
145
	}
146

    
147
	/**
148
	 * Fills the combo with elements and sets up the convenience functions
149
	 * for selection index
150
	 *
151
	 * @param preferredTerms
152
	 */
153
	private void populateTerms(List<T> preferredTerms) {
154

    
155
		combo.removeAll();
156

    
157
		terms = new ArrayList<T>();
158

    
159
		int i = 1;
160
		int index = 0;
161

    
162
		if(addEmptyElement){
163
		    // Add an empty element for when nothing was selected yet
164
		    combo.add(EMPTY_ELEMENT_LABEL);
165
		    terms.add(emptyElement);
166
		}
167

    
168
		if (termComparator != null) {
169
			Collections.sort(preferredTerms, termComparator);
170
		}
171
		for (T term : preferredTerms) {
172
			String label = getLabel(term);
173
			if (label == null) {
174
				if (term.getTitleCache() != null) {
175
					label = term.getTitleCache();
176
					MessagingUtils.warn(getClass(),
177
							"Term does not have a default language representation: " + label
178
									+ ", " + term.getUuid());
179
				} else {
180
					label = "Unknown";
181
					MessagingUtils.warn(getClass(),
182
							"Representation Label and TitleCache empty for term: "
183
									+ term + ", " + term.getUuid());
184
				}
185

    
186
			}
187

    
188
			combo.add(label);
189
			terms.add(term);
190

    
191
			i++;
192
			if (selection != null) {
193
				if (selection.equals(term)) {
194
					index = i;
195
				}
196
			}
197
		}
198

    
199
		if (selection != null && index == 0) {
200
			createTermNotInPreferredTerms(selection);
201
		}
202

    
203
		combo.select(index);
204
	}
205

    
206
	protected List<T> getPreferredTerms(){
207
	    List<T> preferredTerms = new ArrayList<T>();
208
		if (customPreferredTerms != null){
209
			return customPreferredTerms;
210
		}
211
		else if(termType!=null){
212
		    preferredTerms = getTermManager().getPreferredTerms(termType);
213
		}
214
		else if(termVocabulary!=null){
215
		    preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
216
		}
217
		if(termClass!=null){
218
		    preferredTerms = getTermManager().getPreferredTerms(termClass);
219
		}
220
		return preferredTerms;
221
	}
222

    
223
	/**
224
	 * May be overridden by derived classes if the desired label string does not
225
	 * reside in term.getLabel();
226
	 *
227
	 * @param term
228
	 *            a T object.
229
	 * @return a {@link java.lang.String} object.
230
	 */
231
	protected String getLabel(T term) {
232
		if (term == null){
233
			return "";
234
		}else{
235
			String termLabel = null;
236
			if (useAbbrevLabel){
237
				termLabel = term.getIdInVocabulary();
238
			}else{
239
				termLabel = term.getLabel(CdmStore.getDefaultLanguage());
240
			}
241
			if (termLabel == null){
242
			    termLabel = term.getLabel();
243
			}
244
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
245
			    && term.getVocabulary()!=null){
246
			    String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
247
			    if (vocLabel == null){
248
			        vocLabel = term.getVocabulary().getLabel();
249
			    }
250
			    termLabel += " ["+vocLabel+"]";
251
			}
252
            return termLabel;
253
		}
254
	}
255

    
256
	/**
257
	 *
258
	 *
259
	 * @param term
260
	 */
261
	private void createTermNotInPreferredTerms(T term) {
262
		List<T> preferredTerms = getPreferredTerms();
263

    
264
		preferredTerms.add(term);
265

    
266
		populateTerms(preferredTerms);
267
	}
268

    
269
	/** {@inheritDoc} */
270
	@Override
271
    public void widgetSelected(SelectionEvent e) {
272
		selection = terms.get(combo.getSelectionIndex());
273
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
274
	}
275

    
276
	/** {@inheritDoc} */
277
	@Override
278
    public void propertyChange(PropertyChangeEvent event) {
279
		super.propertyChange(event);
280
		if (event != null
281
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
282
						.getProperty())) {
283
			populateTerms(getPreferredTerms());
284
		}
285
	}
286

    
287
	protected TermManager getTermManager() {
288
		return CdmStore.getTermManager();
289
	}
290

    
291
	public int getVisibleItemCount(){
292
		return combo.getVisibleItemCount();
293
	}
294

    
295
	/**
296
	 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
297
	 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
298
	 * given terms. Also, any previous selection will be reseted.</p>
299
	 *
300
	 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
301
	 *
302
	 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
303
	 */
304
	public void setTerms(List<T> terms) {
305
		setSelection(null);
306
		customPreferredTerms = terms;
307
		populateTerms(customPreferredTerms);
308
	}
309

    
310
	public void removeEmptyElement(){
311
	    if(addEmptyElement){
312
	        if(terms.contains(emptyElement)){
313
	            terms.remove(emptyElement);
314
	        }
315
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
316
	            combo.remove(EMPTY_ELEMENT_LABEL);
317
	        }
318
	    }
319
	}
320
}
(3-3/4)