/* * Copyright (c) 2003-2004 Christopher Lenz and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * Christopher Lenz - initial API and implementation * * $Id: AbstractCssScanner.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $ */ package net.sourceforge.phpeclipse.css.ui.internal.text; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sourceforge.phpeclipse.css.ui.text.IColorManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.resource.StringConverter; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.RGB; /** * */ public abstract class AbstractCssScanner extends BufferedRuleBasedScanner { // Inner Classes ----------------------------------------------------------- /** * Internal data structure for associating the various style preferences * of tokens with each other. */ private static final class StyleKeys { /** * The preference key that determines the foreground color of the token. */ private String colorKey; /** * The preference key that indicates whether the token is to be * displayed in bold face. */ private String boldKey; /** * Constructor. * * @param colorKey The color preference key * @param boldKey The preference key determining whether the * corresponding tokens should be rendered bold */ private StyleKeys(String colorKey, String boldKey) { this.colorKey = colorKey; this.boldKey = boldKey; } /** * @see Object#equals(Object) */ public boolean equals(Object o) { if (!(o instanceof StyleKeys)) { return false; } StyleKeys styleKeys = (StyleKeys) o; if (((colorKey != null) && !colorKey.equals(styleKeys.colorKey)) || (colorKey != styleKeys.colorKey)) { return false; } if (((boldKey != null) && !boldKey.equals(styleKeys.boldKey)) || (boldKey != styleKeys.boldKey)) { return false; } return true; } /** * @see Object#hashCode() */ public int hashCode() { int retVal = 17; retVal = (retVal * 37) + (colorKey != null ? colorKey.hashCode() : 0); retVal = (retVal * 37) + (boldKey != null ? boldKey.hashCode() : 0); return retVal; } } // Instance Variables ------------------------------------------------------ /** * The preference store associated with the scanner. */ private IPreferenceStore store; /** * Listener for preference store changes related to tokens. */ private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { String property = event.getProperty(); StyleKeys styleKeys = getStyleKeysContaining(property); if (styleKeys != null) { if (styleKeys.colorKey.equals(property)) { Token token = (Token) tokens.get(styleKeys); handleColorChange(token, event); } else if (styleKeys.boldKey.equals(property)) { Token token = (Token) tokens.get(styleKeys); handleBoldChange(token, event); } } } }; /** * The shared text colors. */ private IColorManager colorManager; /** * A map containing the defined tokens keyed by the color preference key. */ private Map tokens = new HashMap(4); // Constructors ------------------------------------------------------------ /** * Constructor. * * @param store the preference store * @param manager the color manager */ public AbstractCssScanner(IPreferenceStore store, IColorManager manager) { store.addPropertyChangeListener(propertyChangeListener); this.store = store; this.colorManager = manager; } // Public Methods ---------------------------------------------------------- /** * Adapts the tokens managed by this scanner to changes made to the * corresponding preferences. * * @param event the change event fired by the preference store */ public void adaptToPreferenceChange(PropertyChangeEvent event) { String property = event.getProperty(); StyleKeys styleKeys = getStyleKeysContaining(property); if (styleKeys != null) { if (styleKeys.colorKey.equals(property)) { Token token = (Token) tokens.get(styleKeys); handleColorChange(token, event); } else if (styleKeys.boldKey.equals(property)) { Token token = (Token) tokens.get(styleKeys); handleBoldChange(token, event); } } } /** * Called to determine whether the change of a specific preference affects * the presentation of the tokens managed by the scanner. * * @param event the preference change event * @return true if the change affects the presentation of one * of the tokens managed by the scanner, false * otherwise */ public boolean affectsPresentation(PropertyChangeEvent event) { String property = event.getProperty(); return (getStyleKeysContaining(property) != null); } // Protected Methods ------------------------------------------------------- /** * Creates a token with the specified color and style as associated text * attribute. The color and style are specified as preference keys. * * @param colorKey The preference key of the color * @param boldKey The preference key of the boolean value that determines * whether the text should be rendered bold, or null * @return the created token */ protected final IToken createToken(String colorKey, String boldKey) { RGB rgb = PreferenceConverter.getColor(store, colorKey); colorManager.unbindColor(colorKey); colorManager.bindColor(colorKey, rgb); int style = SWT.NORMAL; if ((boldKey != null) && store.getBoolean(boldKey)) { style |= SWT.BOLD; } IToken token = new Token(new TextAttribute( colorManager.getColor(colorKey), null, style)); StyleKeys styleKeys = new StyleKeys(colorKey, boldKey); tokens.put(styleKeys, token); return token; } // Private Methods --------------------------------------------------------- private StyleKeys getStyleKeysContaining(String key) { for (Iterator i = tokens.keySet().iterator(); i.hasNext(); ) { StyleKeys styleKeys = (StyleKeys) i.next(); if (styleKeys.colorKey.equals(key) || styleKeys.boldKey.equals(key)) { return styleKeys; } } return null; } private void handleColorChange(Token token, PropertyChangeEvent event) { RGB rgb = null; Object value = event.getNewValue(); if (value instanceof RGB) { rgb = (RGB) value; } else if (value instanceof String) { rgb = StringConverter.asRGB((String) value); } if (rgb != null) { String key = event.getProperty(); colorManager.unbindColor(key); colorManager.bindColor(key, rgb); Object data = token.getData(); if (data instanceof TextAttribute) { TextAttribute oldAttr = (TextAttribute) data; token.setData(new TextAttribute(colorManager.getColor(key), oldAttr.getBackground(), oldAttr.getStyle())); } } } private void handleBoldChange(Token token, PropertyChangeEvent event) { boolean bold = false; Object value = event.getNewValue(); if (value instanceof Boolean) { bold = ((Boolean) value).booleanValue(); } else if (value instanceof String) { StringConverter.asBoolean((String) value); } Object data = token.getData(); if (data instanceof TextAttribute) { TextAttribute oldAttr = (TextAttribute) data; boolean wasBold = ((oldAttr.getStyle() & SWT.BOLD) != 0); if (wasBold != bold) { int newStyle = bold ? oldAttr.getStyle() | SWT.BOLD : oldAttr.getStyle() ^ SWT.BOLD; token.setData(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), newStyle)); } } } }