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