ref #9939: fix layout issue
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / combo / AbstractComboElement.java
index 359412d34cc41844ce43e107e52b1bca9e5adc44..5ff533fda0a199d8ec24b26f8b0655c7f3aff93e 100644 (file)
@@ -8,21 +8,30 @@
 */
 package eu.etaxonomy.taxeditor.ui.combo;
 
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.eclipse.equinox.internal.p2.ui.misc.StringMatcher;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalListener;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.CCombo;
 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.ui.forms.widgets.TableWrapData;
 
-import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.cdm.common.CdmUtils;
 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
-import eu.etaxonomy.taxeditor.preference.Resources;
-import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
+import eu.etaxonomy.taxeditor.ui.element.AbstractRelevanceFormElement;
 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
+import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
 import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
 import eu.etaxonomy.taxeditor.ui.element.ISelectable;
@@ -31,12 +40,11 @@ import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
 /**
  * @author pplitzner
  * @date Aug 11, 2016
- *
  */
-public abstract class AbstractComboElement<T> extends
-AbstractCdmFormElement implements SelectionListener,
-IEnableableFormElement, ISelectable,
-DisposeListener {
+public abstract class AbstractComboElement<T>
+               extends AbstractRelevanceFormElement
+               implements SelectionListener, IEnableableFormElement,
+                       ISelectable, DisposeListener {
 
     protected static final int DEFAULT_VISIBLE_ITEMS = 10;
 
@@ -44,52 +52,50 @@ DisposeListener {
 
     protected Label label;
 
-    protected final CCombo combo;
+    protected Combo combo;
 
+    public boolean hasNullValue;
 
-    public AbstractComboElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
+    public AbstractComboElement(CdmFormFactory formFactory, ICdmFormElement formElement, boolean hasNullValue) {
         super(formFactory, formElement);
 
         label = formFactory.createLabel(getLayoutComposite(), "");
         addControl(label);
 
         // create combo
-        combo = new CCombo(getLayoutComposite(), SWT.READ_ONLY|SWT.BORDER);
+        combo = new Combo(getLayoutComposite(), SWT.BORDER);
 
         addControl(combo);
         TableWrapData fill_HORIZONTALLY = LayoutConstants.FILL_HORIZONTALLY();
         combo.setLayoutData(fill_HORIZONTALLY);
         fill_HORIZONTALLY.maxWidth = 50;
-        combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
+//        combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
+        //disable mouse-wheel selection
+        combo.addListener(SWT.MouseWheel, e->e.doit=false);
+        this.hasNullValue = hasNullValue;
+    }
+
+    public AbstractComboElement(CdmFormFactory formFactory, ICdmFormElement formElement){
+        this(formFactory, formElement, false);
     }
 
-    /** {@inheritDoc} */
     @Override
     public void setBackground(Color color) {
-        if (label != null) {
+        if (label != null && !label.isDisposed()) {
             label.setBackground(color);
         }
     }
 
-    /** {@inheritDoc} */
     @Override
-    public void setIrrelevant(boolean irrelevant) {
-        String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
-                : Resources.COLOR_COMPOSITE_BACKGROUND;
-
-        Color color = AbstractUtility.getColor(colorId);
+    public void updateCacheRelevance() {
+        Color color = cacheRelevance().getColor();
         combo.setBackground(color);
-        if (label != null) {
-            label.setBackground(color);
-        }
-
     }
 
     public void setVisibleItemCount(int count){
         combo.setVisibleItemCount(count);
     }
 
-    /** {@inheritDoc} */
     @Override
     public void setSelected(boolean selected) {
         setBackground(selected ? SELECTED : getPersistentBackground());
@@ -107,7 +113,6 @@ DisposeListener {
         combo.removeSelectionListener(listener);
     }
 
-    /** {@inheritDoc} */
     @Override
     public void widgetDisposed(DisposeEvent e) {
         PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
@@ -122,11 +127,102 @@ DisposeListener {
         return combo.isEnabled();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void setEnabled(boolean enabled) {
         combo.setEnabled(enabled);
     }
 
     public abstract void setSelection(T selection);
-}
+
+    private AbstractComboElement<T> getComboElement(){
+        return this;
+    }
+
+    protected void addContentProposalAdapter() {
+        ContentProposalAdapter adapter;
+
+        adapter = new ContentProposalAdapter(combo, new ComboContentAdapter(), getProposalProvider(), null, null);
+        adapter.setPropagateKeys(true);
+        adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+        adapter.addContentProposalListener(new IContentProposalListener() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public void proposalAccepted(IContentProposal proposal) {
+                setSelection((T)combo.getData(proposal.getContent()));
+                firePropertyChangeEvent(new CdmPropertyChangeEvent(getComboElement(), null));
+            }
+        });
+    }
+
+    IContentProposalProvider getProposalProvider() {
+        return new IContentProposalProvider() {
+            @Override
+            public IContentProposal[] getProposals(String contents, int position) {
+                String[] items = combo.getItems();
+                if (contents.length() == 0 || items.length == 0) {
+                    return new IContentProposal[0];
+                }
+                StringMatcher matcher = new StringMatcher("*" + contents + "*", true, false); //$NON-NLS-1$ //$NON-NLS-2$
+                ArrayList<String> matches = new ArrayList<>();
+                for (int i = 0; i < items.length; i++) {
+                    if (matcher.match(items[i])) {
+                        matches.add(items[i]);
+                    }
+                }
+
+                Collections.sort(matches);
+
+                // We don't want to autoactivate if the only proposal exactly matches
+                // what is in the combo.  This prevents the popup from
+                // opening when the user is merely scrolling through the combo values or
+                // has accepted a combo value.
+                if (matches.size() == 1 && matches.get(0).equals(combo.getText())) {
+                    return new IContentProposal[0];
+                }
+
+                if (matches.isEmpty()) {
+                    return new IContentProposal[0];
+                }
+
+                // Make the proposals
+                IContentProposal[] proposals = new IContentProposal[matches.size()];
+                for (int i = 0; i < matches.size(); i++) {
+                    final String proposal = matches.get(i);
+                    proposals[i] = new IContentProposal() {
+
+                        @Override
+                        public String getContent() {
+                            return proposal;
+                        }
+
+                        @Override
+                        public int getCursorPosition() {
+                            return proposal.length();
+                        }
+
+                        @Override
+                        public String getDescription() {
+                            return null;
+                        }
+
+                        @Override
+                        public String getLabel() {
+                            return null;
+                        }
+                    };
+                }
+
+                return proposals;
+            }
+        };
+    }
+
+    @Override
+    public String toString() {
+        if (label != null){
+            return CdmUtils.concat("", "ComboElement[", label.getText(),"]");
+        }else{
+            return super.toString();
+        }
+    }
+}
\ No newline at end of file