Templates were updated by pteague. Also a little change by ed_mann.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / JavaSourceViewer.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation 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  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpeclipse.phpeditor;
13
14 import java.util.ArrayList;
15
16 import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager;
17 import net.sourceforge.phpdt.ui.PreferenceConstants;
18 import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
19
20 import org.eclipse.jface.preference.IPreferenceStore;
21 import org.eclipse.jface.preference.PreferenceConverter;
22 import org.eclipse.jface.text.Assert;
23 import org.eclipse.jface.text.ITextPresentationListener;
24 import org.eclipse.jface.text.information.IInformationPresenter;
25 import org.eclipse.jface.text.reconciler.IReconciler;
26 import org.eclipse.jface.text.source.IOverviewRuler;
27 import org.eclipse.jface.text.source.IVerticalRuler;
28 import org.eclipse.jface.text.source.SourceViewerConfiguration;
29 import org.eclipse.jface.text.source.projection.ProjectionViewer;
30 import org.eclipse.jface.util.IPropertyChangeListener;
31 import org.eclipse.jface.util.PropertyChangeEvent;
32 import org.eclipse.swt.custom.StyledText;
33 import org.eclipse.swt.graphics.Color;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.swt.graphics.RGB;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Display;
38 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
39
40 public class JavaSourceViewer extends ProjectionViewer implements
41                 IPropertyChangeListener {
42
43         /**
44          * Text operation code for requesting the outline for the current input.
45          */
46         public static final int SHOW_OUTLINE = 51;
47
48         /**
49          * Text operation code for requesting the outline for the element at the
50          * current position.
51          */
52         public static final int OPEN_STRUCTURE = 52;
53
54         /**
55          * Text operation code for requesting the hierarchy for the current input.
56          */
57         public static final int SHOW_HIERARCHY = 53;
58
59         private IInformationPresenter fOutlinePresenter;
60
61         private IInformationPresenter fStructurePresenter;
62
63         // private IInformationPresenter fHierarchyPresenter;
64
65         /**
66          * This viewer's foreground color.
67          * 
68          * @since 3.0
69          */
70         private Color fForegroundColor;
71
72         /**
73          * The viewer's background color.
74          * 
75          * @since 3.0
76          */
77         private Color fBackgroundColor;
78
79         /**
80          * This viewer's selection foreground color.
81          * 
82          * @since 3.0
83          */
84         private Color fSelectionForegroundColor;
85
86         /**
87          * The viewer's selection background color.
88          * 
89          * @since 3.0
90          */
91         private Color fSelectionBackgroundColor;
92
93         /**
94          * The preference store.
95          * 
96          * @since 3.0
97          */
98         private IPreferenceStore fPreferenceStore;
99
100         /**
101          * Is this source viewer configured?
102          * 
103          * @since 3.0
104          */
105         private boolean fIsConfigured;
106
107         /**
108          * The backspace manager of this viewer.
109          * 
110          * @since 3.0
111          */
112         private SmartBackspaceManager fBackspaceManager;
113
114         public JavaSourceViewer(Composite parent, IVerticalRuler verticalRuler,
115                         IOverviewRuler overviewRuler, boolean showAnnotationsOverview,
116                         int styles, IPreferenceStore store) {
117                 super(parent, verticalRuler, overviewRuler, showAnnotationsOverview,
118                                 styles);
119                 setPreferenceStore(store);
120         }
121
122         /*
123          * @see org.eclipse.jface.text.source.SourceViewer#createFormattingContext()
124          * @since 3.0
125          */
126         // public IFormattingContext createFormattingContext() {
127         //
128         // IFormattingContext context= new CommentFormattingContext();
129         // Map map= new Hashtable(JavaCore.getOptions());
130         //              
131         // context.storeToMap(PreferenceConstants.getPreferenceStore(), map, false);
132         // context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES,
133         // map);
134         //              
135         // return context;
136         // }
137         /*
138          * @see ITextOperationTarget#doOperation(int)
139          */
140         public void doOperation(int operation) {
141                 if (getTextWidget() == null)
142                         return;
143
144                 switch (operation) {
145                 case SHOW_OUTLINE:
146                         fOutlinePresenter.showInformation();
147                         return;
148                 case OPEN_STRUCTURE:
149                         fStructurePresenter.showInformation();
150                         return;
151                 case SHOW_HIERARCHY:
152                         // fHierarchyPresenter.showInformation();
153                         return;
154                 case FORMAT:
155                         Point point = getSelectedRange();
156                         if (point.y == 0) {
157                                 // setSelectedRange(0, getDocument().getLength());
158                                 revealRange(0, getDocument().getLength());
159                         }
160                         break;
161                 }
162
163                 super.doOperation(operation);
164         }
165
166         /*
167          * @see ITextOperationTarget#canDoOperation(int)
168          */
169         public boolean canDoOperation(int operation) {
170                 if (operation == SHOW_OUTLINE)
171                         return fOutlinePresenter != null;
172                 if (operation == OPEN_STRUCTURE)
173                         return fStructurePresenter != null;
174                 if (operation == SHOW_HIERARCHY)
175                         // return fHierarchyPresenter != null;
176                         return false;
177
178                 return super.canDoOperation(operation);
179         }
180
181         /*
182          * @see ISourceViewer#configure(SourceViewerConfiguration)
183          */
184         public void configure(SourceViewerConfiguration configuration) {
185                 super.configure(configuration);
186                 if (configuration instanceof PHPSourceViewerConfiguration) {
187                         fOutlinePresenter = ((PHPSourceViewerConfiguration) configuration)
188                                         .getOutlinePresenter(this, false);
189                         fOutlinePresenter.install(this);
190                 }
191                 if (configuration instanceof PHPSourceViewerConfiguration) {
192                         fStructurePresenter = ((PHPSourceViewerConfiguration) configuration)
193                                         .getOutlinePresenter(this, true);
194                         fStructurePresenter.install(this);
195                 }
196                 if (configuration instanceof PHPSourceViewerConfiguration) {
197                         // fHierarchyPresenter=
198                         // ((PHPSourceViewerConfiguration)configuration).getHierarchyPresenter(this,
199                         // true);
200                         // fHierarchyPresenter.install(this);
201
202                         if (fPreferenceStore != null) {
203                                 fPreferenceStore.addPropertyChangeListener(this);
204                                 initializeViewerColors();
205                         }
206                 }
207                 fIsConfigured = true;
208         }
209
210         protected void initializeViewerColors() {
211                 if (fPreferenceStore != null) {
212
213                         StyledText styledText = getTextWidget();
214
215                         // ----------- foreground color --------------------
216                         Color color = fPreferenceStore
217                                         .getBoolean(PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR) ? null
218                                         : createColor(fPreferenceStore,
219                                                         PreferenceConstants.EDITOR_FOREGROUND_COLOR,
220                                                         styledText.getDisplay());
221                         styledText.setForeground(color);
222
223                         if (fForegroundColor != null)
224                                 fForegroundColor.dispose();
225
226                         fForegroundColor = color;
227
228                         // ---------- background color ----------------------
229                         color = fPreferenceStore
230                                         .getBoolean(PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR) ? null
231                                         : createColor(fPreferenceStore,
232                                                         PreferenceConstants.EDITOR_BACKGROUND_COLOR,
233                                                         styledText.getDisplay());
234                         styledText.setBackground(color);
235
236                         if (fBackgroundColor != null)
237                                 fBackgroundColor.dispose();
238
239                         fBackgroundColor = color;
240
241                         // ----------- selection foreground color --------------------
242                         color = fPreferenceStore
243                                         .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR) ? null
244                                         : createColor(
245                                                         fPreferenceStore,
246                                                         AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR,
247                                                         styledText.getDisplay());
248                         styledText.setSelectionForeground(color);
249
250                         if (fSelectionForegroundColor != null)
251                                 fSelectionForegroundColor.dispose();
252
253                         fSelectionForegroundColor = color;
254
255                         // ---------- selection background color ----------------------
256                         color = fPreferenceStore
257                                         .getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR) ? null
258                                         : createColor(
259                                                         fPreferenceStore,
260                                                         AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR,
261                                                         styledText.getDisplay());
262                         styledText.setSelectionBackground(color);
263
264                         if (fSelectionBackgroundColor != null)
265                                 fSelectionBackgroundColor.dispose();
266
267                         fSelectionBackgroundColor = color;
268                 }
269         }
270
271         /**
272          * Creates a color from the information stored in the given preference
273          * store. Returns <code>null</code> if there is no such information
274          * available.
275          * 
276          * @param store
277          *            the store to read from
278          * @param key
279          *            the key used for the lookup in the preference store
280          * @param display
281          *            the display used create the color
282          * @return the created color according to the specification in the
283          *         preference store
284          * @since 3.0
285          */
286         private Color createColor(IPreferenceStore store, String key,
287                         Display display) {
288
289                 RGB rgb = null;
290
291                 if (store.contains(key)) {
292
293                         if (store.isDefault(key))
294                                 rgb = PreferenceConverter.getDefaultColor(store, key);
295                         else
296                                 rgb = PreferenceConverter.getColor(store, key);
297
298                         if (rgb != null)
299                                 return new Color(display, rgb);
300                 }
301
302                 return null;
303         }
304
305         /*
306          * @see org.eclipse.jface.text.source.ISourceViewerExtension2#unconfigure()
307          * @since 3.0
308          */
309         public void unconfigure() {
310                 if (fOutlinePresenter != null) {
311                         fOutlinePresenter.uninstall();
312                         fOutlinePresenter = null;
313                 }
314                 if (fStructurePresenter != null) {
315                         fStructurePresenter.uninstall();
316                         fStructurePresenter = null;
317                 }
318                 // if (fHierarchyPresenter != null) {
319                 // fHierarchyPresenter.uninstall();
320                 // fHierarchyPresenter= null;
321                 // }
322                 if (fForegroundColor != null) {
323                         fForegroundColor.dispose();
324                         fForegroundColor = null;
325                 }
326                 if (fBackgroundColor != null) {
327                         fBackgroundColor.dispose();
328                         fBackgroundColor = null;
329                 }
330                 if (fPreferenceStore != null)
331                         fPreferenceStore.removePropertyChangeListener(this);
332
333                 super.unconfigure();
334
335                 fIsConfigured = false;
336         }
337
338         /*
339          * @see org.eclipse.jface.text.source.SourceViewer#rememberSelection()
340          */
341         public Point rememberSelection() {
342                 return super.rememberSelection();
343         }
344
345         /*
346          * @see org.eclipse.jface.text.source.SourceViewer#restoreSelection()
347          */
348         public void restoreSelection() {
349                 super.restoreSelection();
350         }
351
352         /*
353          * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
354          */
355         public void propertyChange(PropertyChangeEvent event) {
356                 String property = event.getProperty();
357                 if (PreferenceConstants.EDITOR_FOREGROUND_COLOR.equals(property)
358                                 || PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR
359                                                 .equals(property)
360                                 || PreferenceConstants.EDITOR_BACKGROUND_COLOR.equals(property)
361                                 || PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR
362                                                 .equals(property)
363                                 || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR
364                                                 .equals(property)
365                                 || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR
366                                                 .equals(property)
367                                 || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR
368                                                 .equals(property)
369                                 || AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR
370                                                 .equals(property)) {
371                         initializeViewerColors();
372                 }
373         }
374
375         /**
376          * Sets the preference store on this viewer.
377          * 
378          * @param store
379          *            the preference store
380          * 
381          * @since 3.0
382          */
383         public void setPreferenceStore(IPreferenceStore store) {
384                 if (fIsConfigured && fPreferenceStore != null)
385                         fPreferenceStore.removePropertyChangeListener(this);
386
387                 fPreferenceStore = store;
388
389                 if (fIsConfigured && fPreferenceStore != null) {
390                         fPreferenceStore.addPropertyChangeListener(this);
391                         initializeViewerColors();
392                 }
393         }
394
395         /*
396          * @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite,
397          *      int)
398          */
399         protected void createControl(Composite parent, int styles) {
400                 super.createControl(parent, styles);
401
402                 fBackspaceManager = new SmartBackspaceManager();
403                 fBackspaceManager.install(this);
404         }
405
406         /**
407          * Returns the backspace manager for this viewer.
408          * 
409          * @return the backspace manager for this viewer, or <code>null</code> if
410          *         there is none
411          * @since 3.0
412          */
413         public SmartBackspaceManager getBackspaceManager() {
414                 return fBackspaceManager;
415         }
416
417         /*
418          * @see org.eclipse.jface.text.source.SourceViewer#handleDispose()
419          */
420         protected void handleDispose() {
421                 if (fBackspaceManager != null) {
422                         fBackspaceManager.uninstall();
423                         fBackspaceManager = null;
424                 }
425
426                 super.handleDispose();
427         }
428
429         /**
430          * Prepends the text presentation listener at the beginning of the viewer's
431          * list of text presentation listeners. If the listener is already
432          * registered with the viewer this call moves the listener to the beginning
433          * of the list.
434          * 
435          * @param listener
436          *            the text presentation listener
437          * @since 3.0
438          */
439         public void prependTextPresentationListener(
440                         ITextPresentationListener listener) {
441
442                 Assert.isNotNull(listener);
443
444                 if (fTextPresentationListeners == null)
445                         fTextPresentationListeners = new ArrayList();
446
447                 fTextPresentationListeners.remove(listener);
448                 fTextPresentationListeners.add(0, listener);
449         }
450
451         /**
452          * Sets the given reconciler.
453          * 
454          * @param reconciler
455          *            the reconciler
456          * @since 3.0
457          */
458         void setReconciler(IReconciler reconciler) {
459                 fReconciler = reconciler;
460         }
461
462         /**
463          * Returns the reconciler.
464          * 
465          * @return the reconciler or <code>null</code> if not set
466          * @since 3.0
467          */
468         Object getReconciler() {
469                 return fReconciler;
470         }
471 }