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