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