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