/**
* Copyright (c) 2005-2006 Aptana, Inc.
*
* All rights reserved. This program and the accompanying materials
* are 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. If redistributing this code,
* this entire header must remain intact.
*/
package com.aptana.ide.editors.unified.contentassist;
/***********************************************************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others. All rights reserved. This program and the accompanying materials
* are 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: IBM Corporation - initial API and implementation
**********************************************************************************************************************/
import org.eclipse.jface.contentassist.IContentAssistSubjectControl;
import org.eclipse.jface.contentassist.ISubjectControlContextInformationPresenter;
import org.eclipse.jface.contentassist.ISubjectControlContextInformationValidator;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IEventConsumer;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import com.aptana.ide.editors.unified.contentassist.ContextInformationPopup.ContextFrame;
/**
* This code assist adapter delegates the calls either to a text viewer or to a code assist subject control.
*
* @since 3.0
*/
final class ContentAssistSubjectControlAdapter implements IContentAssistSubjectControl
{
/**
* The text viewer which is used as code assist subject control.
*/
private ITextViewer fViewer;
/**
* The code assist subject control.
*/
private IContentAssistSubjectControl fContentAssistSubjectControl;
/**
* Creates an adapter for the given code assist subject control.
*
* @param contentAssistSubjectControl
* the code assist subject control
*/
ContentAssistSubjectControlAdapter(IContentAssistSubjectControl contentAssistSubjectControl)
{
Assert.isNotNull(contentAssistSubjectControl);
fContentAssistSubjectControl = contentAssistSubjectControl;
}
/**
* Creates an adapter for the given text viewer.
*
* @param viewer
* the text viewer
*/
public ContentAssistSubjectControlAdapter(ITextViewer viewer)
{
Assert.isNotNull(viewer);
fViewer = viewer;
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getLineHeight()
*/
public int getLineHeight()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getLineHeight();
}
return fViewer.getTextWidget().getLineHeight();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getControl()
*/
public Control getControl()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getControl();
}
return fViewer.getTextWidget();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getLocationAtOffset(int)
*/
public Point getLocationAtOffset(int offset)
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getLocationAtOffset(offset);
}
int charCount = fViewer.getTextWidget().getCharCount();
int tempOffset = offset;
if (tempOffset > charCount)
{
tempOffset = charCount;
}
if (tempOffset < 0)
{
tempOffset = 0;
}
// TODO: offset > getCharCount on sporadic occasions. Have to figure out why. Added guard to
// stop exceptions
return fViewer.getTextWidget().getLocationAtOffset(tempOffset);
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getWidgetSelectionRange()
*/
public Point getWidgetSelectionRange()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getWidgetSelectionRange();
}
return fViewer.getTextWidget().getSelectionRange();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getSelectedRange()
*/
public Point getSelectedRange()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getSelectedRange();
}
return fViewer.getSelectedRange();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getCaretOffset()
*/
public int getCaretOffset()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getCaretOffset();
}
return fViewer.getTextWidget().getCaretOffset();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getLineDelimiter()
*/
public String getLineDelimiter()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getLineDelimiter();
}
return fViewer.getTextWidget().getLineDelimiter();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#addKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void addKeyListener(KeyListener keyListener)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.addKeyListener(keyListener);
}
else
{
fViewer.getTextWidget().addKeyListener(keyListener);
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#removeKeyListener(org.eclipse.swt.events.KeyListener)
*/
public void removeKeyListener(KeyListener keyListener)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.removeKeyListener(keyListener);
}
else
{
fViewer.getTextWidget().removeKeyListener(keyListener);
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#getDocument()
*/
public IDocument getDocument()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.getDocument();
}
return fViewer.getDocument();
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#prependVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
*/
public boolean prependVerifyKeyListener(VerifyKeyListener verifyKeyListener)
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.prependVerifyKeyListener(verifyKeyListener);
}
else if (fViewer instanceof ITextViewerExtension)
{
ITextViewerExtension e = (ITextViewerExtension) fViewer;
e.prependVerifyKeyListener(verifyKeyListener);
return true;
}
else
{
StyledText textWidget = fViewer.getTextWidget();
if (Helper.okToUse(textWidget))
{
textWidget.addVerifyKeyListener(verifyKeyListener);
return true;
}
}
return false;
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#appendVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
*/
public boolean appendVerifyKeyListener(VerifyKeyListener verifyKeyListener)
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.appendVerifyKeyListener(verifyKeyListener);
}
else if (fViewer instanceof ITextViewerExtension)
{
ITextViewerExtension extension = (ITextViewerExtension) fViewer;
extension.appendVerifyKeyListener(verifyKeyListener);
return true;
}
else
{
StyledText textWidget = fViewer.getTextWidget();
if (Helper.okToUse(textWidget))
{
textWidget.addVerifyKeyListener(verifyKeyListener);
return true;
}
}
return false;
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#removeVerifyKeyListener(org.eclipse.swt.custom.VerifyKeyListener)
*/
public void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.removeVerifyKeyListener(verifyKeyListener);
}
else if (fViewer instanceof ITextViewerExtension)
{
ITextViewerExtension extension = (ITextViewerExtension) fViewer;
extension.removeVerifyKeyListener(verifyKeyListener);
}
else
{
StyledText textWidget = fViewer.getTextWidget();
if (Helper.okToUse(textWidget))
{
textWidget.removeVerifyKeyListener(verifyKeyListener);
}
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#setEventConsumer(org.eclipse.jface.text.IEventConsumer)
*/
public void setEventConsumer(IEventConsumer eventConsumer)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.setEventConsumer(eventConsumer);
}
else
{
fViewer.setEventConsumer(eventConsumer);
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#setSelectedRange(int, int)
*/
public void setSelectedRange(int i, int j)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.setSelectedRange(i, j);
}
else
{
fViewer.setSelectedRange(i, j);
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#revealRange(int, int)
*/
public void revealRange(int i, int j)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.revealRange(i, j);
}
else
{
fViewer.revealRange(i, j);
}
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#supportsVerifyKeyListener()
*/
public boolean supportsVerifyKeyListener()
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.supportsVerifyKeyListener();
}
return true;
}
/**
* Returns the characters which when typed by the user should automatically initiate proposing completions. The
* position is used to determine the appropriate code assist processor to invoke.
*
* @param contentAssistant
* the code assistant
* @param offset
* a document offset
* @return the auto activation characters
*/
public char[] getCompletionProposalAutoActivationCharacters(ContentAssistant contentAssistant, int offset)
{
if (fContentAssistSubjectControl != null)
{
return contentAssistant.getCompletionProposalAutoActivationCharacters(fContentAssistSubjectControl, offset);
}
return contentAssistant.getCompletionProposalAutoActivationCharacters(fViewer, offset);
}
/**
* Returns the characters which when typed by the user should automatically initiate the presentation of context
* information. The position is used to determine the appropriate code assist processor to invoke.
*
* @param contentAssistant
* the code assistant
* @param offset
* a document offset
* @return the auto activation characters
* @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
*/
char[] getContextInformationAutoActivationCharacters(ContentAssistant contentAssistant, int offset)
{
if (fContentAssistSubjectControl != null)
{
return contentAssistant.getContextInformationAutoActivationCharacters(fContentAssistSubjectControl, offset);
}
return contentAssistant.getContextInformationAutoActivationCharacters(fViewer, offset);
}
/**
* Creates and returns a completion proposal popup for the given code assistant.
*
* @param contentAssistant
* the code assistant
* @param controller
* the additional info controller
* @return the completion proposal popup
*/
CompletionProposalPopup createCompletionProposalPopup(ContentAssistant contentAssistant,
AdditionalInfoController controller)
{
if (fContentAssistSubjectControl != null)
{
return new CompletionProposalPopup(contentAssistant, fContentAssistSubjectControl, controller);
}
return new CompletionProposalPopup(contentAssistant, fViewer, controller);
}
/**
* Creates and returns a context info popup for the given code assistant.
*
* @param contentAssistant
* the code assistant
* @return the context info popup or <code>null</code>
*/
ContextInformationPopup createContextInfoPopup(ContentAssistant contentAssistant)
{
if (fContentAssistSubjectControl != null)
{
return new ContextInformationPopup(contentAssistant, fContentAssistSubjectControl);
}
return new ContextInformationPopup(contentAssistant, fViewer);
}
/**
* 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 code assist processor to
* invoke.
*
* @param contentAssistant
* the code assistant
* @param offset
* a document offset
* @return an validator
*/
public IContextInformationValidator getContextInformationValidator(ContentAssistant contentAssistant, int offset)
{
if (fContentAssistSubjectControl != null)
{
return contentAssistant.getContextInformationValidator(fContentAssistSubjectControl, offset);
}
return contentAssistant.getContextInformationValidator(fViewer, offset);
}
/**
* Returns the context information presenter that should be used to display context information. The position is
* used to determine the appropriate code assist processor to invoke.
*
* @param contentAssistant
* the code assistant
* @param offset
* a document offset
* @return a presenter
*/
public IContextInformationPresenter getContextInformationPresenter(ContentAssistant contentAssistant, int offset)
{
if (fContentAssistSubjectControl != null)
{
return contentAssistant.getContextInformationPresenter(fContentAssistSubjectControl, offset);
}
return contentAssistant.getContextInformationPresenter(fViewer, offset);
}
/**
* Installs this adapter's information validator on the given context frame.
*
* @param frame
* the context frame
*/
public void installValidator(ContextFrame frame)
{
if (fContentAssistSubjectControl != null)
{
if (frame.fValidator instanceof ISubjectControlContextInformationValidator)
{
((ISubjectControlContextInformationValidator) frame.fValidator).install(frame.fInformation,
fContentAssistSubjectControl, frame.fOffset);
}
}
else
{
frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset);
}
}
/**
* Installs this adapter's information presenter on the given context frame.
*
* @param frame
* the context frame
*/
public void installContextInformationPresenter(ContextFrame frame)
{
if (fContentAssistSubjectControl != null)
{
if (frame.fPresenter instanceof ISubjectControlContextInformationPresenter)
{
((ISubjectControlContextInformationPresenter) frame.fValidator).install(frame.fInformation,
fContentAssistSubjectControl, frame.fBeginOffset);
}
}
else
{
frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset);
}
}
/**
* Returns an array of context information objects computed based on the specified document position. The position
* is used to determine the appropriate code assist processor to invoke.
*
* @param contentAssistant
* the code assistant
* @param offset
* a document offset
* @return an array of context information objects
*/
public IContextInformation[] computeContextInformation(ContentAssistant contentAssistant, int offset)
{
if (fContentAssistSubjectControl != null)
{
return contentAssistant.computeContextInformation(fContentAssistSubjectControl, offset);
}
return contentAssistant.computeContextInformation(fViewer, offset);
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#addSelectionListener(org.eclipse.swt.events.SelectionListener)
*/
public boolean addSelectionListener(SelectionListener selectionListener)
{
if (fContentAssistSubjectControl != null)
{
return fContentAssistSubjectControl.addSelectionListener(selectionListener);
}
fViewer.getTextWidget().addSelectionListener(selectionListener);
return true;
}
/**
* @see org.eclipse.jface.contentassist.IContentAssistSubjectControl#removeSelectionListener(org.eclipse.swt.events.SelectionListener)
*/
public void removeSelectionListener(SelectionListener selectionListener)
{
if (selectionListener != null)
{
if (fContentAssistSubjectControl != null)
{
fContentAssistSubjectControl.removeSelectionListener(selectionListener);
}
else
{
fViewer.getTextWidget().removeSelectionListener(selectionListener);
}
}
}
}