/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.model.ui.templates;
import org.eclipse.swt.events.*;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
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.jface.contentassist.*;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.viewers.*;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
// see org.eclipse.ui.contentassist.ContentAssistHandler
public class ContentAssistHandler2 {
private Control control;
private AbstractControlContentAssistSubjectAdapter adapter;
private IContentAssistant assistant;
private FocusListener focusListener;
private ModifyListener modifyListener;
private IHandlerActivation activation;
private ILabelProvider cueLabel;
public static ContentAssistHandler2 createHandlerForCombo(Combo combo, SubjectControlContentAssistant contentAssistant) {
return new ContentAssistHandler2(combo, new ComboContentAssistSubjectAdapter(combo), contentAssistant, null);
}
public static ContentAssistHandler2 createHandlerForText(Text text, SubjectControlContentAssistant contentAssistant, ILabelProvider cueLabel) {
ContentAssistHandler2 cah = new ContentAssistHandler2(text, new TextContentAssistSubjectAdapter(text), contentAssistant, cueLabel);
return cah;
}
private ContentAssistHandler2(
Control control,
AbstractControlContentAssistSubjectAdapter subjectAdapter,
SubjectControlContentAssistant contentAssistant,
ILabelProvider cueLabel) {
this.control = control;
assistant = contentAssistant;
adapter = subjectAdapter;
this.cueLabel = cueLabel;
setEnabled(true);
control.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
setEnabled(false);
}
});
}
public boolean isEnabled() {
return focusListener != null;
}
public void setEnabled(boolean enable) {
if (enable == isEnabled()) return;
if (enable) enable(); else disable();
}
private void enable() {
if (!control.isDisposed()) {
if(assistant instanceof SubjectControlContentAssistant) {
((SubjectControlContentAssistant)assistant).install(adapter);
}
installCueLabelProvider();
installFocusListener();
if (control.isFocusControl())
activate();
}
}
private void disable() {
if (!control.isDisposed()) {
assistant.uninstall();
adapter.setContentAssistCueProvider(null);
control.removeFocusListener(focusListener);
focusListener= null;
if (activation != null)
deactivate();
}
}
private void installCueLabelProvider() {
adapter.setContentAssistCueProvider(cueLabel);
}
private void installFocusListener() {
focusListener = new FocusListener() {
public void focusGained(final FocusEvent e) {
if(control instanceof Text && !control.isDisposed()) {
((Text)control).addModifyListener(getModifyListener());
}
activate();
}
public void focusLost(FocusEvent e) {
if (activation != null)
if(control instanceof Text && modifyListener != null && !control.isDisposed()) {
((Text)control).removeModifyListener(modifyListener);
}
deactivate();
}
};
control.addFocusListener(focusListener);
}
ModifyListener getModifyListener() {
if(modifyListener == null) {
modifyListener = new ModifyListenerImpl();
}
return modifyListener;
}
class ModifyListenerImpl implements ModifyListener {
public void modifyText(ModifyEvent e) {
if(control == null || control.isDisposed()) return;
if(control.isFocusControl()) {
Control c = control.getParent();
while (c != null) {
c.redraw();
if(c instanceof Shell) break; else c = c.getParent();
}
}
}
}
private void activate() {
IHandlerService hs = (IHandlerService)PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
if (hs == null) return;
activation = hs.activateHandler(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS, new H());
}
class H extends AbstractHandler {
public Object execute(ExecutionEvent event) throws ExecutionException {
if (ContentAssistHandler2.this.isEnabled()) // don't call AbstractHandler#isEnabled()!
assistant.showPossibleCompletions();
return null;
}
}
private void deactivate() {
IHandlerService hs = (IHandlerService)PlatformUI.getWorkbench().getAdapter(IHandlerService.class);
if (hs != null) hs.deactivateHandler(activation);
activation = null;
}
}