org.eclipse.recommenders.internal.apidocs.rcp.ApidocsViewUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.recommenders.internal.apidocs.rcp.ApidocsViewUtils.java

Source

/**
 * Copyright (c) 2011 Stefan Henss.
 * 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:
 *    Stefan Henss - initial API and implementation.
 *    Olav Lenz - externalize Strings.
 */
package org.eclipse.recommenders.internal.apidocs.rcp;

import static java.text.MessageFormat.format;
import static org.eclipse.recommenders.rcp.JavaElementSelectionEvent.JavaElementSelectionLocation.METHOD_DECLARATION;
import static org.eclipse.recommenders.rcp.utils.JdtUtils.findTypeFromSignature;
import static org.eclipse.swt.SWT.*;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.ui.JavaElementLabels;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.recommenders.internal.apidocs.rcp.l10n.Messages;
import org.eclipse.recommenders.rcp.JavaElementResolver;
import org.eclipse.recommenders.rcp.JavaElementSelectionEvent;
import org.eclipse.recommenders.utils.Bags;
import org.eclipse.recommenders.utils.names.IMethodName;
import org.eclipse.recommenders.utils.names.Names;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.google.common.base.Optional;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multiset.Entry;
import com.google.common.eventbus.EventBus;

/**
 * Several shortcuts for creating SWT components in the API Docs view default style.
 */
// TODO: Review these methods. not sure they are still the defaults
public final class ApidocsViewUtils {

    public static final Font CODEFONT = JFaceResources.getTextFont();
    public static final Font BOLDFONT = JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT);
    public static final Map<Integer, Color> COLORCACHE = new HashMap<Integer, Color>();

    private ApidocsViewUtils() {
    }

    public static void disposeChildren(Composite parent) {
        for (Control c : parent.getChildren()) {
            c.dispose();
        }
    }

    public static void setInfoBackgroundColor(final Control c) {
        final Display display = c.getDisplay();
        final Color color = display.getSystemColor(COLOR_INFO_BACKGROUND);
        c.setBackground(color);
    }

    public static void setInfoForegroundColor(final Control c) {
        final Display display = c.getDisplay();
        final Color color = display.getSystemColor(SWT.COLOR_INFO_FOREGROUND);
        c.setForeground(color);
    }

    public static Composite createGridComposite(final Composite parent, final int columns, final int hSpacing,
            final int vSpacing, final int hMargin, final int vMargin) {
        final Composite composite = new Composite(parent, SWT.NONE);
        setInfoBackgroundColor(composite);
        final GridLayout layout = GridLayoutFactory.swtDefaults().numColumns(columns).margins(hMargin, vMargin)
                .spacing(hSpacing, vSpacing).create();
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        return composite;
    }

    static void createSeparator(final Composite parent) {
        final Label separator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR);
        separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    }

    public static Table renderMethodDirectivesBlock(final Composite parent, final Multiset<IMethodName> methods,
            final int total, final EventBus bus, final JavaElementResolver resolver, final String middlePhrase) {
        final Table table = new Table(parent, SWT.NONE | SWT.HIDE_SELECTION);
        table.setBackground(createColor(COLOR_INFO_BACKGROUND));
        table.setForeground(createColor(COLOR_INFO_FOREGROUND));
        table.setLayoutData(GridDataFactory.fillDefaults().indent(10, 0).create());

        final TableColumn column1 = new TableColumn(table, SWT.NONE);
        final TableColumn column2 = new TableColumn(table, SWT.NONE);
        final TableColumn column3 = new TableColumn(table, SWT.NONE);
        final TableColumn column4 = new TableColumn(table, SWT.NONE);

        for (final Entry<IMethodName> method : Bags.orderedByCount(methods)) {

            final int frequency = method.getCount();
            final double percentage = frequency / (double) total;
            if (percentage < 0.05) {
                continue;
            }
            final String phraseText = percentageToRecommendationPhrase((int) Math.round(100 * percentage));
            final String stats = format(Messages.TABLE_CELL_SUFFIX_FREQUENCIES, percentage, frequency);

            final Link bar = createMethodLink(table, method.getElement(), resolver, bus);
            final TableItem item = new TableItem(table, SWT.NONE);
            item.setText(new String[] { phraseText, middlePhrase, bar.getText(), stats });
            bold(item, 0);
            final TableEditor editor = new TableEditor(table);
            editor.grabHorizontal = editor.grabVertical = true;
            editor.setEditor(bar, item, 2);
        }
        column1.pack();
        column2.pack();
        column3.pack();
        column4.pack();
        return table;
    }

    public static Link createMethodLink(final Composite parent, final IMethod method, final EventBus workspaceBus) {
        final String text = "<a>" //$NON-NLS-1$
                + JavaElementLabels.getElementLabel(method,
                        JavaElementLabels.M_APP_RETURNTYPE | JavaElementLabels.M_PARAMETER_TYPES)
                + "</a>"; //$NON-NLS-1$
        final String tooltip = JavaElementLabels.getElementLabel(method, JavaElementLabels.DEFAULT_QUALIFIED);

        final Link link = new Link(parent, SWT.NONE);
        link.setText(text);
        link.setBackground(ApidocsViewUtils.createColor(SWT.COLOR_INFO_BACKGROUND));
        link.setToolTipText(tooltip);
        link.setFont(JFaceResources.getDialogFont());
        link.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                final JavaElementSelectionEvent event = new JavaElementSelectionEvent(method, METHOD_DECLARATION);
                workspaceBus.post(event);
            }
        });
        return link;
    }

    public static Link createMethodLink(final Composite parent, final IMethodName method,
            final JavaElementResolver resolver, final EventBus workspaceBus) {
        final String text = "<a>" + Names.vm2srcSimpleMethod(method) + "</a>"; //$NON-NLS$ //$NON-NLS-1$ //$NON-NLS-2$
        final String tooltip = Names.vm2srcQualifiedMethod(method);

        final Link link = new Link(parent, SWT.NONE);
        link.setText(text);
        link.setBackground(ApidocsViewUtils.createColor(SWT.COLOR_INFO_BACKGROUND));
        link.setFont(JFaceResources.getDialogFont());
        link.setToolTipText(tooltip);
        link.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                final Optional<IMethod> opt = resolver.toJdtMethod(method);
                if (opt.isPresent()) {
                    final JavaElementSelectionEvent event = new JavaElementSelectionEvent(opt.get(),
                            METHOD_DECLARATION);
                    workspaceBus.post(event);
                } else {
                    link.setEnabled(false);
                }
            }
        });
        return link;
    }

    /**
     * @param parent
     *            The composite to which the label shall be appended.
     * @param text
     *            The label's text.
     * @param wrap
     *            True, if the label should set GridData in order to be wrapped when it exceeds the parent's width.
     * @return The label created with the specified parameters.
     */
    public static Label createLabel(final Composite parent, final String text, final boolean wrap) {
        return createLabel(parent, text, false, false, SWT.COLOR_INFO_FOREGROUND, wrap);
    }

    public static Label createLabel(final Composite parent, final String text, final boolean bold,
            final boolean code, final int color, final boolean wrap) {
        final Label label = new Label(parent, SWT.WRAP);
        label.setText(text);
        setInfoBackgroundColor(label);
        if (code) {
            label.setFont(CODEFONT);
        } else if (bold) {
            label.setFont(BOLDFONT);
        }
        label.setForeground(createColor(color));
        if (wrap) {
            label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
        }
        return label;
    }

    public static CLabel createCLabel(final Composite parent, final String text, final boolean bold,
            final Image image) {
        final CLabel label = new CLabel(parent, SWT.NONE);
        setInfoBackgroundColor(label);
        label.setText(text);
        if (bold) {
            label.setFont(BOLDFONT);
        }
        label.setImage(image);
        return label;
    }

    /**
     * @param parent
     *            The composite to which the text shall be appended.
     * @param text
     *            The default text of the text widget.
     * @param width
     *            The width of the text widget.
     * @return The text widget created with the specified parameters.
     */
    public static Text createText(final Composite parent, final String text, final int width) {
        final Text textComponent = new Text(parent, SWT.BORDER | SWT.SINGLE);
        textComponent.setText(text);
        final GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
        gridData.widthHint = width;
        textComponent.setLayoutData(gridData);
        return textComponent;
    }

    public static Text createTextArea(final Composite parent, final String text, final int height,
            final int width) {
        final Text textComponent = new Text(parent, SWT.BORDER | SWT.WRAP | SWT.MULTI | SWT.V_SCROLL);
        textComponent.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(width, height).create());
        textComponent.setText(text);
        return textComponent;
    }

    public static StyledText createStyledText(final Composite parent, final String text, final int color,
            final boolean grabExcessHorizontalSpace) {
        final StyledText styledText = new StyledText(parent, SWT.WRAP);
        styledText.setEnabled(false);
        styledText.setDoubleClickEnabled(false);
        styledText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, grabExcessHorizontalSpace, false));
        styledText.setEditable(false);
        styledText.setText(text);
        styledText.setForeground(createColor(color));
        return styledText;
    }

    public static void createStyleRange(final StyledText styledText, final int start, final int length,
            final int fontStyle, final boolean makeBlue, final boolean makeCodeFont) {
        final StyleRange styleRange = new StyleRange();
        styleRange.start = start;
        styleRange.length = length;
        styleRange.fontStyle = fontStyle;
        if (makeBlue) {
            styleRange.foreground = createColor(SWT.COLOR_BLUE);
        }
        if (makeCodeFont) {
            styleRange.font = CODEFONT;
        }
        styledText.setStyleRange(styleRange);
    }

    public static StyleRange createStyleRange(final int start, final int length, final int fontStyle,
            final boolean makeBlue, final boolean makeCodeFont) {
        final StyleRange range = new StyleRange();
        range.start = start;
        range.length = length;
        range.fontStyle = fontStyle;
        if (makeBlue) {
            range.foreground = createColor(SWT.COLOR_BLUE);
        }
        if (makeCodeFont) {
            range.font = CODEFONT;
        }
        return range;
    }

    public static Font bold(Font src, Display d) {
        FontData[] fD = src.getFontData();
        fD[0].setStyle(SWT.BOLD);
        return new Font(d, fD[0]);
    }

    public static void bold(TableItem item, int index) {
        item.setFont(index, bold(item.getFont(), item.getDisplay()));
    }

    public static void bold(Control item) {
        item.setFont(bold(item.getFont(), item.getDisplay()));
    }

    // TODO: Use link and put together with a image into a grid.
    public static CLabel createLink(final Composite parent, final String text, final String tooltip,
            final Image image, final boolean blueColor, final MouseListener listener) {
        final CLabel link = new CLabel(parent, SWT.NONE);
        link.setText(text);
        if (tooltip != null) {
            link.setToolTipText(tooltip);
        }
        if (blueColor) {
            link.setForeground(createColor(SWT.COLOR_BLUE));
        }
        link.setImage(image);
        link.addMouseListener(listener);
        link.setCursor(new Cursor(parent.getDisplay(), SWT.CURSOR_HAND));
        if (blueColor) {
            link.addMouseTrackListener(new MouseTrackAdapter() {

                @Override
                public void mouseExit(final MouseEvent event) {
                    link.setForeground(createColor(SWT.COLOR_BLUE));
                }

                @Override
                public void mouseEnter(final MouseEvent event) {
                    link.setForeground(createColor(SWT.COLOR_DARK_BLUE));
                }
            });
        }
        return link;
    }

    public static String percentageToRecommendationPhrase(final int percentage) {
        if (percentage >= 95) {
            return Messages.TABLE_CELL_FREQUENCY_ALWAYS;
        } else if (percentage >= 65) {
            return Messages.TABLE_CELL_FREQUENCY_USUALLY;
        } else if (percentage >= 25) {
            return Messages.TABLE_CELL_FREQUENCY_SOMETIMES;
        } else if (percentage >= 10) {
            return Messages.TABLE_CELL_FREQUENCY_OCCASIONALLY;
        } else {
            return Messages.TABLE_CELL_FREQUENCY_RARELY;
        }
    }

    public static SourceCodeArea createSourceCodeArea(final Composite parent, final String snippet) {
        final SourceCodeArea area = new SourceCodeArea(parent);
        area.setCode(snippet);
        return area;
    }

    public static Button createButton(final Composite parent, final String text,
            final SelectionListener selectionListener) {
        final Button button = new Button(parent, SWT.NONE);
        button.setText(text);
        button.addSelectionListener(selectionListener);
        return button;
    }

    public static Color createColor(final int swtColor) {
        final Integer color = Integer.valueOf(swtColor);
        if (!COLORCACHE.containsKey(color)) {
            COLORCACHE.put(color, Display.getCurrent().getSystemColor(swtColor));
        }
        return COLORCACHE.get(color);
    }

    public static Composite createComposite(final Composite parent, final int numColumns) {
        final Composite container = new Composite(parent, SWT.NONE);
        setInfoBackgroundColor(container);
        container.setLayout(
                GridLayoutFactory.fillDefaults().margins(10, 0).spacing(0, 0).numColumns(numColumns).create());
        container.setLayoutData(GridDataFactory.fillDefaults().create());
        return container;
    }

    public static Optional<IType> findType(ILocalVariable var) {
        String signature = var.getTypeSignature();
        return findTypeFromSignature(signature, var);
    }

    public static Optional<IType> findType(IField var) {
        try {
            String signature = var.getTypeSignature();
            return findTypeFromSignature(signature, var);
        } catch (JavaModelException e) {
            return Optional.absent();
        }
    }
}