+// $Id$
+/**
+ * Copyright (C) 2013 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.taxeditor.ui.campanula;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Listener;
+
+import eu.etaxonomy.cdm.model.common.DefinedTermBase;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
+import eu.etaxonomy.taxeditor.preference.Resources;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.store.StoreUtil;
+import eu.etaxonomy.taxeditor.store.TermManager;
+import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
+import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
+import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
+import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
+import eu.etaxonomy.taxeditor.ui.element.ISelectable;
+import eu.etaxonomy.taxeditor.ui.section.campanula.compatibility.ICdmFormElement;
+
+/**
+ * @author pplitzner
+ * @date 15.08.2013
+ *
+ */
+public class TermComboFieldController<T extends DefinedTermBase> extends AbstractCdmFormElement implements SelectionListener, DisposeListener, IEnableableFormElement, ISelectable {
+
+ private static final int DEFAULT_VISIBLE_ITEMS = 10;
+
+ private T selection;
+
+ private T emptyElement;
+ private static String EMPTY_ELEMENT_LABEL = "";
+
+// protected Label label;
+ private Combo combo;
+
+ private ArrayList<T> terms;
+
+ private Comparator<T> termComparator;
+
+ private Class<T> termClass;
+
+ private List<T> customPreferredTerms;
+
+ /**
+ * <p>
+ * Constructor for AbstractTermComboElement.
+ * </p>
+ *
+ * @param parentElement
+ * a {@link eu.etaxonomy.taxeditor.ui.element.ICdmFormElement}
+ * object.
+ * @param style
+ * a int.
+ * @param formFactory
+ * a {@link eu.etaxonomy.taxeditor.ui.element.CdmFormFactory}
+ * object.
+ * @param labelString
+ * a {@link java.lang.String} object.
+ * @param selection
+ * a T object.
+ * @param visibleItems
+ * a int.
+ * @param <T>
+ * a T object.
+ */
+ public TermComboFieldController(Combo combo, CdmFormFactory formFactory, ICdmFormElement parentElement, Class<T> termClass, T selection, int style) {
+ super(formFactory, parentElement);
+
+ this.termClass = termClass;
+ setPropertyChangeListeners(formFactory.getPropertyChangeListeners());
+ formFactory.addPropertyChangeListener(this);
+// if (labelString != null) {
+// label = formFactory.createLabel(getLayoutComposite(), labelString);
+// addControl(label);
+// }
+
+ // create combo
+ this.combo = combo;//new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY);
+ addControl(combo);
+// combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
+ combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
+
+ populateTerms(getPreferredTerms());
+
+ combo.addSelectionListener(this);
+ combo.addDisposeListener(this);
+ PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
+
+ if (selection != null) {
+ setSelection(selection);
+ }
+ }
+
+ /**
+ * <p>
+ * Getter for the field <code>selection</code>.
+ * </p>
+ *
+ * @return a T object.
+ */
+ public T getSelection() {
+ return selection;
+ }
+
+ /**
+ * <p>
+ * Sets the selection of the combo to the given T object.
+ * </p>
+ * <p>
+ * Passing <code>null</code> to this method will set the selection to the
+ * empty element and effectively clear the selection
+ * </p>
+ *
+ * @param selection
+ * a T object or <code>null</code> to clear the selection
+ */
+ public void setSelection(T selection) {
+ this.selection = selection;
+
+ this.selection = selection;
+
+ Listener[] listeners = combo.getListeners(SWT.Selection);
+
+ for (Listener listener : listeners) {
+ combo.removeListener(SWT.Selection, listener);
+ }
+ int selectedIndex;
+ if (selection == null) {
+ // set selection to the emptyElement
+ selectedIndex = 0;
+ } else {
+ selectedIndex = terms.indexOf(selection);
+ if (selectedIndex == -1) {
+ createTermNotInPreferredTerms(selection);
+ selectedIndex = terms.indexOf(selection);
+ }
+ }
+ combo.select(selectedIndex);
+
+ for (Listener listener : listeners) {
+ combo.addListener(SWT.Selection, listener);
+ }
+ }
+
+ /**
+ * Fills the combo with elements and sets up the convenience functions for
+ * selection index
+ *
+ * @param preferredTerms
+ */
+ private void populateTerms(List<T> preferredTerms) {
+
+ combo.removeAll();
+
+ terms = new ArrayList<T>();
+
+ int i = 1;
+ int index = 0;
+
+ // Add an empty element for when nothing was selected yet
+ combo.add(EMPTY_ELEMENT_LABEL);
+ terms.add(emptyElement);
+
+ if (termComparator != null) {
+ Collections.sort(preferredTerms, termComparator);
+ }
+ for (T term : preferredTerms) {
+ String label = getLabel(term);
+ if (label == null) {
+ if (term.getTitleCache() != null) {
+ label = term.getTitleCache();
+ StoreUtil.warn(getClass(), "Term does not have a representation: " + term + ", " + term.getUuid());
+ } else {
+ label = "Unknown";
+ StoreUtil.warn(getClass(), "Representation Label and TitleCache empty for term: " + term + ", " + term.getUuid());
+ }
+
+ }
+
+ combo.add(label);
+ terms.add(term);
+
+ i++;
+ if (selection != null) {
+ if (selection.equals(term)) {
+ index = i;
+ }
+ }
+ }
+
+ if (selection != null && index == 0) {
+ createTermNotInPreferredTerms(selection);
+ }
+
+ combo.select(index);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public void setEnabled(boolean enabled) {
+ combo.setEnabled(enabled);
+ }
+
+ /**
+ * <p>
+ * preferredTerms
+ * </p>
+ *
+ * @return a {@link java.util.List} object.
+ */
+ protected List<T> getPreferredTerms() {
+ if (customPreferredTerms != null) {
+ return customPreferredTerms;
+ }
+ return getTermManager().getPreferredTerms(termClass);
+ }
+
+ /**
+ * May be overridden by derived classes if the desired label string does not
+ * reside in term.getLabel();
+ *
+ * @param term
+ * a T object.
+ * @return a {@link java.lang.String} object.
+ */
+ protected String getLabel(T term) {
+ return term.getLabel(CdmStore.getDefaultLanguage());
+ }
+
+ /**
+ *
+ *
+ * @param term
+ */
+ private void createTermNotInPreferredTerms(T term) {
+ List<T> preferredTerms = getPreferredTerms();
+
+ preferredTerms.add(term);
+
+ populateTerms(preferredTerms);
+ }
+
+ /**
+ * <p>
+ * addSelectionListener
+ * </p>
+ *
+ * @param listener
+ * a {@link org.eclipse.swt.events.SelectionListener} object.
+ */
+ public void addSelectionListener(SelectionListener listener) {
+ combo.addSelectionListener(listener);
+ }
+
+ /**
+ * <p>
+ * removeSelectionListener
+ * </p>
+ *
+ * @param listener
+ * a {@link org.eclipse.swt.events.SelectionListener} object.
+ */
+ public void removeSelectionListener(SelectionListener listener) {
+ combo.removeSelectionListener(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt
+ * .events.SelectionEvent)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ selection = terms.get(combo.getSelectionIndex());
+ firePropertyChangeEvent(new CdmPropertyChangeEvent(this, e));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
+ * PropertyChangeEvent)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ super.propertyChange(event);
+ if (event != null && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event.getProperty())) {
+ populateTerms(getPreferredTerms());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setSelected(boolean selected) {
+ setBackground(selected ? SELECTED : getPersistentBackground());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
+ }
+
+ // not used
+ /** {@inheritDoc} */
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setIrrelevant(boolean irrelevant) {
+ String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT : Resources.COLOR_COMPOSITE_BACKGROUND;
+
+ Color color = StoreUtil.getColor(colorId);
+ combo.setBackground(color);
+ }
+
+// /** {@inheritDoc} */
+// @Override
+// public void setBackground(Color color) {
+// if (label != null)
+// label.setBackground(color);
+// }
+
+ /**
+*
+*/
+ protected TermManager getTermManager() {
+ return CdmStore.getTermManager();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int getVisibleItemCount() {
+ return combo.getVisibleItemCount();
+ }
+
+ /**
+ *
+ * @param count
+ */
+ public void setVisibleItemCount(int count) {
+ combo.setVisibleItemCount(count);
+ }
+
+ /**
+ * <p>
+ * A {@link List} of term objects may be passed to this combo box. In this
+ * case, the default behaviour of displaying the preferred terms for the T
+ * type will be overridden and the combo will only display the given terms.
+ * Also, any previous selection will be reseted.
+ * </p>
+ *
+ * <p>
+ * To return to the default of displaying the preferred terms, simply pass
+ * <code>null</code>.
+ * </p>
+ *
+ * @param terms
+ * a {@link List} of T objects or <code>null</code> for default
+ * preferred terms
+ */
+ public void setTerms(List<T> terms) {
+ setSelection(null);
+ customPreferredTerms = terms;
+ populateTerms(customPreferredTerms);
+ }
+}
\ No newline at end of file