unification of bug fixes 1198893, 1404228
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / ui / text / AbstractTextTools.java
1 /*
2  * Copyright (c) 2002-2004 Widespace, OU and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://solareclipse.sourceforge.net/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     Igor Malinin - initial contribution
10  * 
11  * $Id: AbstractTextTools.java,v 1.2 2004-09-22 18:51:51 jsurfer Exp $
12  */
13
14 package net.sourceforge.phpeclipse.ui.text;
15
16 import java.util.HashMap;
17 import java.util.Map;
18
19 import net.sourceforge.phpeclipse.ui.ColorManager;
20 import net.sourceforge.phpeclipse.ui.preferences.ITextStylePreferences;
21
22 import org.eclipse.jface.preference.IPreferenceStore;
23 import org.eclipse.jface.resource.StringConverter;
24 import org.eclipse.jface.text.TextAttribute;
25 import org.eclipse.jface.text.rules.Token;
26 import org.eclipse.jface.util.IPropertyChangeListener;
27 import org.eclipse.jface.util.PropertyChangeEvent;
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.graphics.RGB;
30
31 /**
32  * @author Igor Malinin
33  */
34 public class AbstractTextTools {
35
36         /** The preference store */
37         protected IPreferenceStore store;
38
39         /** The color manager */
40         protected ColorManager colorManager;
41
42         private Map tokens;
43
44         private String[] properties;
45
46         private String[] foregroundPropertyNames;
47
48         private String[] backgroundPropertyNames;
49
50         private String[] stylePropertyNames;
51
52         private IPropertyChangeListener listener;
53
54         /**
55          * Creates a new text tools collection.
56          */
57         public AbstractTextTools(IPreferenceStore store, String[] properties) {
58           this(store, properties, new ColorManager());
59         }
60         /**
61          * Creates a new text tools collection.
62          */
63         public AbstractTextTools(IPreferenceStore store, String[] properties, ColorManager manager) {
64                 this.store = store;
65                 this.properties = properties;
66
67                 colorManager = manager;
68
69                 tokens = new HashMap();
70
71                 int length = properties.length;
72
73                 foregroundPropertyNames = new String[length];
74                 backgroundPropertyNames = new String[length];
75                 stylePropertyNames = new String[length];
76
77                 for (int i = 0; i < length; i++) {
78                         String property = properties[i];
79
80                         String foreground = property
81                                         + ITextStylePreferences.SUFFIX_FOREGROUND;
82                         String background = property
83                                         + ITextStylePreferences.SUFFIX_BACKGROUND;
84                         String style = property + ITextStylePreferences.SUFFIX_STYLE;
85
86                         foregroundPropertyNames[i] = foreground;
87                         backgroundPropertyNames[i] = background;
88                         stylePropertyNames[i] = style;
89
90                         RGB rgb;
91
92                         rgb = getColor(store, foreground);
93                         if (rgb != null) {
94                                 colorManager.bindColor(foreground, rgb);
95                         }
96
97                         rgb = getColor(store, background);
98                         if (rgb != null) {
99                                 colorManager.bindColor(background, rgb);
100                         }
101
102                         tokens.put(property, new Token(new TextAttribute(colorManager
103                                         .getColor(foreground), colorManager.getColor(background),
104                                         getStyle(store, style))));
105                 }
106
107                 listener = new IPropertyChangeListener() {
108
109                         public void propertyChange(PropertyChangeEvent event) {
110                                 adaptToPreferenceChange(event);
111                         }
112                 };
113
114                 store.addPropertyChangeListener(listener);
115         }
116
117         /**
118          * Disposes all the individual tools of this tools collection.
119          */
120         public void dispose() {
121                 if (store != null) {
122                         store.removePropertyChangeListener(listener);
123
124                         store = null;
125                         listener = null;
126                 }
127
128                 if (colorManager != null) {
129                         colorManager.dispose();
130
131                         colorManager = null;
132                 }
133
134                 tokens = null;
135
136                 properties = null;
137                 foregroundPropertyNames = null;
138                 backgroundPropertyNames = null;
139                 stylePropertyNames = null;
140         }
141
142         /**
143          * Returns the color manager which is used to manage any XML-specific
144          * colors needed for such things like syntax highlighting.
145          * 
146          * @return the color manager to be used for XML text viewers
147          */
148         public ColorManager getColorManager() {
149                 return colorManager;
150         }
151
152         public Map getTokens() {
153                 return tokens;
154         }
155
156         protected Token getToken(String key) {
157                 int index = indexOf(key);
158                 if (index < 0) {
159                         return null;
160                 }
161
162                 return (Token) tokens.get(properties[index]);
163         }
164
165         /**
166          * Determines whether the preference change encoded by the given event
167          * changes the behavior of one its contained components.
168          * 
169          * @param event
170          *            the event to be investigated
171          * @return <code>true</code> if event causes a behavioral change
172          */
173         public boolean affectsBehavior(PropertyChangeEvent event) {
174                 return (indexOf(event.getProperty()) >= 0);
175         }
176
177         /**
178          * Adapts the behavior of the contained components to the change encoded in
179          * the given event.
180          * 
181          * @param event
182          *            the event to whch to adapt
183          */
184         public void adaptToPreferenceChange(PropertyChangeEvent event) {
185                 String property = event.getProperty();
186
187                 Token token = getToken(property);
188                 if (token != null) {
189                         if (property.endsWith(ITextStylePreferences.SUFFIX_FOREGROUND)
190                                         || property
191                                                         .endsWith(ITextStylePreferences.SUFFIX_BACKGROUND)) {
192                                 adaptToColorChange(token, event);
193                         } else if (property.endsWith(ITextStylePreferences.SUFFIX_STYLE)) {
194                                 adaptToStyleChange(token, event);
195                         }
196                 }
197         }
198
199         private void adaptToColorChange(Token token, PropertyChangeEvent event) {
200                 RGB rgb = getColor(event.getNewValue());
201
202                 String property = event.getProperty();
203
204                 colorManager.unbindColor(property);
205                 if (rgb != null) {
206                         colorManager.bindColor(property, rgb);
207                 }
208
209                 Object data = token.getData();
210                 if (data instanceof TextAttribute) {
211                         TextAttribute old = (TextAttribute) data;
212
213                         int i = indexOf(property);
214
215                         token.setData(new TextAttribute(colorManager
216                                         .getColor(foregroundPropertyNames[i]), colorManager
217                                         .getColor(backgroundPropertyNames[i]), old.getStyle()));
218                 }
219         }
220
221         private void adaptToStyleChange(Token token, PropertyChangeEvent event) {
222                 int style = getStyle((String) event.getNewValue());
223
224                 Object data = token.getData();
225                 if (data instanceof TextAttribute) {
226                         TextAttribute old = (TextAttribute) data;
227                         if (old.getStyle() != style) {
228                                 token.setData(new TextAttribute(old.getForeground(), old
229                                                 .getBackground(), style));
230                         }
231                 }
232         }
233
234         private int indexOf(String property) {
235                 if (property != null) {
236                         int length = properties.length;
237
238                         for (int i = 0; i < length; i++) {
239                                 if (property.equals(properties[i])
240                                                 || property.equals(foregroundPropertyNames[i])
241                                                 || property.equals(backgroundPropertyNames[i])
242                                                 || property.equals(stylePropertyNames[i])) {
243                                         return i;
244                                 }
245                         }
246                 }
247
248                 return -1;
249         }
250
251         private RGB getColor(IPreferenceStore store, String key) {
252                 return getColor(store.getString(key));
253         }
254
255         private RGB getColor(Object value) {
256                 if (value instanceof RGB) {
257                         return (RGB) value;
258                 }
259
260                 String str = (String) value;
261                 if (str.length() > 0) {
262                         return StringConverter.asRGB(str);
263                 }
264
265                 return null;
266         }
267
268         private int getStyle(IPreferenceStore store, String key) {
269                 return getStyle(store.getString(key));
270         }
271
272         private int getStyle(String value) {
273                 if (value.indexOf(ITextStylePreferences.STYLE_BOLD) >= 0) {
274                         return SWT.BOLD;
275                 }
276
277                 return SWT.NORMAL;
278         }
279 }