blob: 6a49431d6051f6b8e7c0831e736a9cd20ea24129 [file] [log] [blame]
package org.eclipse.jface.text.contentassist;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IEventConsumer;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.util.Assert;
/**
* The standard implementation of the <code>IContentAssistant</code> interface.
* Usually, clients instantiate this class and configure it before using it.
*/
public class ContentAssistant implements IContentAssistant {
/**
* A generic closer class used to monitor various
* interface events in order to determine whether
* content-assist should be terminated and all
* associated windows closed.
*/
class Closer implements ControlListener, MouseListener, FocusListener, IViewportListener {
protected void install() {
Control w= fViewer.getTextWidget();
if (Helper.okToUse(w)) {
Control shell= w.getShell();
shell.addControlListener(this);
w.addMouseListener(this);
w.addFocusListener(this);
}
fViewer.addViewportListener(this);
}
protected void uninstall() {
Control w= fViewer.getTextWidget();
if (Helper.okToUse(w)) {
Control shell= w.getShell();
shell.removeControlListener(this);
w.removeMouseListener(this);
w.removeFocusListener(this);
}
fViewer.removeViewportListener(this);
}
// WindowListener
public void controlResized(ControlEvent e) {
hide();
}
public void controlMoved(ControlEvent e) {
hide();
}
// MouseListener
public void mouseDown(MouseEvent e) {
hide();
}
public void mouseUp(MouseEvent e) {
}
public void mouseDoubleClick(MouseEvent e) {
hide();
}
// FocusListener
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e) {
Control control= fViewer.getTextWidget();
Display d= control.getDisplay();
d.asyncExec(new Runnable() {
public void run() {
if (!fProposalPopup.hasFocus() && !fContextInfoPopup.hasFocus()) {
hide();
}
}
});
}
// IViewPortListener
public void viewportChanged(int topIndex) {
hide();
}
/**
* Hides any open popups.
*/
protected void hide() {
fProposalPopup.hide();
fContextInfoPopup.hide();
}
};
/**
* An implementation of IContentAssistListener, this class is
* used to monitor key events in support of automatic activation
* of the content assistant. If enabled, the implementation utilizes a
* thread to watch for input characters matching the activation
* characters specified by the content assist processor, and if
* detected, will wait the indicated delay interval before
* activating the content assistant.
*/
class AutoAssistListener implements IContentAssistListener, Runnable {
private Thread fThread;
private int fDelayInterval;
private boolean fIsReset= false;
private Object fMutex= new Object();
private int fShowStyle;
private final static int SHOW_PROPOSALS= 1;
private final static int SHOW_CONTEXT_INFO= 2;
protected AutoAssistListener(int delayInterval) {
fDelayInterval= delayInterval;
}
protected void start(int showStyle) {
fShowStyle= showStyle;
fThread= new Thread(this, "AutoAssist Delay"); //$NON-NLS-1$
fThread.start();
}
public void run() {
try {
while (true) {
synchronized (fMutex) {
fMutex.wait(fDelayInterval);
if (fIsReset) {
fIsReset= false;
continue;
}
}
showAssist(fShowStyle);
break;
}
} catch (InterruptedException e) {
}
fThread= null;
}
protected void reset(int showStyle) {
synchronized (fMutex) {
fShowStyle= showStyle;
fIsReset= true;
fMutex.notifyAll();
}
}
protected void stop() {
if (fThread != null) {
fThread.interrupt();
}
}
private boolean contains(char[] characters, char character) {
if (characters != null) {
for (int i= 0; i < characters.length; i++) {
if (character == characters[i])
return true;
}
}
return false;
}
public boolean verifyKey(VerifyEvent e) {
int showStyle;
int pos= fViewer.getSelectedRange().x;
char[] activation= getCompletionProposalAutoActivationCharacters(fViewer.getDocument(), pos);
if (contains(activation, e.character) && !fProposalPopup.isActive())
showStyle= SHOW_PROPOSALS;
else {
activation= getContextInformationAutoActivationCharacters(fViewer.getDocument(), pos);
if (contains(activation, e.character) && !fContextInfoPopup.isActive())
showStyle= SHOW_CONTEXT_INFO;
else {
if (fThread != null && fThread.isAlive())
stop();
return true;
}
}
if (fThread != null && fThread.isAlive())
reset(showStyle);
else
start(showStyle);
return false;
}
public void processEvent(VerifyEvent e) {}
protected void showAssist(final int showStyle) {
Control control= fViewer.getTextWidget();
Display d= control.getDisplay();
if (d != null) {
try {
d.syncExec(new Runnable() {
public void run() {
if (showStyle == SHOW_PROPOSALS)
fProposalPopup.showProposals(false);
else if (showStyle == SHOW_CONTEXT_INFO)
fContextInfoPopup.showContextProposals(false);
}
});
} catch (SWTError e) {
}
}
}
};
/**
* The laypout manager layouts the various
* windows associated with the content assistant based on the
* settings of the content assistant.
*/
class LayoutManager implements Listener {
// Presentation types.
public final static int LAYOUT_PROPOSAL_SELECTOR= 0;
public final static int LAYOUT_CONTEXT_SELECTOR= 1;
public final static int LAYOUT_CONTEXT_INFO_POPUP= 2;
int fContextType= LAYOUT_CONTEXT_SELECTOR;
Shell[] fShells= new Shell[3];
Object[] fPopups= new Object[3];
protected void add(Object popup, Shell shell, int type) {
Assert.isNotNull(popup);
Assert.isTrue(shell != null && !shell.isDisposed());
checkType(type);
if (fShells[type] != shell) {
if (fShells[type] != null)
fShells[type].removeListener(SWT.Dispose, this);
shell.addListener(SWT.Dispose, this);
fShells[type]= shell;
}
fPopups[type]= popup;
if (type == LAYOUT_CONTEXT_SELECTOR || type == LAYOUT_CONTEXT_INFO_POPUP)
fContextType= type;
layout(type);
adjustListeners(type);
}
protected void checkType(int type) {
Assert.isTrue(type == LAYOUT_PROPOSAL_SELECTOR ||
type == LAYOUT_CONTEXT_SELECTOR || type == LAYOUT_CONTEXT_INFO_POPUP);
}
public void handleEvent(Event event) {
Widget source= event.widget;
source.removeListener(SWT.Dispose, this);
int type= getShellType(source);
checkType(type);
fShells[type]= null;
switch (type) {
case LAYOUT_PROPOSAL_SELECTOR:
if (fContextType == LAYOUT_CONTEXT_SELECTOR &&
Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
// Restore event notification to the tip popup.
addContentAssistListener((IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
}
break;
case LAYOUT_CONTEXT_SELECTOR:
if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
if (fProposalPopupOrientation == PROPOSAL_STACKED)
layout(LAYOUT_PROPOSAL_SELECTOR);
// Restore event notification to the proposal popup.
addContentAssistListener((IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
}
fContextType= LAYOUT_CONTEXT_INFO_POPUP;
break;
case LAYOUT_CONTEXT_INFO_POPUP:
if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
if (fContextInfoPopupOrientation == CONTEXT_INFO_BELOW)
layout(LAYOUT_PROPOSAL_SELECTOR);
}
fContextType= LAYOUT_CONTEXT_SELECTOR;
break;
}
}
protected int getShellType(Widget shell) {
for (int i=0; i<fShells.length; i++) {
if (fShells[i] == shell)
return i;
}
return -1;
}
protected void layout(int type) {
switch (type) {
case LAYOUT_PROPOSAL_SELECTOR:
layoutProposalSelector();
break;
case LAYOUT_CONTEXT_SELECTOR:
layoutContextSelector();
break;
case LAYOUT_CONTEXT_INFO_POPUP:
layoutContextInfoPopup();
break;
}
}
protected void layoutProposalSelector() {
if (fContextType == LAYOUT_CONTEXT_INFO_POPUP &&
fContextInfoPopupOrientation == CONTEXT_INFO_BELOW &&
Helper.okToUse(fShells[LAYOUT_CONTEXT_INFO_POPUP])) {
// Stack proposal selector beneath the tip box.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getStackedLocation(fShells[LAYOUT_CONTEXT_INFO_POPUP]));
} else if (fContextType != LAYOUT_CONTEXT_SELECTOR ||
!Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
// There are no other presentations to be concerned with,
// so place the proposal selector beneath the cursor line.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getBelowLocation());
} else {
switch (fProposalPopupOrientation) {
case PROPOSAL_REMOVE:
// Remove the tip selector and place the
// proposal selector beneath the cursor line.
fShells[LAYOUT_CONTEXT_SELECTOR].dispose();
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getBelowLocation());
break;
case PROPOSAL_OVERLAY:
// Overlay the tip selector with the proposal selector.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getBelowLocation());
break;
case PROPOSAL_STACKED:
// Stack the proposal selector beneath the tip selector.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getStackedLocation(fShells[LAYOUT_CONTEXT_SELECTOR]));
break;
}
}
}
protected void layoutContextSelector() {
// Always place the context selector beneath the cursor line.
fShells[LAYOUT_CONTEXT_SELECTOR].setLocation(getBelowLocation());
if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
switch (fProposalPopupOrientation) {
case PROPOSAL_REMOVE:
// Remove the proposal selector.
fShells[LAYOUT_PROPOSAL_SELECTOR].dispose();
break;
case PROPOSAL_OVERLAY:
// The proposal selector has been overlayed by the tip selector.
break;
case PROPOSAL_STACKED:
// Stack the proposal selector beneath the tip selector.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getStackedLocation(fShells[LAYOUT_CONTEXT_SELECTOR]));
break;
}
}
}
protected void layoutContextInfoPopup() {
switch (fContextInfoPopupOrientation) {
case CONTEXT_INFO_ABOVE:
// Place the popup above the cursor line.
Point position= getAboveLocation();
position.y -= fShells[LAYOUT_CONTEXT_INFO_POPUP].getSize().y;
fShells[LAYOUT_CONTEXT_INFO_POPUP].setLocation(position);
break;
case CONTEXT_INFO_BELOW:
// Place the popup beneath the cursor line.
fShells[LAYOUT_CONTEXT_INFO_POPUP].setLocation(getBelowLocation());
if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
// Stack the proposal selector beneath the context info popup.
fShells[LAYOUT_PROPOSAL_SELECTOR].setLocation(getStackedLocation(fShells[LAYOUT_CONTEXT_INFO_POPUP]));
}
break;
}
}
protected Point getAboveLocation() {
StyledText text= fViewer.getTextWidget();
int caret= text.getCaretOffset();
Point p= text.getLocationAtOffset(caret);
return text.toDisplay(p);
}
protected Point getBelowLocation() {
StyledText text= fViewer.getTextWidget();
Point p= getAboveLocation();
return new Point(p.x, p.y + text.getLineHeight());
}
protected Point getStackedLocation(Shell shell) {
Point p= shell.getLocation();
Point size= shell.getSize();
p.x += size.x / 4;
p.y += size.y;
return p;
}
protected void adjustListeners(int type) {
switch (type) {
case LAYOUT_PROPOSAL_SELECTOR:
if (fContextType == LAYOUT_CONTEXT_SELECTOR &&
Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR]))
// Disable event notification to the tip selector.
removeContentAssistListener((IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
break;
case LAYOUT_CONTEXT_SELECTOR:
if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR]))
// Disable event notification to the proposal selector.
removeContentAssistListener((IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
break;
case LAYOUT_CONTEXT_INFO_POPUP:
break;
}
}
};
/**
* Internal key listener and event consumer.
*/
class InternalListener implements VerifyKeyListener, IEventConsumer {
/**
* Verifies key events by notifying the registered listeners.
* Each listener is allowed to indicate that the event has been
* handled and should not be further processed.
*
* @param event the verify event
* @see VerifyKeyListener#verifyKey
*/
public void verifyKey(VerifyEvent e) {
IContentAssistListener[] listeners= (IContentAssistListener[]) fListeners.clone();
for (int i= 0; i < listeners.length; i++) {
if (listeners[i] != null) {
if (!listeners[i].verifyKey(e) || !e.doit)
return;
}
}
}
/*
* @see IEventConsumer#processEvent
*/
public void processEvent(VerifyEvent event) {
installKeyListener();
IContentAssistListener[] listeners= (IContentAssistListener[])fListeners.clone();
for (int i= 0; i < listeners.length; i++) {
if (listeners[i] != null) {
listeners[i].processEvent(event);
if (!event.doit)
return;
}
}
}
};
// Content-Assist Listener types
final static int AUTO_ASSIST= 0;
final static int CONTEXT_SELECTOR= 1;
final static int PROPOSAL_SELECTOR= 2;
final static int CONTEXT_INFO_POPUP= 3;
private int fAutoActivationDelay= 500;
private boolean fIsAutoActivated= false;
private int fProposalPopupOrientation= PROPOSAL_OVERLAY;
private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE;
private Color fContextInfoPopupBackground;
private Map fProcessors;
private ITextViewer fViewer;
private String fLastErrorMessage;
private Closer fCloser;
private LayoutManager fLayoutManager;
private AutoAssistListener fAutoAssistListener;
private InternalListener fInternalListener;
private CompletionProposalPopup fProposalPopup;
private ContextInformationPopup fContextInfoPopup;
private boolean fKeyListenerHooked= false;
private IContentAssistListener[] fListeners= new IContentAssistListener[4];
/**
* Creates a new content assistant. The content assistant is not automatically activated,
* overlays the completion proposals with context information list if necessary, and
* shows the context information above the location at which it was activated. If auto
* activation will be enabled, without further configuration steps, this content assistant
* is activated after a 500 ms delay.
*/
public ContentAssistant() {
}
/**
* Registers a content assist listener.
* The following are valid listener types:
* <ul>
* <li>AUTO_ASSIST
* <li>CONTEXT_SELECTOR
* <li>PROPOSAL_SELECTOR
* <li>CONTEXT_INFO_POPUP
* <ul>
*
* @param listener the listener to register
* @param type the type of listener
*/
void addContentAssistListener(IContentAssistListener listener, int type) {
fListeners[type]= listener;
if (fCloser == null && isCloserNeeded()) {
fCloser= new Closer();
fCloser.install();
}
if (isListenerHookNeeded()) {
fViewer.setEventConsumer(fInternalListener);
installKeyListener();
}
}
/**
* Adds the given shell of the specified type to the layout.
* Valid types are defined by <code>LayoutManager</code>.
*
* @param popup a content assist popup
* @param shell the shell of the content-assist popup
* @param type the type of popup
*/
void addToLayout(Object popup, Shell shell, int type) {
fLayoutManager.add(popup, shell, type);
}
/**
* Returns an array of completion proposals computed based on
* the specified document position. The position is used to
* determine the appropriate content assist processor to invoke.
*
* @param viewer the viewer for which to compute the prosposals
* @param position a document position
* @return an array of completion proposals
*
* @see IContentAssistProcessor#computeCompletionProposals
*/
ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int position) {
fLastErrorMessage= null;
ICompletionProposal[] result= null;
IContentAssistProcessor p= getProcessor(viewer.getDocument(), position);
if (p != null) {
result= p.computeCompletionProposals(viewer, position);
fLastErrorMessage= p.getErrorMessage();
}
return result;
}
/**
* Returns an array of context information objects computed based
* on the specified document position. The position is used to determine
* the appropriate content assist processor to invoke.
*
* @param viewer the viewer for which to compute the context information
* @param position a document position
* @return an array of context information objects
*
* @see IContentAssistProcessor#computeContextInformation
*/
IContextInformation[] computeContextInformation(ITextViewer viewer, int position) {
fLastErrorMessage= null;
IContextInformation[] result= null;
IContentAssistProcessor p= getProcessor(viewer.getDocument(), position);
if (p != null) {
result= p.computeContextInformation(viewer, position);
fLastErrorMessage= p.getErrorMessage();
}
return result;
}
/**
* Sets the content assistant's auto activation state.
*
* @param enabled indicates whether auto activation is enabled or not
*/
public void enableAutoActivation(boolean enabled) {
fIsAutoActivated= enabled;
}
/**
* Returns the characters which when typed by the user should automatically
* initiate proposing completions. The position is used to determine the
* appropriate content assist processor to invoke.
*
* @param document the document
* @param position a document position
* @return the auto activation characters
*
* @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters
*/
private char[] getCompletionProposalAutoActivationCharacters(IDocument document, int position) {
IContentAssistProcessor p= getProcessor(document, position);
if (p != null)
return p.getCompletionProposalAutoActivationCharacters();
return null;
}
/*
* @see IContentAssistant#getContentAssistProcessor
*/
public IContentAssistProcessor getContentAssistProcessor(String contentType) {
if (fProcessors == null)
return null;
return (IContentAssistProcessor) fProcessors.get(contentType);
}
/**
* Returns the background of the context information popup.
*
* @return the background of the context information popup
*/
Color getContextInfoPopupBackground() {
return fContextInfoPopupBackground;
}
/**
* Returns the characters which when typed by the user should automatically
* initiate the presenation of context information. The position is used
* to determine the appropriate content assist processor to invoke.
*
* @param document the document
* @param position a document position
* @return the auto activation characters
*
* @see IContentAssistProcessor#getContextInformationAutoActivationCharacters
*/
private char[] getContextInformationAutoActivationCharacters(IDocument document, int position) {
IContentAssistProcessor p= getProcessor(document, position);
if (p != null)
return p.getContextInformationAutoActivationCharacters();
return null;
}
/**
* Returns the context information validator that should be used to
* determine when the currently displayed context information should
* be dismissed. The position is used to determine the appropriate
* content assist processor to invoke.
*
* @param document the document
* @param position a document position
* @return an array of validator
*
* @see IContentAssistProcessor#getContextInformationValidator
*/
IContextInformationValidator getContextInformationValidator(IDocument document, int position) {
IContentAssistProcessor p= getProcessor(document, position);
if (p != null)
return p.getContextInformationValidator();
return null;
}
/**
* Returns the current content assist error message.
*
* @return an error message or <code>null</code> if no error has occurred
*/
String getErrorMessage() {
return fLastErrorMessage;
}
/**
* Returns the content assist processor for the content
* type of the specified document position.
*
* @param document the document
* @param position a position within the document
* @return a content-assist processor or <code>null</code> if none exists
*/
private IContentAssistProcessor getProcessor(IDocument document, int position) {
try {
String type= document.getContentType(position);
return getContentAssistProcessor(type);
} catch (BadLocationException x) {
}
return null;
}
/*
* @see IContentAssist#install
*/
public void install(ITextViewer textViewer) {
Assert.isNotNull(textViewer);
fViewer= textViewer;
fLayoutManager= new LayoutManager();
fInternalListener= new InternalListener();
fContextInfoPopup= new ContextInformationPopup(this, fViewer);
fProposalPopup= new CompletionProposalPopup(this, fViewer, new AdditionalInfoPopup(fAutoActivationDelay));
if (fIsAutoActivated) {
fAutoAssistListener= new AutoAssistListener(fAutoActivationDelay);
addContentAssistListener(fAutoAssistListener, AUTO_ASSIST);
}
}
/**
* Installs a key listener on the text viewer's widget.
*/
private void installKeyListener() {
if (!fKeyListenerHooked) {
StyledText text= fViewer.getTextWidget();
if (Helper.okToUse(text)) {
text.addVerifyKeyListener(fInternalListener);
fKeyListenerHooked= true;
}
}
}
/**
* Returns whether a closer should be installed.
* A single, shared closer is used to monitor for events
* that should result in any open popups being closed.
*
* @return <code>true</code> if a closer is needed
*/
private boolean isCloserNeeded() {
// Do not include AUTO_ASSIST as it doesn't need a closer.
for (int i= CONTEXT_SELECTOR; i <= CONTEXT_INFO_POPUP; i++) {
if (fListeners[i] != null)
return true;
}
return false;
}
/**
* Returns whether a listener hook should be installed.
* A single, shared listener is used to monitor for events
* that are to be propagated to the registered listeners.
*
* @return <code>true</code> if a listener hook is needed
*/
private boolean isListenerHookNeeded() {
for (int i= AUTO_ASSIST; i <= CONTEXT_INFO_POPUP; i++) {
if (fListeners[i] != null)
return true;
}
return false;
}
/**
* Notifies the controller that a popup has lost focus.
*
* @param e the focus event
*/
void popupFocusLost(FocusEvent e) {
fCloser.focusLost(e);
}
/**
* Unregisters a content assist listener.
*
* @param listener the listener to unregister
* @param type the type of listener
*
* @see #addContentAssistListener
*/
void removeContentAssistListener(IContentAssistListener listener, int type) {
fListeners[type]= null;
if (fCloser != null && !isCloserNeeded()) {
fCloser.uninstall();
fCloser= null;
}
if (!isListenerHookNeeded()) {
uninstallKeyListener();
fViewer.setEventConsumer(null);
}
}
/**
* Sets the delay after which the content assistant is automatically invoked
* if the cursor is behind an auto activation character.
*
* @param delay the auto activation delay
*/
public void setAutoActivationDelay(int delay) {
fAutoActivationDelay= delay;
}
/**
* Registers a given content assist processor for a particular content type.
* If there is already a processor registered for this type, the new processor
* is registered instead of the old one.
*
* @param processor the content assist processor to register, or <code>null</code> to remove an existing one
* @param contentType the content type under which to register
*/
public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) {
Assert.isNotNull(contentType);
if (fProcessors == null)
fProcessors= new HashMap();
if (processor == null)
fProcessors.remove(contentType);
else
fProcessors.put(contentType, processor);
}
/**
* Sets the context information popup's background color.
*
* @param background the background color
*/
public void setContextInformationPopupBackground(Color background) {
fContextInfoPopupBackground= background;
}
/**
* Sets the context information popup's orientation
* The following values may be used:
* <ul>
* <li>CONTEXT_ABOVE<p>
* context information popup should always appear above the line containing
* the current cursor location
* </li>
* <li>CONTEXT_BELOW<p>
* context information popup should always appear below the line containing
* the current cursor location
* </li>
* </ul>
*
* @param orientation the popup's orientation
*/
public void setContextInformationPopupOrientation(int orientation) {
fContextInfoPopupOrientation= orientation;
}
/**
* Sets the proposal popups' orientation
* The following values may be used:
* <ul>
* <li>PROPOSAL_OVERLAY<p>
* proposal popup windows should overlay each other
* </li>
* <li>PROPOSAL_REMOVE<p>
* any currently shown proposal popup should be closed
* </li>
* <li>PROPOSAL_STACKED<p>
* proposal popup windows should be vertical stacked, with no overlap,
* beneath the line containing the current cursor location
* </li>
* </ul>
*
* @param orientation the popup's orientation
*/
public void setProposalPopupOrientation(int orientation) {
fProposalPopupOrientation= orientation;
}
/*
* @see IContentAssist#showContextInformation
*/
public String showContextInformation() {
return fContextInfoPopup.showContextProposals(true);
}
/**
* Requests that the specified context information to be shown.
*
* @param contextInformation the context information to be shown
*/
void showContextInformation(IContextInformation contextInformation) {
fContextInfoPopup.showContextInformation(contextInformation);
}
/*
* @see IContentAssist#showPossibleCompletions
*/
public String showPossibleCompletions() {
return fProposalPopup.showProposals(true);
}
/*
* @see IContentAssist#uninstall
*/
public void uninstall() {
if (fAutoAssistListener != null) {
removeContentAssistListener(fAutoAssistListener, AUTO_ASSIST);
fAutoAssistListener= null;
}
}
/**
* Uninstall the key listener from the text viewer's widget.
*/
private void uninstallKeyListener() {
if (fKeyListenerHooked) {
StyledText text= fViewer.getTextWidget();
if (Helper.okToUse(text)) {
text.removeVerifyKeyListener(fInternalListener);
fKeyListenerHooked= false;
}
}
}
}