ref #6925 Set conversation and cdmEntitySession to null for dispose
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / TermComboElement.java
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 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, 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, 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, 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, labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
87
88 }
89
90 private TermComboElement(CdmFormFactory formFactory,
91 ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
92 int style, boolean useAbbrevLabel, Comparator<T> comparator) {
93 super(formFactory, parentElement);
94
95 this.termType = termType;
96 this.termVocabulary = termVocabulary;
97 this.termClass = termClass;
98 this.addEmptyElement = addEmptyElement;
99 this.useAbbrevLabel = useAbbrevLabel;
100 this.termComparator = comparator;
101 if (labelString != null) {
102 label.setText(labelString);
103 }
104
105 if(termType!=null){
106 //TODO try to remove generic T and avoid classes to be used
107 populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
108 }
109 else if(termVocabulary!=null){
110 populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
111 }
112 else if(this.termClass!=null){
113 populateTerms(getPreferredTerms());
114 }
115
116 combo.addSelectionListener(this);
117 combo.addDisposeListener(this);
118 PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
119
120 if (selection != null) {
121 setSelection(selection);
122 }
123 }
124
125 /**
126 * <p>Sets the selection of the combo to the given T object.</p>
127 * <p>Passing <code>null</code> to this method will set the selection to
128 * the empty element and effectively clear the selection</p>
129 *
130 * @param selection
131 * a T object or <code>null</code> to clear the selection
132 */
133 @Override
134 public void setSelection(T selection) {
135 this.selection = selection;
136
137 Listener[] listeners = combo.getListeners(SWT.Selection);
138
139 for (Listener listener : listeners) {
140 combo.removeListener(SWT.Selection, listener);
141 }
142 int selectedIndex;
143 if(selection == null){
144 // set selection to the emptyElement
145 selectedIndex = 0;
146 }else{
147 selectedIndex = terms.indexOf(selection);
148 if (selectedIndex == -1) {
149 createTermNotInPreferredTerms(selection);
150 selectedIndex = terms.indexOf(selection);
151 }
152 }
153 combo.select(selectedIndex);
154
155 for (Listener listener : listeners) {
156 combo.addListener(SWT.Selection, listener);
157 }
158 }
159
160 /**
161 * Fills the combo with elements and sets up the convenience functions
162 * for selection index
163 *
164 * @param preferredTerms
165 */
166 private void populateTerms(List<T> preferredTerms) {
167
168 combo.removeAll();
169
170 terms = new ArrayList<T>();
171
172 int i = 1;
173 int index = 0;
174
175 if(addEmptyElement){
176 // Add an empty element for when nothing was selected yet
177 combo.add(EMPTY_ELEMENT_LABEL);
178 terms.add(emptyElement);
179 }
180
181 if (termComparator != null) {
182 Collections.sort(preferredTerms, termComparator);
183 }
184 for (T term : preferredTerms) {
185 String label = getLabel(term);
186 if (label == null) {
187 if (term.getTitleCache() != null) {
188 label = term.getTitleCache();
189 MessagingUtils.warn(getClass(),
190 "Term does not have a default language representation: " + label
191 + ", " + term.getUuid());
192 } else {
193 label = "Unknown";
194 MessagingUtils.warn(getClass(),
195 "Representation Label and TitleCache empty for term: "
196 + term + ", " + term.getUuid());
197 }
198
199 }
200
201 combo.add(label);
202 terms.add(term);
203
204 i++;
205 if (selection != null) {
206 if (selection.equals(term)) {
207 index = i;
208 }
209 }
210 }
211
212 if (selection != null && index == 0) {
213 createTermNotInPreferredTerms(selection);
214 }
215
216 combo.select(index);
217
218 }
219
220 protected List<T> getPreferredTerms(){
221 List<T> preferredTerms = new ArrayList<T>();
222 if (customPreferredTerms != null){
223 return customPreferredTerms;
224 }
225 else if(termType!=null){
226 preferredTerms = getTermManager().getPreferredTerms(termType);
227 }
228 else if(termVocabulary!=null){
229 preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
230 }
231 if(termClass!=null){
232 preferredTerms = getTermManager().getPreferredTerms(termClass);
233 }
234 return preferredTerms;
235 }
236
237 /**
238 * May be overridden by derived classes if the desired label string does not
239 * reside in term.getLabel();
240 *
241 * @param term
242 * a T object.
243 * @return a {@link java.lang.String} object.
244 */
245 protected String getLabel(T term) {
246 if (term == null){
247 return "";
248 }else{
249 String termLabel = null;
250 if (useAbbrevLabel){
251 termLabel = term.getIdInVocabulary();
252 }else{
253 termLabel = term.getLabel(CdmStore.getDefaultLanguage());
254 }
255 if (termLabel == null){
256 termLabel = term.getLabel();
257 }
258 if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
259 && term.getVocabulary()!=null){
260 String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
261 if (vocLabel == null){
262 vocLabel = term.getVocabulary().getLabel();
263 }
264 termLabel += " ["+vocLabel+"]";
265 }
266 return termLabel;
267 }
268 }
269
270 /**
271 *
272 *
273 * @param term
274 */
275 private void createTermNotInPreferredTerms(T term) {
276 List<T> preferredTerms = getPreferredTerms();
277
278 preferredTerms.add(term);
279
280 populateTerms(preferredTerms);
281 }
282
283 /** {@inheritDoc} */
284 @Override
285 public void widgetSelected(SelectionEvent e) {
286 selection = terms.get(combo.getSelectionIndex());
287 firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
288 }
289
290 /** {@inheritDoc} */
291 @Override
292 public void propertyChange(PropertyChangeEvent event) {
293 super.propertyChange(event);
294 if (event != null
295 && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
296 .getProperty())) {
297 populateTerms(getPreferredTerms());
298 }
299 }
300
301 protected TermManager getTermManager() {
302 return CdmStore.getTermManager();
303 }
304
305 public int getVisibleItemCount(){
306 return combo.getVisibleItemCount();
307 }
308
309 /**
310 * <p>A {@link List} of term objects may be passed to this combo box. In this case, the default behaviour
311 * of displaying the preferred terms for the T type will be overridden and the combo will only display the
312 * given terms. Also, any previous selection will be reseted.</p>
313 *
314 * <p>To return to the default of displaying the preferred terms, simply pass <code>null</code>.</p>
315 *
316 * @param terms a {@link List} of T objects or <code>null</code> for default preferred terms
317 */
318 public void setTerms(List<T> terms) {
319 setSelection(null);
320 customPreferredTerms = terms;
321 populateTerms(customPreferredTerms);
322 }
323
324 public void removeEmptyElement(){
325 if(addEmptyElement){
326 if(terms.contains(emptyElement)){
327 terms.remove(emptyElement);
328 }
329 if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
330 combo.remove(EMPTY_ELEMENT_LABEL);
331 }
332 }
333 }
334 }