Skip to main content
summaryrefslogtreecommitdiffstats
blob: ae6acd20c1dad928b58eaa3d90c797f8c821ac90 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.contentassist;

import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;

import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.contentassist.AbstractControlContentAssistSubjectAdapter;
import org.eclipse.jface.contentassist.ComboContentAssistSubjectAdapter;
import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
import org.eclipse.jface.contentassist.TextContentAssistSubjectAdapter;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.LabelProvider;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.internal.texteditor.NLSUtility;
import org.eclipse.ui.keys.IBindingService;

import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;


/**
 * A content assistant handler which handles the key binding and
 * the cue for a {@link org.eclipse.jface.text.contentassist.ContentAssistant}
 * and its subject adapter.
 *
 * @since 3.0
 * @deprecated As of 3.2, replaced by JFace field assist support
 */
@Deprecated
public class ContentAssistHandler {
	/**
	 * The target control.
	 */
	private Control fControl;
	/**
	 * The content assist subject adapter.
	 */
	private AbstractControlContentAssistSubjectAdapter fContentAssistSubjectAdapter;
	/**
	 * The content assistant.
	 */
	private SubjectControlContentAssistant fContentAssistant;
	/**
	 * The currently installed FocusListener, or <code>null</code> iff none installed.
	 * This is also used as flag to tell whether content assist is enabled
	 */
	private FocusListener fFocusListener;
	/**
	 * The currently installed IHandlerActivation, or <code>null</code> iff none installed.
	 */
	private IHandlerActivation fHandlerActivation;

	/**
	 * Creates a new {@link ContentAssistHandler} for the given {@link Combo}.
	 * Only a single {@link ContentAssistHandler} may be installed on a {@link Combo} instance.
	 * Content Assist is enabled by default.
	 *
	 * @param combo target combo
	 * @param contentAssistant a configured content assistant
	 * @return a new {@link ContentAssistHandler}
	 */
	public static ContentAssistHandler createHandlerForCombo(Combo combo, SubjectControlContentAssistant contentAssistant) {
		return new ContentAssistHandler(combo, new ComboContentAssistSubjectAdapter(combo), contentAssistant);
	}

	/**
	 * Creates a new {@link ContentAssistHandler} for the given {@link Text}.
	 * Only a single {@link ContentAssistHandler} may be installed on a {@link Text} instance.
	 * Content Assist is enabled by default.
	 *
	 * @param text target text
	 * @param contentAssistant a configured content assistant
	 * @return a new {@link ContentAssistHandler}
	 */
	public static ContentAssistHandler createHandlerForText(Text text, SubjectControlContentAssistant contentAssistant) {
		return new ContentAssistHandler(text, new TextContentAssistSubjectAdapter(text), contentAssistant);
	}

	/**
	 * Internal constructor.
	 *
	 * @param control target control
	 * @param subjectAdapter content assist subject adapter
	 * @param contentAssistant content assistant
	 */
	private ContentAssistHandler(
			Control control,
			AbstractControlContentAssistSubjectAdapter subjectAdapter,
			SubjectControlContentAssistant contentAssistant) {
		fControl= control;
		fContentAssistant= contentAssistant;
		fContentAssistSubjectAdapter= subjectAdapter;
		setEnabled(true);
		fControl.addDisposeListener(e -> setEnabled(false));
	}

	/**
	 * @return <code>true</code> iff content assist is enabled
	 */
	public boolean isEnabled() {
		return fFocusListener != null;
	}

	/**
	 * Controls enablement of content assist.
	 * When enabled, a cue is shown next to the focused field
	 * and the affordance hover shows the shortcut.
	 *
	 * @param enable enable content assist iff true
	 */
	public void setEnabled(boolean enable) {
		if (enable == isEnabled())
			return;

		if (enable)
			enable();
		else
			disable();
	}

	/**
	 * Enable content assist.
	 */
	private void enable() {
		if (! fControl.isDisposed()) {
			fContentAssistant.install(fContentAssistSubjectAdapter);
			installCueLabelProvider();
			installFocusListener();
			if (fControl.isFocusControl())
				activateHandler();
		}
	}

	/**
	 * Disable content assist.
	 */
	private void disable() {
		if (! fControl.isDisposed()) {
			fContentAssistant.uninstall();
			fContentAssistSubjectAdapter.setContentAssistCueProvider(null);
			fControl.removeFocusListener(fFocusListener);
			fFocusListener= null;
			if (fHandlerActivation != null)
				deactivateHandler();
		}
	}

	/**
	 * Create and install the {@link LabelProvider} for fContentAssistSubjectAdapter.
	 */
	private void installCueLabelProvider() {
		ILabelProvider labelProvider= new LabelProvider() {
			@Override
			public String getText(Object element) {
				IBindingService bindingService= PlatformUI.getWorkbench().getAdapter(IBindingService.class);
				TriggerSequence[] activeBindings= bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
				if (activeBindings.length == 0)
					return ContentAssistMessages.ContentAssistHandler_contentAssistAvailable;
				return NLSUtility.format(ContentAssistMessages.ContentAssistHandler_contentAssistAvailableWithKeyBinding, activeBindings[0].format());
			}
		};
		fContentAssistSubjectAdapter.setContentAssistCueProvider(labelProvider);
	}

	/**
	 * Create fFocusListener and install it on fControl.
	 */
	private void installFocusListener() {
		fFocusListener= new FocusListener() {
			@Override
			public void focusGained(final FocusEvent e) {
				if (fHandlerActivation == null)
					activateHandler();
			}
			@Override
			public void focusLost(FocusEvent e) {
				if (fHandlerActivation != null)
					deactivateHandler();
			}
		};
		fControl.addFocusListener(fFocusListener);
	}

	/**
	 * Create and register fHandlerSubmission.
	 */
	private void activateHandler() {
		IHandlerService handlerService= PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
		if (handlerService == null)
			return;

		IHandler handler= new AbstractHandler() {
			@Override
			public Object execute(ExecutionEvent event) throws ExecutionException {
				if (ContentAssistHandler.this.isEnabled()) // don't call AbstractHandler#isEnabled()!
					fContentAssistant.showPossibleCompletions();
				return null;
			}
		};
		fHandlerActivation= handlerService.activateHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, handler);
	}

	/**
	 * Unregister the {@link IHandlerActivation} from the shell.
	 */
	private void deactivateHandler() {
		IHandlerService handlerService= PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
		if (handlerService != null)
			handlerService.deactivateHandler(fHandlerActivation);
		fHandlerActivation= null;
	}
}

Back to the top