*/
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;
/**
* @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;
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());
combo.removeSelectionListener(listener);
}
- /** {@inheritDoc} */
@Override
public void widgetDisposed(DisposeEvent e) {
PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
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