org.eclipse.mylyn.commons.workbench.DecoratingPatternStyledCellLabelProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.commons.workbench.DecoratingPatternStyledCellLabelProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *     Perforce - enhancements for bug 319469
 *******************************************************************************/

package org.eclipse.mylyn.commons.workbench;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IDecorationContext;
import org.eclipse.jface.viewers.IFontProvider;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.misc.StringMatcher;
import org.eclipse.ui.internal.misc.StringMatcher.Position;

/**
 * A decorating styled label provider that supports highlighting of substrings that match a pattern. Based on
 * {@link DecoratingFileSearchLabelProvider}.
 * 
 * @author Kevin Sawicki
 * @see DecoratingFileSearchLabelProvider
 * @since 3.7
 */
public class DecoratingPatternStyledCellLabelProvider extends DecoratingStyledCellLabelProvider
        implements IPropertyChangeListener, ILabelProvider {

    /**
     * Color to use to decorate matches.
     */
    static final String HIGHLIGHT_BG_COLOR_NAME = "org.eclipse.jdt.ui.ColoredLabels.match_highlight"; //$NON-NLS-1$

    static final Styler HIGHLIGHT_STYLE = StyledString.createColorRegistryStyler(null, HIGHLIGHT_BG_COLOR_NAME);

    private static class PatternStyledLabelProvider extends StyledCellLabelProvider
            implements IStyledLabelProvider, IColorProvider, IFontProvider {

        private final ILabelProvider labelProvider;

        private StringMatcher matcher = null;

        public PatternStyledLabelProvider(ILabelProvider provider) {
            this.labelProvider = provider;
        }

        /**
         * Set the pattern to highlight
         * 
         * @param pattern
         */
        public void setPattern(String pattern) {
            if (pattern != null && pattern.length() > 0) {
                this.matcher = new StringMatcher(pattern, true, false);
            } else {
                this.matcher = null;
            }
        }

        public StyledString getStyledText(Object element) {
            StyledString styled = null;
            String label = this.labelProvider.getText(element);
            if (matcher == null || label.length() == 0) {
                styled = new StyledString(label);
            } else {
                styled = new StyledString();
                int start = 0;
                int end = 0;
                int length = label.length();
                Position position = matcher.find(label, start, length);
                while (position != null) {
                    end = position.getStart();
                    styled.append(label.substring(start, end));
                    start = position.getEnd();
                    styled.append(label.substring(end, start), HIGHLIGHT_STYLE);
                    position = matcher.find(label, start, length);
                }
                if (start > 0 && start < length) {
                    styled.append(label.substring(start));
                }
            }
            return styled;
        }

        public Image getImage(Object element) {
            return this.labelProvider.getImage(element);
        }

        public Font getFont(Object element) {
            if (labelProvider instanceof IFontProvider) {
                return ((IFontProvider) this.labelProvider).getFont(element);
            }
            return null;
        }

        public Color getForeground(Object element) {
            if (labelProvider instanceof IColorProvider) {
                return ((IColorProvider) this.labelProvider).getForeground(element);
            }
            return null;
        }

        public Color getBackground(Object element) {
            if (labelProvider instanceof IColorProvider) {
                return ((IColorProvider) this.labelProvider).getBackground(element);
            }
            return null;
        }

    }

    private final ILabelProvider labelProvider;

    /**
     * Create a new repository search styled label provider that wraps an {@link ILabelProvider}
     * 
     * @param labelProvider
     * @param decorator
     * @param decorationContext
     */
    public DecoratingPatternStyledCellLabelProvider(ILabelProvider labelProvider, ILabelDecorator decorator,
            IDecorationContext decorationContext) {
        super(new PatternStyledLabelProvider(labelProvider), decorator, decorationContext);
        this.labelProvider = labelProvider;
    }

    /**
     * @see org.eclipse.jface.viewers.StyledCellLabelProvider#initialize(org.eclipse.jface.viewers.ColumnViewer,
     *      org.eclipse.jface.viewers.ViewerColumn)
     */
    @Override
    public void initialize(ColumnViewer viewer, ViewerColumn column) {
        PlatformUI.getPreferenceStore().addPropertyChangeListener(this);
        JFaceResources.getColorRegistry().addListener(this);

        setOwnerDrawEnabled(
                PlatformUI.getPreferenceStore().getBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS));

        super.initialize(viewer, column);
    }

    /**
     * Get underyling label provider
     * 
     * @return label provider
     */
    public ILabelProvider getLabelProvider() {
        return this.labelProvider;
    }

    /**
     * @see org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider#dispose()
     */
    @Override
    public void dispose() {
        PlatformUI.getPreferenceStore().removePropertyChangeListener(this);
        JFaceResources.getColorRegistry().removeListener(this);
        this.labelProvider.dispose();
        super.dispose();
    }

    /**
     * Set the pattern to highlight
     * 
     * @param pattern
     */
    public void setPattern(String pattern) {
        ((PatternStyledLabelProvider) getStyledStringProvider()).setPattern(pattern);
    }

    /**
     * Refresh the labels on viewer associated with this label provider. This method must be called on the UI-thread.
     */
    protected void refresh() {
        ColumnViewer viewer = getViewer();
        if (viewer != null) {
            boolean coloredLabels = PlatformUI.getPreferenceStore()
                    .getBoolean(IWorkbenchPreferenceConstants.USE_COLORED_LABELS);
            if (coloredLabels || coloredLabels != isOwnerDrawEnabled()) {
                setOwnerDrawEnabled(coloredLabels);
                viewer.refresh();
            }
        }
    }

    /**
     * Schedule a refresh of this label provider. This method can be called from any thread.
     */
    protected void scheduleRefresh() {
        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
            public void run() {
                refresh();
            }
        });
    }

    /**
     * @param event
     */
    public void propertyChange(PropertyChangeEvent event) {
        String property = event.getProperty();
        if (IWorkbenchPreferenceConstants.USE_COLORED_LABELS.equals(property)
                || HIGHLIGHT_BG_COLOR_NAME.equals(property)) {
            scheduleRefresh();
        }
    }

    /**
     * Get text of element from underyling label provider
     * 
     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
     */
    public String getText(Object element) {
        return this.labelProvider.getText(element);
    }

    /**
     * Override preparation of style range to add border dot about highlight regions that don't have colors applied
     * 
     * @see org.eclipse.jface.viewers.StyledCellLabelProvider#prepareStyleRange(org.eclipse.swt.custom.StyleRange,
     *      boolean)
     */
    @Override
    protected StyleRange prepareStyleRange(StyleRange styleRange, boolean applyColors) {
        boolean addBorder = !applyColors && styleRange.background != null;
        styleRange = super.prepareStyleRange(styleRange, applyColors);
        if (addBorder) {
            styleRange.borderStyle = SWT.BORDER_DOT;
        }
        return styleRange;
    }

}