/******************************************************************************* * Copyright (c) 2014 Pivotal, 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 * * Contributors: * Pivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.editor.support.hover; import org.eclipse.jface.internal.text.html.BrowserInformationControlInput; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.ITextHoverExtension; import org.eclipse.jface.text.ITextHoverExtension2; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.ui.editors.text.EditorsUI; import org.springframework.ide.eclipse.editor.support.util.HtmlUtil; /** * An implementation of Eclipse's {@link ITextHover} and some of its clunky 'extension' * interfaces, that wraps a simple 'HoverInfoProvider' (so that implementing something * to provide hover infos based on an editor's contents doesn't have to be horribly * complicated). * * @author Kris De Volder */ @SuppressWarnings("restriction") public class HoverInfoTextHover implements ITextHover, ITextHoverExtension, ITextHoverExtension2 { private HoverInfoProvider _hovers; private ITextHover delegate; /** * Create a {@link HoverInfoTextHover} based on a given {@link HoverInfoProvider}. It is also possible * to provide an optioanl {@link ITextHover} delegate. This 'wrapper' will try to delegate hover info * requests to the delegate and combine its results with our own {@link HoverInfoProvider} in some * sensible way. Note however that for this to work the delegate must produce hover informations * that can be properly displayed by our own {@link HoverInformationControl}, essentially this * means they must be based on {@link BrowserInformationControlInput}. If that is not the * case then our {@link HoverInformationControl} will not be able to display them correctly. */ public HoverInfoTextHover(ISourceViewer sourceViewer, HoverInfoProvider hoverInfoProvider, ITextHover delegate) { this._hovers = hoverInfoProvider; this.delegate = delegate; } public IRegion getHoverRegion(ITextViewer tv, int offset) { //Note that we ask the 'delegate' first. This is because it handles info about // error markers from annotations model. And this info should 'override' // information about property if (delegate!=null) { IRegion r = delegate.getHoverRegion(tv, offset); if (r!=null) { return r; } } return hovers_getHoverRegion(tv.getDocument(), offset); } public String getHoverInfo(ITextViewer tv, IRegion r) { String s = delegate.getHoverInfo(tv, r); if (s!=null) { return HtmlUtil.text2html(s); } return hovers_getHoverInfo(tv.getDocument(), r).getHtml(); } @Override public Object getHoverInfo2(ITextViewer tv, IRegion r) { if (delegate instanceof ITextHoverExtension2) { Object it = ((ITextHoverExtension2) delegate).getHoverInfo2(tv, r); if (it!=null) { if (it instanceof String) { return HtmlUtil.text2html((String)it); } else { return it; } } } else if (delegate instanceof ITextHover) { String it = delegate.getHoverInfo(tv, r); if (it!=null) { return HtmlUtil.text2html(it); } } return hovers_getHoverInfo(tv.getDocument(), r); } @Override public IInformationControlCreator getHoverControlCreator() { return new HoverInformationControlCreator(EditorsUI.getTooltipAffordanceString()); } private IRegion hovers_getHoverRegion(IDocument document, int offset) { IRegion r = _hovers.getHoverRegion(document, offset); // System.out.println("getHRegion("+offset+") => "+r); return r; } private HoverInfo hovers_getHoverInfo(IDocument document, IRegion r) { HoverInfo result = _hovers.getHoverInfo(document, r); // System.out.println("getHInfo("+r+") => "+result); return result; } }