new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / PHPEditor.java
index ef1bbab..a2f3ae0 100644 (file)
@@ -12,26 +12,35 @@ Contributors:
     Klaus Hartlage - www.eclipseproject.de
 **********************************************************************/
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.ResourceBundle;
 import java.util.StringTokenizer;
 
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IMember;
+import net.sourceforge.phpdt.core.ISourceRange;
+import net.sourceforge.phpdt.core.ISourceReference;
+import net.sourceforge.phpdt.core.JavaModelException;
 import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
 import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
 import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
 import net.sourceforge.phpdt.ui.IContextMenuConstants;
+import net.sourceforge.phpdt.ui.JavaUI;
 import net.sourceforge.phpdt.ui.PreferenceConstants;
 import net.sourceforge.phpdt.ui.actions.GenerateActionGroup;
 import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
 import net.sourceforge.phpdt.ui.text.IColorManager;
 import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPCore;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 import net.sourceforge.phpeclipse.phpeditor.php.IPHPPartitionScannerConstants;
 
+import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.action.Action;
@@ -52,18 +61,21 @@ import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.ITextHover;
 import org.eclipse.jface.text.ITextInputListener;
 import org.eclipse.jface.text.ITextOperationTarget;
+import org.eclipse.jface.text.ITextSelection;
 import org.eclipse.jface.text.ITextViewer;
 import org.eclipse.jface.text.ITextViewerExtension2;
 import org.eclipse.jface.text.ITextViewerExtension3;
 import org.eclipse.jface.text.ITypedRegion;
 import org.eclipse.jface.text.Position;
 import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextSelection;
 import org.eclipse.jface.text.information.IInformationProvider;
 import org.eclipse.jface.text.information.InformationPresenter;
 import org.eclipse.jface.text.source.Annotation;
 import org.eclipse.jface.text.source.AnnotationRulerColumn;
 import org.eclipse.jface.text.source.CompositeRuler;
 import org.eclipse.jface.text.source.IAnnotationAccess;
+import org.eclipse.jface.text.source.IAnnotationModel;
 import org.eclipse.jface.text.source.IOverviewRuler;
 import org.eclipse.jface.text.source.ISharedTextColors;
 import org.eclipse.jface.text.source.ISourceViewer;
@@ -76,8 +88,12 @@ import org.eclipse.jface.text.source.SourceViewer;
 import org.eclipse.jface.text.source.SourceViewerConfiguration;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BidiSegmentEvent;
 import org.eclipse.swt.custom.BidiSegmentListener;
@@ -95,6 +111,7 @@ import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Cursor;
 import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.widgets.Composite;
@@ -102,13 +119,17 @@ import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.actions.ActionContext;
 import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.editors.text.DefaultEncodingSupport;
 import org.eclipse.ui.editors.text.IEncodingSupport;
+import org.eclipse.ui.part.IShowInTargetList;
 import org.eclipse.ui.texteditor.AddTaskAction;
 import org.eclipse.ui.texteditor.ContentAssistAction;
 import org.eclipse.ui.texteditor.DefaultRangeIndicator;
@@ -117,17 +138,52 @@ import org.eclipse.ui.texteditor.IDocumentProvider;
 import org.eclipse.ui.texteditor.IEditorStatusLine;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
 import org.eclipse.ui.texteditor.ResourceAction;
 import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
 import org.eclipse.ui.texteditor.StatusTextEditor;
 import org.eclipse.ui.texteditor.TextEditorAction;
 import org.eclipse.ui.texteditor.TextOperationAction;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.tasklist.TaskList;
 
 /**
  * PHP specific text editor.
  */
 public abstract class PHPEditor extends StatusTextEditor implements IViewPartInputProvider { // extends TextEditor {
+  /**
+        * "Smart" runnable for updating the outline page's selection.
+        */
+  class OutlinePageSelectionUpdater implements Runnable {
+
+    /** Has the runnable already been posted? */
+    private boolean fPosted = false;
+
+    public OutlinePageSelectionUpdater() {
+    }
+
+    /*
+     * @see Runnable#run()
+     */
+    public void run() {
+      synchronizeOutlinePageSelection();
+      fPosted = false;
+    }
+
+    /**
+     * Posts this runnable into the event queue.
+     */
+    public void post() {
+      if (fPosted)
+        return;
+
+      Shell shell = getSite().getShell();
+      if (shell != null & !shell.isDisposed()) {
+        fPosted = true;
+        shell.getDisplay().asyncExec(this);
+      }
+    }
+  };
   class SelectionChangedListener implements ISelectionChangedListener {
     public void selectionChanged(SelectionChangedEvent event) {
       doSelectionChanged(event);
@@ -138,15 +194,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   * Link mode.  
   */
   class MouseClickListener
-    implements
-      KeyListener,
-      MouseListener,
-      MouseMoveListener,
-      FocusListener,
-      PaintListener,
-      IPropertyChangeListener,
-      IDocumentListener,
-      ITextInputListener {
+    implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, IPropertyChangeListener, IDocumentListener, ITextInputListener {
 
     /** The session is active. */
     private boolean fActive;
@@ -402,25 +450,25 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
         return null;
 
       return null;
-      //                               IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
-      //                               if (input == null)
-      //                                       return null;
-      //
-      //                               try {
-      //                               
-      //                                       IJavaElement[] elements= null;
-      //                                       synchronized (input) {
-      //                                               elements= ((ICodeAssist) input).codeSelect(offset, 0);
-      //                                       }
-      //                               
-      //                                       if (elements == null || elements.length == 0)
-      //                                               return null;
-      //                                       
-      //                                       return selectWord(viewer.getDocument(), offset);
-      //                                       
-      //                               } catch (JavaModelException e) {
-      //                                       return null;    
-      //                               }
+      //                               IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
+      //                               if (input == null)
+      //                                       return null;
+      //      
+      //                               try {
+      //                               
+      //                                       IJavaElement[] elements= null;
+      //                                       synchronized (input) {
+      //                                               elements= ((ICodeAssist) input).codeSelect(offset, 0);
+      //                                       }
+      //                               
+      //                                       if (elements == null || elements.length == 0)
+      //                                               return null;
+      //                                       
+      //                                       return selectWord(viewer.getDocument(), offset);
+      //                                       
+      //                               } catch (JavaModelException e) {
+      //                                       return null;    
+      //                               }
     }
 
     private int getCurrentTextOffset(ISourceViewer viewer) {
@@ -765,8 +813,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     }
 
     private boolean includes(IRegion region, IRegion position) {
-      return position.getOffset() >= region.getOffset()
-        && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
+      return position.getOffset() >= region.getOffset() && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
     }
 
     private Point getMinimumLocation(StyledText text, int offset, int length) {
@@ -960,11 +1007,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   private final static String LINE_NUMBER_COLOR = PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
   /** Preference key for the link color */
   private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR;
+  /** Preference key for compiler task tags */
+  private final static String COMPILER_TASK_TAGS = PHPCore.COMPILER_TASK_TAGS;
 
   // protected PHPActionGroup fActionGroups;
+  //  /** The outline page */
+  //  private AbstractContentOutlinePage fOutlinePage;
   /** The outline page */
-  private AbstractContentOutlinePage fOutlinePage;
-
+  protected JavaOutlinePage fOutlinePage;
+  /** Outliner context menu Id */
+  protected String fOutlinerContextMenuId;
+  /** Indicates whether this editor should react on outline page selection changes */
+  private int fIgnoreOutlinePageSelection;
+  
+       /** The outline page selection updater */
+       private OutlinePageSelectionUpdater fUpdater;
   //  protected PHPSyntaxParserThread fValidationThread = null;
 
   // private IPreferenceStore fPHPPrefStore;
@@ -973,6 +1030,8 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
 
   /** The editor's bracket matcher */
   private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS);
+
+
   /** The line number ruler column */
   private LineNumberRulerColumn fLineNumberRulerColumn;
   /** This editor's encoding support */
@@ -998,6 +1057,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
 
   /** The preference property change listener for java core. */
   private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
+  /**
+   * Returns the most narrow java element including the given offset
+   * 
+   * @param offset the offset inside of the requested element
+   */
+  abstract protected IJavaElement getElementAt(int offset);
+
+  /**
+   * Returns the java element of this editor's input corresponding to the given IJavaElement
+   */
+  abstract protected IJavaElement getCorrespondingElement(IJavaElement element);
+  /**
+        * Sets the input of the editor's outline page.
+        */
+  abstract protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input);
 
   /**
    * Default constructor.
@@ -1012,8 +1086,8 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     // don't activate this scope without synchronizing plugin.xml !!!
     //    setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$
 
-    //    if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
-    //      fUpdater= new OutlinePageSelectionUpdater();
+        if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
+          fUpdater= new OutlinePageSelectionUpdater();
   }
   //
   //   /**
@@ -1038,7 +1112,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     if (fEncodingSupport != null)
       fEncodingSupport.reset();
   }
-  
+
   /*
    * Update the hovering behavior depending on the preferences.
    */
@@ -1069,13 +1143,22 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     }
   }
 
+  public void updatedTitleImage(Image image) {
+    setTitleImage(image);
+  }
   /*
    * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
    */
   public Object getViewPartInput() {
     return getEditorInput().getAdapter(IResource.class);
   }
-
+  /*
+   * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
+   */
+  protected void doSetSelection(ISelection selection) {
+    super.doSetSelection(selection);
+    synchronizeOutlinePageSelection();
+  }
   /*
    * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.
    * widgets.Composite)
@@ -1099,6 +1182,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     fInformationPresenter = new InformationPresenter(informationControlCreator);
     fInformationPresenter.setSizeConstraints(60, 10, true, true);
     fInformationPresenter.install(getSourceViewer());
+
   }
 
   /**
@@ -1112,15 +1196,22 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   }
 
   /**
+        * Sets the outliner's context menu ID.
+        */
+  protected void setOutlinerContextMenuId(String menuId) {
+    fOutlinerContextMenuId = menuId;
+  }
+
+  /**
    *  Returns the standard action group of this editor.
    */
   protected ActionGroup getActionGroup() {
     return fActionGroups;
   }
 
-  public AbstractContentOutlinePage getfOutlinePage() {
-    return fOutlinePage;
-  }
+  //  public JavaOutlinePage getfOutlinePage() {
+  //    return fOutlinePage;
+  //  }
 
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method extend the 
@@ -1144,11 +1235,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
 
     setAction(
       "ContentAssistTip",
-      new TextOperationAction(
-        PHPEditorMessages.getResourceBundle(),
-        "ContentAssistTip.",
-        this,
-        ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION));
+      new TextOperationAction(PHPEditorMessages.getResourceBundle(), "ContentAssistTip.", this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION));
 
     action = new ContentAssistAction(PHPEditorMessages.getResourceBundle(), "ContentAssistProposal.", this); //$NON-NLS-1$
     action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
@@ -1244,46 +1331,46 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
    * <code>AbstractTextEditor</code> method performs any extra 
    * revert behavior required by the php editor.
    */
-  public void doRevertToSaved() {
-    super.doRevertToSaved();
-    if (fOutlinePage != null)
-      fOutlinePage.update();
-  }
+  //  public void doRevertToSaved() {
+  //    super.doRevertToSaved();
+  //    if (fOutlinePage != null)
+  //      fOutlinePage.update();
+  //  }
 
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method performs any extra 
    * save behavior required by the php editor.
    */
-  public void doSave(IProgressMonitor monitor) {
-    super.doSave(monitor);
-    // compile or not, according to the user preferences
-    // IPreferenceStore store = getPreferenceStore(); 
-
-    // the parse on save was changed to the eclipse "builders" concept
-    //    if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
-    //      IAction a = PHPParserAction.getInstance();
-    //      if (a != null)
-    //        a.run();
-    //    }
+  //  public void doSave(IProgressMonitor monitor) {
+  //    super.doSave(monitor);
+  // compile or not, according to the user preferences
+  // IPreferenceStore store = getPreferenceStore(); 
+
+  // the parse on save was changed to the eclipse "builders" concept
+  //    if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
+  //      IAction a = PHPParserAction.getInstance();
+  //      if (a != null)
+  //        a.run();
+  //    }
 
-    //    if (SWT.getPlatform().equals("win32")) {
-    //      IAction a = ShowExternalPreviewAction.getInstance();
-    //      if (a != null)
-    //        a.run();
-    //    }
-    if (fOutlinePage != null)
-      fOutlinePage.update();
-  }
+  //    if (SWT.getPlatform().equals("win32")) {
+  //      IAction a = ShowExternalPreviewAction.getInstance();
+  //      if (a != null)
+  //        a.run();
+  //    }
+  //    if (fOutlinePage != null)
+  //      fOutlinePage.update();
+  //  }
 
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method performs any extra 
    * save as behavior required by the php editor.
    */
-  public void doSaveAs() {
-    super.doSaveAs();
-    if (fOutlinePage != null)
-      fOutlinePage.update();
-  }
+  //  public void doSaveAs() {
+  //    super.doSaveAs();
+  //    if (fOutlinePage != null)
+  //      fOutlinePage.update();
+  //  }
   /*
         * @see StatusTextEditor#getStatusHeader(IStatus)
         */
@@ -1323,16 +1410,21 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
    * <code>AbstractTextEditor</code> method performs sets the 
    * input of the outline page after AbstractTextEditor has set input.
    */
+  //  protected void doSetInput(IEditorInput input) throws CoreException {
+  //    super.doSetInput(input);
+  //
+  //    if (fEncodingSupport != null)
+  //      fEncodingSupport.reset();
+  //    if (fOutlinePage != null)
+  //      fOutlinePage.setInput(input);
+  //    //             setOutlinePageInput(fOutlinePage, input);
+  //  } 
   protected void doSetInput(IEditorInput input) throws CoreException {
     super.doSetInput(input);
-
     if (fEncodingSupport != null)
       fEncodingSupport.reset();
-    if (fOutlinePage != null)
-      fOutlinePage.setInput(input);
-    //         setOutlinePageInput(fOutlinePage, input);
+    setOutlinePageInput(fOutlinePage, input);
   }
-
   /*
    * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
    */
@@ -1365,14 +1457,20 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   /**
    * Creates the outline page used with this editor.
    */
-  protected AbstractContentOutlinePage createOutlinePage() {
+  protected JavaOutlinePage createOutlinePage() {
 
-    AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this);
+    //    AbstractContentOutlinePage page = new PHPContentOutlinePage(getDocumentProvider(), this);
+    //
+    //    page.addSelectionChangedListener(fSelectionChangedListener);
+    //    //    setOutlinePageInput(page, getEditorInput());
+    //    if (getEditorInput() != null)
+    //      fOutlinePage.setInput(getEditorInput());
+    //
+    //    return page;
+    JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this);
 
     page.addSelectionChangedListener(fSelectionChangedListener);
-    //    setOutlinePageInput(page, getEditorInput());
-    if (getEditorInput() != null)
-      fOutlinePage.setInput(getEditorInput());
+    setOutlinePageInput(page, getEditorInput());
 
     return page;
   }
@@ -1387,56 +1485,263 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
       resetHighlightRange();
     }
   }
+  /**
+   * Synchronizes the outliner selection with the actual cursor
+   * position in the editor.
+   */
+  public void synchronizeOutlinePageSelection() {
+
+    //         if (isEditingScriptRunning())
+    //                 return;
+
+    ISourceViewer sourceViewer = getSourceViewer();
+    if (sourceViewer == null || fOutlinePage == null)
+      return;
+
+    StyledText styledText = sourceViewer.getTextWidget();
+    if (styledText == null)
+      return;
+
+    int caret = 0;
+    if (sourceViewer instanceof ITextViewerExtension3) {
+      ITextViewerExtension3 extension = (ITextViewerExtension3) sourceViewer;
+      caret = extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
+    } else {
+      int offset = sourceViewer.getVisibleRegion().getOffset();
+      caret = offset + styledText.getCaretOffset();
+    }
+
+    IJavaElement element = getElementAt(caret);
+    if (element instanceof ISourceReference) {
+      fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+      fOutlinePage.select((ISourceReference) element);
+      fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
+    }
+  }
   protected void updateStateDependentActions() {
     super.updateStateDependentActions();
     fGenerateActionGroup.editorStateChanged();
   }
 
+  protected void setSelection(ISourceReference reference, boolean moveCursor) {
+
+    ISelection selection = getSelectionProvider().getSelection();
+    if (selection instanceof TextSelection) {
+      TextSelection textSelection = (TextSelection) selection;
+      if (textSelection.getOffset() != 0 || textSelection.getLength() != 0)
+        markInNavigationHistory();
+    }
+
+    if (reference != null) {
+
+      StyledText textWidget = null;
+
+      ISourceViewer sourceViewer = getSourceViewer();
+      if (sourceViewer != null)
+        textWidget = sourceViewer.getTextWidget();
+
+      if (textWidget == null)
+        return;
+
+      try {
+
+        ISourceRange range = reference.getSourceRange();
+        if (range == null)
+          return;
+
+        int offset = range.getOffset();
+        int length = range.getLength();
+
+        if (offset < 0 || length < 0)
+          return;
+
+        textWidget.setRedraw(false);
+
+        setHighlightRange(offset, length, moveCursor);
+
+        if (!moveCursor)
+          return;
+
+        offset = -1;
+        length = -1;
+
+        if (reference instanceof IMember) {
+          range = ((IMember) reference).getNameRange();
+          if (range != null) {
+            offset = range.getOffset();
+            length = range.getLength();
+          }
+        }
+        //                                     else if (reference instanceof IImportDeclaration) {
+        //                                             String name= ((IImportDeclaration) reference).getElementName();
+        //                                             if (name != null && name.length() > 0) {
+        //                                                     String content= reference.getSource();
+        //                                                     if (content != null) {
+        //                                                             offset= range.getOffset() + content.indexOf(name);
+        //                                                             length= name.length();
+        //                                                     }
+        //                                             }
+        //                                     } else if (reference instanceof IPackageDeclaration) {
+        //                                             String name= ((IPackageDeclaration) reference).getElementName();
+        //                                             if (name != null && name.length() > 0) {
+        //                                                     String content= reference.getSource();
+        //                                                     if (content != null) {
+        //                                                             offset= range.getOffset() + content.indexOf(name);
+        //                                                             length= name.length();
+        //                                                     }
+        //                                             }
+        //                                     }
+
+        if (offset > -1 && length > 0) {
+          sourceViewer.revealRange(offset, length);
+          sourceViewer.setSelectedRange(offset, length);
+        }
+
+      } catch (JavaModelException x) {
+      } catch (IllegalArgumentException x) {
+      } finally {
+        if (textWidget != null)
+          textWidget.setRedraw(true);
+      }
+
+    } else if (moveCursor) {
+      resetHighlightRange();
+    }
+
+    markInNavigationHistory();
+  }
+
+  public void setSelection(IJavaElement element) {
+
+    if (element == null || element instanceof ICompilationUnit) { // || element instanceof IClassFile) {
+      /*
+       * If the element is an ICompilationUnit this unit is either the input
+       * of this editor or not being displayed. In both cases, nothing should
+       * happened. (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
+       */
+      return;
+    }
+
+    IJavaElement corresponding = getCorrespondingElement(element);
+    if (corresponding instanceof ISourceReference) {
+      ISourceReference reference = (ISourceReference) corresponding;
+      // set hightlight range
+      setSelection(reference, true);
+      // set outliner selection
+      if (fOutlinePage != null) {
+        fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+        fOutlinePage.select(reference);
+        fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
+      }
+    }
+  }
+
+       public synchronized void editingScriptStarted() {
+               ++ fIgnoreOutlinePageSelection;
+       }
+       
+       public synchronized void editingScriptEnded() {
+               -- fIgnoreOutlinePageSelection;
+       }
+       
+       public synchronized boolean isEditingScriptRunning() {
+               return (fIgnoreOutlinePageSelection > 0);
+       }
+       
   /** The <code>PHPEditor</code> implementation of this 
    * <code>AbstractTextEditor</code> method performs gets
    * the java content outline page if request is for a an 
    * outline page.
    */
   public Object getAdapter(Class required) {
+
     if (IContentOutlinePage.class.equals(required)) {
-      if (fOutlinePage == null) {
-        fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
-        if (getEditorInput() != null)
-          fOutlinePage.setInput(getEditorInput());
-      }
+      if (fOutlinePage == null)
+        fOutlinePage = createOutlinePage();
       return fOutlinePage;
     }
 
     if (IEncodingSupport.class.equals(required))
       return fEncodingSupport;
 
+    if (required == IShowInTargetList.class) {
+      return new IShowInTargetList() {
+        public String[] getShowInTargetIds() {
+          return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
+        }
+
+      };
+    }
+
     return super.getAdapter(required);
   }
+  //  public Object getAdapter(Class required) {
+  //    if (IContentOutlinePage.class.equals(required)) {
+  //      if (fOutlinePage == null) {
+  //        fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
+  //        if (getEditorInput() != null)
+  //          fOutlinePage.setInput(getEditorInput());
+  //      }
+  //      return fOutlinePage;
+  //    }
+  //
+  //    if (IEncodingSupport.class.equals(required))
+  //      return fEncodingSupport;
+  //
+  //    return super.getAdapter(required);
+  //  }
 
   protected void doSelectionChanged(SelectionChangedEvent event) {
+    ISourceReference reference = null;
+
+    ISelection selection = event.getSelection();
+    Iterator iter = ((IStructuredSelection) selection).iterator();
+    while (iter.hasNext()) {
+      Object o = iter.next();
+      if (o instanceof ISourceReference) {
+        reference = (ISourceReference) o;
+        break;
+      }
+    }
 
-    //                 ISourceReference reference= null;
-    //         
-    //                 ISelection selection= event.getSelection();
-    //                 Iterator iter= ((IStructuredSelection) selection).iterator();
-    //                 while (iter.hasNext()) {
-    //                         Object o= iter.next();
-    //                         if (o instanceof ISourceReference) {
-    //                                 reference= (ISourceReference) o;
-    //                                 break;
-    //                         }
-    //                 }
     if (!isActivePart() && PHPeclipsePlugin.getActivePage() != null)
       PHPeclipsePlugin.getActivePage().bringToTop(this);
 
-    //                 try {
-    //                         editingScriptStarted();
-    //                         setSelection(reference, !isActivePart());
-    //                 } finally {
-    //                         editingScriptEnded();
-    //                 }
+    try {
+      editingScriptStarted();
+      setSelection(reference, !isActivePart());
+    } finally {
+      editingScriptEnded();
+    }
   }
+  /*
+        * @see AbstractTextEditor#adjustHighlightRange(int, int)
+        */
+  protected void adjustHighlightRange(int offset, int length) {
+
+    try {
 
+      IJavaElement element = getElementAt(offset);
+      while (element instanceof ISourceReference) {
+        ISourceRange range = ((ISourceReference) element).getSourceRange();
+        if (offset < range.getOffset() + range.getLength() && range.getOffset() < offset + length) {
+          setHighlightRange(range.getOffset(), range.getLength(), true);
+          if (fOutlinePage != null) {
+            fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
+            fOutlinePage.select((ISourceReference) element);
+            fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
+          }
+          return;
+        }
+        element = element.getParent();
+      }
+
+    } catch (JavaModelException x) {
+      PHPeclipsePlugin.log(x.getStatus());
+    }
+
+    resetHighlightRange();
+  }
   protected boolean isActivePart() {
     IWorkbenchWindow window = getSite().getWorkbenchWindow();
     IPartService service = window.getPartService();
@@ -1444,7 +1749,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     return part != null && part.equals(this);
   }
 
-               
+
   //  public void openContextHelp() {
   //    IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
   //    ITextSelection selection = (ITextSelection) this.getSelectionProvider().getSelection();
@@ -1518,15 +1823,20 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
       }
 
       if (fLineNumberRulerColumn != null
-        && (LINE_NUMBER_COLOR.equals(property)
-          || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
-          || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
+        && (LINE_NUMBER_COLOR.equals(property) || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
 
         initializeLineNumberRulerColumn(fLineNumberRulerColumn);
       }
 
-      if (isJavaEditorHoverProperty(property)) {
+      if (isJavaEditorHoverProperty(property))
         updateHoverBehavior();
+
+      if (BROWSER_LIKE_LINKS.equals(property)) {
+        if (isBrowserLikeLinks())
+          enableBrowserLikeLinks();
+        else
+          disableBrowserLikeLinks();
+        return;
       }
 
     } finally {
@@ -1578,16 +1888,16 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   //    }
   //  }
 
-  private boolean isJavaEditorHoverProperty(String property) {
-    return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_NONE_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property)
-      || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property);
-  }
+  //  private boolean isJavaEditorHoverProperty(String property) {
+  //    return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_NONE_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property)
+  //      || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property);
+  //  }
 
   /**
    * Shows the line number ruler column.
@@ -1599,6 +1909,10 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
       c.addDecorator(1, createLineNumberRulerColumn());
     }
   }
+  private boolean isJavaEditorHoverProperty(String property) {
+    return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
+  }
+
   /**
         * Return whether the browser like links should be enabled
         * according to the preference store settings.
@@ -1636,11 +1950,12 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
    * @param event the property change event
    */
   protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
-    //         if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
-    //                 ISourceViewer sourceViewer= getSourceViewer();
-    //                 if (sourceViewer != null && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())))
-    //                         sourceViewer.invalidateTextPresentation();
-    //         }
+    if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
+      ISourceViewer sourceViewer = getSourceViewer();
+      if (sourceViewer != null
+        && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event.getNewValue())))
+        sourceViewer.invalidateTextPresentation();
+    }
   }
 
   /**
@@ -1666,6 +1981,15 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     }
   }
 
+       /*
+        * @see AbstractTextEditor#handleCursorPositionChanged()
+        */
+       protected void handleCursorPositionChanged() {
+               super.handleCursorPositionChanged();
+               if (!isEditingScriptRunning() && fUpdater != null)
+                       fUpdater.post();
+       }
+       
   /**
    * Initializes the given line number ruler column from the preference store.
    * @param rulerColumn the ruler column to be initialized
@@ -1785,19 +2109,15 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
   /** Preference key for error indication in overview ruler */
   protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
   /** Preference key for warning indication in overview ruler */
-  protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER =
-    PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
+  protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
   /** Preference key for task indication in overview ruler */
   protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
   /** Preference key for bookmark indication in overview ruler */
-  protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER =
-    PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
+  protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
   /** Preference key for search result indication in overview ruler */
-  protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER =
-    PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
+  protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
   /** Preference key for unknown annotation indication in overview ruler */
-  protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER =
-    PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
+  protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
   //           /** Preference key for compiler task tags */
   //           private final static String COMPILER_TASK_TAGS= JavaCore.COMPILER_TASK_TAGS;
   /** Preference key for browser like links */
@@ -1811,8 +2131,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
    * 
    * @since 2.1.1
    */
-  private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK =
-    PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
+  private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
 
   private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
 
@@ -1881,6 +2200,7 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
 
     fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey());
+
   }
   /**
     * Jumps to the matching bracket.
@@ -2109,4 +2429,99 @@ public abstract class PHPEditor extends StatusTextEditor implements IViewPartInp
     return textTools.affectsBehavior(event);
   }
 
+  /**
+   * Jumps to the error next according to the given direction.
+   */
+  public void gotoError(boolean forward) {
+
+    ISelectionProvider provider = getSelectionProvider();
+
+    ITextSelection s = (ITextSelection) provider.getSelection();
+    Position errorPosition = new Position(0, 0);
+    IJavaAnnotation nextError = getNextError(s.getOffset(), forward, errorPosition);
+
+    if (nextError != null) {
+
+      IMarker marker = null;
+      if (nextError instanceof MarkerAnnotation)
+        marker = ((MarkerAnnotation) nextError).getMarker();
+      else {
+        Iterator e = nextError.getOverlaidIterator();
+        if (e != null) {
+          while (e.hasNext()) {
+            Object o = e.next();
+            if (o instanceof MarkerAnnotation) {
+              marker = ((MarkerAnnotation) o).getMarker();
+              break;
+            }
+          }
+        }
+      }
+
+      if (marker != null) {
+        IWorkbenchPage page = getSite().getPage();
+        IViewPart view = view = page.findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
+        if (view instanceof TaskList) {
+          StructuredSelection ss = new StructuredSelection(marker);
+          ((TaskList) view).setSelection(ss, true);
+        }
+      }
+
+      selectAndReveal(errorPosition.getOffset(), errorPosition.getLength());
+      setStatusLineErrorMessage(nextError.getMessage());
+
+    } else {
+
+      setStatusLineErrorMessage(null);
+
+    }
+  }
+
+  private IJavaAnnotation getNextError(int offset, boolean forward, Position errorPosition) {
+
+    IJavaAnnotation nextError = null;
+    Position nextErrorPosition = null;
+
+    IDocument document = getDocumentProvider().getDocument(getEditorInput());
+    int endOfDocument = document.getLength();
+    int distance = 0;
+
+    IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
+    Iterator e = new JavaAnnotationIterator(model, false);
+    while (e.hasNext()) {
+
+      IJavaAnnotation a = (IJavaAnnotation) e.next();
+      if (a.hasOverlay() || !a.isProblem())
+        continue;
+
+      Position p = model.getPosition((Annotation) a);
+      if (!p.includes(offset)) {
+
+        int currentDistance = 0;
+
+        if (forward) {
+          currentDistance = p.getOffset() - offset;
+          if (currentDistance < 0)
+            currentDistance = endOfDocument - offset + p.getOffset();
+        } else {
+          currentDistance = offset - p.getOffset();
+          if (currentDistance < 0)
+            currentDistance = offset + endOfDocument - p.getOffset();
+        }
+
+        if (nextError == null || currentDistance < distance) {
+          distance = currentDistance;
+          nextError = a;
+          nextErrorPosition = p;
+        }
+      }
+    }
+
+    if (nextErrorPosition != null) {
+      errorPosition.setOffset(nextErrorPosition.getOffset());
+      errorPosition.setLength(nextErrorPosition.getLength());
+    }
+
+    return nextError;
+  }
 }