1.0.4 release
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPEditor.java
1 package net.sourceforge.phpeclipse.phpeditor;
2
3 /**********************************************************************
4 Copyright (c) 2000, 2002 IBM Corp. and others.
5 All rights reserved. This program and the accompanying materials
6 are made available under the terms of the Common Public License v1.0
7 which accompanies this distribution, and is available at
8 http://www.eclipse.org/legal/cpl-v10.html
9
10 Contributors:
11     IBM Corporation - Initial implementation
12     Klaus Hartlage - www.eclipseproject.de
13 **********************************************************************/
14 import net.sourceforge.phpeclipse.IPreferenceConstants;
15 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
16 import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
17 import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor;
18 import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.jface.action.Action;
22 import org.eclipse.jface.action.IAction;
23 import org.eclipse.jface.action.MenuManager;
24 import org.eclipse.jface.preference.IPreferenceStore;
25 import org.eclipse.jface.preference.PreferenceConverter;
26 import org.eclipse.jface.text.BadLocationException;
27 import org.eclipse.jface.text.IDocument;
28 import org.eclipse.jface.text.ITextOperationTarget;
29 import org.eclipse.jface.text.source.AnnotationRulerColumn;
30 import org.eclipse.jface.text.source.CompositeRuler;
31 import org.eclipse.jface.text.source.ISourceViewer;
32 import org.eclipse.jface.text.source.IVerticalRuler;
33 import org.eclipse.jface.text.source.IVerticalRulerColumn;
34 import org.eclipse.jface.text.source.LineNumberRulerColumn;
35 import org.eclipse.jface.util.IPropertyChangeListener;
36 import org.eclipse.jface.util.PropertyChangeEvent;
37 import org.eclipse.swt.graphics.Point;
38 import org.eclipse.swt.graphics.RGB;
39 import org.eclipse.ui.IEditorInput;
40 import org.eclipse.ui.editors.text.TextEditor;
41 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
42 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
43 import org.eclipse.ui.texteditor.TextOperationAction;
44 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
45 /**
46  * PHP specific text editor.
47  */
48 public class PHPEditor extends TextEditor  {
49
50   protected PHPActionGroup actionGroup;
51   /** The outline page */
52   private PHPContentOutlinePage fOutlinePage;
53   private IPreferenceStore phpPrefStore;
54
55   /** The line number ruler column */
56   private LineNumberRulerColumn fLineNumberRulerColumn;
57
58   /**
59    * Default constructor.
60    */
61   public PHPEditor() {
62     super();
63   }
64
65   public PHPContentOutlinePage getfOutlinePage() {
66     return fOutlinePage;
67   }
68
69   /** The <code>PHPEditor</code> implementation of this 
70    * <code>AbstractTextEditor</code> method extend the 
71    * actions to add those specific to the receiver
72    */
73   protected void createActions() {
74     super.createActions();
75     setAction(
76       "ContentAssistProposal",
77       new TextOperationAction(
78         PHPEditorMessages.getResourceBundle(),
79         "ContentAssistProposal.",
80         this,
81         ISourceViewer.CONTENTASSIST_PROPOSALS));
82     setAction(
83       "ContentAssistTip",
84       new TextOperationAction(
85         PHPEditorMessages.getResourceBundle(),
86         "ContentAssistTip.",
87         this,
88         ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION));
89
90     Action action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Comment.", this, ITextOperationTarget.PREFIX);
91     action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
92     setAction("Comment", action);
93
94     action = new TextOperationAction(PHPEditorMessages.getResourceBundle(), "Uncomment.", this, ITextOperationTarget.STRIP_PREFIX);
95     action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT);
96     setAction("Uncomment", action);
97
98     actionGroup = new PHPActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
99
100     markAsStateDependentAction("Comment", true); //$NON-NLS-1$
101     markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$
102     
103   }
104
105   /** The <code>PHPEditor</code> implementation of this 
106    * <code>AbstractTextEditor</code> method performs any extra 
107    * disposal actions required by the php editor.
108    */
109   public void dispose() {
110     PHPEditorEnvironment.disconnect(this);
111     if (fOutlinePage != null)
112       fOutlinePage.setInput(null);
113     super.dispose();
114   }
115
116   /** The <code>PHPEditor</code> implementation of this 
117    * <code>AbstractTextEditor</code> method performs any extra 
118    * revert behavior required by the php editor.
119    */
120   public void doRevertToSaved() {
121     super.doRevertToSaved();
122     if (fOutlinePage != null)
123       fOutlinePage.update();
124   }
125
126   /** The <code>PHPEditor</code> implementation of this 
127    * <code>AbstractTextEditor</code> method performs any extra 
128    * save behavior required by the php editor.
129    */
130   public void doSave(IProgressMonitor monitor) {
131     super.doSave(monitor);
132     // compile or not, according to the user preferences
133     IPreferenceStore store = phpPrefStore;
134     if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
135       IAction a = PHPParserAction.getInstance();
136       if (a != null)
137         a.run();
138     }
139     if (fOutlinePage != null)
140       fOutlinePage.update();
141   }
142
143   /** The <code>PHPEditor</code> implementation of this 
144    * <code>AbstractTextEditor</code> method performs any extra 
145    * save as behavior required by the php editor.
146    */
147   public void doSaveAs() {
148     super.doSaveAs();
149     if (fOutlinePage != null)
150       fOutlinePage.update();
151   }
152
153   /** The <code>PHPEditor</code> implementation of this 
154    * <code>AbstractTextEditor</code> method performs sets the 
155    * input of the outline page after AbstractTextEditor has set input.
156    */
157   public void doSetInput(IEditorInput input) throws CoreException {
158     super.doSetInput(input);
159     if (fOutlinePage != null)
160       fOutlinePage.setInput(input);
161   }
162
163   /** The <code>PHPEditor</code> implementation of this 
164    * <code>AbstractTextEditor</code> method adds any 
165    * PHPEditor specific entries.
166    */
167   public void editorContextMenuAboutToShow(MenuManager menu) {
168     super.editorContextMenuAboutToShow(menu);
169     //  addAction(menu, "ContentAssistProposal"); //$NON-NLS-1$
170     //  addAction(menu, "ContentAssistTip"); //$NON-NLS-1$
171     actionGroup.fillContextMenu(menu);
172   }
173
174   /** The <code>PHPEditor</code> implementation of this 
175    * <code>AbstractTextEditor</code> method performs gets
176    * the java content outline page if request is for a an 
177    * outline page.
178    */
179   public Object getAdapter(Class required) {
180     if (IContentOutlinePage.class.equals(required)) {
181       if (fOutlinePage == null) {
182         fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
183         if (getEditorInput() != null)
184           fOutlinePage.setInput(getEditorInput());
185       }
186       return fOutlinePage;
187     }
188     return super.getAdapter(required);
189   }
190
191 //  public void openContextHelp() {
192 //    IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
193 //    ITextSelection selection = (ITextSelection) this.getSelectionProvider().getSelection();
194 //    int pos = selection.getOffset();
195 //    String word = getFunctionName(doc, pos);
196 //    openContextHelp(word);
197 //  }
198 //
199 //  private void openContextHelp(String word) {
200 //    open(word);
201 //  }
202 //
203 //  public static void open(String word) {
204 //    IHelp help = WorkbenchHelp.getHelpSupport();
205 //    if (help != null) {
206 //      IHelpResource helpResource = new PHPFunctionHelpResource(word);
207 //      WorkbenchHelp.getHelpSupport().displayHelpResource(helpResource);
208 //    } else {
209 //      //   showMessage(shell, dialogTitle, ActionMessages.getString("Open help not available"), false); //$NON-NLS-1$
210 //    }
211 //  }
212
213   private String getFunctionName(IDocument doc, int pos) {
214     Point word = PHPWordExtractor.findWord(doc, pos);
215     if (word != null) {
216       try {
217         return doc.get(word.x, word.y).replace('_', '-');
218       } catch (BadLocationException e) {
219       }
220     }
221     return "";
222   }
223
224   /*
225      * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
226      */
227   protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
228
229     try {
230
231       ISourceViewer sourceViewer = getSourceViewer();
232       if (sourceViewer == null)
233         return;
234
235       String property = event.getProperty();
236
237       //      if (JavaSourceViewerConfiguration.PREFERENCE_TAB_WIDTH.equals(property)) {
238       //        Object value= event.getNewValue();
239       //        if (value instanceof Integer) {
240       //          sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
241       //        } else if (value instanceof String) {
242       //          sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
243       //        }
244       //        return;
245       //      }
246
247       if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
248         if (isLineNumberRulerVisible())
249           showLineNumberRuler();
250         else
251           hideLineNumberRuler();
252         return;
253       }
254
255       if (fLineNumberRulerColumn != null
256         && (IPreferenceConstants.LINE_NUMBER_COLOR.equals(property)
257           || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
258           || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
259
260         initializeLineNumberRulerColumn(fLineNumberRulerColumn);
261       }
262
263     } finally {
264       super.handlePreferenceStoreChanged(event);
265     }
266   }
267   /**
268    * Shows the line number ruler column.
269    */
270   private void showLineNumberRuler() {
271     IVerticalRuler v = getVerticalRuler();
272     if (v instanceof CompositeRuler) {
273       CompositeRuler c = (CompositeRuler) v;
274       c.addDecorator(1, createLineNumberRulerColumn());
275     }
276   }
277
278   /**
279   * Return whether the line number ruler column should be 
280   * visible according to the preference store settings.
281   * @return <code>true</code> if the line numbers should be visible
282   */
283   private boolean isLineNumberRulerVisible() {
284     // IPreferenceStore store= getPreferenceStore();
285     return phpPrefStore.getBoolean(IPreferenceConstants.LINE_NUMBER_RULER);
286   }
287   /**
288    * Hides the line number ruler column.
289    */
290   private void hideLineNumberRuler() {
291     IVerticalRuler v = getVerticalRuler();
292     if (v instanceof CompositeRuler) {
293       CompositeRuler c = (CompositeRuler) v;
294       c.removeDecorator(1);
295     }
296   }
297
298   /**
299   * Initializes the given line number ruler column from the preference store.
300   * @param rulerColumn the ruler column to be initialized
301   */
302   protected void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) {
303     //   JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
304     PHPColorProvider manager = PHPEditorEnvironment.getPHPColorProvider();
305
306     if (phpPrefStore != null) {
307
308       RGB rgb = null;
309       // foreground color
310       if (phpPrefStore.contains(IPreferenceConstants.LINE_NUMBER_COLOR)) {
311         if (phpPrefStore.isDefault(IPreferenceConstants.LINE_NUMBER_COLOR))
312           rgb = PreferenceConverter.getDefaultColor(phpPrefStore, IPreferenceConstants.LINE_NUMBER_COLOR);
313         else
314           rgb = PreferenceConverter.getColor(phpPrefStore, IPreferenceConstants.LINE_NUMBER_COLOR);
315       }
316       rulerColumn.setForeground(manager.getColor(rgb));
317
318       rgb = null;
319       // background color
320       if (!phpPrefStore.getBoolean(IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
321         if (phpPrefStore.contains(IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND)) {
322           if (phpPrefStore.isDefault(IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND))
323             rgb = PreferenceConverter.getDefaultColor(phpPrefStore, IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND);
324           else
325             rgb = PreferenceConverter.getColor(phpPrefStore, IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND);
326         }
327         rulerColumn.setBackground(manager.getColor(rgb));
328       }
329
330     }
331   }
332
333   /**
334    * Creates a new line number ruler column that is appropriately initialized.
335    */
336   protected IVerticalRulerColumn createLineNumberRulerColumn() {
337     fLineNumberRulerColumn = new LineNumberRulerColumn();
338     initializeLineNumberRulerColumn(fLineNumberRulerColumn);
339     return fLineNumberRulerColumn;
340   }
341
342   /*
343    * @see AbstractTextEditor#createVerticalRuler()
344    */
345   protected IVerticalRuler createVerticalRuler() {
346     CompositeRuler ruler = new CompositeRuler();
347     ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
348     if (isLineNumberRulerVisible())
349       ruler.addDecorator(1, createLineNumberRulerColumn());
350     return ruler;
351   }
352
353   /* (non-Javadoc)
354    * Method declared on AbstractTextEditor
355    */
356   protected void initializeEditor() {
357     PHPEditorEnvironment.connect(this);
358
359     setSourceViewerConfiguration(new PHPSourceViewerConfiguration());
360     setRangeIndicator(new DefaultRangeIndicator());
361     setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
362     setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
363     // setDocumentProvider(PHPeclipsePlugin.getCompilationUnitDocumentProvider());
364     phpPrefStore = PHPeclipsePlugin.getDefault().getPreferenceStore();
365
366     phpPrefStore.addPropertyChangeListener(new IPropertyChangeListener() {
367       public void propertyChange(PropertyChangeEvent event) {
368         PHPCodeScanner scanner = PHPEditorEnvironment.getPHPCodeScanner();
369         if (scanner != null) {
370           scanner.updateToken(PHPEditorEnvironment.getPHPColorProvider());
371         }
372         if (getSourceViewer() != null) {
373           getSourceViewer().invalidateTextPresentation();
374         }
375
376         String property = event.getProperty();
377         if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
378           if (isLineNumberRulerVisible())
379             showLineNumberRuler();
380           else
381             hideLineNumberRuler();
382           return;
383         }
384       }
385     });
386   }
387 }