479f88068772250a3342e992ad28a372bb00b69b
[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.phpdt.internal.ui.actions.CompositeActionGroup;
15 import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
16 import net.sourceforge.phpeclipse.IPreferenceConstants;
17 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
18 import net.sourceforge.phpeclipse.phpeditor.php.PHPCodeScanner;
19 import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
20
21 import org.eclipse.core.runtime.CoreException;
22 import org.eclipse.core.runtime.IProgressMonitor;
23 import org.eclipse.jface.action.Action;
24 import org.eclipse.jface.action.IAction;
25 import org.eclipse.jface.action.MenuManager;
26 import org.eclipse.jface.preference.IPreferenceStore;
27 import org.eclipse.jface.preference.PreferenceConverter;
28 import org.eclipse.jface.text.IDocument;
29 import org.eclipse.jface.text.ITextOperationTarget;
30 import org.eclipse.jface.text.source.AnnotationRulerColumn;
31 import org.eclipse.jface.text.source.CompositeRuler;
32 import org.eclipse.jface.text.source.ISourceViewer;
33 import org.eclipse.jface.text.source.IVerticalRuler;
34 import org.eclipse.jface.text.source.IVerticalRulerColumn;
35 import org.eclipse.jface.text.source.LineNumberRulerColumn;
36 import org.eclipse.jface.util.IPropertyChangeListener;
37 import org.eclipse.jface.util.PropertyChangeEvent;
38 import org.eclipse.swt.graphics.RGB;
39 import org.eclipse.ui.IEditorInput;
40 import org.eclipse.ui.actions.ActionContext;
41 import org.eclipse.ui.actions.ActionGroup;
42 import org.eclipse.ui.editors.text.TextEditor;
43 import org.eclipse.ui.texteditor.ContentAssistAction;
44 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
45 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
46 import org.eclipse.ui.texteditor.TextOperationAction;
47 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
48 /**
49  * PHP specific text editor.
50  */
51 public class PHPEditor extends TextEditor {
52
53   // protected PHPActionGroup fActionGroups;
54   /** The outline page */
55   private PHPContentOutlinePage fOutlinePage;
56   private IPreferenceStore phpPrefStore;
57
58   /** The line number ruler column */
59   private LineNumberRulerColumn fLineNumberRulerColumn;
60
61   protected CompositeActionGroup fActionGroups;
62   /** The standard action groups added to the menu */
63   private GenerateActionGroup fGenerateActionGroup;
64   private CompositeActionGroup fContextMenuGroup;
65   /**
66    * Default constructor.
67    */
68   public PHPEditor() {
69     super();
70     setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
71   }
72   //
73   //    /**
74   //     * @see IMember#getCompilationUnit()
75   //     */
76   //    public ICompilationUnit getCompilationUnit() {
77   //            return this; 
78   //    }
79   //    /**
80   //     * @see org.phpeclipse.phpdt.internal.compiler.env.ICompilationUnit#getContents()
81   //     */
82   //    public char[] getContents() {
83   //            IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
84   //    
85   //            return doc.get().toCharArray();
86   //    }
87
88   /**
89    * Returns this document's complete text.
90    *
91    * @return the document's complete text
92    */
93   public String get() {
94     IDocument doc =
95       this.getDocumentProvider().getDocument(this.getEditorInput());
96     return doc.get();
97   }
98
99   /**
100    *  Returns the standard action group of this editor.
101    */
102   protected ActionGroup getActionGroup() {
103     return fActionGroups;
104   }
105
106   public PHPContentOutlinePage getfOutlinePage() {
107     return fOutlinePage;
108   }
109
110   /** The <code>PHPEditor</code> implementation of this 
111    * <code>AbstractTextEditor</code> method extend the 
112    * actions to add those specific to the receiver
113    */
114   protected void createActions() {
115     super.createActions();
116
117     Action action;
118     //    setAction(
119     //      "ContentAssistProposal",
120     //      new TextOperationAction(
121     //        PHPEditorMessages.getResourceBundle(),
122     //        "ContentAssistProposal.",
123     //        this,
124     //        ISourceViewer.CONTENTASSIST_PROPOSALS));
125     action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$
126     action.setActionDefinitionId(
127       PHPEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
128     setAction("ContentAssistProposal", action); //$NON-NLS-1$
129
130     //  System.out.println(action.getId());
131     //  System.out.println(action.getActionDefinitionId());
132
133     setAction(
134       "ContentAssistTip",
135       new TextOperationAction(
136         PHPEditorMessages.getResourceBundle(),
137         "ContentAssistTip.",
138         this,
139         ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION));
140
141     action =
142       new TextOperationAction(
143         PHPEditorMessages.getResourceBundle(),
144         "Comment.",
145         this,
146         ITextOperationTarget.PREFIX);
147     action.setActionDefinitionId(PHPEditorActionDefinitionIds.COMMENT);
148     setAction("Comment", action);
149
150     //  System.out.println(action.getId());
151     //  System.out.println(action.getActionDefinitionId());
152
153     action =
154       new TextOperationAction(
155         PHPEditorMessages.getResourceBundle(),
156         "Uncomment.",
157         this,
158         ITextOperationTarget.STRIP_PREFIX);
159     action.setActionDefinitionId(PHPEditorActionDefinitionIds.UNCOMMENT);
160     setAction("Uncomment", action);
161
162     action = new TextOperationAction(
163         PHPEditorMessages.getResourceBundle(), "Format.", this, ISourceViewer.FORMAT); //$NON-NLS-1$
164     action.setActionDefinitionId(PHPEditorActionDefinitionIds.FORMAT);
165     setAction("Format", action); //$NON-NLS-1$
166     
167     //  System.out.println(action.getId());
168     //  System.out.println(action.getActionDefinitionId());
169
170     //  fActionGroups = new PHPActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
171
172     markAsStateDependentAction("Comment", true); //$NON-NLS-1$
173     markAsStateDependentAction("Uncomment", true); //$NON-NLS-1$
174     markAsStateDependentAction("Format", true); //$NON-NLS-1$
175     
176     fGenerateActionGroup =
177       new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT);
178
179     fActionGroups =
180       new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
181
182     // We have to keep the context menu group separate to have better control over positioning
183     fContextMenuGroup =
184       new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup });
185     //      rg, 
186     //      new LocalHistoryActionGroup(this, ITextEditorActionConstants.GROUP_EDIT)});
187   }
188
189   /** The <code>PHPEditor</code> implementation of this 
190    * <code>AbstractTextEditor</code> method performs any extra 
191    * disposal actions required by the php editor.
192    */
193   public void dispose() {
194     PHPEditorEnvironment.disconnect(this);
195     if (fOutlinePage != null)
196       fOutlinePage.setInput(null);
197
198     if (fActionGroups != null)
199       fActionGroups.dispose();
200
201     super.dispose();
202   }
203
204   /** The <code>PHPEditor</code> implementation of this 
205    * <code>AbstractTextEditor</code> method performs any extra 
206    * revert behavior required by the php editor.
207    */
208   public void doRevertToSaved() {
209     super.doRevertToSaved();
210     if (fOutlinePage != null)
211       fOutlinePage.update();
212   }
213
214   /** The <code>PHPEditor</code> implementation of this 
215    * <code>AbstractTextEditor</code> method performs any extra 
216    * save behavior required by the php editor.
217    */
218   public void doSave(IProgressMonitor monitor) {
219     super.doSave(monitor);
220     // compile or not, according to the user preferences
221     IPreferenceStore store = phpPrefStore;
222     if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
223       IAction a = PHPParserAction.getInstance();
224       if (a != null)
225         a.run();
226     }
227     if (fOutlinePage != null)
228       fOutlinePage.update();
229   }
230
231   /** The <code>PHPEditor</code> implementation of this 
232    * <code>AbstractTextEditor</code> method performs any extra 
233    * save as behavior required by the php editor.
234    */
235   public void doSaveAs() {
236     super.doSaveAs();
237     if (fOutlinePage != null)
238       fOutlinePage.update();
239   }
240
241   /** The <code>PHPEditor</code> implementation of this 
242    * <code>AbstractTextEditor</code> method performs sets the 
243    * input of the outline page after AbstractTextEditor has set input.
244    */
245   public void doSetInput(IEditorInput input) throws CoreException {
246     super.doSetInput(input);
247     if (fOutlinePage != null)
248       fOutlinePage.setInput(input);
249   }
250
251   /** The <code>PHPEditor</code> implementation of this 
252    * <code>AbstractTextEditor</code> method adds any 
253    * PHPEditor specific entries.
254    */
255   public void editorContextMenuAboutToShow(MenuManager menu) {
256     super.editorContextMenuAboutToShow(menu);
257     //  addAction(menu, "ContentAssistProposal"); //$NON-NLS-1$
258     //  addAction(menu, "ContentAssistTip"); //$NON-NLS-1$
259     addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format"); //$NON-NLS-1$ 
260     
261     // fActionGroups.fillContextMenu(menu);
262     
263     ActionContext context =
264       new ActionContext(getSelectionProvider().getSelection());
265     fContextMenuGroup.setContext(context);
266     fContextMenuGroup.fillContextMenu(menu);
267     fContextMenuGroup.setContext(null);
268   }
269
270   protected void updateStateDependentActions() {
271     super.updateStateDependentActions();
272     fGenerateActionGroup.editorStateChanged();
273   }
274
275   /** The <code>PHPEditor</code> implementation of this 
276    * <code>AbstractTextEditor</code> method performs gets
277    * the java content outline page if request is for a an 
278    * outline page.
279    */
280   public Object getAdapter(Class required) {
281     if (IContentOutlinePage.class.equals(required)) {
282       if (fOutlinePage == null) {
283         fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
284         if (getEditorInput() != null)
285           fOutlinePage.setInput(getEditorInput());
286       }
287       return fOutlinePage;
288     }
289     return super.getAdapter(required);
290   }
291
292   //  public void openContextHelp() {
293   //    IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
294   //    ITextSelection selection = (ITextSelection) this.getSelectionProvider().getSelection();
295   //    int pos = selection.getOffset();
296   //    String word = getFunctionName(doc, pos);
297   //    openContextHelp(word);
298   //  }
299   //
300   //  private void openContextHelp(String word) {
301   //    open(word);
302   //  }
303   //
304   //  public static void open(String word) {
305   //    IHelp help = WorkbenchHelp.getHelpSupport();
306   //    if (help != null) {
307   //      IHelpResource helpResource = new PHPFunctionHelpResource(word);
308   //      WorkbenchHelp.getHelpSupport().displayHelpResource(helpResource);
309   //    } else {
310   //      //   showMessage(shell, dialogTitle, ActionMessages.getString("Open help not available"), false); //$NON-NLS-1$
311   //    }
312   //  }
313
314   //    private String getFunctionName(IDocument doc, int pos) {
315   //            Point word = PHPWordExtractor.findWord(doc, pos);
316   //            if (word != null) {
317   //                    try {
318   //                            return doc.get(word.x, word.y).replace('_', '-');
319   //                    } catch (BadLocationException e) {
320   //                    }
321   //            }
322   //            return "";
323   //    }
324
325   /*
326      * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
327      */
328   protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
329
330     try {
331
332       ISourceViewer sourceViewer = getSourceViewer();
333       if (sourceViewer == null)
334         return;
335
336       String property = event.getProperty();
337
338       //      if (JavaSourceViewerConfiguration.PREFERENCE_TAB_WIDTH.equals(property)) {
339       //        Object value= event.getNewValue();
340       //        if (value instanceof Integer) {
341       //          sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
342       //        } else if (value instanceof String) {
343       //          sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
344       //        }
345       //        return;
346       //      }
347
348       if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
349         if (isLineNumberRulerVisible())
350           showLineNumberRuler();
351         else
352           hideLineNumberRuler();
353         return;
354       }
355
356       if (fLineNumberRulerColumn != null
357         && (IPreferenceConstants.LINE_NUMBER_COLOR.equals(property)
358           || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
359           || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
360
361         initializeLineNumberRulerColumn(fLineNumberRulerColumn);
362       }
363
364     } finally {
365       super.handlePreferenceStoreChanged(event);
366     }
367   }
368   /**
369    * Shows the line number ruler column.
370    */
371   private void showLineNumberRuler() {
372     IVerticalRuler v = getVerticalRuler();
373     if (v instanceof CompositeRuler) {
374       CompositeRuler c = (CompositeRuler) v;
375       c.addDecorator(1, createLineNumberRulerColumn());
376     }
377   }
378
379   /**
380   * Return whether the line number ruler column should be 
381   * visible according to the preference store settings.
382   * @return <code>true</code> if the line numbers should be visible
383   */
384   private boolean isLineNumberRulerVisible() {
385     // IPreferenceStore store= getPreferenceStore();
386     return phpPrefStore.getBoolean(IPreferenceConstants.LINE_NUMBER_RULER);
387   }
388   /**
389    * Hides the line number ruler column.
390    */
391   private void hideLineNumberRuler() {
392     IVerticalRuler v = getVerticalRuler();
393     if (v instanceof CompositeRuler) {
394       CompositeRuler c = (CompositeRuler) v;
395       try {
396         c.removeDecorator(1);
397       } catch (Throwable e) {
398       }
399     }
400   }
401
402   /**
403   * Initializes the given line number ruler column from the preference store.
404   * @param rulerColumn the ruler column to be initialized
405   */
406   protected void initializeLineNumberRulerColumn(LineNumberRulerColumn rulerColumn) {
407     //   JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
408     PHPColorProvider manager = PHPEditorEnvironment.getPHPColorProvider();
409
410     if (phpPrefStore != null) {
411
412       RGB rgb = null;
413       // foreground color
414       if (phpPrefStore.contains(IPreferenceConstants.LINE_NUMBER_COLOR)) {
415         if (phpPrefStore.isDefault(IPreferenceConstants.LINE_NUMBER_COLOR))
416           rgb =
417             PreferenceConverter.getDefaultColor(
418               phpPrefStore,
419               IPreferenceConstants.LINE_NUMBER_COLOR);
420         else
421           rgb =
422             PreferenceConverter.getColor(
423               phpPrefStore,
424               IPreferenceConstants.LINE_NUMBER_COLOR);
425       }
426       rulerColumn.setForeground(manager.getColor(rgb));
427
428       rgb = null;
429       // background color
430       if (!phpPrefStore
431         .getBoolean(
432           IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
433         if (phpPrefStore
434           .contains(IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND)) {
435           if (phpPrefStore
436             .isDefault(IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND))
437             rgb =
438               PreferenceConverter.getDefaultColor(
439                 phpPrefStore,
440                 IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND);
441           else
442             rgb =
443               PreferenceConverter.getColor(
444                 phpPrefStore,
445                 IPreferenceConstants.PREFERENCE_COLOR_BACKGROUND);
446         }
447         rulerColumn.setBackground(manager.getColor(rgb));
448       }
449
450     }
451   }
452
453   /**
454    * Creates a new line number ruler column that is appropriately initialized.
455    */
456   protected IVerticalRulerColumn createLineNumberRulerColumn() {
457     fLineNumberRulerColumn = new LineNumberRulerColumn();
458     initializeLineNumberRulerColumn(fLineNumberRulerColumn);
459     return fLineNumberRulerColumn;
460   }
461
462   /*
463    * @see AbstractTextEditor#createVerticalRuler()
464    */
465   protected IVerticalRuler createVerticalRuler() {
466     CompositeRuler ruler = new CompositeRuler();
467     ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
468     if (isLineNumberRulerVisible())
469       ruler.addDecorator(1, createLineNumberRulerColumn());
470     return ruler;
471   }
472
473   /* (non-Javadoc)
474    * Method declared on AbstractTextEditor
475    */
476   protected void initializeEditor() {
477     PHPEditorEnvironment.connect(this);
478
479     setSourceViewerConfiguration(new PHPSourceViewerConfiguration(this));
480     setRangeIndicator(new DefaultRangeIndicator());
481     setEditorContextMenuId("#PHPEditorContext"); //$NON-NLS-1$
482     setRulerContextMenuId("#PHPRulerContext"); //$NON-NLS-1$
483     // setDocumentProvider(PHPeclipsePlugin.getCompilationUnitDocumentProvider());
484     phpPrefStore = PHPeclipsePlugin.getDefault().getPreferenceStore();
485
486     phpPrefStore.addPropertyChangeListener(new IPropertyChangeListener() {
487       public void propertyChange(PropertyChangeEvent event) {
488         PHPCodeScanner scanner = PHPEditorEnvironment.getPHPCodeScanner();
489         if (scanner != null) {
490           scanner.updateToken(PHPEditorEnvironment.getPHPColorProvider());
491         }
492         if (getSourceViewer() != null) {
493           getSourceViewer().invalidateTextPresentation();
494         }
495
496         String property = event.getProperty();
497         if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
498           if (isLineNumberRulerVisible())
499             showLineNumberRuler();
500           else
501             hideLineNumberRuler();
502           return;
503         }
504       }
505     });
506   }
507 }