/*******************************************************************************
* Copyright (c) 2002, 2009 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
* Ericsson - Fix improper hover order (Bug 294812)
*******************************************************************************/
package melnorme.lang.ide.ui.editor.hover;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import static melnorme.utilbox.core.CoreUtil.option;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.ui.texteditor.ITextEditor;
import melnorme.lang.ide.core.LangCore;
import melnorme.lang.ide.core.text.JavaWordFinder;
import melnorme.lang.ide.ui.LangEditorTextHoversRegistry;
import melnorme.lang.tooling.common.ISourceBuffer;
/**
* 'Fake' hover used to choose the best available hover.
* This hover is always the first hover used and will delegate the hover
* request to the best of the real hovers. The 'best' hover is the first
* hover that returns some text for the specified parameters.
*
*/
public class BestMatchHover extends AbstractEditorTextHover
implements IInformationProviderExtension2 {
protected final ISourceBuffer sourceBuffer;
protected final ITextEditor editor; // can be null
protected List<ILangEditorTextHover<?>> fInstantiatedTextHovers;
protected ILangEditorTextHover<?> matchedHover;
public BestMatchHover(ISourceBuffer sourceBuffer, ITextEditor editor) {
this.sourceBuffer = assertNotNull(sourceBuffer);
this.editor = editor; // Note, editor not necessarily a lang editor, could be compare editor or null
prepareTextHovers();
}
protected void installTextHovers() {
List<Class<? extends ILangEditorTextHover<?>>> textHoverSpecs =
LangEditorTextHoversRegistry.getTextHoversSpecifications();
fInstantiatedTextHovers = new ArrayList<>(textHoverSpecs.size());
for (int i= 0; i < textHoverSpecs.size(); i++) {
Class<? extends ILangEditorTextHover<?>> klass = textHoverSpecs.get(i);
try {
fInstantiatedTextHovers.add(klass.newInstance());
} catch (InstantiationException e) {
LangCore.logInternalError(e);
} catch (IllegalAccessException e) {
LangCore.logInternalError(e);
}
}
}
protected void prepareTextHovers() {
installTextHovers();
}
@Override
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
return doGetHoverRegion(textViewer, offset);
}
public static IRegion doGetHoverRegion(ITextViewer textViewer, int offset) {
return JavaWordFinder.findWord(textViewer.getDocument(), offset);
}
@Override
public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
// getHoverInfo2 is called automatically, in background thread, so don't allow the buffer to be saved.
ISourceBuffer hoverSourceBuffer = sourceBuffer.getReadOnlyView();
return getInformation(textViewer, hoverRegion, hoverSourceBuffer);
}
public Object getInformation(ITextViewer textViewer, IRegion hoverRegion, ISourceBuffer hoverSourceBuffer) {
matchedHover = null;
for (ILangEditorTextHover<?> hover : fInstantiatedTextHovers) {
if (hover == null)
continue;
Object info = hover.getHoverInfo(hoverSourceBuffer, hoverRegion, option(editor), textViewer);
if (info != null) {
matchedHover = hover;
return info;
}
}
return null;
}
@Override
public IInformationControlCreator getHoverControlCreator() {
if(matchedHover == null) {
return null;
}
return matchedHover.getHoverControlCreator();
}
@Override
public IInformationControlCreator getInformationPresenterControlCreator() {
if(matchedHover == null) {
return null;
}
return matchedHover.getInformationPresenterControlCreator();
}
}