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;
+        }
+    }
+
+}