/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.ui.internal.texteditor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.jface.text.AbstractInformationControlManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.IAnnotationHoverExtension;
import org.eclipse.jface.text.source.ILineRange;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
/**
* Information presenter used to present focused ("sticky") information shells.
*
* @since 3.5
*/
public class FocusedInformationPresenter extends InformationPresenter {
/**
* Information provider used to present focused information shells.
*/
public final static class InformationProvider implements IInformationProvider, IInformationProviderExtension, IInformationProviderExtension2 {
private IRegion fHoverRegion;
private Object fHoverInfo;
private IInformationControlCreator fControlCreator;
public InformationProvider(IRegion hoverRegion, Object hoverInfo, IInformationControlCreator controlCreator) {
fHoverRegion= hoverRegion;
fHoverInfo= hoverInfo;
fControlCreator= controlCreator;
}
/*
* @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int)
*/
public IRegion getSubject(ITextViewer textViewer, int invocationOffset) {
return fHoverRegion;
}
/**
* {@inheritDoc}
*
* @deprecated As of 2.1, replaced by {@link IInformationProviderExtension#getInformation2(ITextViewer, IRegion)}
*/
public String getInformation(ITextViewer textViewer, IRegion subject) {
return fHoverInfo == null ? null : fHoverInfo.toString();
}
/*
* @see org.eclipse.jface.text.information.IInformationProviderExtension#getInformation2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
* @since 3.2
*/
public Object getInformation2(ITextViewer textViewer, IRegion subject) {
return fHoverInfo;
}
/*
* @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
*/
public IInformationControlCreator getInformationPresenterControlCreator() {
return fControlCreator;
}
}
/**
* The default information control creator.
*/
private static class DefaultInformationControlCreator implements IInformationControlCreator {
public IInformationControl createInformationControl(Shell shell) {
return new DefaultInformationControl(shell, true);
}
}
private final ISourceViewer fSourceViewer;
private final SourceViewerConfiguration fSourceViewerConfiguration;
/**
* Creates a focused information presenter and installs it on the source viewer.
*
* @param sourceViewer the source viewer
* @param sourceViewerConfiguration the configuration
*/
public FocusedInformationPresenter(ISourceViewer sourceViewer, SourceViewerConfiguration sourceViewerConfiguration) {
super(new DefaultInformationControlCreator());
fSourceViewer= sourceViewer;
fSourceViewerConfiguration= sourceViewerConfiguration;
// sizes: see org.eclipse.jface.text.TextViewer.TEXT_HOVER_*_CHARS
setSizeConstraints(100, 12, true, true);
install(sourceViewer);
setDocumentPartitioning(sourceViewerConfiguration.getConfiguredDocumentPartitioning(sourceViewer));
}
/**
* Tries show a focused ("sticky") annotation hover.
*
* @param annotationHover the annotation hover to show
* @param line the line for which to show the hover
* @return <code>true</code> if successful, <code>false</code> otherwise
*/
public boolean openFocusedAnnotationHover(IAnnotationHover annotationHover, int line) {
try {
// compute the hover information
Object hoverInfo;
if (annotationHover instanceof IAnnotationHoverExtension) {
IAnnotationHoverExtension extension= (IAnnotationHoverExtension) annotationHover;
ILineRange hoverLineRange= extension.getHoverLineRange(fSourceViewer, line);
if (hoverLineRange == null)
return false;
final int maxVisibleLines= Integer.MAX_VALUE; // allow any number of lines being displayed, as we support scrolling
hoverInfo= extension.getHoverInfo(fSourceViewer, hoverLineRange, maxVisibleLines);
} else {
hoverInfo= annotationHover.getHoverInfo(fSourceViewer, line);
}
// hover region: the beginning of the concerned line to place the control right over the line
IDocument document= fSourceViewer.getDocument();
int offset= document.getLineOffset(line);
String contentType= TextUtilities.getContentType(document, fSourceViewerConfiguration.getConfiguredDocumentPartitioning(fSourceViewer), offset, true);
IInformationControlCreator controlCreator= null;
if (annotationHover instanceof IInformationProviderExtension2) // this is undocumented, but left here for backwards compatibility
controlCreator= ((IInformationProviderExtension2) annotationHover).getInformationPresenterControlCreator();
else if (annotationHover instanceof IAnnotationHoverExtension)
controlCreator= ((IAnnotationHoverExtension) annotationHover).getHoverControlCreator();
IInformationProvider informationProvider= new InformationProvider(new Region(offset, 0), hoverInfo, controlCreator);
setOffset(offset);
setAnchor(AbstractInformationControlManager.ANCHOR_RIGHT);
setMargins(4, 0); // AnnotationBarHoverManager sets (5,0), minus SourceViewer.GAP_SIZE_1
setInformationProvider(informationProvider, contentType);
showInformation();
return true;
} catch (BadLocationException e) {
return false;
}
}
}