ref #7040 Fix addition of empty element in combos
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / TermComboElement.java
index f05cbe1c497ca468f04b11402df608d77165402e..7bd6f3b71497dd9de4618b301d626ad173d26147 100644 (file)
 /**
- * 
+ *
  */
 package eu.etaxonomy.taxeditor.ui.combo;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 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.Label;
 import org.eclipse.swt.widgets.Listener;
 
-import eu.etaxonomy.cdm.model.common.DefinedTerm;
 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
 import eu.etaxonomy.cdm.model.common.TermType;
+import eu.etaxonomy.cdm.model.common.TermVocabulary;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
 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.campanula.compatibility.ICdmFormElement;
-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.element.LayoutConstants;
+import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
 
 /**
- * <p>
- * Abstract AbstractTermComboElement class.
- * </p>
- * 
  * @author n.hoffmann
  * @created Nov 5, 2009
  * @version 1.0
  * @param <T>
  */
 public class TermComboElement<T extends DefinedTermBase>
-               extends AbstractCdmFormElement implements SelectionListener,
-               DisposeListener, IEnableableFormElement, ISelectable {
-
-       private static final int DEFAULT_VISIBLE_ITEMS = 10;
-       
-       private T selection;
+               extends AbstractComboElement<T> {
 
        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 TermComboElement(CdmFormFactory formFactory,
-                       ICdmFormElement parentElement, TermType termType, String labelString, T selection,
-                       int style) {
-               super(formFactory, parentElement);
-               
-               this.termClass =  (Class<T>) DefinedTerm.class;
-               
-               if (labelString != null) {
-                       label = formFactory.createLabel(getLayoutComposite(), labelString);
-                       addControl(label);
-               }
-
-               // create combo
-               combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY);
-               addControl(combo);
-               combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
-               combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
+       public Comparator<T> getTermComparator() {
+               return termComparator;
+       }
 
-               populateTerms(filterDefinedTermByTermType(getPreferredTerms(), termType));
+       public void setTermComparator(Comparator<T> termComparator) {
+               this.termComparator = termComparator;
+               List<T> termsWithoutNull = terms.subList(1, terms.size());
 
-               combo.addSelectionListener(this);
-               combo.addDisposeListener(this);
-               PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
+               populateTerms(termsWithoutNull);
 
-               if (selection != null) {
-                       setSelection(selection);
-               }
        }
 
-       /**
-        * <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 TermComboElement(CdmFormFactory formFactory,
-                       ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection,
-                       int style) {
-               super(formFactory, parentElement);
-               
-               this.termClass = termClass;
-               
-               if (labelString != null) {
-                       label = formFactory.createLabel(getLayoutComposite(), labelString);
-                       addControl(label);
-               }
+       private final TermType termType;
+       private final TermVocabulary termVocabulary;
+       private final Class<T> termClass;
 
-               // create combo
-               combo = new Combo(getLayoutComposite(), SWT.BORDER | SWT.READ_ONLY);
-               addControl(combo);
-               combo.setLayoutData(LayoutConstants.FILL_HORIZONTALLY());
-               combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
+       private List<T> customPreferredTerms;
 
-               populateTerms(getPreferredTerms());
+       private boolean useAbbrevLabel = false;
+       private boolean addEmptyElement;
 
-               combo.addSelectionListener(this);
-               combo.addDisposeListener(this);
-               PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
+       public TermComboElement(CdmFormFactory formFactory,
+                       ICdmFormElement parentElement, TermType termType, String labelString, T selection, boolean addEmptyElement,
+                       int style, boolean useAbbrevLabel, Comparator<T> comparator) {
+               this(formFactory, parentElement, null, termType, null, labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
+       }
 
-               if (selection != null) {
-                       setSelection(selection);
-               }
+       public TermComboElement(CdmFormFactory formFactory,
+               ICdmFormElement parentElement, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
+               int style, boolean useAbbrevLabel, Comparator<T> comparator) {
+           this(formFactory, parentElement, null, null, termVocabulary, labelString, selection, addEmptyElement, style, useAbbrevLabel, comparator);
        }
 
-       /**
-        * <p>
-        * Getter for the field <code>selection</code>.
-        * </p>
-        * 
-        * @return a T object.
-        */
-       public T getSelection() {
-               return selection;
+    public TermComboElement(CdmFormFactory formFactory,
+            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
+            int style) {
+        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style, false, null);
+    }
+    public TermComboElement(CdmFormFactory formFactory,
+            ICdmFormElement parentElement, Class<T> termClass, String labelString, T selection, boolean addEmptyElement,
+            int style, boolean useAbbrevLabel) {
+        this(formFactory, parentElement, termClass, null, null, labelString, selection, addEmptyElement, style, useAbbrevLabel, null);
+
+    }
+
+       private TermComboElement(CdmFormFactory formFactory,
+               ICdmFormElement parentElement, Class<T> termClass, TermType termType, TermVocabulary<?> termVocabulary, String labelString, T selection, boolean addEmptyElement,
+               int style, boolean useAbbrevLabel, Comparator<T> comparator) {
+        super(formFactory, parentElement);
+
+        this.termType = termType;
+        this.termVocabulary = termVocabulary;
+        this.termClass = termClass;
+        this.addEmptyElement = addEmptyElement;
+        this.useAbbrevLabel = useAbbrevLabel;
+        this.termComparator = comparator;
+        if (labelString != null) {
+            label.setText(labelString);
+        }
+
+        if(termType!=null){
+            //TODO try to remove generic T and avoid classes to be used
+            populateTerms((List<T>) getTermManager().getPreferredTerms(termType));
+        }
+        else if(termVocabulary!=null){
+            populateTerms((List<T>) getTermManager().getPreferredTerms(termVocabulary));
+        }
+        else if(this.termClass!=null){
+            populateTerms(getPreferredTerms());
+        }
+
+        combo.addSelectionListener(this);
+        combo.addDisposeListener(this);
+        PreferencesUtil.getPreferenceStore().addPropertyChangeListener(this);
+
+        if (selection != null) {
+            setSelection(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 
+        * <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;
-               
+       @Override
+    public void setSelection(T selection) {
                this.selection = selection;
-               
+
                Listener[] listeners = combo.getListeners(SWT.Selection);
 
                for (Listener listener : listeners) {
@@ -219,7 +160,7 @@ public class TermComboElement<T extends DefinedTermBase>
        /**
         * Fills the combo with elements and sets up the convenience functions
         * for selection index
-        * 
+        *
         * @param preferredTerms
         */
        private void populateTerms(List<T> preferredTerms) {
@@ -231,32 +172,30 @@ public class TermComboElement<T extends DefinedTermBase>
                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);
                }
+               terms.addAll(preferredTerms);
+
+               List<String> labels = new ArrayList<>();
                for (T term : preferredTerms) {
                        String label = getLabel(term);
                        if (label == null) {
                                if (term.getTitleCache() != null) {
                                        label = term.getTitleCache();
-                                       StoreUtil.warn(getClass(),
+                                       MessagingUtils.warn(getClass(),
                                                        "Term does not have a default language representation: " + label
                                                                        + ", " + term.getUuid());
                                } else {
                                        label = "Unknown";
-                                       StoreUtil.warn(getClass(),
+                                       MessagingUtils.warn(getClass(),
                                                        "Representation Label and TitleCache empty for term: "
                                                                        + term + ", " + term.getUuid());
                                }
 
                        }
 
-                       combo.add(label);
-                       terms.add(term);
+                       labels.add(label);
 
                        i++;
                        if (selection != null) {
@@ -266,40 +205,44 @@ public class TermComboElement<T extends DefinedTermBase>
                        }
                }
 
-               if (selection != null && index == 0) {
+               String[] items = labels.toArray(new String[0]);
+        combo.setItems(items);
+
+        if(addEmptyElement){
+            // Add an empty element for when nothing was selected yet
+            combo.add(EMPTY_ELEMENT_LABEL, 0);
+            terms.add(0, emptyElement);
+        }
+
+        if (selection != null && index == 0) {
                        createTermNotInPreferredTerms(selection);
                }
 
                combo.select(index);
-       }
 
-       /*
-        * (non-Javadoc)
-        * @see eu.etaxonomy.taxeditor.forms.IEnableableFormElement#setEnabled(boolean)
-        */
-       /** {@inheritDoc} */
-       public void setEnabled(boolean enabled) {
-               combo.setEnabled(enabled);
        }
 
-       /**
-        * <p>
-        * preferredTerms
-        * </p>
-        * 
-        * @return a {@link java.util.List} object.
-        */
        protected List<T> getPreferredTerms(){
+           List<T> preferredTerms = new ArrayList<T>();
                if (customPreferredTerms != null){
                        return customPreferredTerms;
                }
-               return getTermManager().getPreferredTerms(termClass);
+               else if(termType!=null){
+                   preferredTerms = getTermManager().getPreferredTerms(termType);
+               }
+               else if(termVocabulary!=null){
+                   preferredTerms = getTermManager().getPreferredTerms(termVocabulary);
+               }
+               if(termClass!=null){
+                   preferredTerms = getTermManager().getPreferredTerms(termClass);
+               }
+               return preferredTerms;
        }
 
        /**
         * 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.
@@ -308,13 +251,30 @@ public class TermComboElement<T extends DefinedTermBase>
                if (term == null){
                        return "";
                }else{
-                       return term.getLabel(CdmStore.getDefaultLanguage());
+                       String termLabel = null;
+                       if (useAbbrevLabel){
+                               termLabel = term.getIdInVocabulary();
+                       }else{
+                               termLabel = term.getLabel(CdmStore.getDefaultLanguage());
+                       }
+                       if (termLabel == null){
+                           termLabel = term.getLabel();
+                       }
+                       if(PreferencesUtil.getPreferenceStore().getBoolean(IPreferenceKeys.SHOW_VOCABULARY_ID_FOR_TERM_LABELS)
+                           && term.getVocabulary()!=null){
+                           String vocLabel = term.getVocabulary().getLabel(CdmStore.getDefaultLanguage());
+                           if (vocLabel == null){
+                               vocLabel = term.getVocabulary().getLabel();
+                           }
+                           termLabel += " ["+vocLabel+"]";
+                       }
+            return termLabel;
                }
        }
 
        /**
-        * 
-        * 
+        *
+        *
         * @param term
         */
        private void createTermNotInPreferredTerms(T term) {
@@ -325,51 +285,16 @@ public class TermComboElement<T extends DefinedTermBase>
                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} */
-       public void widgetSelected(SelectionEvent e) {
+       @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} */
-       public void propertyChange(PropertyChangeEvent event) {
+       @Override
+    public void propertyChange(PropertyChangeEvent event) {
                super.propertyChange(event);
                if (event != null
                                && PreferencesUtil.PREFERRED_TERMS_CHANGE.equals(event
@@ -378,67 +303,21 @@ public class TermComboElement<T extends DefinedTermBase>
                }
        }
 
-       /** {@inheritDoc} */
-       public void setSelected(boolean selected) {
-               setBackground(selected ? SELECTED : getPersistentBackground());
-       }
-
-       /** {@inheritDoc} */
-       public void widgetDisposed(DisposeEvent e) {
-               PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
-       }
-
-       // not used
-       /** {@inheritDoc} */
-       public void widgetDefaultSelected(SelectionEvent e) {
-       }
-
-       /** {@inheritDoc} */
-       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 
+        * 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) {
@@ -446,14 +325,15 @@ public class TermComboElement<T extends DefinedTermBase>
                customPreferredTerms = terms;
                populateTerms(customPreferredTerms);
        }
-       
-       private List<T> filterDefinedTermByTermType(List<T> terms, TermType termType) {
-               List<T> definedTerms = new ArrayList<T>();
-               for(T term : terms){
-                       if(term.getTermType().equals(termType)) {
-                               definedTerms.add(term);
-                       }
-               }               
-               return definedTerms;
+
+       public void removeEmptyElement(){
+           if(addEmptyElement){
+               if(terms.contains(emptyElement)){
+                   terms.remove(emptyElement);
+               }
+               if(Arrays.asList(combo.getItems()).contains(EMPTY_ELEMENT_LABEL)){
+                   combo.remove(EMPTY_ELEMENT_LABEL);
+               }
+           }
        }
 }