Mercurial > projects > dwt-addons
diff dwtx/jface/viewers/DecoratingStyledCellLabelProvider.d @ 70:46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 22 May 2008 01:36:46 +0200 |
parents | |
children | 4878bef4a38e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/viewers/DecoratingStyledCellLabelProvider.d Thu May 22 01:36:46 2008 +0200 @@ -0,0 +1,318 @@ +/******************************************************************************* + * Copyright (c) 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 + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module dwtx.jface.viewers.DecoratingStyledCellLabelProvider; + + +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.Image; +import dwtx.core.runtime.Assert; +import dwtx.jface.viewers.StyledString.Styler; + +/** + * A {@link DecoratingStyledCellLabelProvider} is a + * {@link DelegatingStyledCellLabelProvider} that uses a nested + * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider} to compute + * styled text label and image and takes a {@link ILabelDecorator} to decorate + * the label. + * + * <p> + * Use this label provider as a replacement for the + * {@link DecoratingLabelProvider} when decorating styled text labels. + * </p> + * + * <p> + * The {@link DecoratingStyledCellLabelProvider} will try to evaluate the text + * decoration added by the {@link ILabelDecorator} and will apply the style + * returned by {@link #getDecorationStyle(Object)} + * </p> + * <p> + * The {@link ILabelDecorator} can optionally implement {@link IColorDecorator} + * and {@link IFontDecorator} to provide foreground and background color and + * font decoration. + * </p> + * + * @since 3.4 + */ +public class DecoratingStyledCellLabelProvider extends + DelegatingStyledCellLabelProvider { + + private ILabelDecorator decorator; + private IDecorationContext decorationContext= DecorationContext.DEFAULT_CONTEXT; + private ILabelProviderListener labelProviderListener; + + /** + * Creates a {@link DecoratingStyledCellLabelProvider} that delegates the + * requests for styled labels and for images to a + * {@link DelegatingStyledCellLabelProvider.IStyledLabelProvider}. + * + * @param labelProvider + * the styled label provider + * @param decorator + * a label decorator or <code>null</code> to not decorate the + * label + * @param decorationContext + * a decoration context or <code>null</code> if the no + * decorator is configured or the default decorator should be + * used + */ + public DecoratingStyledCellLabelProvider( + IStyledLabelProvider labelProvider, ILabelDecorator decorator, + IDecorationContext decorationContext) { + super(labelProvider); + + this.decorator = decorator; + this.decorationContext = decorationContext !is null ? decorationContext + : DecorationContext.DEFAULT_CONTEXT; + + this.labelProviderListener = new ILabelProviderListener() { + public void labelProviderChanged(LabelProviderChangedEvent event) { + fireLabelProviderChanged(event); + } + }; + labelProvider.addListener(this.labelProviderListener); + if (decorator !is null) + decorator.addListener(this.labelProviderListener); + } + + /** + * Returns the decoration context associated with this label provider. It + * will be passed to the decorator if the decorator is an instance of + * {@link LabelDecorator}. + * + * @return the decoration context associated with this label provider + */ + public IDecorationContext getDecorationContext() { + return this.decorationContext; + } + + /** + * Set the decoration context that will be based to the decorator for this + * label provider if that decorator implements {@link LabelDecorator}. + * + * @param decorationContext + * the decoration context. + */ + public void setDecorationContext(IDecorationContext decorationContext) { + Assert.isNotNull(decorationContext); + this.decorationContext = decorationContext; + } + + private bool waitForPendingDecoration(ViewerCell cell) { + if (this.decorator is null) + return false; + + Object element = cell.getElement(); + String oldText = cell.getText(); + + bool isDecorationPending = false; + if (this.decorator instanceof LabelDecorator) { + isDecorationPending = !((LabelDecorator) this.decorator) + .prepareDecoration(element, oldText, getDecorationContext()); + } else if (this.decorator instanceof IDelayedLabelDecorator) { + isDecorationPending = !((IDelayedLabelDecorator) this.decorator) + .prepareDecoration(element, oldText); + } + if (isDecorationPending && oldText.length() is 0) { + // item is empty: is shown for the first time: don't wait + return false; + } + return isDecorationPending; + } + + public void update(ViewerCell cell) { + if (waitForPendingDecoration(cell)) { + return; // wait until the decoration is ready + } + super.update(cell); + } + + public Color getForeground(Object element) { + if (this.decorator instanceof IColorDecorator) { + Color foreground = ((IColorDecorator) this.decorator) + .decorateForeground(element); + if (foreground !is null) + return foreground; + } + return super.getForeground(element); + } + + public Color getBackground(Object element) { + if (this.decorator instanceof IColorDecorator) { + Color color = ((IColorDecorator) this.decorator) + .decorateBackground(element); + if (color !is null) + return color; + } + return super.getBackground(element); + } + + public Font getFont(Object element) { + if (this.decorator instanceof IFontDecorator) { + Font font = ((IFontDecorator) this.decorator).decorateFont(element); + if (font !is null) + return font; + } + return super.getFont(element); + } + + public Image getImage(Object element) { + Image image = super.getImage(element); + if (this.decorator is null) { + return image; + } + Image decorated = null; + if (this.decorator instanceof LabelDecorator) { + decorated = ((LabelDecorator) this.decorator).decorateImage(image, + element, getDecorationContext()); + } else { + decorated = this.decorator.decorateImage(image, element); + } + if (decorated !is null) + return decorated; + + return image; + } + + /** + * Returns the styled text for the label of the given element. + * + * @param element + * the element for which to provide the styled label text + * @return the styled text string used to label the element + */ + protected StyledString getStyledText(Object element) { + StyledString styledString = super.getStyledText(element); + if (this.decorator is null) { + return styledString; + } + + String label = styledString.getString(); + String decorated; + if (this.decorator instanceof LabelDecorator) { + decorated = ((LabelDecorator) this.decorator).decorateText(label, + element, getDecorationContext()); + } else { + decorated = this.decorator.decorateText(label, element); + } + if (decorated is null) + return styledString; + + int originalStart = decorated.indexOf(label); + if (originalStart is -1) { + return new StyledString(decorated); // the decorator did + // something wild + } + + if (decorated.length() is label.length()) + return styledString; + + Styler style = getDecorationStyle(element); + if (originalStart > 0) { + StyledString newString = new StyledString(decorated + .substring(0, originalStart), style); + newString.append(styledString); + styledString = newString; + } + if (decorated.length() > originalStart + label.length()) { // decorator + // appended + // something + return styledString.append(decorated.substring(originalStart + + label.length()), style); + } + return styledString; + } + + /** + * Sets the {@link StyledString.Styler} to be used for string + * decorations. By default the + * {@link StyledString#DECORATIONS_STYLER decoration style}. Clients + * can override. + * + * Note that it is the client's responsibility to react on color changes of + * the decoration color by refreshing the view + * + * @param element + * the element that has been decorated + * + * @return return the decoration style + */ + protected Styler getDecorationStyle(Object element) { + return StyledString.DECORATIONS_STYLER; + } + + /** + * Returns the decorator or <code>null</code> if no decorator is installed + * + * @return the decorator or <code>null</code> if no decorator is installed + */ + public ILabelDecorator getLabelDecorator() { + return this.decorator; + } + + /** + * Sets the label decorator. Removes all known listeners from the old + * decorator, and adds all known listeners to the new decorator. The old + * decorator is not disposed. Fires a label provider changed event + * indicating that all labels should be updated. Has no effect if the given + * decorator is identical to the current one. + * + * @param newDecorator + * the label decorator, or <code>null</code> if no decorations + * are to be applied + */ + public void setLabelDecorator(ILabelDecorator newDecorator) { + ILabelDecorator oldDecorator = this.decorator; + if (oldDecorator !is newDecorator) { + if (oldDecorator !is null) + oldDecorator.removeListener(this.labelProviderListener); + this.decorator = newDecorator; + if (newDecorator !is null) { + newDecorator.addListener(this.labelProviderListener); + } + } + fireLabelProviderChanged(new LabelProviderChangedEvent(this)); + } + + public void addListener(ILabelProviderListener listener) { + super.addListener(listener); + if (this.decorator !is null) { + this.decorator.addListener(this.labelProviderListener); + } + } + + public void removeListener(ILabelProviderListener listener) { + super.removeListener(listener); + if (this.decorator !is null) { + this.decorator.removeListener(this.labelProviderListener); + } + } + + public bool isLabelProperty(Object element, String property) { + if (super.isLabelProperty(element, property)) { + return true; + } + return this.decorator !is null + && this.decorator.isLabelProperty(element, property); + } + + public void dispose() { + super.dispose(); + if (this.decorator !is null) { + this.decorator.removeListener(this.labelProviderListener); + this.decorator.dispose(); + this.decorator = null; + } + } + +}