From 2b3d31bb3155513f069cefdc95f5ac85955ba747 Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Wed, 19 Dec 2007 23:53:11 +0000 Subject: [PATCH] [204587][204588] Added the IElementPropertiesProvider and PropertyBasedLabelProvider. --- .../META-INF/MANIFEST.MF | 1 + .../IElementPropertiesProvider.java | 27 ++ .../ILabelAttributeChangedListener.java | 19 ++ .../properties/IPropertiesUpdate.java | 21 ++ .../viewmodel/properties/LabelAttribute.java | 109 +++++++ .../ui/viewmodel/properties/LabelColor.java | 71 +++++ .../viewmodel/properties/LabelColumnInfo.java | 158 +++++++++++ .../ui/viewmodel/properties/LabelFont.java | 57 ++++ .../ui/viewmodel/properties/LabelImage.java | 53 ++++ .../ui/viewmodel/properties/LabelText.java | 86 ++++++ .../PropertyBasedLabelProvider.java | 265 ++++++++++++++++++ 11 files changed, 867 insertions(+) create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java create mode 100644 plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java diff --git a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF index 6cc41f28e37..2ffed4637d8 100644 --- a/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.dd.dsf.ui/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Eclipse-LazyStart: true Export-Package: org.eclipse.dd.dsf.ui.concurrent, org.eclipse.dd.dsf.ui.viewmodel, org.eclipse.dd.dsf.ui.viewmodel.dm, + org.eclipse.dd.dsf.ui.viewmodel.properties, org.eclipse.dd.dsf.ui.viewmodel.update, org.eclipse.dd.dsf.ui.viewmodel.update.actions Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java new file mode 100644 index 00000000000..139bd3408cd --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IElementPropertiesProvider.java @@ -0,0 +1,27 @@ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + + +/** + * Provides context-sensitive properties. Can be registered as an adapter for + * an element or implemented directly + */ +public interface IElementPropertiesProvider { + + /** + * Updates the specified property sets. + * + * @param updates each update specifies the element and context for which + * a set of properties is requested and stores them + */ + public void update(IPropertiesUpdate[] updates); + + /** + * Returns a user-presentable name for the given property. + */ + public String getPropertyName(String property); + + /** + * Returns a description for the given property. + */ + public String getPropertyDescription(String property); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java new file mode 100644 index 00000000000..6f60b2c33d0 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/ILabelAttributeChangedListener.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +/** + * + */ +public interface ILabelAttributeChangedListener { + + public void attributesChanged(); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java new file mode 100644 index 00000000000..c81586edba4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/IPropertiesUpdate.java @@ -0,0 +1,21 @@ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate; + +/** + * Context sensitive properties update request for an element. + */ +public interface IPropertiesUpdate extends IViewerUpdate { + /** + * Returns the list of element properties that the provider should set. + * If null, all available properties should be set. + */ + public String[] getProperties(); + + /** + * Sets the given property to update. + * @param property Property ID. + * @param value Property value. + */ + public void setProperty(String property, Object value); +} diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java new file mode 100644 index 00000000000..e615c0ce5f4 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelAttribute.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * This is a base class for a label attribute used in generating label + * information based on properties of an element. There are currently + * four types of attributes: text, image, font, and color, and a given + * attribute can be either enabled or disabled based on the element + * properties. + *

+ * Clients are intended to override this class and its extensions to + * implement the {@link LabelAttribute#isEnabled(Map)} and + * {@link LabelAttribute#getPropertyNames()} methods as needed. Clients can + * also override how the attribute settings are stored, for example in + * order to use a preference. + * + * @see PropertyBasedLabelProvider + * @see LabelColumnInfo + */ +@SuppressWarnings("restriction") +abstract public class LabelAttribute { + public static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0]; + + /** + * Listeners for when this attribute is modified. + */ + private ListenerList fListeners = new ListenerList(); + + public LabelAttribute() { + } + + /** + * Disposes this attribute. + */ + public void dispose() { + } + + /** + * Registers the given listener for changes in this attribute. A change in + * the attributes of a label should cause a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Calls the listeners to notify them that this attribute has changed. + */ + protected void fireAttributeChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + /** + * Returns the propertis that are needed by this attribute in order to + * determine whether this attribute is enabled and/or for the actual + * attribute itself. + * @return Array of names of properties for the element properties provider. + */ + public String[] getPropertyNames() { + return EMPTY_PROPERTY_NAMES_ARRAY; + } + + /** + * Returns whether this attribute is enabled for an element which has + * the given properties. + * @param properties Map or element properties. The client should ensure + * that all properties specified by {@link #getPropertyNames()} are + * supplied in this map. + * @return true if this attribute is enabled. + */ + public boolean isEnabled(Map properties) { + return true; + } + + /** + * Updates the label with this attribute. + * + * @param update Label update object to write to. + * @param columnIndex Colum index to write at. + * @param properties Element properties to use. + */ + abstract public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties); +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java new file mode 100644 index 00000000000..a4582b17f41 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColor.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.swt.graphics.RGB; + +/** + * The color attribute of a label. It determines what foreground and + * background color to use for the given label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ + +@SuppressWarnings("restriction") +public class LabelColor extends LabelAttribute { + private RGB fForeground; + private RGB fBackground; + + public LabelColor() { + this(null, null); + } + + public LabelColor(RGB foreground, RGB background) { + fForeground = foreground; + fBackground = background; + } + + public RGB getForeground() { + return fForeground; + } + + public RGB getBackground() { + return fBackground; + } + + public void setForeground(RGB foreground) { + fForeground = foreground; + fireAttributeChanged(); + } + + public void setBackground(RGB background) { + fBackground = background; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + RGB foreground = getForeground(); + if (foreground != null) { + update.setForeground(foreground, columnIndex); + } + + RGB background = getBackground(); + if (background != null) { + update.setBackground(background, columnIndex); + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java new file mode 100644 index 00000000000..c22d5e5a6ee --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelColumnInfo.java @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * Class used by the PropertyBasedLabelProvider to generate store + * label attributes related to a single column. Each column info is + * configured with an array of attributes (there are currently four + * types of attributes: text, image, font, and color), which are + * evaluated in order to generate the label. + *

+ * Clients are not intended to extend this class. + * + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class LabelColumnInfo implements ILabelAttributeChangedListener { + + private static final LabelAttribute[] EMPTY_ATTRIBUTES_ARRAY = new LabelAttribute[0]; + + /** + * Calculated list of property names that need to be retrieved to + * generate the label for this column. + */ + private String[] fPropertyNames; + + /** + * Array of label attribute objects. + */ + private LabelAttribute[] fLabelAttributes; + + /** + * Listeners for when column attributes are modified. + */ + private ListenerList fListeners = new ListenerList(); + + /** + * Creates the column info object with given array of attributes. + * @param attributeInfos Attributes for the label. + */ + public LabelColumnInfo(LabelAttribute[] attributes) + { + fLabelAttributes = attributes; + + List names = new LinkedList(); + for (LabelAttribute attr : attributes) { + attr.addChangedListener(this); + for (String name : attr.getPropertyNames()) { + names.add(name); + } + } + + fPropertyNames = names.toArray(new String[names.size()]); + } + + /** + * Disposes this column info object and the attribute objects + * within it. + */ + public void dispose() { + for (LabelAttribute attr : fLabelAttributes) { + attr.dispose(); + attr.removeChangedListener(this); + } + fLabelAttributes = EMPTY_ATTRIBUTES_ARRAY; + fPropertyNames = null; + } + + /** + * Returns the property names that need to be retrieved in order + * to generate the label for this column. + */ + public String[] getPropertyNames() { return fPropertyNames; } + + /** + * Returns the list of configured label attributes for this column. + */ + public LabelAttribute[] getLabelAttributes() { return fLabelAttributes; } + + /** + * Registers the given listener for changes in the attributes of this + * column. A change in the attributes of a label should cause + * a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Listener method called by the attribute objects. + * @see ILabelAttributeChangedListener + */ + public void attributesChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + /** + * Updates the label parameters for this column based on the provided + * properties. The label information is written to the givne label + * update under the given column index. + * @param update Update to write to. + * @param columnIndex Column to write label information under. + * @param properties Map of properties to use to generate the label. + */ + public void updateColumn(ILabelUpdate update, int columnIndex, Map properties) { + boolean textSet = false; + boolean imageSet = false; + boolean fontSet = false; + boolean colorSet = false; + + LabelAttribute[] labelAttributes = getLabelAttributes(); + for (LabelAttribute info : labelAttributes) { + + if (!(info instanceof LabelText && textSet) && + !(info instanceof LabelImage && imageSet) && + !(info instanceof LabelFont && fontSet) && + !(info instanceof LabelColor && colorSet) && + info.isEnabled(properties)) + { + info.updateAttribute(update, columnIndex, properties); + + textSet = textSet || info instanceof LabelText; + imageSet = imageSet || info instanceof LabelImage; + fontSet = fontSet || info instanceof LabelFont; + colorSet = colorSet || info instanceof LabelColor; + } + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java new file mode 100644 index 00000000000..303a6f48fda --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelFont.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.FontData; + +/** + * The font attribute of a label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelFont extends LabelAttribute { + private static final FontData DEFAULT_FONT = JFaceResources.getDefaultFontDescriptor().getFontData()[0]; + + /** + * The font data of this attribute. + */ + private FontData fFontData; + + public LabelFont() { + this(DEFAULT_FONT); + } + + public LabelFont(FontData fontData) { + fFontData = fontData; + } + + public FontData getFontData() { + return fFontData; + } + + public void setFontData(FontData fontData) { + fFontData = fontData; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + update.setFontData(getFontData(), columnIndex); + } + +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java new file mode 100644 index 00000000000..143ad406582 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelImage.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Map; + +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * The image attribute of a label. + * + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelImage extends LabelAttribute { + private ImageDescriptor fImageDescriptor; + + public LabelImage() { + this(null); + } + + public LabelImage(ImageDescriptor image) { + fImageDescriptor = image; + } + + public ImageDescriptor getImageDescriptor() { + return fImageDescriptor; + } + + public void setImageDescriptor(ImageDescriptor image) { + fImageDescriptor = image; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + ImageDescriptor descriptor = getImageDescriptor(); + if (descriptor != null) { + update.setImageDescriptor(descriptor, columnIndex); + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java new file mode 100644 index 00000000000..298eec8d851 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/LabelText.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.text.MessageFormat; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * The text attribute of a label. It uses a message format string in order to + * compose the text string. The parameter names determine the array of objects + * given to the message format. + * + * @see MessageFormat#format(Object[], StringBuffer, java.text.FieldPosition) + * @see LabelAttribute + * @see LabelColumnInfo + * @see PropertyBasedLabelProvider + */ +@SuppressWarnings("restriction") +public class LabelText extends LabelAttribute { + + public static final MessageFormat DEFAULT_MESSAGE = new MessageFormat(""); + + /** + * Message format used to generate the label text. + * + */ + private MessageFormat fMessageFormat; + + /** + * The property names needed for the message format. The property values + * corresponding to these names are given the the {@link MessageFormat#format(Object[], StringBuffer, java.text.FieldPosition)} + * method. + */ + private String[] fPropertyNames; + + public LabelText() { + this(DEFAULT_MESSAGE, EMPTY_PROPERTY_NAMES_ARRAY); + } + + public LabelText(MessageFormat format, String[] propertyNames) { + fMessageFormat = format; + fPropertyNames = propertyNames; + } + + @Override + public String[] getPropertyNames() { + return fPropertyNames; + } + + public MessageFormat getMessageFormat() { + return fMessageFormat; + } + + public void setMessageFormat(MessageFormat messageFormat) { + fMessageFormat = messageFormat; + fireAttributeChanged(); + } + + @Override + public void updateAttribute(ILabelUpdate update, int columnIndex, Map properties) { + String[] propertyNames = getPropertyNames(); + Object[] propertyValues = new Object[propertyNames.length]; + for (int i = 0; i < propertyNames.length; i++) { + propertyValues[i] = properties.get(propertyNames[i]); + } + + try { + update.setLabel(getMessageFormat().format(propertyValues, new StringBuffer(), null).toString(), columnIndex); + } catch (IllegalArgumentException e) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, 0, "Failed formatting a message for column " + columnIndex + ", for update " + update, e)); //$NON-NLS-1$ //$NON-NLS-2$ + } + } +} \ No newline at end of file diff --git a/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java new file mode 100644 index 00000000000..f13ccd36c18 --- /dev/null +++ b/plugins/org.eclipse.dd.dsf.ui/src/org/eclipse/dd/dsf/ui/viewmodel/properties/PropertyBasedLabelProvider.java @@ -0,0 +1,265 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.dsf.ui.viewmodel.properties; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.ListenerList; +import org.eclipse.core.runtime.Status; +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ImmediateExecutor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.service.IDsfService; +import org.eclipse.dd.dsf.ui.DsfUIPlugin; +import org.eclipse.dd.dsf.ui.viewmodel.VMViewerUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; + +/** + * A configurable label provider which uses element's property label provider + * to set element's label attributes. + *

+ * When this provider is registered for an element it calculates the properties + * that need to be retrieved based on view's active columns, and then it calls the + * element's property provider to retrieve those properties. After the property + * values are retrieved, they are processed in order to produce correct label text, + * images, fonts, and colors, for the given element. + */ +@SuppressWarnings("restriction") +@ThreadSafe +public class PropertyBasedLabelProvider + implements IElementLabelProvider, ILabelAttributeChangedListener +{ + private static final String[] EMPTY_PROPERTY_NAMES_ARRAY = new String[0]; + + /** + * Properties update used as to collect property data from the provider. + */ + private class PropertiesUpdate extends VMViewerUpdate implements IPropertiesUpdate { + + private final String[] fProperties; + private final Map fValues; + + public PropertiesUpdate(String[] properties, ILabelUpdate labelUpdate, DataRequestMonitor> rm) { + super(labelUpdate, rm); + fProperties = properties; + fValues = fProperties != null + ? new HashMap(properties.length * 4 / 3, 0.75f) + : new HashMap(); + } + + public String[] getProperties() { + return fProperties; + } + + public void setProperty(String property, Object value) { + fValues.put(property, value); + } + + /** + * Overrides the standard done in order to store the retrieved values + * in the client's request monitor. + */ + @Override + public void done() { + @SuppressWarnings("unchecked") + DataRequestMonitor> rm = (DataRequestMonitor>)fRequestMonitor; + if (fProperties == null || fValues.size() >= fProperties.length) { + rm.setData(fValues); + } else { + rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfService.REQUEST_FAILED, "Incomplete properties updated", null)); //$NON-NLS-1$ + } + super.done(); + } + } + + /** + * Attribute information for each column by column ID. + */ + private Map fColumnInfos = Collections.synchronizedMap(new HashMap()); + + private ListenerList fListeners = new ListenerList(); + + /** + * Standard constructor. A property based label constructor does not + * initialize column attribute information {@link #setColumnInfo(String, LabelColumnInfo)} + * must be called to configure each column. + */ + public PropertyBasedLabelProvider() { + } + + /** + * Disposes this label provider and its configured column info objects. + */ + public void dispose() { + LabelColumnInfo[] infos = null; + synchronized (fColumnInfos) { + infos = fColumnInfos.values().toArray(new LabelColumnInfo[fColumnInfos.size()]); + fColumnInfos.clear(); + } + for (LabelColumnInfo info : infos) { + info.dispose(); + } + } + + /** + * Sets the given column info object for the given column ID. This column + * info will be used to generate the label when the given column is visibile. + * @param columnId Column ID that the given column info is being registered for. + * @param info Column 'info' object containing column attributes. + * @return The previous column info object configured for this ID. + */ + public LabelColumnInfo setColumnInfo(String columnId, LabelColumnInfo info) { + LabelColumnInfo oldInfo = fColumnInfos.put(columnId, info); + info.addChangedListener(this); + if (oldInfo != null) { + info.removeChangedListener(this); + } + return oldInfo; + } + + /** + * Returns the given column info object for the given column ID. + * @param columnId Column ID to retrieve the column info for. + * @@return Column 'info' object containing column attributes. + */ + public LabelColumnInfo getColumnInfo(String column) { + return fColumnInfos.get(column); + } + + /** + * Registers the given listener for changes in the attributes of this + * label provider. A change in the attributes of a label should cause + * a view to repaint. + * @param listener Listener to register. + */ + public void addChangedListener(ILabelAttributeChangedListener listener) { + fListeners.add(listener); + } + + /** + * Unregisters the given listener. + * @param listener Listener to unregister. + */ + public void removeChangedListener(ILabelAttributeChangedListener listener) { + fListeners.remove(listener); + } + + /** + * Listener method called by label provider's column info objects. + * @see ILabelAttributeChangedListener + */ + public void attributesChanged() { + Object[] listeners = fListeners.getListeners(); + for (Object listener : listeners) { + ((ILabelAttributeChangedListener)listener).attributesChanged(); + } + } + + public void update(ILabelUpdate[] labelUpdates) { + IElementPropertiesProvider propertiesProvider = getElementPropertiesProvider(labelUpdates[0].getElement()); + if (propertiesProvider == null) { + for (ILabelUpdate update : labelUpdates) { + update.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, "Properties-based label provider " + this + " failed to generate a label, no properties provider registered for element: " + labelUpdates[0].getElement())); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + String[] columnIds = labelUpdates[0].getColumnIds(); + String[] propertyNames = calcPropertyNamesForColumns(columnIds); + + // Call the properties provider. Create a request monitor for each label update. + // We can use an immediate executor for the request monitor because the label provider + // is thread safe. + IPropertiesUpdate[] propertiesUpdates = new IPropertiesUpdate[labelUpdates.length]; + for (int i = 0; i < labelUpdates.length; i++) { + final ILabelUpdate labelUpdate = labelUpdates[i]; + propertiesUpdates[i] = new PropertiesUpdate( + propertyNames, labelUpdates[i], + new DataRequestMonitor>(ImmediateExecutor.getInstance(), null) { + @Override + protected void handleCompleted() { + if (getStatus().isOK()) { + updateLabel(labelUpdate, getData()); + } + labelUpdate.done(); + } + }); + } + propertiesProvider.update(propertiesUpdates); + } + + /** + * Calculates the names of properties that have to be retrieved from the property + * provider to generate the labels for given columns. + * @param columnIds Column IDs to check. + * @return Array of property names. + */ + private String[] calcPropertyNamesForColumns(String[] columnIds) { + if (columnIds == null) { + LabelColumnInfo columnInfo = getColumnInfo(null); + if (columnInfo != null) { + return columnInfo.getPropertyNames(); + } else { + return EMPTY_PROPERTY_NAMES_ARRAY; + } + } else { + List properties = new LinkedList(); + for (String columnId : columnIds) { + LabelColumnInfo info = getColumnInfo(columnId); + if (info != null) { + String[] infoPropertyNames = info.getPropertyNames(); + for (int i = 0; i < infoPropertyNames.length; i++) { + properties.add(infoPropertyNames[i]); + } + } + } + return properties.toArray(new String[properties.size()]); + } + } + + /** + * Updates the label information based on given map of properties. + * @param update Label update to write to. + * @param properties Properties retrieved from the element properties provider. + */ + protected void updateLabel(ILabelUpdate update, Map properties) { + if (update.getColumnIds() == null) { + LabelColumnInfo info = getColumnInfo(null); + if (info != null) { + info.updateColumn(update, 0, properties); + } + } else { + String[] columnIds = update.getColumnIds(); + + for (int i = 0; i < columnIds.length; i++) { + LabelColumnInfo info = getColumnInfo(columnIds[i]); + if (info != null) { + info.updateColumn(update, i, properties); + } + } + } + + update.done(); + } + + private IElementPropertiesProvider getElementPropertiesProvider(Object element) { + if (element instanceof IAdaptable) { + return (IElementPropertiesProvider)((IAdaptable)element).getAdapter(IElementPropertiesProvider.class); + } + return null; + } +}