intial source from ttp://www.sf.net/projects/wdte
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.css.ui / src / net / sourceforge / phpeclipse / css / ui / text / CssTextTools.java
1 /*
2  * Copyright (c) 2003-2004 Christopher Lenz 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://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *   Christopher Lenz - initial API and implementation
10  * 
11  * $Id: CssTextTools.java,v 1.1 2004-09-02 18:11:51 jsurfer Exp $
12  */
13
14 package net.sourceforge.phpeclipse.css.ui.text;
15
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.Map;
19
20 import net.sourceforge.phpeclipse.css.core.CssCore;
21 import net.sourceforge.phpeclipse.css.core.profiles.IProfile;
22 import net.sourceforge.phpeclipse.css.ui.internal.text.CssCodeScanner;
23 import net.sourceforge.phpeclipse.css.ui.internal.text.CssColorManager;
24 import net.sourceforge.phpeclipse.css.ui.internal.text.CssCommentScanner;
25 import net.sourceforge.phpeclipse.css.ui.internal.text.CssPartitionScanner;
26 import net.sourceforge.phpeclipse.css.ui.internal.text.CssStringScanner;
27
28 import org.eclipse.jface.preference.IPreferenceStore;
29 import org.eclipse.jface.text.IDocument;
30 import org.eclipse.jface.text.IDocumentExtension3;
31 import org.eclipse.jface.text.IDocumentPartitioner;
32 import org.eclipse.jface.text.rules.DefaultPartitioner;
33 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
34 import org.eclipse.jface.text.rules.RuleBasedScanner;
35 import org.eclipse.jface.util.IPropertyChangeListener;
36 import org.eclipse.jface.util.PropertyChangeEvent;
37
38 /**
39  * Tools required to configure a CSS text viewer.
40  * 
41  * <p> 
42  *  The color manager and all scanners exist only one time, i.e. the same 
43  *  instances are returned to all clients. Thus, clients share those tools.
44  * </p>
45  */
46 public class CssTextTools {
47
48         // Instance Variables ------------------------------------------------------
49
50         /**
51          * The preference store to use.
52          */
53         private IPreferenceStore store;
54
55         /**
56          * Listener for changes to the preference store.
57          */
58         private IPropertyChangeListener propertyChangeListener =
59                 new IPropertyChangeListener() {
60                         public void propertyChange(PropertyChangeEvent event) {
61                                 adaptToPreferenceChange(event);
62                         }
63                 };
64
65         /**
66          * The color manager.
67          */
68         private IColorManager colorManager;
69
70         /**
71          * The partition scanner.
72          */
73         private CssPartitionScanner partitionScanner;
74
75         /**
76          * Map of the code scanners, keyed by profile ID.
77          */
78         private Map codeScanners = new HashMap();
79
80         /**
81          * The token scanner for syntax highlighting comments in CSS source.
82          */
83         private CssCommentScanner commentScanner;
84
85         /**
86          * The token scanner for syntax highlighting string literals in CSS source.
87          */
88         private CssStringScanner stringScanner;
89
90         // Constructors ------------------------------------------------------------
91
92         /**
93          * Creates a new CSS text tools collection.
94          * 
95          * @param store the preference store to initialize the text tools. The text
96          *        tools instance installs a listener on the passed preference store
97          *        to adapt itself to changes in the preference store.
98          */
99         public CssTextTools(IPreferenceStore store) {
100                 this(store, true);
101         }
102
103         /**
104          * Creates a new CSS text tools collection.
105          * 
106          * @param store the preference store to initialize the text tools. The text
107          *        tool instance installs a listener on the passed preference store
108          *        to adapt itself to changes in the preference store.
109          * @param autoDisposeOnDisplayDispose if <code>true</code>      the color
110          *        manager automatically disposes all managed colors when the current
111          *        display gets disposed and all calls to
112          *        {@link org.eclipse.jface.text.source.ISharedTextColors#dispose()}
113          *        are ignored.
114          */
115         public CssTextTools(IPreferenceStore store,
116                         boolean autoDisposeOnDisplayDispose) {
117                 store.addPropertyChangeListener(propertyChangeListener);
118                 this.store = store;
119
120                 colorManager = new CssColorManager(autoDisposeOnDisplayDispose);
121                 partitionScanner = new CssPartitionScanner();
122                 commentScanner = new CssCommentScanner(store, colorManager);
123                 stringScanner = new CssStringScanner(store, colorManager);
124         }
125
126         // Public Methods ----------------------------------------------------------
127
128         /**
129          * Returns whether the specified change to the preference store would effect
130          * the presentation of CSS text.
131          * 
132          * @param event the preference store change event
133          * @return <code>true</code> if the specified event affects the presentation
134          *        of CSS text, <code>false</code> otherwise
135          */
136         public boolean affectsPresentation(PropertyChangeEvent event) {
137                 for (Iterator i = codeScanners.keySet().iterator(); i.hasNext();) {
138                         CssCodeScanner scanner = (CssCodeScanner)
139                                         codeScanners.get(i.next());
140                         if (scanner.affectsPresentation(event)) {
141                                 return true;
142                         }
143                 }
144                 if (commentScanner.affectsPresentation(event)
145                  || stringScanner.affectsPresentation(event)) {
146                         return true;
147                 }
148                 return false;
149         }
150
151         /**
152          * Factory method for creating a Java-specific document partitioner
153          * using this object's partitions scanner. This method is a 
154          * convenience method.
155          *
156          * @return a newly created Java document partitioner
157          */
158         public IDocumentPartitioner createDocumentPartitioner() {
159                 String[] types = new String[] {
160                         CssPartitionScanner.CSS_COMMENT,
161                         CssPartitionScanner.CSS_STRING
162                 };
163                 return new DefaultPartitioner(getPartitionScanner(), types);
164         }
165
166         /**
167          * Disposes all the individual tools of this tools collection.
168          */
169         public void dispose() {
170
171                 // dispose the scanners
172                 codeScanners.clear();
173                 commentScanner = null;
174                 stringScanner = null;
175                 partitionScanner = null;
176
177                 // dispose the color manager
178                 if (colorManager != null) {
179                         colorManager.dispose();
180                         colorManager = null;
181                 }
182                 
183                 // detach from the preference store
184                 if (store != null) {
185                         store.removePropertyChangeListener(propertyChangeListener);
186                         propertyChangeListener = null;
187                         store = null;
188                 }
189         }
190
191         /**
192          * Returns the color manager which is used to manage
193          * any Java-specific colors needed for such things like syntax highlighting.
194          *
195          * @return the color manager to be used for Java text viewers
196          */
197         public IColorManager getColorManager() {
198                 return colorManager;
199         }
200
201         /**
202          * Returns a scanner which is configured to scan CSS source code.
203          *
204          * @param profile the profile for which to retrieve the code scanner
205          * @return a CSS source code scanner
206          */
207         public RuleBasedScanner getCodeScanner(IProfile profile) {
208                 if (profile == null) {
209                         // use the default profile
210                         profile = CssCore.getDefault().getProfileManager().getProfile(null);
211                 }
212                 String profileId = profile.getDescriptor().getId();
213                 RuleBasedScanner codeScanner = (RuleBasedScanner)
214                         codeScanners.get(profileId);
215                 if (codeScanner == null) {
216                         codeScanner = new CssCodeScanner(store, this.colorManager, profile);
217                         codeScanners.put(profileId, codeScanner);
218                 }
219                 return codeScanner;
220         }
221
222         /**
223          * Returns a scanner which is configured to scan CSS comments.
224          *
225          * @return a CSS comment scanner
226          */
227         public RuleBasedScanner getCommentScanner() {
228                 return commentScanner;
229         }
230
231         /**
232          * Returns a scanner which is configured to scan CSS strings.
233          *
234          * @return a CSS string scanner
235          */
236         public RuleBasedScanner getStringScanner() {
237                 return stringScanner;
238         }
239
240         /**
241          * Returns a scanner which is configured to scan CSS-specific partitions,
242          * which are comments, strings and regular code.
243          *
244          * @return a CSS partition scanner
245          */
246         public IPartitionTokenScanner getPartitionScanner() {
247                 return partitionScanner;
248         }
249
250         /**
251          * Sets up the given document for the default partitioning.
252          * 
253          * @param document the document to be set up
254          */
255         public void setupDocument(IDocument document) {
256                 setupDocument(document, IDocumentExtension3.DEFAULT_PARTITIONING);
257         }
258
259         /**
260          * Sets up the given document for the given partitioning.
261          * 
262          * @param document the document to be set up
263          * @param partitioning the document partitioning
264          */
265         public void setupDocument(IDocument document, String partitioning) {
266                 IDocumentPartitioner partitioner = createDocumentPartitioner();
267                 if (document instanceof IDocumentExtension3) {
268                         IDocumentExtension3 extension = (IDocumentExtension3) document;
269                         extension.setDocumentPartitioner(partitioning, partitioner);
270                 } else {
271                         document.setDocumentPartitioner(partitioner);
272                 }
273                 partitioner.connect(document);
274         }
275
276         // Protected Methods -------------------------------------------------------
277
278         /**
279          * Adapts the behavior of the contained components to the change according
280          * to the given event.
281          * 
282          * @param event the event to which to adapt
283          */
284         protected void adaptToPreferenceChange(PropertyChangeEvent event) {
285                 for (Iterator i = codeScanners.keySet().iterator(); i.hasNext();) {
286                         CssCodeScanner scanner = (CssCodeScanner)
287                                         codeScanners.get(i.next());
288                         if (scanner.affectsPresentation(event)) {
289                                 scanner.adaptToPreferenceChange(event);
290                         }
291                 }
292                 if (commentScanner.affectsPresentation(event)) {
293                         commentScanner.adaptToPreferenceChange(event);
294                 }
295                 if (stringScanner.affectsPresentation(event)) {
296                         stringScanner.adaptToPreferenceChange(event);
297                 }
298         }
299
300 }