Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 73633 Details for
Bug 188333
[Viewers] Label provider for multi-colored TableItems/TreeItems
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Implementation and snippets
patch.txt (text/plain), 43.70 KB, created by
Michael Chervil
on 2007-07-12 04:01:48 EDT
(
hide
)
Description:
Implementation and snippets
Filename:
MIME Type:
Creator:
Michael Chervil
Created:
2007-07-12 04:01:48 EDT
Size:
43.70 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jface >Index: src/org/eclipse/jface/viewers/StyledViewerLabel.java >=================================================================== >RCS file: src/org/eclipse/jface/viewers/StyledViewerLabel.java >diff -N src/org/eclipse/jface/viewers/StyledViewerLabel.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/viewers/StyledViewerLabel.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,50 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Michael Krkoska 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: >+ * Michael Krkoska - initial API and implementation >+ ******************************************************************************/ >+ >+package org.eclipse.jface.viewers; >+ >+import org.eclipse.swt.custom.StyleRange; >+import org.eclipse.swt.graphics.Image; >+ >+/** >+ * A viewer label for usage with {@link StyledCellLabelProvider}. >+ * >+ * @since 3.4 >+ * @author Michael Krkoska <michael.krkoska@gmail.com> >+ */ >+public class StyledViewerLabel extends ViewerLabel { >+ >+ StyleRange[] styleRanges; >+ >+ /** >+ * @param initialText >+ * @param initialImage >+ */ >+ public StyledViewerLabel(String initialText, Image initialImage) { >+ super(initialText, initialImage); >+ } >+ >+ /** >+ * @return Returns the styleRanges for this label. >+ */ >+ public StyleRange[] getStyleRanges() { >+ return styleRanges; >+ } >+ >+ /** >+ * @param styleRanges >+ * The styleRanges for this label. If null, no styles are >+ * applied. >+ */ >+ public void setStyleRanges(StyleRange[] styleRanges) { >+ this.styleRanges = styleRanges; >+ } >+} >Index: src/org/eclipse/jface/viewers/StyledCellLabelProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/viewers/StyledCellLabelProvider.java >diff -N src/org/eclipse/jface/viewers/StyledCellLabelProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/viewers/StyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,579 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Michael Krkoska 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: >+ * Michael Krkoska - initial API and implementation >+ * Tom Schindl - initial API >+ *******************************************************************************/ >+package org.eclipse.jface.viewers; >+ >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.Map; >+ >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.StyleRange; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Device; >+import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.FontData; >+import org.eclipse.swt.graphics.FontMetrics; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.GlyphMetrics; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.graphics.TextLayout; >+import org.eclipse.swt.graphics.TextStyle; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.Tree; >+import org.eclipse.swt.widgets.Widget; >+ >+/** >+ * A CellLabelProvider which supports styled labels by using owner draw. >+ * <p> >+ * For providing the label's styles, create a subclass and overwrite >+ * {@link StyledCellLabelProvider#getStyledViewerLabel(Object)} . The default >+ * values for colors and fonts, which are applied on all parts of the label >+ * where no style is specified, can be provided by implementing >+ * {@link IFontProvider} or {@link IColorProvider} in the subclass. >+ * </p> >+ * <p> >+ * To specify the position of the image provided by the label provider, include >+ * the IMAGE_PLACEHOLDER char in your label. If this char is not included, the >+ * label is positioned at the beginning. >+ * </p> >+ * <p> >+ * To set up styled labels for your viewer's control, you must call >+ * {@link OwnerDrawLabelProvider#setUpOwnerDraw(ColumnViewer)}. >+ * </p> >+ * <p> >+ * For multi line labels usage of StyledMultiLineProvider is recommended. >+ * </p> >+ * >+ * @since 3.4 >+ * @author Michael Krkoska <michael.krkoska@gmail.com> >+ * @author Tom Schindl <tom.schindl@bestsolution.at> >+ */ >+public class StyledCellLabelProvider extends OwnerDrawLabelProvider implements >+ ILabelProvider { >+ >+ /** >+ * This is the char which can be used as placeholder for an image in the >+ * label. >+ */ >+ public static final char IMAGE_PLACEHOLDER = '\uFFFC'; >+ >+ /** >+ * Style constant for centering the viewer's items vertically if their >+ * heights are less than the maximum vertical height. >+ */ >+ public static final int CENTER_ITEMS_VERTICALLY = 1; >+ /** >+ * Style constant for centering the text of a viewer's item vertically if >+ * its height is less than the height of the item's image. >+ */ >+ public static final int CENTER_TEXT_VERTICALLY = 2; >+ /** >+ * Style constant for indicating that the styled colors are to be applied >+ * even it the viewer's item is selected. Default is not to apply colors. >+ */ >+ public static final int APPLY_COLORS_ON_SELECTION = 4; >+ >+ private static final boolean isCarbon = SWT.getPlatform().equals("carbon"); //$NON-NLS-1$ >+ >+ boolean centerItemsVertically = false; >+ boolean centerTextVertically = false; >+ boolean applyColorsOnSelection = false; >+ >+ ColumnViewer viewer; >+ private IFontProvider fontProvider = null; >+ private IColorProvider colorProvider = null; >+ >+ private Map styledFonts = new HashMap(); >+ >+ private int cacheKeyIndex = -1; >+ private Object cacheKeyElement = null; >+ private StyledViewerLabel cachedViewerLabel = null; >+ private TextLayout cachedTextLayout = null; >+ private boolean paintFollowsMeasureImmediately = true; >+ >+ /** >+ * Creates a new StyledCellLabelProvider. >+ * >+ * @param viewer >+ * @param style >+ * the style bits >+ * @see StyledCellLabelProvider#CENTER_ITEMS_VERTICALLY >+ * @see StyledCellLabelProvider#CENTER_TEXT_VERTICALLY >+ * @see StyledCellLabelProvider#APPLY_COLORS_ON_SELECTION >+ */ >+ public StyledCellLabelProvider(ColumnViewer viewer, int style) { >+ this.viewer = viewer; >+ if ((CENTER_ITEMS_VERTICALLY & style) != 0) { >+ centerItemsVertically = true; >+ } >+ if ((CENTER_TEXT_VERTICALLY & style) != 0) { >+ centerTextVertically = true; >+ } >+ if ((APPLY_COLORS_ON_SELECTION & style) != 0) { >+ applyColorsOnSelection = true; >+ } >+ if (this instanceof IFontProvider) { >+ fontProvider = (IFontProvider) this; >+ } >+ if (this instanceof IColorProvider) { >+ colorProvider = (IColorProvider) this; >+ } >+ } >+ >+ public void dispose() { >+ super.dispose(); >+ for (Iterator iterator = styledFonts.values().iterator(); iterator >+ .hasNext();) { >+ Font f = (Font) iterator.next(); >+ f.dispose(); >+ } >+ styledFonts.clear(); >+ if (cachedTextLayout != null && !cachedTextLayout.isDisposed()) >+ cachedTextLayout.dispose(); >+ } >+ >+ public Image getImage(Object element) { >+ return null; >+ } >+ >+ public String getText(Object element) { >+ return ""; //$NON-NLS-1$ >+ } >+ >+ /** >+ * Creates a TextLayout instance for either measuring or painting the item, >+ * using the StyleRanges contained in the {@link StyledViewerLabel}. >+ * >+ * Adds an image at the first occurence of >+ * {@link StyledCellLabelProvider#IMAGE_PLACEHOLDER} or at the beginning of >+ * the label. >+ * >+ * @param event >+ * the measure or paint event for which a TextLayout is needed >+ * @param viewerLabel >+ * the viewer label containing the text, image and styles for the >+ * TextLayout >+ * @return a TextLayout instance which must be disposed after use. >+ */ >+ protected TextLayout createTextLayout(Event event, >+ StyledViewerLabel viewerLabel) { >+ String label = viewerLabel.getText(); >+ Image image = viewerLabel.getImage(); >+ Font defaultFont = viewerLabel.getFont(); >+ if (defaultFont == null) >+ defaultFont = viewer.getControl().getFont(); >+ Color defaultBackground = viewerLabel.getBackground(); >+ boolean applyColors = (applyColorsOnSelection || (event.detail & SWT.SELECTED) == 0); >+ >+ Display display = event.display; >+ TextLayout layout = new TextLayout(display); >+ >+ int maxFontHeight = 0; >+ layout.setFont(defaultFont); >+ maxFontHeight = getFontHeight(defaultFont); >+ >+ int rangeOffset = 0, imageOffset = 0; >+ GlyphMetrics imageMetrics = null; >+ TextStyle imageStyle = null; >+ if (image != null) { >+ int index = label.indexOf(IMAGE_PLACEHOLDER); >+ String labelWithImage = label; >+ if (index < 0) { >+ labelWithImage = IMAGE_PLACEHOLDER + " " + label; //$NON-NLS-1$ >+ rangeOffset = 2; >+ } >+ layout.setText(labelWithImage); >+ imageOffset = Math.max(0, index); >+ Rectangle bounds = image.getBounds(); >+ imageStyle = new TextStyle(null, null, null); >+ imageMetrics = new GlyphMetrics(bounds.height, 0, bounds.width); >+ imageStyle.metrics = imageMetrics; >+ } else { >+ layout.setText(label); >+ } >+ >+ StyleRange[] styleRanges = viewerLabel.getStyleRanges(); >+ if (styleRanges != null) { >+ for (int i = 0; i < styleRanges.length; i++) { >+ StyleRange styleRange = styleRanges[i]; >+ checkFont(display, styleRange); >+ if (!applyColors) { >+ styleRange = stripColors(styleRange); >+ } >+ layout.setStyle(styleRange, styleRange.start + rangeOffset, >+ styleRange.start + rangeOffset + styleRange.length - 1); >+ if (styleRange.font != null) { >+ maxFontHeight = Math.max(maxFontHeight, >+ getFontHeight(styleRange.font)); >+ } >+ } >+ } >+ >+ if (imageStyle != null) { >+ layout.setStyle(imageStyle, imageOffset, imageOffset); >+ } >+ >+ if (centerTextVertically && imageMetrics != null) { >+ int lineCount = layout.getLineCount(); >+ if (lineCount == 1 && imageMetrics.ascent > maxFontHeight) { >+ // vertically center the text if there is an image bigger than >+ // the text. >+ int height = imageMetrics.ascent; >+ int space = (height - maxFontHeight); >+ imageMetrics.ascent = (maxFontHeight) + Math.round(space / 2f); >+ // TODO why does it look better (at least on win xp) with this >+ // added pixel? >+ layout.setDescent(height - imageMetrics.ascent + 1); >+ } >+ >+ } >+ >+ if (defaultBackground != null && applyColors) { >+ int[] ranges = layout.getRanges(); >+ int oldEnd = -1; >+ TextStyle[] styles = layout.getStyles(); >+ for (int i = 0, length = ranges.length; i < length; i += 2) { >+ int start = ranges[i]; >+ int end = ranges[i + 1]; >+ if (start > oldEnd + 1) { >+ TextStyle style = new TextStyle(null, null, >+ defaultBackground); >+ layout.setStyle(style, oldEnd + 1, start - 1); >+ } >+ >+ TextStyle style = styles[i >> 1]; >+ if (style.background == null) { >+ style.background = defaultBackground; >+ layout.setStyle(style, start, end); >+ } >+ >+ oldEnd = end; >+ } >+ if (layout.getText().length() > oldEnd + 1) { >+ TextStyle style = new TextStyle(null, null, defaultBackground); >+ layout.setStyle(style, oldEnd + 1, >+ layout.getText().length() - 1); >+ } >+ } >+ >+ return layout; >+ } >+ >+ /** >+ * Handle the erase event. The default implementation does nothing to ensure >+ * keep native selection highlighting working. >+ * >+ * @param event >+ * the erase event >+ * @param element >+ * the model object >+ * @see SWT#EraseItem >+ */ >+ protected void erase(Event event, Object element) { >+ event.detail &= ~SWT.FOREGROUND; >+ } >+ >+ /** >+ * Returns a StyledViewerLabel instance containing the text, image and style >+ * information to use for displaying element. >+ * >+ * The default implementation sets the default font and colors if this >+ * StyledCellLabelProvider implements {@link IFontProvider} or >+ * {@link IColorProvider}. These are applied on the label if they are not >+ * overwritten by styles. >+ * >+ * This implementation does not set any styles. To achieve this, you should >+ * subclass, call super.getStyledViewerLabel(Object) and set your styles in >+ * the instance. >+ * >+ * @param element >+ * the element to create a viewer label for >+ * @return the styled viewer label containing the information how to display >+ * element >+ */ >+ protected StyledViewerLabel getStyledViewerLabel(Object element) { >+ StyledViewerLabel viewerLabel = new StyledViewerLabel(null, null); >+ viewerLabel.setImage(getImage(element)); >+ viewerLabel.setText(getText(element)); >+ viewerLabel.setFont(getDefaultFont(element)); >+ viewerLabel.setBackground(getDefaultBackground(element)); >+ viewerLabel.setForeground(getDefaultForeground(element)); >+ return viewerLabel; >+ } >+ >+ protected void measure(Event event, Object element) { >+ int height = isCarbon ? getCurrentHeight(event.widget) : 0; >+ >+ StyledViewerLabel viewerLabel = getStyledViewerLabel(element); >+ >+ measure(event, element, viewerLabel); >+ >+ if (isCarbon && event.height != height) { >+ // On Carbon the first cell in a Table is not updated properly, if >+ // the size changes. >+ viewer.getControl().redraw(); >+ } >+ } >+ >+ /** >+ * Handle the MeasureItem event. >+ * >+ * @param event >+ * The MeasureItem event >+ * @param element >+ * The element of the viewer's item of this MeasureItem event >+ * @param viewerLabel >+ * The ViewerLabel of the viewer's item of this MeasureItem event >+ * @see SWT#MeasureItem >+ */ >+ protected void measure(Event event, Object element, >+ StyledViewerLabel viewerLabel) { >+ TextLayout textLayout = createTextLayout(event, viewerLabel); >+ Rectangle bounds = textLayout.getBounds(); >+ event.setBounds(new Rectangle(0, 0, bounds.width, bounds.height)); >+ >+ putIntoCache(event, element, viewerLabel, textLayout); >+ } >+ >+ protected void paint(Event event, Object element) { >+ checkEventOrder(event, element); >+ StyledViewerLabel viewerLabel = getViewerLabelFromCache(event, element); >+ if (viewerLabel == null) >+ viewerLabel = getStyledViewerLabel(element); >+ paint(event, element, viewerLabel); >+ } >+ >+ /** >+ * Handle the PaintItem event. >+ * >+ * @param event >+ * The PaintItem event >+ * @param element >+ * The element of the viewer's item of this PaintItem event >+ * @param viewerLabel >+ * The ViewerLabel of the viewer's item of this PaintItem event >+ * @see SWT#PaintItem >+ */ >+ protected void paint(Event event, Object element, >+ StyledViewerLabel viewerLabel) { >+ >+ String label = viewerLabel.getText(); >+ Image image = viewerLabel.getImage(); >+ Color defaultBackground = viewerLabel.getBackground(); >+ >+ TextLayout textLayout = getLayoutFromCache(event, element); >+ if (textLayout == null >+ || (!applyColorsOnSelection && (event.detail & SWT.SELECTED) != 0)) >+ /* >+ * if painting selection and not applying colors, don't use cache, >+ * since at cache time we didn't know about SWT.SELECTED, since this >+ * detail is not set in MeasureItem >+ */ >+ textLayout = createTextLayout(event, viewerLabel); >+ >+ boolean applyColors = (applyColorsOnSelection || (event.detail & SWT.SELECTED) == 0); >+ GC gc = event.gc; >+ Color oldForeground = gc.getForeground(), oldBackground = gc >+ .getBackground(); >+ Color foreground = viewerLabel.getForeground(); >+ if (foreground != null && applyColors) { >+ gc.setForeground(foreground); >+ } >+ >+ if (defaultBackground != null && applyColors) { >+ gc.setBackground(defaultBackground); >+ } >+ >+ int heightOffset = 0; >+ if (centerItemsVertically) { >+ heightOffset = (event.height - textLayout.getBounds().height) / 2; >+ heightOffset = Math.max(0, heightOffset); >+ } >+ >+ textLayout.draw(gc, event.x, event.y + heightOffset); >+ >+ if (image != null) { >+ int imageOffset = Math.max(0, label.indexOf(IMAGE_PLACEHOLDER)); >+ int lineIndex = textLayout.getLineIndex(imageOffset); >+ FontMetrics lineMetrics = textLayout.getLineMetrics(lineIndex); >+ Point point = textLayout.getLocation(imageOffset, false); >+ GlyphMetrics glyphMetrics = textLayout.getStyle(imageOffset).metrics; >+ int y = event.y + point.y + lineMetrics.getAscent() >+ - glyphMetrics.ascent + heightOffset; >+ // Following line is because of a strange incorrect measurement of 3 >+ // pixels under win32 in some cases. >+ y = Math.max(event.y, y); >+ gc.drawImage(image, event.x + point.x, y); >+ } >+ textLayout.dispose(); >+ >+ gc.setForeground(oldForeground); >+ gc.setBackground(oldBackground); >+ } >+ >+ int getFontHeight(Font font) { >+ int h = 0; >+ FontData[] fontData = font.getFontData(); >+ for (int i = 0; i < fontData.length; i++) { >+ h = Math.max(h, (int) fontData[i].height); >+ } >+ return h; >+ } >+ >+ private void checkEventOrder(Event event, Object element) { >+ // checks if the event order of this SWT implementation is cachable >+ if (!paintFollowsMeasureImmediately || cacheKeyElement != element >+ || cacheKeyIndex != event.index) >+ paintFollowsMeasureImmediately = false; >+ } >+ >+ private void checkFont(Device device, StyleRange styleRange) { >+ int fontStyle = styleRange.fontStyle; >+ if (fontStyle != SWT.NORMAL) { >+ Font font = styleRange.font; >+ if (font == null) { >+ font = JFaceResources.getDefaultFont(); >+ } >+ boolean wrongStyle = false; >+ FontData[] fontData = font.getFontData(); >+ for (int i = 0, length = fontData.length; i < length && !wrongStyle; i++) { >+ if (fontData[i].getStyle() != fontStyle) { >+ wrongStyle = true; >+ } >+ } >+ if (wrongStyle) { >+ fontData = getFontData(font, fontStyle); >+ // TODO using fontData[0] as cache key might be wrong on motif >+ font = (Font) styledFonts.get(fontData[0]); >+ if (font == null) { >+ font = new Font(device, fontData); >+ styledFonts.put(fontData[0], font); >+ } >+ } >+ styleRange.font = font; >+ } >+ } >+ >+ private int getCurrentHeight(Widget widget) { >+ if (widget instanceof Table) >+ return ((Table) widget).getItemHeight(); >+ if (widget instanceof Tree) >+ return ((Tree) widget).getItemHeight(); >+ return -1; >+ } >+ >+ /** >+ * Provides a default background color for the given element, which is used >+ * for the part of the label where no background color is specified in the >+ * StyleRanges provided by the StyledViewerLabel. >+ * >+ * @param element >+ * the element >+ * @return the background color for the element, or <code>null</code> to >+ * use the default background color >+ */ >+ private Color getDefaultBackground(Object element) { >+ if (colorProvider != null) { >+ return colorProvider.getBackground(element); >+ } >+ return null; >+ } >+ >+ /** >+ * Provides a default font for the given element, which is used for the part >+ * of the label where no font is specified in the StyleRanges provided by >+ * the StyledViewerLabel. >+ * >+ * @param element >+ * the element >+ * @return the font for the element, or <code>null</code> to use the >+ * default font >+ */ >+ private Font getDefaultFont(Object element) { >+ if (fontProvider != null) { >+ return fontProvider.getFont(element); >+ } >+ return null; >+ } >+ >+ /** >+ * Provides a default foreground color for the given element, which is used >+ * for the part of the label where no foreground color is specified in the >+ * StyleRanges provided by the StyledViewerLabel. >+ * >+ * @param element >+ * the element >+ * @return the foreground color for the element, or <code>null</code> to >+ * use the default foreground color >+ */ >+ private Color getDefaultForeground(Object element) { >+ if (colorProvider != null) { >+ return colorProvider.getForeground(element); >+ } >+ return null; >+ } >+ >+ private FontData[] getFontData(Font font, int style) { >+ FontData[] fontDatas = font.getFontData(); >+ for (int i = 0; i < fontDatas.length; i++) { >+ fontDatas[i].setStyle(style); >+ } >+ return fontDatas; >+ } >+ >+ private TextLayout getLayoutFromCache(Event event, Object element) { >+ if (paintFollowsMeasureImmediately && cacheKeyElement == element >+ && cacheKeyIndex == event.index && cachedTextLayout != null >+ && !cachedTextLayout.isDisposed()) >+ return cachedTextLayout; >+ return null; >+ } >+ >+ private StyledViewerLabel getViewerLabelFromCache(Event event, >+ Object element) { >+ if (paintFollowsMeasureImmediately && cacheKeyElement == element >+ && cacheKeyIndex == event.index && cachedViewerLabel != null) >+ return cachedViewerLabel; >+ return null; >+ } >+ >+ private void putIntoCache(Event event, Object element, >+ StyledViewerLabel viewerLabel, TextLayout textLayout) { >+ cacheKeyElement = element; >+ cacheKeyIndex = event.index; >+ if(cachedTextLayout != null && !cachedTextLayout.isDisposed()) >+ cachedTextLayout.dispose(); >+ cachedTextLayout = textLayout; >+ cachedViewerLabel = viewerLabel; >+ } >+ >+ private StyleRange stripColors(StyleRange style) { >+ if (style.background == null && style.foreground == null) >+ return style; >+ StyleRange clone = new StyleRange(style.start, style.length, null, null); >+ clone.font = style.font; >+ clone.fontStyle = style.fontStyle; >+ clone.rise = style.rise; >+ clone.strikeout = style.strikeout; >+ if (style.metrics != null) { >+ clone.metrics = new GlyphMetrics(style.metrics.ascent, >+ style.metrics.descent, style.metrics.width); >+ } >+ return clone; >+ } >+ >+} >Index: src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java >=================================================================== >RCS file: src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java >diff -N src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/jface/viewers/WrappedStyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,150 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Michael Krkoska 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: >+ * Michael Krkoska - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.jface.viewers; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.Image; >+ >+/** >+ * A wrapper for using {@link StyledCellLabelProvider} with classic label >+ * providers implementing any of ILabelProvider, IFontProvider, IColorProvider >+ * or the corresponding table variants. >+ * >+ * The provided color and font information is used as default style for the >+ * item. >+ * >+ * @since 3.4 >+ * @author Michael Krkoska <michael.krkoska@gmail.com> >+ */ >+public class WrappedStyledCellLabelProvider extends StyledCellLabelProvider >+ implements IColorProvider, IFontProvider { >+ >+ private ILabelProvider labelProvider; >+ private IFontProvider fontProvider = null; >+ private IColorProvider colorProvider = null; >+ private ITableLabelProvider tableLabelProvider = null; >+ private ITableFontProvider tableFontProvider = null; >+ private ITableColorProvider tableColorProvider = null; >+ private int columnIndex; >+ >+ /** >+ * Creates a WrappedStyledCellLabelProvider for usage with a ViewerColumn. >+ * >+ * @param viewer >+ * the viewer for this CellLabelProvider >+ * @param style >+ * the style bits for this StyledCellLabelProvider >+ * @param labelProvider >+ * the label provider implementing ILabelProvider and optionally >+ * IFontProvider or IColorProvider >+ */ >+ public WrappedStyledCellLabelProvider(ColumnViewer viewer, int style, >+ IBaseLabelProvider labelProvider) { >+ this(viewer, style, labelProvider, 0); >+ } >+ >+ /** >+ * Creates a WrappedStyledCellLabelProvider for usage with a ViewerColumn. >+ * >+ * @param viewer >+ * the viewer for this CellLabelProvider >+ * @param style >+ * the style bits for this StyledCellLabelProvider >+ * @param labelProvider >+ * the label provider implementing ILabelProvider and optionally >+ * IFontProvider or IColorProvider >+ * @param columnIndex >+ * the column index to pass to a wrapped ITable*Provider >+ */ >+ public WrappedStyledCellLabelProvider(ColumnViewer viewer, int style, >+ IBaseLabelProvider labelProvider, int columnIndex) { >+ super(viewer, style); >+ this.columnIndex = columnIndex; >+ setLabelProvider(labelProvider); >+ } >+ >+ public Color getBackground(Object element) { >+ if (tableColorProvider != null) { >+ return tableColorProvider.getBackground(element, columnIndex); >+ } >+ if (colorProvider != null && columnIndex == 0) { >+ return colorProvider.getBackground(element); >+ } >+ return null; >+ } >+ >+ public Font getFont(Object element) { >+ if (tableFontProvider != null) { >+ return tableFontProvider.getFont(element, columnIndex); >+ } >+ if (fontProvider != null && columnIndex == 0) { >+ return fontProvider.getFont(element); >+ } >+ return null; >+ } >+ >+ public Color getForeground(Object element) { >+ if (tableColorProvider != null) { >+ return tableColorProvider.getForeground(element, columnIndex); >+ } >+ if (colorProvider != null && columnIndex == 0) { >+ return colorProvider.getForeground(element); >+ } >+ return null; >+ } >+ >+ public Image getImage(Object element) { >+ if (tableLabelProvider != null) { >+ return tableLabelProvider.getColumnImage(element, columnIndex); >+ } >+ if (columnIndex == 0) { >+ return labelProvider.getImage(element); >+ } >+ return null; >+ } >+ >+ public String getText(Object element) { >+ if (tableLabelProvider != null) { >+ return tableLabelProvider.getColumnText(element, columnIndex); >+ } >+ if (columnIndex == 0) { >+ return labelProvider.getText(element); >+ } >+ return ""; //$NON-NLS-1$ >+ } >+ >+ private void setLabelProvider(IBaseLabelProvider labelProvider) { >+ Assert.isTrue(labelProvider instanceof ITableLabelProvider >+ || labelProvider instanceof ILabelProvider); >+ if (labelProvider instanceof ILabelProvider) { >+ this.labelProvider = (ILabelProvider) labelProvider; >+ } >+ if (labelProvider instanceof IFontProvider) { >+ fontProvider = (IFontProvider) labelProvider; >+ } >+ if (labelProvider instanceof IColorProvider) { >+ colorProvider = (IColorProvider) labelProvider; >+ } >+ if (labelProvider instanceof ITableLabelProvider) { >+ tableLabelProvider = (ITableLabelProvider) labelProvider; >+ } >+ if (labelProvider instanceof ITableFontProvider) { >+ tableFontProvider = (ITableFontProvider) labelProvider; >+ } >+ if (labelProvider instanceof ITableColorProvider) { >+ tableColorProvider = (ITableColorProvider) labelProvider; >+ } >+ } >+ >+} >#P org.eclipse.jface.snippets >Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet043StyledCellLabelProvider.java >=================================================================== >RCS file: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet043StyledCellLabelProvider.java >diff -N Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet043StyledCellLabelProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet043StyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,274 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Michael Krkoska 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: >+ * Michael Krkoska - initial API and implementation >+ *******************************************************************************/ >+ >+package org.eclipse.jface.snippets.viewers; >+ >+import java.util.ArrayList; >+import java.util.Iterator; >+import java.util.List; >+import java.util.regex.Matcher; >+import java.util.regex.Pattern; >+ >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.text.TextPresentation; >+import org.eclipse.jface.viewers.ArrayContentProvider; >+import org.eclipse.jface.viewers.ColumnPixelData; >+import org.eclipse.jface.viewers.ColumnViewer; >+import org.eclipse.jface.viewers.IColorProvider; >+import org.eclipse.jface.viewers.IFontProvider; >+import org.eclipse.jface.viewers.OwnerDrawLabelProvider; >+import org.eclipse.jface.viewers.StyledCellLabelProvider; >+import org.eclipse.jface.viewers.StyledViewerLabel; >+import org.eclipse.jface.viewers.TableLayout; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.TableViewerColumn; >+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.FontData; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Listener; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.swt.widgets.Text; >+ >+/** >+ * A TableViewer using a StyledCellLabelProvider to show some of the >+ * possibilities: >+ * <ul> >+ * <li>placing the image provided by the label provider anywhere in the label</li> >+ * <li>multi-line labels (currently only by placing line breaks in the label)</li> >+ * <li>multi font labels</li> >+ * <li>multi colored labels</li> >+ * </ul> >+ * >+ * @author Michael Krkoska <michael.krkoska@gmail.com> >+ */ >+public class Snippet043StyledCellLabelProvider { >+ >+ private static final String[] TEXT = new String[] { // >+ // >+ "TextStyle defines a set of styles that can be\n" + // >+ "applied to a range of text. The hashCode() method\n" + // >+ "in this class uses the values of the public fields to",// >+ "compute the hash value.\uFFFC When storing instances\n" + // >+ "of the class in hashed collections do not modify\n" + // >+ "these fields after the object has been inserted.",// >+ "Application code does not need to explicitly\n" + // >+ "release the resources managed and thus no\n" + // >+ "dispose() method is provided.\uFFFC", }; >+ >+ private static final Pattern METHODS = Pattern.compile("\\w+\\(\\)"); >+ private static final int SHELL_WIDTH = 640; >+ private static final Display DISPLAY = Display.getDefault(); >+ private static int IMAGE_SIZE = 16; >+ private static final Image IMAGE1 = new Image(DISPLAY, DISPLAY >+ .getSystemImage(SWT.ICON_WARNING).getImageData().scaledTo( >+ IMAGE_SIZE, IMAGE_SIZE)); >+ private static final Image IMAGE2 = new Image(DISPLAY, DISPLAY >+ .getSystemImage(SWT.ICON_ERROR).getImageData().scaledTo(IMAGE_SIZE, >+ IMAGE_SIZE)); >+ >+ public static void main(String[] args) { >+ >+ Shell shell = new Shell(DISPLAY, SWT.CLOSE); >+ shell.setSize(SHELL_WIDTH, 300); >+ shell.setLayout(new GridLayout(2, false)); >+ >+ Snippet043StyledCellLabelProvider example = new Snippet043StyledCellLabelProvider(); >+ example.createPartControl(shell); >+ >+ shell.open(); >+ >+ while (!shell.isDisposed()) { >+ if (!DISPLAY.readAndDispatch()) { >+ DISPLAY.sleep(); >+ } >+ } >+ DISPLAY.dispose(); >+ } >+ >+ private TableViewer viewer; >+ >+ private Text text; >+ >+ public Snippet043StyledCellLabelProvider() { >+ int defaultSize = JFaceResources.getDefaultFontDescriptor() >+ .getFontData()[0].getHeight(); >+ JFaceResources.getFontRegistry().put( >+ "Courier", >+ new FontData[] { new FontData("Courier New", defaultSize, >+ SWT.NORMAL) }); >+ FontData[] fontData = JFaceResources.getFontRegistry() >+ .defaultFontDescriptor().getFontData(); >+ fontData[0].setHeight(fontData[0].getHeight() + 2); >+ JFaceResources.getFontRegistry().put("BiggerDefault", fontData); >+ } >+ >+ public void createPartControl(Composite parent) { >+ Label label = new Label(parent, SWT.NONE); >+ label.setText("type something here:"); >+ >+ text = new Text(parent, SWT.NONE); >+ text.setText("hash"); >+ text.setSelection(0, 4); >+ text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); >+ text.addListener(SWT.Modify, new Listener() { >+ >+ public void handleEvent(Event event) { >+ viewer.refresh(); >+ } >+ }); >+ >+ // SWT.FULL_SELECTION is needed on win32 as long as Bug 168807 exists >+ viewer = new TableViewer(parent, SWT.FULL_SELECTION); >+ >+ GridData data = new GridData(GridData.GRAB_HORIZONTAL >+ | GridData.GRAB_VERTICAL | GridData.FILL_BOTH); >+ data.horizontalSpan = 2; >+ viewer.getControl().setLayoutData(data); >+ >+ viewer.setContentProvider(new ArrayContentProvider()); >+ createColumns(); >+ >+ OwnerDrawLabelProvider.setUpOwnerDraw(viewer); >+ viewer.setInput(TEXT); >+ } >+ >+ private void createColumns() { >+ TableLayout layout = new TableLayout(); >+ viewer.getTable().setLayout(layout); >+ viewer.getTable().setHeaderVisible(true); >+ viewer.getTable().setLinesVisible(true); >+ >+ int width = SHELL_WIDTH - 2 * 5 >+ - viewer.getTable().getShell().computeTrim(0, 0, 0, 0).width; >+ int width1 = width / 2; >+ int width2 = width - width1; >+ >+ TableViewerColumn tc = new TableViewerColumn(viewer, SWT.NONE); >+ tc.getColumn().setText("col1"); >+ layout.addColumnData(new ColumnPixelData(width1)); >+ tc.setLabelProvider(new MyStyleRangeLabelProviderCol1(viewer, >+ StyledCellLabelProvider.CENTER_ITEMS_VERTICALLY)); >+ >+ tc = new TableViewerColumn(viewer, SWT.NONE); >+ tc.getColumn().setText("col2"); >+ layout.addColumnData(new ColumnPixelData(width2)); >+ tc.setLabelProvider(new MyStyleRangeLabelProviderCol2(viewer, >+ StyledCellLabelProvider.CENTER_ITEMS_VERTICALLY)); >+ } >+ >+ private StyleRange[] getStyleRanges(Object element, String label) { >+ String searchText = text.getText(); >+ TextPresentation tp = new TextPresentation(); >+ if (searchText.length() > 0) { >+ Color yellow = text.getDisplay().getSystemColor(SWT.COLOR_YELLOW); >+ int index = -1; >+ while ((index = label.indexOf(searchText, index + 1)) >= 0) { >+ StyleRange styleRange = new StyleRange(index, searchText >+ .length(), null, yellow); >+ tp.mergeStyleRange(styleRange); >+ } >+ } >+ >+ Font courier = JFaceResources.getFont("Courier"); >+ Matcher matcher = METHODS.matcher(label); >+ while (matcher.find()) { >+ StyleRange styleRange = new StyleRange(matcher.start(), matcher >+ .end() >+ - matcher.start(), null, null); >+ styleRange.font = courier; >+ tp.mergeStyleRange(styleRange); >+ } >+ >+ List ranges = new ArrayList(); >+ for (Iterator iterator = tp.getAllStyleRangeIterator(); iterator >+ .hasNext();) { >+ ranges.add(iterator.next()); >+ } >+ return (StyleRange[]) ranges.toArray(new StyleRange[ranges.size()]); >+ } >+ >+ private class MyStyleRangeLabelProviderCol1 extends StyledCellLabelProvider >+ implements IColorProvider, IFontProvider { >+ >+ public MyStyleRangeLabelProviderCol1(ColumnViewer viewer, int style) { >+ super(viewer, style); >+ } >+ >+ public Color getBackground(Object element) { >+ return null; >+ } >+ >+ public Font getFont(Object element) { >+ if (element == TEXT[0]) { >+ return JFaceResources.getFont("BiggerDefault"); >+ } >+ return null; >+ } >+ >+ public Color getForeground(Object element) { >+ if (element == TEXT[1]) { >+ return DISPLAY.getSystemColor(SWT.COLOR_DARK_RED); >+ } >+ return null; >+ } >+ >+ public Image getImage(Object element) { >+ return IMAGE1; >+ } >+ >+ public String getText(Object element) { >+ return element.toString(); >+ } >+ >+ protected StyledViewerLabel getStyledViewerLabel(Object element) { >+ StyledViewerLabel viewerLabel = super.getStyledViewerLabel(element); >+ viewerLabel.setStyleRanges(getStyleRanges(element, viewerLabel >+ .getText())); >+ return viewerLabel; >+ } >+ } >+ >+ private class MyStyleRangeLabelProviderCol2 extends >+ MyStyleRangeLabelProviderCol1 { >+ >+ public MyStyleRangeLabelProviderCol2(ColumnViewer viewer, int style) { >+ super(viewer, style); >+ } >+ >+ public Font getFont(Object element) { >+ if (element == TEXT[1]) { >+ return JFaceResources.getFont("BiggerDefault"); >+ } >+ return null; >+ } >+ >+ public Color getForeground(Object element) { >+ if (element == TEXT[2]) { >+ return DISPLAY.getSystemColor(SWT.COLOR_DARK_RED); >+ } >+ return null; >+ } >+ >+ public Image getImage(Object element) { >+ return IMAGE2; >+ } >+ } >+ >+} >Index: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042WrappedStyledCellLabelProvider.java >=================================================================== >RCS file: Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042WrappedStyledCellLabelProvider.java >diff -N Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042WrappedStyledCellLabelProvider.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ Eclipse JFace Snippets/org/eclipse/jface/snippets/viewers/Snippet042WrappedStyledCellLabelProvider.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,167 @@ >+/******************************************************************************* >+ * Copyright (c) 2007 Michael Krkoska 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: >+ * Michael Krkoska - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jface.snippets.viewers; >+ >+import java.util.regex.Pattern; >+ >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.viewers.ArrayContentProvider; >+import org.eclipse.jface.viewers.ColumnPixelData; >+import org.eclipse.jface.viewers.ColumnViewer; >+import org.eclipse.jface.viewers.IBaseLabelProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.jface.viewers.OwnerDrawLabelProvider; >+import org.eclipse.jface.viewers.StyledCellLabelProvider; >+import org.eclipse.jface.viewers.StyledViewerLabel; >+import org.eclipse.jface.viewers.TableLayout; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.TableViewerColumn; >+import org.eclipse.jface.viewers.WrappedStyledCellLabelProvider; >+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.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Shell; >+ >+/** >+ * A simple TableViewer using a StyledCellLabelProvider to color a part of the >+ * label. To show how to re-use existing label providers, a >+ * WrappedStyledCellLabelProvider is used instead of the preferable >+ * StyledCellLabelProviders. >+ * >+ * @author Michael Krkoska <michael.krkoska@gmail.com> >+ */ >+public class Snippet042WrappedStyledCellLabelProvider { >+ >+ static final Display DISPLAY = Display.getDefault(); >+ static final Color GREEN = DISPLAY.getSystemColor(SWT.COLOR_DARK_GREEN); >+ static final Image IMAGE_BIG = DISPLAY.getSystemImage(SWT.ICON_WARNING); >+ static final Image IMAGE = new Image(DISPLAY, IMAGE_BIG.getImageData() >+ .scaledTo(16, 16)); >+ static final Pattern BRACES = Pattern.compile("\\(.*\\)"); >+ >+ public static void main(String[] args) { >+ >+ Shell shell = new Shell(DISPLAY, SWT.CLOSE); >+ shell.setSize(300, 300); >+ shell.setLayout(new GridLayout()); >+ >+ Snippet042WrappedStyledCellLabelProvider example = new Snippet042WrappedStyledCellLabelProvider(); >+ example.createPartControl(shell); >+ >+ shell.open(); >+ >+ while (!shell.isDisposed()) { >+ if (!DISPLAY.readAndDispatch()) { >+ DISPLAY.sleep(); >+ } >+ } >+ DISPLAY.dispose(); >+ } >+ >+ private TableViewer viewer; >+ private StyleRange[] styles; >+ >+ public void createPartControl(Composite parent) { >+ // SWT.FULL_SELECTION is needed on win32 as long as Bug 168807 exists >+ viewer = new TableViewer(parent, SWT.FULL_SELECTION); >+ >+ GridData data = new GridData(GridData.GRAB_HORIZONTAL >+ | GridData.GRAB_VERTICAL | GridData.FILL_BOTH); >+ viewer.getControl().setLayoutData(data); >+ >+ viewer.setContentProvider(new ArrayContentProvider()); >+ createColumns(); >+ >+ OwnerDrawLabelProvider.setUpOwnerDraw(viewer); >+ >+ String[] s = new String[10]; >+ String ip = " " + StyledCellLabelProvider.IMAGE_PLACEHOLDER; >+ for (int i = 0; i < s.length; i++) { >+ s[i] = "row " + i + (i % 3 == 1 ? ip : "") + " (green)" >+ + (i % 3 == 2 ? ip : ""); >+ } >+ viewer.setInput(s); >+ } >+ >+ private void createColumns() { >+ TableLayout layout = new TableLayout(); >+ viewer.getTable().setLayout(layout); >+ viewer.getTable().setHeaderVisible(true); >+ viewer.getTable().setLinesVisible(true); >+ >+ int width = 300 - 2 * 5 - viewer.getTable().getShell().computeTrim(0, >+ 0, 0, 0).width; >+ >+ IBaseLabelProvider labelProvider = new OldLabelProvider(); >+ >+ TableViewerColumn tc = new TableViewerColumn(viewer, SWT.NONE); >+ tc.getColumn().setText("col1"); >+ layout.addColumnData(new ColumnPixelData(width)); >+ tc.setLabelProvider(new MyWrappedStyledCellLabelProvider(viewer, >+ StyledCellLabelProvider.CENTER_ITEMS_VERTICALLY >+ | StyledCellLabelProvider.CENTER_TEXT_VERTICALLY, >+ labelProvider)); >+ } >+ >+ private final class OldLabelProvider extends LabelProvider { >+ >+ public Font getFont(Object element) { >+ return JFaceResources.getFont("Font"); >+ } >+ >+ public Image getImage(Object element) { >+ // if(element.toString().startsWith("row 1")) >+ // return IMAGE_BIG; >+ if (!element.toString().startsWith("row 0")) { >+ return IMAGE; >+ } >+ return null; >+ } >+ >+ public String getText(Object element) { >+ return element == null ? "" : element.toString(); //$NON-NLS-1$ >+ } >+ } >+ >+ private final class MyWrappedStyledCellLabelProvider extends >+ WrappedStyledCellLabelProvider { >+ >+ public MyWrappedStyledCellLabelProvider(ColumnViewer viewer, int style, >+ IBaseLabelProvider labelProvider) { >+ super(viewer, style, labelProvider); >+ } >+ >+ protected StyledViewerLabel getStyledViewerLabel(Object element) { >+ StyledViewerLabel viewerLabel = super.getStyledViewerLabel(element); >+ viewerLabel.setStyleRanges(getStyleRanges(element, viewerLabel >+ .getText())); >+ return viewerLabel; >+ } >+ >+ public StyleRange[] getStyleRanges(Object element, String label) { >+ if (styles == null) { >+ styles = new StyleRange[2]; >+ styles[0] = new StyleRange(6, 9, GREEN, null); >+ styles[1] = new StyleRange(0, 5, null, null); >+ styles[1].fontStyle = SWT.BOLD; >+ } >+ return styles; >+ } >+ >+ } >+ >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 188333
:
72297
|
72298
|
72299
|
72300
|
72421
|
72422
|
72423
|
72424
|
72495
|
72496
|
72539
|
72542
|
72592
|
73167
|
73272
|
73353
|
73614
|
73626
|
73633
|
73818
|
80884
|
80912
|
82965
|
83672