Package org.erlide.ui.editors.erl.hover

Source Code of org.erlide.ui.editors.erl.hover.ErlTextHover$HoverControlCreator

/*******************************************************************************
* Copyright (c) 2004 Vlad Dumitrescu 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:
*     Vlad Dumitrescu
*******************************************************************************/
package org.erlide.ui.editors.erl.hover;

import java.net.URL;
import java.util.Collection;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
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.Region;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.EditorsUI;
import org.erlide.backend.BackendCore;
import org.erlide.engine.ErlangEngine;
import org.erlide.engine.model.IErlModel;
import org.erlide.engine.model.erlang.IErlFunction;
import org.erlide.engine.model.erlang.IErlPreprocessorDef;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.engine.services.parsing.ErlToken;
import org.erlide.engine.services.search.OpenResult;
import org.erlide.engine.services.search.OtpDocService;
import org.erlide.runtime.api.IOtpRpc;
import org.erlide.ui.actions.OpenUtils;
import org.erlide.ui.editors.erl.AbstractErlangEditor;
import org.erlide.ui.editors.erl.ErlangEditor;
import org.erlide.ui.internal.ErlBrowserInformationControlInput;
import org.erlide.ui.internal.ErlideUIPlugin;
import org.erlide.ui.internal.information.ErlInformationPresenter;
import org.erlide.ui.internal.information.HoverUtil;
import org.erlide.ui.internal.information.PresenterControlCreator;
import org.erlide.ui.prefs.plugin.EditorPreferencePage;
import org.erlide.ui.util.eclipse.text.BrowserInformationControl;
import org.erlide.ui.util.eclipse.text.HTMLPrinter;
import org.erlide.util.ErlLogger;
import org.erlide.util.Util;
import org.osgi.framework.Bundle;

import com.ericsson.otp.erlang.OtpErlangObject;
import com.ericsson.otp.erlang.OtpErlangTuple;

public class ErlTextHover implements ITextHover, IInformationProviderExtension2,
        ITextHoverExtension, ITextHoverExtension2 {

    private static URL fgStyleSheet = null;
    private IInformationControlCreator fHoverControlCreator;
    private PresenterControlCreator fPresenterControlCreator;
    private final AbstractErlangEditor fEditor;

    public ErlTextHover(final AbstractErlangEditor editor) {
        fEditor = editor;
        initStyleSheet();
    }

    @Override
    public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {
        return internalGetHoverRegion(offset, fEditor);
    }

    private static IRegion internalGetHoverRegion(final int offset,
            final AbstractErlangEditor editor) {
        if (editor == null) {
            return null;
        }
        editor.reconcileNow();
        final ErlToken token = editor.getScanner().getTokenAt(offset);
        if (token == null) {
            return null;
        }
        return new Region(token.getOffset(), token.getLength());
    }

    private void initStyleSheet() {
        final Bundle bundle = Platform.getBundle(ErlideUIPlugin.PLUGIN_ID);
        if (fgStyleSheet != null) {
            return;
        }
        fgStyleSheet = bundle.getEntry("/edoc.css"); //$NON-NLS-1$
        if (fgStyleSheet != null) {

            try {
                fgStyleSheet = FileLocator.toFileURL(fgStyleSheet);
            } catch (final Exception e) {
            }
        }
    }

    /**
     * @param textViewer
     * @param offset
     * @param length
     */
    private static String makeDebuggerVariableHover(final ITextViewer textViewer,
            final int offset, final int length) {
        final IAdaptable adaptable = DebugUITools.getDebugContext();
        if (adaptable != null) {
            final IStackFrame frame = (IStackFrame) adaptable
                    .getAdapter(IStackFrame.class);
            try {
                if (frame != null && frame.hasVariables()) {
                    String varName = "";
                    try {
                        varName = textViewer.getDocument().get(offset, length);
                    } catch (final BadLocationException e) {
                    }
                    if (varName.length() > 0) {
                        final String firstLetter = varName.substring(0, 1);
                        if (firstLetter.toUpperCase().equals(firstLetter)) {
                            final IVariable[] vars = frame.getVariables();
                            for (final IVariable variable : vars) {
                                if (variable.getName().equals(varName)) {
                                    final String value = variable.getValue()
                                            .getValueString();
                                    return makeVariablePresentation(varName, value);
                                }
                            }
                        }
                    }
                }
            } catch (final DebugException e) {
            }
        }
        return "";
    }

    private static String makeVariablePresentation(final String varName,
            final String value) {
        return varName + " = " + value;
    }

    @Override
    public IInformationControlCreator getInformationPresenterControlCreator() {
        if (fPresenterControlCreator == null) {
            fPresenterControlCreator = new PresenterControlCreator(fEditor);
        }
        return fPresenterControlCreator;
    }

    @Override
    public IInformationControlCreator getHoverControlCreator() {
        if (fHoverControlCreator == null) {
            fHoverControlCreator = new HoverControlCreator(
                    getInformationPresenterControlCreator());
        }
        return fHoverControlCreator;
    }

    public static final class HoverControlCreator extends
            AbstractReusableInformationControlCreator {
        IInformationControlCreator fInformationPresenterControlCreator;

        public HoverControlCreator(
                final IInformationControlCreator informationPresenterControlCreator) {
            fInformationPresenterControlCreator = informationPresenterControlCreator;
        }

        @Override
        protected IInformationControl doCreateInformationControl(final Shell parent) {
            IInformationControl control;
            if (BrowserInformationControl.isAvailable(parent)) {
                control = new BrowserInformationControl(parent,
                        JFaceResources.DIALOG_FONT,
                        EditorsUI.getTooltipAffordanceString()) {
                    @Override
                    public IInformationControlCreator getInformationPresenterControlCreator() {
                        return fInformationPresenterControlCreator;
                    }

                    @Override
                    public void setSize(final int width0, final int height0) {
                        // default size is too small
                        final Point bounds = getSizeConstraints();
                        int width = width0;
                        int height = height0;
                        if (bounds != null) {
                            if (bounds.x != SWT.DEFAULT) {
                                width = Math.min(bounds.x, width * 2);
                            }
                            if (bounds.y != SWT.DEFAULT) {
                                height = Math.min(bounds.y, height * 2);
                            }
                        }
                        super.setSize(width, height);
                    }
                };
            } else {
                control = new DefaultInformationControl(parent,
                        EditorsUI.getTooltipAffordanceString(),
                        new ErlInformationPresenter(true));
            }
            return control;
        }
    }

    public static ErlBrowserInformationControlInput getHoverInfoForOffset(
            final int offset, final ErlangEditor editor) {
        final ITextViewer textViewer = editor.getViewer();
        final IRegion region = internalGetHoverRegion(offset, editor);
        if (region != null) {
            return internalGetHoverInfo(editor, textViewer, region);
        }
        return null;
    }

    @Deprecated
    @Override
    public String getHoverInfo(final ITextViewer textViewer, final IRegion hoverRegion) {
        if (isHoverDisabled()) {
            return null;
        }
        final ErlBrowserInformationControlInput input = (ErlBrowserInformationControlInput) getHoverInfo2(
                textViewer, hoverRegion);
        return input == null ? "" : input.getHtml();
    }

    private static boolean isHoverDisabled() {
        return !EditorPreferencePage.getEnableHover();
    }

    @Override
    public Object getHoverInfo2(final ITextViewer textViewer, final IRegion hoverRegion) {
        if (isHoverDisabled()) {
            return null;
        }
        return internalGetHoverInfo(fEditor, textViewer, hoverRegion);
    }

    private static ErlBrowserInformationControlInput internalGetHoverInfo(
            final AbstractErlangEditor editor, final ITextViewer textViewer,
            final IRegion hoverRegion) {
        if (editor == null) {
            return null;
        }
        final StringBuffer result = new StringBuffer();
        OpenResult element = null;
        // TODO our model is too coarse, here we need access to expressions
        final Collection<OtpErlangObject> fImports = ErlangEngine.getInstance()
                .getModelUtilService().getImportsAsList(editor.getModule());

        final int offset = hoverRegion.getOffset();
        final int length = hoverRegion.getLength();

        final String debuggerVar = makeDebuggerVariableHover(textViewer, offset, length);
        if (debuggerVar.length() > 0) {
            result.append(debuggerVar);
        }
        final String stateDir = ErlangEngine.getInstance().getStateDir();

        final IErlProject erlProject = editor.getProject();

        String docPath = "";
        String anchor = "";
        try {
            if (erlProject == null) {
                return null;
            }
            final IOtpRpc backend = BackendCore.getBuildBackend(erlProject);
            if (backend == null) {
                return null;
            }

            final IErlModel model = ErlangEngine.getInstance().getModel();
            final String externalModulesString = erlProject.getProperties()
                    .getExternalModules();
            final OtpErlangTuple t = (OtpErlangTuple) ErlangEngine
                    .getInstance()
                    .getService(OtpDocService.class)
                    .getOtpDoc(
                            backend,
                            offset,
                            stateDir,
                            editor.getScannerName(),
                            fImports,
                            externalModulesString,
                            model.getPathVars(editor.getModule()
                                    .getCorrespondingResource()));
            ErlLogger.debug("otp doc %s", t);
            if (Util.isOk(t)) {
                element = OpenResult.build(t.elementAt(2));
                final String docStr = Util.stringValue(t.elementAt(1));
                result.append(docStr);
                if (t.arity() > 4) {
                    docPath = Util.stringValue(t.elementAt(3));
                    anchor = Util.stringValue(t.elementAt(4));
                }
            } else {
                element = OpenResult.build(t);
                final Object found = new OpenUtils().findOpenResult(editor,
                        editor.getModule(), erlProject, element,
                        editor.getElementAt(offset, false));
                if (found instanceof IErlFunction) {
                    final IErlFunction function = (IErlFunction) found;
                    final String comment = HoverUtil.getDocumentationString(
                            function.getComments(), function.getTypespec());
                    if (comment.length() == 0) {
                        return null;
                    }
                    result.append(HTMLPrinter.asHtml(comment));
                } else if (found instanceof IErlPreprocessorDef) {
                    final IErlPreprocessorDef preprocessorDef = (IErlPreprocessorDef) found;
                    result.append(preprocessorDef.getExtra());
                }
            }
        } catch (final Exception e) {
            ErlLogger.warn(e);
            return null;
        }
        final String strResult = HoverUtil.getHTMLAndReplaceJSLinks(result);
        return new ErlBrowserInformationControlInput(null, editor, element, strResult,
                20, HoverUtil.getDocumentationURL(docPath, anchor));
    }
}
TOP

Related Classes of org.erlide.ui.editors.erl.hover.ErlTextHover$HoverControlCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.