intial source from ttp://www.sf.net/projects/wdte
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.css.ui / src / net / sourceforge / phpeclipse / css / ui / internal / text / AbstractCssScanner.java
diff --git a/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AbstractCssScanner.java b/archive/net.sourceforge.phpeclipse.css.ui/src/net/sourceforge/phpeclipse/css/ui/internal/text/AbstractCssScanner.java
new file mode 100644 (file)
index 0000000..b5149db
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * 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));
+                       }
+               }
+       }
+
+}