--- /dev/null
+/*
+ * 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 <code>true</code> if the change affects the presentation of one
+ * of the tokens managed by the scanner, <code>false</code>
+ * 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 <code>null</code>
+ * @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));
+ }
+ }
+ }
+
+}