com.google.dart.tools.ui.internal.text.functions.ChangeHoverInformationControl.java Source code

Java tutorial

Introduction

Here is the source code for com.google.dart.tools.ui.internal.text.functions.ChangeHoverInformationControl.java

Source

/*
 * Copyright (c) 2011, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.dart.tools.ui.internal.text.functions;

import com.google.dart.tools.ui.internal.text.dart.hover.SourceViewerInformationControl;
import com.google.dart.tools.ui.text.DartPartitions;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

/**
 * Specialized source viewer information control used to display quick diff hovers.
 */
class ChangeHoverInformationControl extends SourceViewerInformationControl {

    /** The font name for the viewer font - the same as the java editor's. */
    private static final String SYMBOLIC_FONT_NAME = "com.google.dart.tools.ui.editors.textfont"; //$NON-NLS-1$

    /**
     * The maximum width of the control, set in <code>setSizeConstraints(int, int)</code>.
     */
    int fMaxWidth = Integer.MAX_VALUE;
    /**
     * The maximum height of the control, set in <code>setSizeConstraints(int, int)</code>.
     */
    int fMaxHeight = Integer.MAX_VALUE;

    /**
     * The partition type to be used as the starting partition type by the partition scanner.
     */
    private String fPartition;
    /** The horizontal scroll index. */
    private int fHorizontalScrollPixel;

    /**
     * Creates a new information control.
     * 
     * @param parent the shell that is the parent of this hover / control
     * @param shellStyle the additional styles for the shell
     * @param style the additional styles for the styled text widget
     * @param partition the initial partition type to be used for the underlying viewer
     * @param statusFieldText the text to be used in the optional status field or <code>null</code> if
     *          the status field should be hidden
     */
    public ChangeHoverInformationControl(Shell parent, int shellStyle, int style, String partition,
            String statusFieldText) {
        super(parent, shellStyle, style, statusFieldText);
        setViewerFont();
        setStartingPartitionType(partition);
    }

    /*
     * @see org.eclipse.jface.text.IInformationControl#computeSizeHint()
     */
    @Override
    public Point computeSizeHint() {
        Point size = super.computeSizeHint();
        size.x = Math.min(size.x, fMaxWidth);
        size.y = Math.min(size.y, fMaxHeight);
        return size;
    }

    /*
     * @see com.google.dart.tools.ui.functions.java.hover.SourceViewerInformationControl
     * #hasContents()
     */
    @Override
    public boolean hasContents() {
        return super.hasContents() && fMaxWidth > 0;
    }

    /**
     * Sets the horizontal scroll index in pixels.
     * 
     * @param scrollIndex the new horizontal scroll index
     */
    public void setHorizontalScrollPixel(int scrollIndex) {
        scrollIndex = Math.max(0, scrollIndex);
        fHorizontalScrollPixel = scrollIndex;
    }

    /*
     * @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
     */
    @Override
    public void setInformation(String content) {
        super.setInformation(content);
        IDocument doc = getViewer().getDocument();
        if (doc == null) {
            return;
        }

        // ensure that we can scroll enough
        ensureScrollable();

        String start = null;
        if (DartPartitions.DART_DOC.equals(fPartition)) {
            start = "/**" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
        } else if (DartPartitions.DART_MULTI_LINE_COMMENT.equals(fPartition)) {
            start = "/*" + doc.getLegalLineDelimiters()[0]; //$NON-NLS-1$
        }
        if (start != null) {
            try {
                doc.replace(0, 0, start);
                int startLen = start.length();
                getViewer().setDocument(doc, startLen, doc.getLength() - startLen);
            } catch (BadLocationException e) {
                // impossible
                Assert.isTrue(false);
            }
        }

        getViewer().getTextWidget().setHorizontalPixel(fHorizontalScrollPixel);
    }

    /*
     * @see org.eclipse.jface.text.IInformationControl#setSizeConstraints(int, int)
     */
    @Override
    public void setSizeConstraints(int maxWidth, int maxHeight) {
        fMaxWidth = maxWidth;
        fMaxHeight = maxHeight;
    }

    /**
     * Sets the initial partition for the underlying source viewer.
     * 
     * @param partition the partition type
     */
    public void setStartingPartitionType(String partition) {
        if (partition == null) {
            fPartition = IDocument.DEFAULT_CONTENT_TYPE;
        } else {
            fPartition = partition;
        }
    }

    /**
     * Ensures that the control can be scrolled at least to <code>fHorizontalScrollPixel</code> and
     * adjusts <code>fMaxWidth</code> accordingly.
     */
    private void ensureScrollable() {
        IDocument doc = getViewer().getDocument();
        if (doc == null) {
            return;
        }

        StyledText widget = getViewer().getTextWidget();
        if (widget == null || widget.isDisposed()) {
            return;
        }

        int last = doc.getNumberOfLines() - 1;
        GC gc = new GC(widget);
        gc.setFont(widget.getFont());
        int maxWidth = 0;
        String content = new String();

        try {
            for (int i = 0; i <= last; i++) {
                IRegion line;
                line = doc.getLineInformation(i);
                content = doc.get(line.getOffset(), line.getLength());
                int width = gc.textExtent(content).x;
                if (width > maxWidth) {
                    maxWidth = width;
                }
            }
        } catch (BadLocationException e) {
            return;
        } finally {
            gc.dispose();
        }

        // limit the size of the window to the maximum width minus scrolling,
        // but never more than the configured max size (viewport size).
        fMaxWidth = Math.max(0, Math.min(fMaxWidth, maxWidth - fHorizontalScrollPixel + 8));
    }

    /**
     * Sets the font for this viewer sustaining selection and scroll position.
     */
    private void setViewerFont() {
        Font font = JFaceResources.getFont(SYMBOLIC_FONT_NAME);

        if (getViewer().getDocument() != null) {

            Point selection = getViewer().getSelectedRange();
            int topIndex = getViewer().getTopIndex();

            StyledText styledText = getViewer().getTextWidget();
            Control parent = styledText;
            if (getViewer() instanceof ITextViewerExtension) {
                ITextViewerExtension extension = (ITextViewerExtension) getViewer();
                parent = extension.getControl();
            }

            parent.setRedraw(false);

            styledText.setFont(font);

            getViewer().setSelectedRange(selection.x, selection.y);
            getViewer().setTopIndex(topIndex);

            if (parent instanceof Composite) {
                Composite composite = (Composite) parent;
                composite.layout(true);
            }

            parent.setRedraw(true);

        } else {
            StyledText styledText = getViewer().getTextWidget();
            styledText.setFont(font);
        }
    }
}