1 /******************************************************************************* 2 * Copyright (c) 2000, 2018 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.contentassist; 15 16 import org.eclipse.swt.events.FocusEvent; 17 import org.eclipse.swt.events.FocusListener; 18 import org.eclipse.swt.widgets.Combo; 19 import org.eclipse.swt.widgets.Control; 20 import org.eclipse.swt.widgets.Text; 21 22 import org.eclipse.core.commands.AbstractHandler; 23 import org.eclipse.core.commands.ExecutionEvent; 24 import org.eclipse.core.commands.ExecutionException; 25 import org.eclipse.core.commands.IHandler; 26 27 import org.eclipse.jface.bindings.TriggerSequence; 28 import org.eclipse.jface.contentassist.AbstractControlContentAssistSubjectAdapter; 29 import org.eclipse.jface.contentassist.ComboContentAssistSubjectAdapter; 30 import org.eclipse.jface.contentassist.SubjectControlContentAssistant; 31 import org.eclipse.jface.contentassist.TextContentAssistSubjectAdapter; 32 import org.eclipse.jface.viewers.ILabelProvider; 33 import org.eclipse.jface.viewers.LabelProvider; 34 35 import org.eclipse.ui.PlatformUI; 36 import org.eclipse.ui.handlers.IHandlerActivation; 37 import org.eclipse.ui.handlers.IHandlerService; 38 import org.eclipse.ui.internal.texteditor.NLSUtility; 39 import org.eclipse.ui.keys.IBindingService; 40 41 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; 42 43 44 /** 45 * A content assistant handler which handles the key binding and 46 * the cue for a {@link org.eclipse.jface.text.contentassist.ContentAssistant} 47 * and its subject adapter. 48 * 49 * @since 3.0 50 * @deprecated As of 3.2, replaced by JFace field assist support 51 */ 52 @Deprecated 53 public class ContentAssistHandler { 54 /** 55 * The target control. 56 */ 57 private Control fControl; 58 /** 59 * The content assist subject adapter. 60 */ 61 private AbstractControlContentAssistSubjectAdapter fContentAssistSubjectAdapter; 62 /** 63 * The content assistant. 64 */ 65 private SubjectControlContentAssistant fContentAssistant; 66 /** 67 * The currently installed FocusListener, or <code>null</code> iff none installed. 68 * This is also used as flag to tell whether content assist is enabled 69 */ 70 private FocusListener fFocusListener; 71 /** 72 * The currently installed IHandlerActivation, or <code>null</code> iff none installed. 73 */ 74 private IHandlerActivation fHandlerActivation; 75 76 /** 77 * Creates a new {@link ContentAssistHandler} for the given {@link Combo}. 78 * Only a single {@link ContentAssistHandler} may be installed on a {@link Combo} instance. 79 * Content Assist is enabled by default. 80 * 81 * @param combo target combo 82 * @param contentAssistant a configured content assistant 83 * @return a new {@link ContentAssistHandler} 84 */ createHandlerForCombo(Combo combo, SubjectControlContentAssistant contentAssistant)85 public static ContentAssistHandler createHandlerForCombo(Combo combo, SubjectControlContentAssistant contentAssistant) { 86 return new ContentAssistHandler(combo, new ComboContentAssistSubjectAdapter(combo), contentAssistant); 87 } 88 89 /** 90 * Creates a new {@link ContentAssistHandler} for the given {@link Text}. 91 * Only a single {@link ContentAssistHandler} may be installed on a {@link Text} instance. 92 * Content Assist is enabled by default. 93 * 94 * @param text target text 95 * @param contentAssistant a configured content assistant 96 * @return a new {@link ContentAssistHandler} 97 */ createHandlerForText(Text text, SubjectControlContentAssistant contentAssistant)98 public static ContentAssistHandler createHandlerForText(Text text, SubjectControlContentAssistant contentAssistant) { 99 return new ContentAssistHandler(text, new TextContentAssistSubjectAdapter(text), contentAssistant); 100 } 101 102 /** 103 * Internal constructor. 104 * 105 * @param control target control 106 * @param subjectAdapter content assist subject adapter 107 * @param contentAssistant content assistant 108 */ ContentAssistHandler( Control control, AbstractControlContentAssistSubjectAdapter subjectAdapter, SubjectControlContentAssistant contentAssistant)109 private ContentAssistHandler( 110 Control control, 111 AbstractControlContentAssistSubjectAdapter subjectAdapter, 112 SubjectControlContentAssistant contentAssistant) { 113 fControl= control; 114 fContentAssistant= contentAssistant; 115 fContentAssistSubjectAdapter= subjectAdapter; 116 setEnabled(true); 117 fControl.addDisposeListener(e -> setEnabled(false)); 118 } 119 120 /** 121 * @return <code>true</code> iff content assist is enabled 122 */ isEnabled()123 public boolean isEnabled() { 124 return fFocusListener != null; 125 } 126 127 /** 128 * Controls enablement of content assist. 129 * When enabled, a cue is shown next to the focused field 130 * and the affordance hover shows the shortcut. 131 * 132 * @param enable enable content assist iff true 133 */ setEnabled(boolean enable)134 public void setEnabled(boolean enable) { 135 if (enable == isEnabled()) 136 return; 137 138 if (enable) 139 enable(); 140 else 141 disable(); 142 } 143 144 /** 145 * Enable content assist. 146 */ enable()147 private void enable() { 148 if (! fControl.isDisposed()) { 149 fContentAssistant.install(fContentAssistSubjectAdapter); 150 installCueLabelProvider(); 151 installFocusListener(); 152 if (fControl.isFocusControl()) 153 activateHandler(); 154 } 155 } 156 157 /** 158 * Disable content assist. 159 */ disable()160 private void disable() { 161 if (! fControl.isDisposed()) { 162 fContentAssistant.uninstall(); 163 fContentAssistSubjectAdapter.setContentAssistCueProvider(null); 164 fControl.removeFocusListener(fFocusListener); 165 fFocusListener= null; 166 if (fHandlerActivation != null) 167 deactivateHandler(); 168 } 169 } 170 171 /** 172 * Create and install the {@link LabelProvider} for fContentAssistSubjectAdapter. 173 */ installCueLabelProvider()174 private void installCueLabelProvider() { 175 ILabelProvider labelProvider= new LabelProvider() { 176 @Override 177 public String getText(Object element) { 178 IBindingService bindingService= PlatformUI.getWorkbench().getAdapter(IBindingService.class); 179 TriggerSequence[] activeBindings= bindingService.getActiveBindingsFor(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); 180 if (activeBindings.length == 0) 181 return ContentAssistMessages.ContentAssistHandler_contentAssistAvailable; 182 return NLSUtility.format(ContentAssistMessages.ContentAssistHandler_contentAssistAvailableWithKeyBinding, activeBindings[0].format()); 183 } 184 }; 185 fContentAssistSubjectAdapter.setContentAssistCueProvider(labelProvider); 186 } 187 188 /** 189 * Create fFocusListener and install it on fControl. 190 */ installFocusListener()191 private void installFocusListener() { 192 fFocusListener= new FocusListener() { 193 @Override 194 public void focusGained(final FocusEvent e) { 195 if (fHandlerActivation == null) 196 activateHandler(); 197 } 198 @Override 199 public void focusLost(FocusEvent e) { 200 if (fHandlerActivation != null) 201 deactivateHandler(); 202 } 203 }; 204 fControl.addFocusListener(fFocusListener); 205 } 206 207 /** 208 * Create and register fHandlerSubmission. 209 */ activateHandler()210 private void activateHandler() { 211 IHandlerService handlerService= PlatformUI.getWorkbench().getAdapter(IHandlerService.class); 212 if (handlerService == null) 213 return; 214 215 IHandler handler= new AbstractHandler() { 216 @Override 217 public Object execute(ExecutionEvent event) throws ExecutionException { 218 if (ContentAssistHandler.this.isEnabled()) // don't call AbstractHandler#isEnabled()! 219 fContentAssistant.showPossibleCompletions(); 220 return null; 221 } 222 }; 223 fHandlerActivation= handlerService.activateHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, handler); 224 } 225 226 /** 227 * Unregister the {@link IHandlerActivation} from the shell. 228 */ deactivateHandler()229 private void deactivateHandler() { 230 IHandlerService handlerService= PlatformUI.getWorkbench().getAdapter(IHandlerService.class); 231 if (handlerService != null) 232 handlerService.deactivateHandler(fHandlerActivation); 233 fHandlerActivation= null; 234 } 235 } 236