Project

General

Profile

Download (7.52 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2016 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.taxeditor.ui.combo;
10

    
11
import java.util.ArrayList;
12

    
13
import org.eclipse.equinox.internal.p2.ui.misc.StringMatcher;
14
import org.eclipse.jface.fieldassist.ComboContentAdapter;
15
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
16
import org.eclipse.jface.fieldassist.IContentProposal;
17
import org.eclipse.jface.fieldassist.IContentProposalListener;
18
import org.eclipse.jface.fieldassist.IContentProposalProvider;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.events.DisposeEvent;
21
import org.eclipse.swt.events.DisposeListener;
22
import org.eclipse.swt.events.SelectionEvent;
23
import org.eclipse.swt.events.SelectionListener;
24
import org.eclipse.swt.graphics.Color;
25
import org.eclipse.swt.widgets.Combo;
26
import org.eclipse.swt.widgets.Label;
27
import org.eclipse.ui.forms.widgets.TableWrapData;
28

    
29
import eu.etaxonomy.taxeditor.model.AbstractUtility;
30
import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
31
import eu.etaxonomy.taxeditor.preference.Resources;
32
import eu.etaxonomy.taxeditor.ui.element.AbstractCdmFormElement;
33
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
34
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent;
35
import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
36
import eu.etaxonomy.taxeditor.ui.element.IEnableableFormElement;
37
import eu.etaxonomy.taxeditor.ui.element.ISelectable;
38
import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
39

    
40
/**
41
 * @author pplitzner
42
 * @date Aug 11, 2016
43
 */
44
public abstract class AbstractComboElement<T> 
45
		extends AbstractCdmFormElement 
46
		implements SelectionListener, IEnableableFormElement, 
47
			ISelectable, DisposeListener {
48

    
49
    protected static final int DEFAULT_VISIBLE_ITEMS = 10;
50

    
51
    protected T selection;
52

    
53
    protected Label label;
54

    
55
    protected Combo combo;
56

    
57
    public boolean hasNullValue;
58

    
59
    public AbstractComboElement(CdmFormFactory formFactory, ICdmFormElement formElement, boolean hasNullValue) {
60
        super(formFactory, formElement);
61

    
62
        label = formFactory.createLabel(getLayoutComposite(), "");
63
        addControl(label);
64

    
65
        // create combo
66
        combo = new Combo(getLayoutComposite(), SWT.BORDER);
67

    
68
        addControl(combo);
69
        TableWrapData fill_HORIZONTALLY = LayoutConstants.FILL_HORIZONTALLY();
70
        combo.setLayoutData(fill_HORIZONTALLY);
71
        fill_HORIZONTALLY.maxWidth = 50;
72
//        combo.setVisibleItemCount(DEFAULT_VISIBLE_ITEMS);
73
        //disable mouse-wheel selection
74
        combo.addListener(SWT.MouseWheel, e->e.doit=false);
75
        this.hasNullValue = hasNullValue;
76
    }
77

    
78
    public AbstractComboElement(CdmFormFactory formFactory, ICdmFormElement formElement){
79
        this(formFactory, formElement, false);
80
    }
81

    
82
    @Override
83
    public void setBackground(Color color) {
84
        if (label != null) {
85
            label.setBackground(color);
86
        }
87
    }
88

    
89
    @Override
90
    public void setIrrelevant(boolean irrelevant) {
91
        String colorId = irrelevant ? Resources.COLOR_COMPOSITE_IRRELEVANT
92
                : Resources.COLOR_COMPOSITE_BACKGROUND;
93

    
94
        Color color = AbstractUtility.getColor(colorId);
95
        combo.setBackground(color);
96
        if (label != null) {
97
            label.setBackground(color);
98
        }
99
    }
100

    
101
    public void setVisibleItemCount(int count){
102
        combo.setVisibleItemCount(count);
103
    }
104

    
105
    @Override
106
    public void setSelected(boolean selected) {
107
        setBackground(selected ? SELECTED : getPersistentBackground());
108
    }
109

    
110
    public T getSelection() {
111
        return selection;
112
    }
113

    
114
    public void addSelectionListener(SelectionListener listener) {
115
        combo.addSelectionListener(listener);
116
    }
117

    
118
    public void removeSelectionListener(SelectionListener listener) {
119
        combo.removeSelectionListener(listener);
120
    }
121

    
122
    @Override
123
    public void widgetDisposed(DisposeEvent e) {
124
        PreferencesUtil.getPreferenceStore().removePropertyChangeListener(this);
125
    }
126

    
127
    @Override
128
    public void widgetDefaultSelected(SelectionEvent e) {
129
    }
130

    
131
    @Override
132
    public boolean isEnabled() {
133
        return combo.isEnabled();
134
    }
135

    
136
    @Override
137
    public void setEnabled(boolean enabled) {
138
        combo.setEnabled(enabled);
139
    }
140

    
141
    public abstract void setSelection(T selection);
142

    
143
    private AbstractComboElement<T> getComboElement(){
144
        return this;
145
    }
146

    
147
    protected void addContentProposalAdapter() {
148
        ContentProposalAdapter adapter;
149

    
150
        adapter = new ContentProposalAdapter(combo, new ComboContentAdapter(), getProposalProvider(), null, null);
151
        adapter.setPropagateKeys(true);
152
        adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
153
        adapter.addContentProposalListener(new IContentProposalListener() {
154
            @SuppressWarnings("unchecked")
155
            @Override
156
            public void proposalAccepted(IContentProposal proposal) {
157
                setSelection((T)combo.getData(proposal.getContent()));
158
                firePropertyChangeEvent(new CdmPropertyChangeEvent(getComboElement(), null));
159
            }
160
        });
161
    }
162

    
163
    IContentProposalProvider getProposalProvider() {
164
        return new IContentProposalProvider() {
165
            @Override
166
            public IContentProposal[] getProposals(String contents, int position) {
167
                String[] items = combo.getItems();
168
                if (contents.length() == 0 || items.length == 0) {
169
                    return new IContentProposal[0];
170
                }
171
                StringMatcher matcher = new StringMatcher("*" + contents + "*", true, false); //$NON-NLS-1$ //$NON-NLS-2$
172
                ArrayList<String> matches = new ArrayList<>();
173
                for (int i = 0; i < items.length; i++) {
174
                    if (matcher.match(items[i])) {
175
                        matches.add(items[i]);
176
                    }
177
                }
178

    
179
                // We don't want to autoactivate if the only proposal exactly matches
180
                // what is in the combo.  This prevents the popup from
181
                // opening when the user is merely scrolling through the combo values or
182
                // has accepted a combo value.
183
                if (matches.size() == 1 && matches.get(0).equals(combo.getText())) {
184
                    return new IContentProposal[0];
185
                }
186

    
187
                if (matches.isEmpty()) {
188
                    return new IContentProposal[0];
189
                }
190

    
191
                // Make the proposals
192
                IContentProposal[] proposals = new IContentProposal[matches.size()];
193
                for (int i = 0; i < matches.size(); i++) {
194
                    final String proposal = matches.get(i);
195
                    proposals[i] = new IContentProposal() {
196

    
197
                        @Override
198
                        public String getContent() {
199
                            return proposal;
200
                        }
201

    
202
                        @Override
203
                        public int getCursorPosition() {
204
                            return proposal.length();
205
                        }
206

    
207
                        @Override
208
                        public String getDescription() {
209
                            return null;
210
                        }
211

    
212
                        @Override
213
                        public String getLabel() {
214
                            return null;
215
                        }
216
                    };
217
                }
218

    
219
                return proposals;
220
            }
221
        };
222
    }
223
}
(2-2/8)