Project

General

Profile

Download (8.78 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 addEmptyElement;
52

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

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

    
65
    public TermComboElement(CdmFormFactory formFactory,
66
            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
67
            int style) {
68
        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style);
69
    }
70

    
71
	private TermComboElement(CdmFormFactory formFactory,
72
	        ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
73
	        int style) {
74
        super(formFactory, parentElement);
75

    
76
        this.termType = termType;
77
        this.termVocabulary = termVocabulary;
78
        this.termClass = termClass;
79
        this.addEmptyElement = addEmptyElement;
80

    
81
        if (labelString != null) {
82
            label.setText(labelString);
83
        }
84

    
85
        if(termType!=null){
86
            //TODO try to remove generic T and avoid classes to be used
87
            populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
88
        }
89
        else if(termVocabulary!=null){
90
            populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
91
        }
92
        else if(this.termClass!=null){
93
            populateTerms(getPreferredTerms());
94
        }
95

    
96
        combo.addSelectionListener(this);
97
        combo.addDisposeListener(this);
98
        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
99

    
100
        if (selection != null) {
101
            setSelection(selection);
102
        }
103
	}
104

    
105
	/**
106
	 * <p>Sets the selection of the combo to the given T object.</p>
107
	 * <p>Passing <code>null</code> to this method will set the selection to
108
	 * the empty element and effectively clear the selection</p>
109
	 *
110
	 * @param selection
111
	 *            a T object or <code>null</code> to clear the selection
112
	 */
113
	@Override
114
    public void setSelection(T selection) {
115
		this.selection = selection;
116

    
117
		Listener[] listeners = combo.getListeners(SWT.Selection);
118

    
119
		for (Listener listener : listeners) {
120
			combo.removeListener(SWT.Selection, listener);
121
		}
122
		int selectedIndex;
123
		if(selection == null){
124
			// set selection to the emptyElement
125
			selectedIndex = 0;
126
		}else{
127
			selectedIndex = terms.indexOf(selection);
128
			if (selectedIndex == -1) {
129
				createTermNotInPreferredTerms(selection);
130
				selectedIndex = terms.indexOf(selection);
131
			}
132
		}
133
		combo.select(selectedIndex);
134

    
135
		for (Listener listener : listeners) {
136
			combo.addListener(SWT.Selection, listener);
137
		}
138
	}
139

    
140
	/**
141
	 * Fills the combo with elements and sets up the convenience functions
142
	 * for selection index
143
	 *
144
	 * @param preferredTerms
145
	 */
146
	private void populateTerms(List<T> preferredTerms) {
147

    
148
		combo.removeAll();
149

    
150
		terms = new ArrayList<T>();
151

    
152
		int i = 1;
153
		int index = 0;
154

    
155
		if(addEmptyElement){
156
		    // Add an empty element for when nothing was selected yet
157
		    combo.add(EMPTY_ELEMENT_LABEL);
158
		    terms.add(emptyElement);
159
		}
160

    
161
		if (termComparator != null) {
162
			Collections.sort(preferredTerms, termComparator);
163
		}
164
		for (T term : preferredTerms) {
165
			String label = getLabel(term);
166
			if (label == null) {
167
				if (term.getTitleCache() != null) {
168
					label = term.getTitleCache();
169
					MessagingUtils.warn(getClass(),
170
							"Term does not have a default language representation: " + label
171
									+ ", " + term.getUuid());
172
				} else {
173
					label = "Unknown";
174
					MessagingUtils.warn(getClass(),
175
							"Representation Label and TitleCache empty for term: "
176
									+ term + ", " + term.getUuid());
177
				}
178

    
179
			}
180

    
181
			combo.add(label);
182
			terms.add(term);
183

    
184
			i++;
185
			if (selection != null) {
186
				if (selection.equals(term)) {
187
					index = i;
188
				}
189
			}
190
		}
191

    
192
		if (selection != null && index == 0) {
193
			createTermNotInPreferredTerms(selection);
194
		}
195

    
196
		combo.select(index);
197
	}
198

    
199
	protected List<T> getPreferredTerms(){
200
	    List<T> preferredTerms = new ArrayList<T>();
201
		if (customPreferredTerms != null){
202
			return customPreferredTerms;
203
		}
204
		else if(termType!=null){
205
		    preferredTerms = getTermManager().getPreferredTerms(termType);
206
		}
207
		else if(termVocabulary!=null){
208
		    preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
209
		}
210
		if(termClass!=null){
211
		    preferredTerms = getTermManager().getPreferredTerms(termClass);
212
		}
213
		return preferredTerms;
214
	}
215

    
216
	/**
217
	 * May be overridden by derived classes if the desired label string does not
218
	 * reside in term.getLabel();
219
	 *
220
	 * @param term
221
	 *            a T object.
222
	 * @return a {@link java.lang.String} object.
223
	 */
224
	protected String getLabel(T term) {
225
		if (term == null){
226
			return "";
227
		}else{
228
			String termLabel = term.getLabel(CdmStore.getDefaultLanguage());
229
			if (termLabel == null){
230
			    termLabel = term.getLabel();
231
			}
232
			if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
233
			    && term.getVocabulary()!=null){
234
			    String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
235
			    if (vocLabel == null){
236
			        vocLabel = term.getVocabulary().getLabel();
237
			    }
238
			    termLabel += " ["+vocLabel+"]";
239
			}
240
            return termLabel;
241
		}
242
	}
243

    
244
	/**
245
	 *
246
	 *
247
	 * @param term
248
	 */
249
	private void createTermNotInPreferredTerms(T term) {
250
		List<T> preferredTerms = getPreferredTerms();
251

    
252
		preferredTerms.add(term);
253

    
254
		populateTerms(preferredTerms);
255
	}
256

    
257
	/** {@inheritDoc} */
258
	@Override
259
    public void widgetSelected(SelectionEvent e) {
260
		selection = terms.get(combo.getSelectionIndex());
261
		firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
262
	}
263

    
264
	/** {@inheritDoc} */
265
	@Override
266
    public void propertyChange(PropertyChangeEvent event) {
267
		super.propertyChange(event);
268
		if (event != null
269
				&& PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
270
						.getProperty())) {
271
			populateTerms(getPreferredTerms());
272
		}
273
	}
274

    
275
	protected TermManager getTermManager() {
276
		return CdmStore.getTermManager();
277
	}
278

    
279
	public int getVisibleItemCount(){
280
		return combo.getVisibleItemCount();
281
	}
282

    
283
	/**
284
	 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
285
	 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
286
	 * given terms. Also, any previous selection will be reseted.</p>
287
	 *
288
	 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
289
	 *
290
	 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
291
	 */
292
	public void setTerms(List<T> terms) {
293
		setSelection(null);
294
		customPreferredTerms = terms;
295
		populateTerms(customPreferredTerms);
296
	}
297

    
298
	public void removeEmptyElement(){
299
	    if(addEmptyElement){
300
	        if(terms.contains(emptyElement)){
301
	            terms.remove(emptyElement);
302
	        }
303
	        if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
304
	            combo.remove(EMPTY_ELEMENT_LABEL);
305
	        }
306
	    }
307
	}
308
}
(3-3/4)