1 package net.sourceforge.phpeclipse.phpeditor;
 
   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
 
  11  IBM Corporation - Initial implementation
 
  13  **********************************************************************/
 
  14 import java.lang.reflect.InvocationTargetException;
 
  15 import java.lang.reflect.Method;
 
  16 import java.text.BreakIterator;
 
  17 import java.text.CharacterIterator;
 
  18 import java.util.ArrayList;
 
  19 import java.util.HashMap;
 
  20 import java.util.Iterator;
 
  21 import java.util.List;
 
  23 import java.util.ResourceBundle;
 
  24 import java.util.StringTokenizer;
 
  26 import net.sourceforge.phpdt.core.ICompilationUnit;
 
  27 import net.sourceforge.phpdt.core.IImportContainer;
 
  28 import net.sourceforge.phpdt.core.IImportDeclaration;
 
  29 import net.sourceforge.phpdt.core.IJavaElement;
 
  30 import net.sourceforge.phpdt.core.IJavaProject;
 
  31 import net.sourceforge.phpdt.core.IMember;
 
  32 import net.sourceforge.phpdt.core.ISourceRange;
 
  33 import net.sourceforge.phpdt.core.ISourceReference;
 
  34 import net.sourceforge.phpdt.core.JavaCore;
 
  35 import net.sourceforge.phpdt.core.JavaModelException;
 
  36 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
 
  37 import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup;
 
  38 import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup;
 
  39 import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter;
 
  40 import net.sourceforge.phpdt.internal.ui.text.CustomSourceInformationControl;
 
  41 import net.sourceforge.phpdt.internal.ui.text.DocumentCharacterIterator;
 
  42 import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter;
 
  43 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
 
  44 import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator;
 
  45 import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher;
 
  46 import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter;
 
  47 import net.sourceforge.phpdt.internal.ui.text.java.JavaExpandHover;
 
  48 import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider;
 
  49 import net.sourceforge.phpdt.ui.IContextMenuConstants;
 
  50 import net.sourceforge.phpdt.ui.JavaUI;
 
  51 import net.sourceforge.phpdt.ui.PreferenceConstants;
 
  52 import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction;
 
  53 import net.sourceforge.phpdt.ui.actions.OpenEditorActionGroup;
 
  54 import net.sourceforge.phpdt.ui.text.JavaTextTools;
 
  55 import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration;
 
  56 import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider;
 
  57 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
  59 import org.eclipse.core.resources.IMarker;
 
  60 import org.eclipse.core.resources.IResource;
 
  61 import org.eclipse.core.runtime.CoreException;
 
  62 import org.eclipse.core.runtime.IProgressMonitor;
 
  63 import org.eclipse.core.runtime.IStatus;
 
  64 import org.eclipse.core.runtime.Preferences;
 
  65 import org.eclipse.core.runtime.Status;
 
  66 import org.eclipse.core.runtime.jobs.Job;
 
  67 import org.eclipse.jface.action.Action;
 
  68 import org.eclipse.jface.action.GroupMarker;
 
  69 import org.eclipse.jface.action.IAction;
 
  70 import org.eclipse.jface.action.MenuManager;
 
  71 import org.eclipse.jface.action.Separator;
 
  72 import org.eclipse.jface.preference.IPreferenceStore;
 
  73 import org.eclipse.jface.preference.PreferenceConverter;
 
  74 import org.eclipse.jface.text.BadLocationException;
 
  75 import org.eclipse.jface.text.DefaultInformationControl;
 
  76 import org.eclipse.jface.text.DocumentEvent;
 
  77 import org.eclipse.jface.text.IDocument;
 
  78 import org.eclipse.jface.text.IDocumentListener;
 
  79 import org.eclipse.jface.text.IInformationControl;
 
  80 import org.eclipse.jface.text.IInformationControlCreator;
 
  81 import org.eclipse.jface.text.IRegion;
 
  82 import org.eclipse.jface.text.ISynchronizable;
 
  83 import org.eclipse.jface.text.ITextHover;
 
  84 import org.eclipse.jface.text.ITextInputListener;
 
  85 import org.eclipse.jface.text.ITextPresentationListener;
 
  86 import org.eclipse.jface.text.ITextSelection;
 
  87 import org.eclipse.jface.text.ITextViewer;
 
  88 import org.eclipse.jface.text.ITextViewerExtension2;
 
  89 import org.eclipse.jface.text.ITextViewerExtension3;
 
  90 import org.eclipse.jface.text.ITextViewerExtension4;
 
  91 import org.eclipse.jface.text.ITextViewerExtension5;
 
  92 import org.eclipse.jface.text.ITypedRegion;
 
  93 import org.eclipse.jface.text.Position;
 
  94 import org.eclipse.jface.text.Region;
 
  95 import org.eclipse.jface.text.TextPresentation;
 
  96 import org.eclipse.jface.text.TextSelection;
 
  97 import org.eclipse.jface.text.TextUtilities;
 
  98 import org.eclipse.jface.text.information.IInformationProvider;
 
  99 import org.eclipse.jface.text.information.InformationPresenter;
 
 100 import org.eclipse.jface.text.reconciler.IReconciler;
 
 101 import org.eclipse.jface.text.source.Annotation;
 
 102 import org.eclipse.jface.text.source.AnnotationRulerColumn;
 
 103 import org.eclipse.jface.text.source.CompositeRuler;
 
 104 import org.eclipse.jface.text.source.IAnnotationModel;
 
 105 import org.eclipse.jface.text.source.IAnnotationModelExtension;
 
 106 import org.eclipse.jface.text.source.IOverviewRuler;
 
 107 import org.eclipse.jface.text.source.ISourceViewer;
 
 108 import org.eclipse.jface.text.source.ISourceViewerExtension2;
 
 109 import org.eclipse.jface.text.source.IVerticalRuler;
 
 110 import org.eclipse.jface.text.source.OverviewRuler;
 
 111 import org.eclipse.jface.text.source.SourceViewerConfiguration;
 
 112 import org.eclipse.jface.text.source.projection.ProjectionSupport;
 
 113 import org.eclipse.jface.text.source.projection.ProjectionViewer;
 
 114 import org.eclipse.jface.util.IPropertyChangeListener;
 
 115 import org.eclipse.jface.util.ListenerList;
 
 116 import org.eclipse.jface.util.PropertyChangeEvent;
 
 117 import org.eclipse.jface.viewers.DoubleClickEvent;
 
 118 import org.eclipse.jface.viewers.IDoubleClickListener;
 
 119 import org.eclipse.jface.viewers.IPostSelectionProvider;
 
 120 import org.eclipse.jface.viewers.ISelection;
 
 121 import org.eclipse.jface.viewers.ISelectionChangedListener;
 
 122 import org.eclipse.jface.viewers.ISelectionProvider;
 
 123 import org.eclipse.jface.viewers.IStructuredSelection;
 
 124 import org.eclipse.jface.viewers.SelectionChangedEvent;
 
 125 import org.eclipse.jface.viewers.StructuredSelection;
 
 126 import org.eclipse.swt.SWT;
 
 127 import org.eclipse.swt.custom.BidiSegmentEvent;
 
 128 import org.eclipse.swt.custom.BidiSegmentListener;
 
 129 import org.eclipse.swt.custom.ST;
 
 130 import org.eclipse.swt.custom.StyleRange;
 
 131 import org.eclipse.swt.custom.StyledText;
 
 132 import org.eclipse.swt.events.FocusEvent;
 
 133 import org.eclipse.swt.events.FocusListener;
 
 134 import org.eclipse.swt.events.KeyEvent;
 
 135 import org.eclipse.swt.events.KeyListener;
 
 136 import org.eclipse.swt.events.MouseEvent;
 
 137 import org.eclipse.swt.events.MouseListener;
 
 138 import org.eclipse.swt.events.MouseMoveListener;
 
 139 import org.eclipse.swt.events.PaintEvent;
 
 140 import org.eclipse.swt.events.PaintListener;
 
 141 import org.eclipse.swt.graphics.Color;
 
 142 import org.eclipse.swt.graphics.Cursor;
 
 143 import org.eclipse.swt.graphics.GC;
 
 144 import org.eclipse.swt.graphics.Image;
 
 145 import org.eclipse.swt.graphics.Point;
 
 146 import org.eclipse.swt.graphics.RGB;
 
 147 import org.eclipse.swt.widgets.Composite;
 
 148 import org.eclipse.swt.widgets.Control;
 
 149 import org.eclipse.swt.widgets.Display;
 
 150 import org.eclipse.swt.widgets.Shell;
 
 151 import org.eclipse.ui.IEditorInput;
 
 152 import org.eclipse.ui.IPageLayout;
 
 153 import org.eclipse.ui.IPartService;
 
 154 import org.eclipse.ui.ISelectionListener;
 
 155 import org.eclipse.ui.IViewPart;
 
 156 import org.eclipse.ui.IWorkbenchPage;
 
 157 import org.eclipse.ui.IWorkbenchPart;
 
 158 import org.eclipse.ui.IWorkbenchWindow;
 
 159 import org.eclipse.ui.actions.ActionContext;
 
 160 import org.eclipse.ui.actions.ActionGroup;
 
 161 import org.eclipse.ui.editors.text.DefaultEncodingSupport;
 
 162 import org.eclipse.ui.editors.text.EditorsUI;
 
 163 import org.eclipse.ui.editors.text.IEncodingSupport;
 
 164 import org.eclipse.ui.part.IShowInTargetList;
 
 165 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
 
 166 import org.eclipse.ui.texteditor.AnnotationPreference;
 
 167 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
 
 168 import org.eclipse.ui.texteditor.IDocumentProvider;
 
 169 import org.eclipse.ui.texteditor.IEditorStatusLine;
 
 170 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 
 171 import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
 
 172 import org.eclipse.ui.texteditor.IUpdate;
 
 173 import org.eclipse.ui.texteditor.MarkerAnnotation;
 
 174 import org.eclipse.ui.texteditor.ResourceAction;
 
 175 import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
 
 176 import org.eclipse.ui.texteditor.TextEditorAction;
 
 177 import org.eclipse.ui.texteditor.TextNavigationAction;
 
 178 import org.eclipse.ui.texteditor.TextOperationAction;
 
 179 import org.eclipse.ui.views.contentoutline.ContentOutline;
 
 180 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 
 181 import org.eclipse.ui.views.tasklist.TaskList;
 
 184  * PHP specific text editor.
 
 186 public abstract class PHPEditor extends AbstractDecoratedTextEditor implements IViewPartInputProvider {
 
 187   //extends StatusTextEditor implements IViewPartInputProvider { // extends
 
 191    * Internal implementation class for a change listener.
 
 195   protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener {
 
 198      * Installs this selection changed listener with the given selection provider. If the selection provider is a post selection
 
 199      * provider, post selection changed events are the preferred choice, otherwise normal selection changed events are requested.
 
 201      * @param selectionProvider
 
 203     public void install(ISelectionProvider selectionProvider) {
 
 204       if (selectionProvider == null)
 
 207       if (selectionProvider instanceof IPostSelectionProvider) {
 
 208         IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
 
 209         provider.addPostSelectionChangedListener(this);
 
 211         selectionProvider.addSelectionChangedListener(this);
 
 216      * Removes this selection changed listener from the given selection provider.
 
 218      * @param selectionProvider
 
 219      *          the selection provider
 
 221     public void uninstall(ISelectionProvider selectionProvider) {
 
 222       if (selectionProvider == null)
 
 225       if (selectionProvider instanceof IPostSelectionProvider) {
 
 226         IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
 
 227         provider.removePostSelectionChangedListener(this);
 
 229         selectionProvider.removeSelectionChangedListener(this);
 
 235    * Updates the Java outline page selection and this editor's range indicator.
 
 239   private class EditorSelectionChangedListener extends AbstractSelectionChangedListener {
 
 242      * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
 
 244     public void selectionChanged(SelectionChangedEvent event) {
 
 245       // XXX: see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56161
 
 246       PHPEditor.this.selectionChanged();
 
 251    * "Smart" runnable for updating the outline page's selection.
 
 253   //  class OutlinePageSelectionUpdater implements Runnable {
 
 255   //    /** Has the runnable already been posted? */
 
 256   //    private boolean fPosted = false;
 
 258   //    public OutlinePageSelectionUpdater() {
 
 262   //     * @see Runnable#run()
 
 264   //    public void run() {
 
 265   //      synchronizeOutlinePageSelection();
 
 270   //     * Posts this runnable into the event queue.
 
 272   //    public void post() {
 
 276   //      Shell shell = getSite().getShell();
 
 277   //      if (shell != null & !shell.isDisposed()) {
 
 279   //        shell.getDisplay().asyncExec(this);
 
 283   class SelectionChangedListener implements ISelectionChangedListener {
 
 284     public void selectionChanged(SelectionChangedEvent event) {
 
 285       doSelectionChanged(event);
 
 290    * Adapts an options {@link java.util.Map}to {@link org.eclipse.jface.preference.IPreferenceStore}.
 
 292    * This preference store is read-only i.e. write access throws an {@link java.lang.UnsupportedOperationException}.
 
 297   private static class OptionsAdapter implements IPreferenceStore {
 
 300      * A property change event filter.
 
 302     public interface IPropertyChangeEventFilter {
 
 305        * Should the given event be filtered?
 
 308        *          The property change event.
 
 309        * @return <code>true</code> iff the given event should be filtered.
 
 311       public boolean isFiltered(PropertyChangeEvent event);
 
 316      * Property change listener. Listens for events in the options Map and fires a
 
 317      * {@link org.eclipse.jface.util.PropertyChangeEvent}on this adapter with arguments from the received event.
 
 319     private class PropertyChangeListener implements IPropertyChangeListener {
 
 324       public void propertyChange(PropertyChangeEvent event) {
 
 325         if (getFilter().isFiltered(event))
 
 328         if (event.getNewValue() == null)
 
 329           fOptions.remove(event.getProperty());
 
 331           fOptions.put(event.getProperty(), event.getNewValue());
 
 333         firePropertyChangeEvent(event.getProperty(), event.getOldValue(), event.getNewValue());
 
 337     /** Listeners on this adapter */
 
 338     private ListenerList fListeners = new ListenerList();
 
 340     /** Listener on the adapted options Map */
 
 341     private IPropertyChangeListener fListener = new PropertyChangeListener();
 
 343     /** Adapted options Map */
 
 344     private Map fOptions;
 
 346     /** Preference store through which events are received. */
 
 347     private IPreferenceStore fMockupPreferenceStore;
 
 349     /** Property event filter. */
 
 350     private IPropertyChangeEventFilter fFilter;
 
 353      * Initialize with the given options.
 
 356      *          The options to wrap
 
 357      * @param mockupPreferenceStore
 
 358      *          the mock-up preference store
 
 360      *          the property change filter
 
 362     public OptionsAdapter(Map options, IPreferenceStore mockupPreferenceStore, IPropertyChangeEventFilter filter) {
 
 363       fMockupPreferenceStore = mockupPreferenceStore;
 
 371     public void addPropertyChangeListener(IPropertyChangeListener listener) {
 
 372       if (fListeners.size() == 0)
 
 373         fMockupPreferenceStore.addPropertyChangeListener(fListener);
 
 374       fListeners.add(listener);
 
 380     public void removePropertyChangeListener(IPropertyChangeListener listener) {
 
 381       fListeners.remove(listener);
 
 382       if (fListeners.size() == 0)
 
 383         fMockupPreferenceStore.removePropertyChangeListener(fListener);
 
 389     public boolean contains(String name) {
 
 390       return fOptions.containsKey(name);
 
 396     public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
 
 397       PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
 
 398       Object[] listeners = fListeners.getListeners();
 
 399       for (int i = 0; i < listeners.length; i++)
 
 400         ((IPropertyChangeListener) listeners[i]).propertyChange(event);
 
 406     public boolean getBoolean(String name) {
 
 407       boolean value = BOOLEAN_DEFAULT_DEFAULT;
 
 408       String s = (String) fOptions.get(name);
 
 410         value = s.equals(TRUE);
 
 417     public boolean getDefaultBoolean(String name) {
 
 418       return BOOLEAN_DEFAULT_DEFAULT;
 
 424     public double getDefaultDouble(String name) {
 
 425       return DOUBLE_DEFAULT_DEFAULT;
 
 431     public float getDefaultFloat(String name) {
 
 432       return FLOAT_DEFAULT_DEFAULT;
 
 438     public int getDefaultInt(String name) {
 
 439       return INT_DEFAULT_DEFAULT;
 
 445     public long getDefaultLong(String name) {
 
 446       return LONG_DEFAULT_DEFAULT;
 
 452     public String getDefaultString(String name) {
 
 453       return STRING_DEFAULT_DEFAULT;
 
 459     public double getDouble(String name) {
 
 460       double value = DOUBLE_DEFAULT_DEFAULT;
 
 461       String s = (String) fOptions.get(name);
 
 464           value = new Double(s).doubleValue();
 
 465         } catch (NumberFormatException e) {
 
 474     public float getFloat(String name) {
 
 475       float value = FLOAT_DEFAULT_DEFAULT;
 
 476       String s = (String) fOptions.get(name);
 
 479           value = new Float(s).floatValue();
 
 480         } catch (NumberFormatException e) {
 
 489     public int getInt(String name) {
 
 490       int value = INT_DEFAULT_DEFAULT;
 
 491       String s = (String) fOptions.get(name);
 
 494           value = new Integer(s).intValue();
 
 495         } catch (NumberFormatException e) {
 
 504     public long getLong(String name) {
 
 505       long value = LONG_DEFAULT_DEFAULT;
 
 506       String s = (String) fOptions.get(name);
 
 509           value = new Long(s).longValue();
 
 510         } catch (NumberFormatException e) {
 
 519     public String getString(String name) {
 
 520       String value = (String) fOptions.get(name);
 
 522         value = STRING_DEFAULT_DEFAULT;
 
 529     public boolean isDefault(String name) {
 
 536     public boolean needsSaving() {
 
 537       return !fOptions.isEmpty();
 
 543     public void putValue(String name, String value) {
 
 544       throw new UnsupportedOperationException();
 
 550     public void setDefault(String name, double value) {
 
 551       throw new UnsupportedOperationException();
 
 557     public void setDefault(String name, float value) {
 
 558       throw new UnsupportedOperationException();
 
 564     public void setDefault(String name, int value) {
 
 565       throw new UnsupportedOperationException();
 
 571     public void setDefault(String name, long value) {
 
 572       throw new UnsupportedOperationException();
 
 578     public void setDefault(String name, String defaultObject) {
 
 579       throw new UnsupportedOperationException();
 
 585     public void setDefault(String name, boolean value) {
 
 586       throw new UnsupportedOperationException();
 
 592     public void setToDefault(String name) {
 
 593       throw new UnsupportedOperationException();
 
 599     public void setValue(String name, double value) {
 
 600       throw new UnsupportedOperationException();
 
 606     public void setValue(String name, float value) {
 
 607       throw new UnsupportedOperationException();
 
 613     public void setValue(String name, int value) {
 
 614       throw new UnsupportedOperationException();
 
 620     public void setValue(String name, long value) {
 
 621       throw new UnsupportedOperationException();
 
 627     public void setValue(String name, String value) {
 
 628       throw new UnsupportedOperationException();
 
 634     public void setValue(String name, boolean value) {
 
 635       throw new UnsupportedOperationException();
 
 639      * Returns the adapted options Map.
 
 641      * @return Returns the adapted options Map.
 
 643     public Map getOptions() {
 
 648      * Returns the mock-up preference store, events are received through this preference store.
 
 650      * @return Returns the mock-up preference store.
 
 652     public IPreferenceStore getMockupPreferenceStore() {
 
 653       return fMockupPreferenceStore;
 
 657      * Set the event filter to the given filter.
 
 662     public void setFilter(IPropertyChangeEventFilter filter) {
 
 667      * Returns the event filter.
 
 669      * @return The event filter.
 
 671     public IPropertyChangeEventFilter getFilter() {
 
 679   //  class MouseClickListener implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener,
 
 680   //      IPropertyChangeListener, IDocumentListener, ITextInputListener {
 
 682   //    /** The session is active. */
 
 683   //    private boolean fActive;
 
 685   //    /** The currently active style range. */
 
 686   //    private IRegion fActiveRegion;
 
 688   //    /** The currently active style range as position. */
 
 689   //    private Position fRememberedPosition;
 
 691   //    /** The hand cursor. */
 
 692   //    private Cursor fCursor;
 
 694   //    /** The link color. */
 
 695   //    private Color fColor;
 
 697   //    /** The key modifier mask. */
 
 698   //    private int fKeyModifierMask;
 
 700   //    public void deactivate() {
 
 701   //      deactivate(false);
 
 704   //    public void deactivate(boolean redrawAll) {
 
 708   //      repairRepresentation(redrawAll);
 
 712   //    public void install() {
 
 714   //      ISourceViewer sourceViewer = getSourceViewer();
 
 715   //      if (sourceViewer == null)
 
 718   //      StyledText text = sourceViewer.getTextWidget();
 
 719   //      if (text == null || text.isDisposed())
 
 722   //      updateColor(sourceViewer);
 
 724   //      sourceViewer.addTextInputListener(this);
 
 726   //      IDocument document = sourceViewer.getDocument();
 
 727   //      if (document != null)
 
 728   //        document.addDocumentListener(this);
 
 730   //      text.addKeyListener(this);
 
 731   //      text.addMouseListener(this);
 
 732   //      text.addMouseMoveListener(this);
 
 733   //      text.addFocusListener(this);
 
 734   //      text.addPaintListener(this);
 
 736   //      updateKeyModifierMask();
 
 738   //      IPreferenceStore preferenceStore = getPreferenceStore();
 
 739   //      preferenceStore.addPropertyChangeListener(this);
 
 742   //    private void updateKeyModifierMask() {
 
 743   //      String modifiers = getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER);
 
 744   //      fKeyModifierMask = computeStateMask(modifiers);
 
 745   //      if (fKeyModifierMask == -1) {
 
 746   //        // Fallback to stored state mask
 
 747   //        fKeyModifierMask = getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
 
 752   //    private int computeStateMask(String modifiers) {
 
 753   //      if (modifiers == null)
 
 756   //      if (modifiers.length() == 0)
 
 759   //      int stateMask = 0;
 
 760   //      StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
 
 761   //      while (modifierTokenizer.hasMoreTokens()) {
 
 762   //        int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
 
 763   //        if (modifier == 0 || (stateMask & modifier) == modifier)
 
 765   //        stateMask = stateMask | modifier;
 
 770   //    public void uninstall() {
 
 772   //      if (fColor != null) {
 
 777   //      if (fCursor != null) {
 
 778   //        fCursor.dispose();
 
 782   //      ISourceViewer sourceViewer = getSourceViewer();
 
 783   //      if (sourceViewer == null)
 
 786   //      sourceViewer.removeTextInputListener(this);
 
 788   //      IDocument document = sourceViewer.getDocument();
 
 789   //      if (document != null)
 
 790   //        document.removeDocumentListener(this);
 
 792   //      IPreferenceStore preferenceStore = getPreferenceStore();
 
 793   //      if (preferenceStore != null)
 
 794   //        preferenceStore.removePropertyChangeListener(this);
 
 796   //      StyledText text = sourceViewer.getTextWidget();
 
 797   //      if (text == null || text.isDisposed())
 
 800   //      text.removeKeyListener(this);
 
 801   //      text.removeMouseListener(this);
 
 802   //      text.removeMouseMoveListener(this);
 
 803   //      text.removeFocusListener(this);
 
 804   //      text.removePaintListener(this);
 
 808   //     * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
 
 810   //    public void propertyChange(PropertyChangeEvent event) {
 
 811   //      if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
 
 812   //        ISourceViewer viewer = getSourceViewer();
 
 813   //        if (viewer != null)
 
 814   //          updateColor(viewer);
 
 815   //      } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
 
 816   //        updateKeyModifierMask();
 
 820   //    private void updateColor(ISourceViewer viewer) {
 
 821   //      if (fColor != null)
 
 824   //      StyledText text = viewer.getTextWidget();
 
 825   //      if (text == null || text.isDisposed())
 
 828   //      Display display = text.getDisplay();
 
 829   //      fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR, display);
 
 833   //     * Creates a color from the information stored in the given preference store. Returns <code>null</code> if there is no such
 
 834   //     * information available.
 
 836   //    private Color createColor(IPreferenceStore store, String key, Display display) {
 
 840   //      if (store.contains(key)) {
 
 842   //        if (store.isDefault(key))
 
 843   //          rgb = PreferenceConverter.getDefaultColor(store, key);
 
 845   //          rgb = PreferenceConverter.getColor(store, key);
 
 848   //          return new Color(display, rgb);
 
 854   //    private void repairRepresentation() {
 
 855   //      repairRepresentation(false);
 
 858   //    private void repairRepresentation(boolean redrawAll) {
 
 860   //      if (fActiveRegion == null)
 
 863   //      ISourceViewer viewer = getSourceViewer();
 
 864   //      if (viewer != null) {
 
 865   //        resetCursor(viewer);
 
 867   //        int offset = fActiveRegion.getOffset();
 
 868   //        int length = fActiveRegion.getLength();
 
 871   //        if (!redrawAll && viewer instanceof ITextViewerExtension2)
 
 872   //          ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length);
 
 874   //          viewer.invalidateTextPresentation();
 
 876   //        // remove underline
 
 877   //        if (viewer instanceof ITextViewerExtension3) {
 
 878   //          ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
 
 879   //          offset = extension.modelOffset2WidgetOffset(offset);
 
 881   //          offset -= viewer.getVisibleRegion().getOffset();
 
 884   //        StyledText text = viewer.getTextWidget();
 
 886   //          text.redrawRange(offset, length, true);
 
 887   //        } catch (IllegalArgumentException x) {
 
 888   //          PHPeclipsePlugin.log(x);
 
 892   //      fActiveRegion = null;
 
 895   //    // will eventually be replaced by a method provided by jdt.core
 
 896   //    private IRegion selectWord(IDocument document, int anchor) {
 
 899   //        int offset = anchor;
 
 902   //        while (offset >= 0) {
 
 903   //          c = document.getChar(offset);
 
 904   //          if (!Scanner.isPHPIdentifierPart(c))
 
 909   //        int start = offset;
 
 912   //        int length = document.getLength();
 
 914   //        while (offset < length) {
 
 915   //          c = document.getChar(offset);
 
 916   //          if (!Scanner.isPHPIdentifierPart(c))
 
 924   //          return new Region(start, 0);
 
 926   //          return new Region(start + 1, end - start - 1);
 
 928   //      } catch (BadLocationException x) {
 
 933   //    IRegion getCurrentTextRegion(ISourceViewer viewer) {
 
 935   //      int offset = getCurrentTextOffset(viewer);
 
 940   //      // IJavaElement input= SelectionConverter.getInput(PHPEditor.this);
 
 941   //      // if (input == null)
 
 946   //      // IJavaElement[] elements= null;
 
 947   //      // synchronized (input) {
 
 948   //      // elements= ((ICodeAssist) input).codeSelect(offset, 0);
 
 951   //      // if (elements == null || elements.length == 0)
 
 954   //      // return selectWord(viewer.getDocument(), offset);
 
 956   //      // } catch (JavaModelException e) {
 
 961   //    private int getCurrentTextOffset(ISourceViewer viewer) {
 
 964   //        StyledText text = viewer.getTextWidget();
 
 965   //        if (text == null || text.isDisposed())
 
 968   //        Display display = text.getDisplay();
 
 969   //        Point absolutePosition = display.getCursorLocation();
 
 970   //        Point relativePosition = text.toControl(absolutePosition);
 
 972   //        int widgetOffset = text.getOffsetAtLocation(relativePosition);
 
 973   //        if (viewer instanceof ITextViewerExtension3) {
 
 974   //          ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
 
 975   //          return extension.widgetOffset2ModelOffset(widgetOffset);
 
 977   //          return widgetOffset + viewer.getVisibleRegion().getOffset();
 
 980   //      } catch (IllegalArgumentException e) {
 
 985   //    private void highlightRegion(ISourceViewer viewer, IRegion region) {
 
 987   //      if (region.equals(fActiveRegion))
 
 990   //      repairRepresentation();
 
 992   //      StyledText text = viewer.getTextWidget();
 
 993   //      if (text == null || text.isDisposed())
 
 996   //      // highlight region
 
1000   //      if (viewer instanceof ITextViewerExtension3) {
 
1001   //        ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
 
1002   //        IRegion widgetRange = extension.modelRange2WidgetRange(region);
 
1003   //        if (widgetRange == null)
 
1006   //        offset = widgetRange.getOffset();
 
1007   //        length = widgetRange.getLength();
 
1010   //        offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
 
1011   //        length = region.getLength();
 
1014   //      StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset);
 
1015   //      Color foregroundColor = fColor;
 
1016   //      Color backgroundColor = oldStyleRange == null ? text.getBackground() : oldStyleRange.background;
 
1017   //      StyleRange styleRange = new StyleRange(offset, length, foregroundColor, backgroundColor);
 
1018   //      text.setStyleRange(styleRange);
 
1021   //      text.redrawRange(offset, length, true);
 
1023   //      fActiveRegion = region;
 
1026   //    private void activateCursor(ISourceViewer viewer) {
 
1027   //      StyledText text = viewer.getTextWidget();
 
1028   //      if (text == null || text.isDisposed())
 
1030   //      Display display = text.getDisplay();
 
1031   //      if (fCursor == null)
 
1032   //        fCursor = new Cursor(display, SWT.CURSOR_HAND);
 
1033   //      text.setCursor(fCursor);
 
1036   //    private void resetCursor(ISourceViewer viewer) {
 
1037   //      StyledText text = viewer.getTextWidget();
 
1038   //      if (text != null && !text.isDisposed())
 
1039   //        text.setCursor(null);
 
1041   //      if (fCursor != null) {
 
1042   //        fCursor.dispose();
 
1048   //     * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
 
1050   //    public void keyPressed(KeyEvent event) {
 
1057   //      if (event.keyCode != fKeyModifierMask) {
 
1064   //      // removed for #25871
 
1066   //      // ISourceViewer viewer= getSourceViewer();
 
1067   //      // if (viewer == null)
 
1070   //      // IRegion region= getCurrentTextRegion(viewer);
 
1071   //      // if (region == null)
 
1074   //      // highlightRegion(viewer, region);
 
1075   //      // activateCursor(viewer);
 
1079   //     * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
 
1081   //    public void keyReleased(KeyEvent event) {
 
1090   //     * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
 
1092   //    public void mouseDoubleClick(MouseEvent e) {
 
1096   //     * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
 
1098   //    public void mouseDown(MouseEvent event) {
 
1103   //      if (event.stateMask != fKeyModifierMask) {
 
1108   //      if (event.button != 1) {
 
1115   //     * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
 
1117   //    public void mouseUp(MouseEvent e) {
 
1122   //      if (e.button != 1) {
 
1127   //      boolean wasActive = fCursor != null;
 
1132   //        IAction action = getAction("OpenEditor"); //$NON-NLS-1$
 
1133   //        if (action != null)
 
1139   //     * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
 
1141   //    public void mouseMove(MouseEvent event) {
 
1143   //      if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
 
1149   //        if (event.stateMask != fKeyModifierMask)
 
1151   //        // modifier was already pressed
 
1155   //      ISourceViewer viewer = getSourceViewer();
 
1156   //      if (viewer == null) {
 
1161   //      StyledText text = viewer.getTextWidget();
 
1162   //      if (text == null || text.isDisposed()) {
 
1167   //      if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
 
1172   //      IRegion region = getCurrentTextRegion(viewer);
 
1173   //      if (region == null || region.getLength() == 0) {
 
1174   //        repairRepresentation();
 
1178   //      highlightRegion(viewer, region);
 
1179   //      activateCursor(viewer);
 
1183   //     * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
 
1185   //    public void focusGained(FocusEvent e) {
 
1189   //     * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
 
1191   //    public void focusLost(FocusEvent event) {
 
1196   //     * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
 
1198   //    public void documentAboutToBeChanged(DocumentEvent event) {
 
1199   //      if (fActive && fActiveRegion != null) {
 
1200   //        fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
 
1202   //          event.getDocument().addPosition(fRememberedPosition);
 
1203   //        } catch (BadLocationException x) {
 
1204   //          fRememberedPosition = null;
 
1210   //     * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
 
1212   //    public void documentChanged(DocumentEvent event) {
 
1213   //      if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) {
 
1214   //        event.getDocument().removePosition(fRememberedPosition);
 
1215   //        fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
 
1217   //      fRememberedPosition = null;
 
1219   //      ISourceViewer viewer = getSourceViewer();
 
1220   //      if (viewer != null) {
 
1221   //        StyledText widget = viewer.getTextWidget();
 
1222   //        if (widget != null && !widget.isDisposed()) {
 
1223   //          widget.getDisplay().asyncExec(new Runnable() {
 
1224   //            public void run() {
 
1233   //     * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
 
1234   //     * org.eclipse.jface.text.IDocument)
 
1236   //    public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
 
1237   //      if (oldInput == null)
 
1240   //      oldInput.removeDocumentListener(this);
 
1244   //     * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
 
1245   //     * org.eclipse.jface.text.IDocument)
 
1247   //    public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
 
1248   //      if (newInput == null)
 
1250   //      newInput.addDocumentListener(this);
 
1254   //     * @see PaintListener#paintControl(PaintEvent)
 
1256   //    public void paintControl(PaintEvent event) {
 
1257   //      if (fActiveRegion == null)
 
1260   //      ISourceViewer viewer = getSourceViewer();
 
1261   //      if (viewer == null)
 
1264   //      StyledText text = viewer.getTextWidget();
 
1265   //      if (text == null || text.isDisposed())
 
1271   //      if (viewer instanceof ITextViewerExtension3) {
 
1273   //        ITextViewerExtension3 extension = (ITextViewerExtension3) viewer;
 
1274   //        IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset, length));
 
1275   //        if (widgetRange == null)
 
1278   //        offset = widgetRange.getOffset();
 
1279   //        length = widgetRange.getLength();
 
1283   //        IRegion region = viewer.getVisibleRegion();
 
1284   //        if (!includes(region, fActiveRegion))
 
1287   //        offset = fActiveRegion.getOffset() - region.getOffset();
 
1288   //        length = fActiveRegion.getLength();
 
1291   //      // support for bidi
 
1292   //      Point minLocation = getMinimumLocation(text, offset, length);
 
1293   //      Point maxLocation = getMaximumLocation(text, offset, length);
 
1295   //      int x1 = minLocation.x;
 
1296   //      int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
 
1297   //      int y = minLocation.y + text.getLineHeight() - 1;
 
1299   //      GC gc = event.gc;
 
1300   //      if (fColor != null && !fColor.isDisposed())
 
1301   //        gc.setForeground(fColor);
 
1302   //      gc.drawLine(x1, y, x2, y);
 
1305   //    private boolean includes(IRegion region, IRegion position) {
 
1306   //      return position.getOffset() >= region.getOffset()
 
1307   //          && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
 
1310   //    private Point getMinimumLocation(StyledText text, int offset, int length) {
 
1311   //      Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
 
1313   //      for (int i = 0; i <= length; i++) {
 
1314   //        Point location = text.getLocationAtOffset(offset + i);
 
1316   //        if (location.x < minLocation.x)
 
1317   //          minLocation.x = location.x;
 
1318   //        if (location.y < minLocation.y)
 
1319   //          minLocation.y = location.y;
 
1322   //      return minLocation;
 
1325   //    private Point getMaximumLocation(StyledText text, int offset, int length) {
 
1326   //      Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
 
1328   //      for (int i = 0; i <= length; i++) {
 
1329   //        Point location = text.getLocationAtOffset(offset + i);
 
1331   //        if (location.x > maxLocation.x)
 
1332   //          maxLocation.x = location.x;
 
1333   //        if (location.y > maxLocation.y)
 
1334   //          maxLocation.y = location.y;
 
1337   //      return maxLocation;
 
1343   class MouseClickListener implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener,
 
1344       IPropertyChangeListener, IDocumentListener, ITextInputListener, ITextPresentationListener {
 
1346     /** The session is active. */
 
1347     private boolean fActive;
 
1349     /** The currently active style range. */
 
1350     private IRegion fActiveRegion;
 
1352     /** The currently active style range as position. */
 
1353     private Position fRememberedPosition;
 
1355     /** The hand cursor. */
 
1356     private Cursor fCursor;
 
1358     /** The link color. */
 
1359     private Color fColor;
 
1361     /** The key modifier mask. */
 
1362     private int fKeyModifierMask;
 
1364     public void deactivate() {
 
1368     public void deactivate(boolean redrawAll) {
 
1372       repairRepresentation(redrawAll);
 
1376     public void install() {
 
1377       ISourceViewer sourceViewer = getSourceViewer();
 
1378       if (sourceViewer == null)
 
1381       StyledText text = sourceViewer.getTextWidget();
 
1382       if (text == null || text.isDisposed())
 
1385       updateColor(sourceViewer);
 
1387       sourceViewer.addTextInputListener(this);
 
1389       IDocument document = sourceViewer.getDocument();
 
1390       if (document != null)
 
1391         document.addDocumentListener(this);
 
1393       text.addKeyListener(this);
 
1394       text.addMouseListener(this);
 
1395       text.addMouseMoveListener(this);
 
1396       text.addFocusListener(this);
 
1397       text.addPaintListener(this);
 
1399       ((ITextViewerExtension4) sourceViewer).addTextPresentationListener(this);
 
1401       updateKeyModifierMask();
 
1403       IPreferenceStore preferenceStore = getPreferenceStore();
 
1404       preferenceStore.addPropertyChangeListener(this);
 
1407     private void updateKeyModifierMask() {
 
1408       String modifiers = getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER);
 
1409       fKeyModifierMask = computeStateMask(modifiers);
 
1410       if (fKeyModifierMask == -1) {
 
1411         // Fall back to stored state mask
 
1412         fKeyModifierMask = getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK);
 
1416     private int computeStateMask(String modifiers) {
 
1417       if (modifiers == null)
 
1420       if (modifiers.length() == 0)
 
1424       StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$
 
1425       while (modifierTokenizer.hasMoreTokens()) {
 
1426         int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken());
 
1427         if (modifier == 0 || (stateMask & modifier) == modifier)
 
1429         stateMask = stateMask | modifier;
 
1434     public void uninstall() {
 
1436       if (fColor != null) {
 
1441       if (fCursor != null) {
 
1446       ISourceViewer sourceViewer = getSourceViewer();
 
1447       if (sourceViewer != null)
 
1448         sourceViewer.removeTextInputListener(this);
 
1450       IDocumentProvider documentProvider = getDocumentProvider();
 
1451       if (documentProvider != null) {
 
1452         IDocument document = documentProvider.getDocument(getEditorInput());
 
1453         if (document != null)
 
1454           document.removeDocumentListener(this);
 
1457       IPreferenceStore preferenceStore = getPreferenceStore();
 
1458       if (preferenceStore != null)
 
1459         preferenceStore.removePropertyChangeListener(this);
 
1461       if (sourceViewer == null)
 
1464       StyledText text = sourceViewer.getTextWidget();
 
1465       if (text == null || text.isDisposed())
 
1468       text.removeKeyListener(this);
 
1469       text.removeMouseListener(this);
 
1470       text.removeMouseMoveListener(this);
 
1471       text.removeFocusListener(this);
 
1472       text.removePaintListener(this);
 
1474       ((ITextViewerExtension4) sourceViewer).removeTextPresentationListener(this);
 
1478      * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
 
1480     public void propertyChange(PropertyChangeEvent event) {
 
1481       if (event.getProperty().equals(PHPEditor.LINK_COLOR)) {
 
1482         ISourceViewer viewer = getSourceViewer();
 
1484           updateColor(viewer);
 
1485       } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) {
 
1486         updateKeyModifierMask();
 
1490     private void updateColor(ISourceViewer viewer) {
 
1494       StyledText text = viewer.getTextWidget();
 
1495       if (text == null || text.isDisposed())
 
1498       Display display = text.getDisplay();
 
1499       fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR, display);
 
1503      * Creates a color from the information stored in the given preference store.
 
1506      *          the preference store
 
1511      * @return the color or <code>null</code> if there is no such information available
 
1513     private Color createColor(IPreferenceStore store, String key, Display display) {
 
1517       if (store.contains(key)) {
 
1519         if (store.isDefault(key))
 
1520           rgb = PreferenceConverter.getDefaultColor(store, key);
 
1522           rgb = PreferenceConverter.getColor(store, key);
 
1525           return new Color(display, rgb);
 
1531     private void repairRepresentation() {
 
1532       repairRepresentation(false);
 
1535     private void repairRepresentation(boolean redrawAll) {
 
1537       if (fActiveRegion == null)
 
1540       int offset = fActiveRegion.getOffset();
 
1541       int length = fActiveRegion.getLength();
 
1542       fActiveRegion = null;
 
1544       ISourceViewer viewer = getSourceViewer();
 
1545       if (viewer != null) {
 
1547         resetCursor(viewer);
 
1549         // Invalidate ==> remove applied text presentation
 
1550         if (!redrawAll && viewer instanceof ITextViewerExtension2)
 
1551           ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length);
 
1553           viewer.invalidateTextPresentation();
 
1556         if (viewer instanceof ITextViewerExtension5) {
 
1557           ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
1558           offset = extension.modelOffset2WidgetOffset(offset);
 
1560           offset -= viewer.getVisibleRegion().getOffset();
 
1563           StyledText text = viewer.getTextWidget();
 
1565           text.redrawRange(offset, length, false);
 
1566         } catch (IllegalArgumentException x) {
 
1567           //                                    JavaPlugin.log(x);
 
1572     // will eventually be replaced by a method provided by jdt.core
 
1573     private IRegion selectWord(IDocument document, int anchor) {
 
1576         int offset = anchor;
 
1579         while (offset >= 0) {
 
1580           c = document.getChar(offset);
 
1581           if (!Scanner.isPHPIdentifierPart(c) && c != '$')
 
1589         int length = document.getLength();
 
1591         while (offset < length) {
 
1592           c = document.getChar(offset);
 
1593           if (!Scanner.isPHPIdentifierPart(c) && c != '$')
 
1601           return new Region(start, 0);
 
1603           return new Region(start + 1, end - start - 1);
 
1605       } catch (BadLocationException x) {
 
1610     IRegion getCurrentTextRegion(ISourceViewer viewer) {
 
1612       int offset = getCurrentTextOffset(viewer);
 
1616       IJavaElement input = SelectionConverter.getInput(PHPEditor.this);
 
1622       //                                IJavaElement[] elements= null;
 
1623       //                                synchronized (input) {
 
1624       //                                        elements= ((ICodeAssist) input).codeSelect(offset, 0);
 
1627       //                                if (elements == null || elements.length == 0)
 
1630       return selectWord(viewer.getDocument(), offset);
 
1632       //                        } catch (JavaModelException e) {
 
1637     private int getCurrentTextOffset(ISourceViewer viewer) {
 
1640         StyledText text = viewer.getTextWidget();
 
1641         if (text == null || text.isDisposed())
 
1644         Display display = text.getDisplay();
 
1645         Point absolutePosition = display.getCursorLocation();
 
1646         Point relativePosition = text.toControl(absolutePosition);
 
1648         int widgetOffset = text.getOffsetAtLocation(relativePosition);
 
1649         if (viewer instanceof ITextViewerExtension5) {
 
1650           ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
1651           return extension.widgetOffset2ModelOffset(widgetOffset);
 
1653           return widgetOffset + viewer.getVisibleRegion().getOffset();
 
1656       } catch (IllegalArgumentException e) {
 
1661     public void applyTextPresentation(TextPresentation textPresentation) {
 
1662       if (fActiveRegion == null)
 
1664       IRegion region = textPresentation.getExtent();
 
1665       if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region.getOffset()
 
1666           && region.getOffset() + region.getLength() > fActiveRegion.getOffset())
 
1667         textPresentation.mergeStyleRange(new StyleRange(fActiveRegion.getOffset(), fActiveRegion.getLength(), fColor, null));
 
1670     private void highlightRegion(ISourceViewer viewer, IRegion region) {
 
1672       if (region.equals(fActiveRegion))
 
1675       repairRepresentation();
 
1677       StyledText text = viewer.getTextWidget();
 
1678       if (text == null || text.isDisposed())
 
1684       if (viewer instanceof ITextViewerExtension5) {
 
1685         ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
1686         IRegion widgetRange = extension.modelRange2WidgetRange(region);
 
1687         if (widgetRange == null)
 
1690         offset = widgetRange.getOffset();
 
1691         length = widgetRange.getLength();
 
1694         offset = region.getOffset() - viewer.getVisibleRegion().getOffset();
 
1695         length = region.getLength();
 
1697       text.redrawRange(offset, length, false);
 
1699       // Invalidate region ==> apply text presentation
 
1700       fActiveRegion = region;
 
1701       if (viewer instanceof ITextViewerExtension2)
 
1702         ((ITextViewerExtension2) viewer).invalidateTextPresentation(region.getOffset(), region.getLength());
 
1704         viewer.invalidateTextPresentation();
 
1707     private void activateCursor(ISourceViewer viewer) {
 
1708       StyledText text = viewer.getTextWidget();
 
1709       if (text == null || text.isDisposed())
 
1711       Display display = text.getDisplay();
 
1712       if (fCursor == null)
 
1713         fCursor = new Cursor(display, SWT.CURSOR_HAND);
 
1714       text.setCursor(fCursor);
 
1717     private void resetCursor(ISourceViewer viewer) {
 
1718       StyledText text = viewer.getTextWidget();
 
1719       if (text != null && !text.isDisposed())
 
1720         text.setCursor(null);
 
1722       if (fCursor != null) {
 
1729      * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
 
1731     public void keyPressed(KeyEvent event) {
 
1738       if (event.keyCode != fKeyModifierMask) {
 
1745       //                        removed for #25871
 
1747       //                        ISourceViewer viewer= getSourceViewer();
 
1748       //                        if (viewer == null)
 
1751       //                        IRegion region= getCurrentTextRegion(viewer);
 
1752       //                        if (region == null)
 
1755       //                        highlightRegion(viewer, region);
 
1756       //                        activateCursor(viewer);
 
1760      * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
 
1762     public void keyReleased(KeyEvent event) {
 
1771      * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
 
1773     public void mouseDoubleClick(MouseEvent e) {
 
1777      * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
 
1779     public void mouseDown(MouseEvent event) {
 
1784       if (event.stateMask != fKeyModifierMask) {
 
1789       if (event.button != 1) {
 
1796      * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
 
1798     public void mouseUp(MouseEvent e) {
 
1803       if (e.button != 1) {
 
1808       boolean wasActive = fCursor != null;
 
1813         IAction action = getAction("OpenEditor"); //$NON-NLS-1$
 
1820      * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
 
1822     public void mouseMove(MouseEvent event) {
 
1824       if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) {
 
1830         if (event.stateMask != fKeyModifierMask)
 
1832         // modifier was already pressed
 
1836       ISourceViewer viewer = getSourceViewer();
 
1837       if (viewer == null) {
 
1842       StyledText text = viewer.getTextWidget();
 
1843       if (text == null || text.isDisposed()) {
 
1848       if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) {
 
1853       IRegion region = getCurrentTextRegion(viewer);
 
1854       if (region == null || region.getLength() == 0) {
 
1855         repairRepresentation();
 
1859       highlightRegion(viewer, region);
 
1860       activateCursor(viewer);
 
1864      * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
 
1866     public void focusGained(FocusEvent e) {
 
1870      * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
 
1872     public void focusLost(FocusEvent event) {
 
1877      * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
 
1879     public void documentAboutToBeChanged(DocumentEvent event) {
 
1880       if (fActive && fActiveRegion != null) {
 
1881         fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
 
1883           event.getDocument().addPosition(fRememberedPosition);
 
1884         } catch (BadLocationException x) {
 
1885           fRememberedPosition = null;
 
1891      * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
 
1893     public void documentChanged(DocumentEvent event) {
 
1894       if (fRememberedPosition != null) {
 
1895         if (!fRememberedPosition.isDeleted()) {
 
1897           event.getDocument().removePosition(fRememberedPosition);
 
1898           fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
 
1899           fRememberedPosition = null;
 
1901           ISourceViewer viewer = getSourceViewer();
 
1902           if (viewer != null) {
 
1903             StyledText widget = viewer.getTextWidget();
 
1904             if (widget != null && !widget.isDisposed()) {
 
1905               widget.getDisplay().asyncExec(new Runnable() {
 
1914           fActiveRegion = null;
 
1915           fRememberedPosition = null;
 
1922      * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument,
 
1923      *      org.eclipse.jface.text.IDocument)
 
1925     public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
 
1926       if (oldInput == null)
 
1929       oldInput.removeDocumentListener(this);
 
1933      * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument,
 
1934      *      org.eclipse.jface.text.IDocument)
 
1936     public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
 
1937       if (newInput == null)
 
1939       newInput.addDocumentListener(this);
 
1943      * @see PaintListener#paintControl(PaintEvent)
 
1945     public void paintControl(PaintEvent event) {
 
1946       if (fActiveRegion == null)
 
1949       ISourceViewer viewer = getSourceViewer();
 
1953       StyledText text = viewer.getTextWidget();
 
1954       if (text == null || text.isDisposed())
 
1960       if (viewer instanceof ITextViewerExtension5) {
 
1962         ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
1963         IRegion widgetRange = extension.modelRange2WidgetRange(fActiveRegion);
 
1964         if (widgetRange == null)
 
1967         offset = widgetRange.getOffset();
 
1968         length = widgetRange.getLength();
 
1972         IRegion region = viewer.getVisibleRegion();
 
1973         if (!includes(region, fActiveRegion))
 
1976         offset = fActiveRegion.getOffset() - region.getOffset();
 
1977         length = fActiveRegion.getLength();
 
1981       Point minLocation = getMinimumLocation(text, offset, length);
 
1982       Point maxLocation = getMaximumLocation(text, offset, length);
 
1984       int x1 = minLocation.x;
 
1985       int x2 = minLocation.x + maxLocation.x - minLocation.x - 1;
 
1986       int y = minLocation.y + text.getLineHeight() - 1;
 
1989       if (fColor != null && !fColor.isDisposed())
 
1990         gc.setForeground(fColor);
 
1991       gc.drawLine(x1, y, x2, y);
 
1994     private boolean includes(IRegion region, IRegion position) {
 
1995       return position.getOffset() >= region.getOffset()
 
1996           && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength();
 
1999     private Point getMinimumLocation(StyledText text, int offset, int length) {
 
2000       Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
 
2002       for (int i = 0; i <= length; i++) {
 
2003         Point location = text.getLocationAtOffset(offset + i);
 
2005         if (location.x < minLocation.x)
 
2006           minLocation.x = location.x;
 
2007         if (location.y < minLocation.y)
 
2008           minLocation.y = location.y;
 
2014     private Point getMaximumLocation(StyledText text, int offset, int length) {
 
2015       Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
 
2017       for (int i = 0; i <= length; i++) {
 
2018         Point location = text.getLocationAtOffset(offset + i);
 
2020         if (location.x > maxLocation.x)
 
2021           maxLocation.x = location.x;
 
2022         if (location.y > maxLocation.y)
 
2023           maxLocation.y = location.y;
 
2031    * This action dispatches into two behaviours: If there is no current text hover, the javadoc is displayed using information
 
2032    * presenter. If there is a current text hover, it is converted into a information presenter in order to make it sticky.
 
2034   class InformationDispatchAction extends TextEditorAction {
 
2036     /** The wrapped text operation action. */
 
2037     private final TextOperationAction fTextOperationAction;
 
2040      * Creates a dispatch action.
 
2042     public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) {
 
2043       super(resourceBundle, prefix, PHPEditor.this);
 
2044       if (textOperationAction == null)
 
2045         throw new IllegalArgumentException();
 
2046       fTextOperationAction = textOperationAction;
 
2050      * @see org.eclipse.jface.action.IAction#run()
 
2054       ISourceViewer sourceViewer = getSourceViewer();
 
2055       if (sourceViewer == null) {
 
2056         fTextOperationAction.run();
 
2060       if (!(sourceViewer instanceof ITextViewerExtension2)) {
 
2061         fTextOperationAction.run();
 
2065       ITextViewerExtension2 textViewerExtension2 = (ITextViewerExtension2) sourceViewer;
 
2067       // does a text hover exist?
 
2068       ITextHover textHover = textViewerExtension2.getCurrentTextHover();
 
2069       if (textHover == null) {
 
2070         fTextOperationAction.run();
 
2074       Point hoverEventLocation = textViewerExtension2.getHoverEventLocation();
 
2075       int offset = computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y);
 
2077         fTextOperationAction.run();
 
2082         // get the text hover content
 
2083         IDocument document = sourceViewer.getDocument();
 
2084         String contentType = document.getContentType(offset);
 
2086         final IRegion hoverRegion = textHover.getHoverRegion(sourceViewer, offset);
 
2087         if (hoverRegion == null)
 
2090         final String hoverInfo = textHover.getHoverInfo(sourceViewer, hoverRegion);
 
2092         // with information provider
 
2093         IInformationProvider informationProvider = new IInformationProvider() {
 
2095            * @see org.eclipse.jface.text.information.IInformationProvider#getSubject(org.eclipse.jface.text.ITextViewer, int)
 
2097           public IRegion getSubject(ITextViewer textViewer, int offset) {
 
2102            * @see org.eclipse.jface.text.information.IInformationProvider#getInformation(org.eclipse.jface.text.ITextViewer,
 
2103            *      org.eclipse.jface.text.IRegion)
 
2105           public String getInformation(ITextViewer textViewer, IRegion subject) {
 
2110         fInformationPresenter.setOffset(offset);
 
2111         fInformationPresenter.setInformationProvider(informationProvider, contentType);
 
2112         fInformationPresenter.showInformation();
 
2114       } catch (BadLocationException e) {
 
2118     // modified version from TextViewer
 
2119     private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {
 
2121       StyledText styledText = textViewer.getTextWidget();
 
2122       IDocument document = textViewer.getDocument();
 
2124       if (document == null)
 
2128         int widgetLocation = styledText.getOffsetAtLocation(new Point(x, y));
 
2129         if (textViewer instanceof ITextViewerExtension3) {
 
2130           ITextViewerExtension3 extension = (ITextViewerExtension3) textViewer;
 
2131           return extension.widgetOffset2ModelOffset(widgetLocation);
 
2133           IRegion visibleRegion = textViewer.getVisibleRegion();
 
2134           return widgetLocation + visibleRegion.getOffset();
 
2136       } catch (IllegalArgumentException e) {
 
2144    * This action implements smart home.
 
2146    * Instead of going to the start of a line it does the following:
 
2147    *  - if smart home/end is enabled and the caret is after the line's first non-whitespace then the caret is moved directly before
 
2148    * it, taking JavaDoc and multi-line comments into account. - if the caret is before the line's first non-whitespace the caret is
 
2149    * moved to the beginning of the line - if the caret is at the beginning of the line see first case.
 
2153   protected class SmartLineStartAction extends LineStartAction {
 
2156      * Creates a new smart line start action
 
2159      *          the styled text widget
 
2161      *          a boolean flag which tells if the text up to the beginning of the line should be selected
 
2163     public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) {
 
2164       super(textWidget, doSelect);
 
2168      * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String, int,
 
2171     protected int getLineStartPosition(final IDocument document, final String line, final int length, final int offset) {
 
2173       String type = IDocument.DEFAULT_CONTENT_TYPE;
 
2175         type = TextUtilities.getContentType(document, IPHPPartitions.PHP_PARTITIONING, offset, true);
 
2176       } catch (BadLocationException exception) {
 
2177         // Should not happen
 
2180       int index = super.getLineStartPosition(document, line, length, offset);
 
2181       if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT) || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) {
 
2182         if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') {
 
2185           } while (index < length && Character.isWhitespace(line.charAt(index)));
 
2188         if (index < length - 1 && line.charAt(index) == '/' && line.charAt(index + 1) == '/') {
 
2192           } while (index < length && Character.isWhitespace(line.charAt(index)));
 
2200    * Text navigation action to navigate to the next sub-word.
 
2204   protected abstract class NextSubWordAction extends TextNavigationAction {
 
2206     protected JavaWordIterator fIterator = new JavaWordIterator();
 
2209      * Creates a new next sub-word action.
 
2212      *          Action code for the default operation. Must be an action code from
 
2213      * @see org.eclipse.swt.custom.ST.
 
2215     protected NextSubWordAction(int code) {
 
2216       super(getSourceViewer().getTextWidget(), code);
 
2220      * @see org.eclipse.jface.action.IAction#run()
 
2223       // Check whether we are in a java code partition and the preference is enabled
 
2224       final IPreferenceStore store = getPreferenceStore();
 
2225       if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
 
2230       final ISourceViewer viewer = getSourceViewer();
 
2231       final IDocument document = viewer.getDocument();
 
2232       fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
 
2233       int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
 
2237       int next = findNextPosition(position);
 
2238       if (next != BreakIterator.DONE) {
 
2239         setCaretPosition(next);
 
2240         getTextWidget().showSelection();
 
2241         fireSelectionChanged();
 
2247      * Finds the next position after the given position.
 
2250      *          the current position
 
2251      * @return the next position
 
2253     protected int findNextPosition(int position) {
 
2254       ISourceViewer viewer = getSourceViewer();
 
2256       while (position != BreakIterator.DONE && widget == -1) { // TODO: optimize
 
2257         position = fIterator.following(position);
 
2258         if (position != BreakIterator.DONE)
 
2259           widget = modelOffset2WidgetOffset(viewer, position);
 
2265      * Sets the caret position to the sub-word boundary given with <code>position</code>.
 
2268      *          Position where the action should move the caret
 
2270     protected abstract void setCaretPosition(int position);
 
2274    * Text navigation action to navigate to the next sub-word.
 
2278   protected class NavigateNextSubWordAction extends NextSubWordAction {
 
2281      * Creates a new navigate next sub-word action.
 
2283     public NavigateNextSubWordAction() {
 
2284       super(ST.WORD_NEXT);
 
2288      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
 
2290     protected void setCaretPosition(final int position) {
 
2291       getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
 
2296    * Text operation action to delete the next sub-word.
 
2300   protected class DeleteNextSubWordAction extends NextSubWordAction implements IUpdate {
 
2303      * Creates a new delete next sub-word action.
 
2305     public DeleteNextSubWordAction() {
 
2306       super(ST.DELETE_WORD_NEXT);
 
2310      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
 
2312     protected void setCaretPosition(final int position) {
 
2313       if (!validateEditorInputState())
 
2316       final ISourceViewer viewer = getSourceViewer();
 
2317       final int caret = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
 
2320         viewer.getDocument().replace(caret, position - caret, ""); //$NON-NLS-1$
 
2321       } catch (BadLocationException exception) {
 
2322         // Should not happen
 
2327      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#findNextPosition(int)
 
2329     protected int findNextPosition(int position) {
 
2330       return fIterator.following(position);
 
2334      * @see org.eclipse.ui.texteditor.IUpdate#update()
 
2336     public void update() {
 
2337       setEnabled(isEditorInputModifiable());
 
2342    * Text operation action to select the next sub-word.
 
2346   protected class SelectNextSubWordAction extends NextSubWordAction {
 
2349      * Creates a new select next sub-word action.
 
2351     public SelectNextSubWordAction() {
 
2352       super(ST.SELECT_WORD_NEXT);
 
2356      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int)
 
2358     protected void setCaretPosition(final int position) {
 
2359       final ISourceViewer viewer = getSourceViewer();
 
2361       final StyledText text = viewer.getTextWidget();
 
2362       if (text != null && !text.isDisposed()) {
 
2364         final Point selection = text.getSelection();
 
2365         final int caret = text.getCaretOffset();
 
2366         final int offset = modelOffset2WidgetOffset(viewer, position);
 
2368         if (caret == selection.x)
 
2369           text.setSelectionRange(selection.y, offset - selection.y);
 
2371           text.setSelectionRange(selection.x, offset - selection.x);
 
2377    * Text navigation action to navigate to the previous sub-word.
 
2381   protected abstract class PreviousSubWordAction extends TextNavigationAction {
 
2383     protected JavaWordIterator fIterator = new JavaWordIterator();
 
2386      * Creates a new previous sub-word action.
 
2389      *          Action code for the default operation. Must be an action code from
 
2390      * @see org.eclipse.swt.custom.ST.
 
2392     protected PreviousSubWordAction(final int code) {
 
2393       super(getSourceViewer().getTextWidget(), code);
 
2397      * @see org.eclipse.jface.action.IAction#run()
 
2400       // Check whether we are in a java code partition and the preference is enabled
 
2401       final IPreferenceStore store = getPreferenceStore();
 
2402       if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
 
2407       final ISourceViewer viewer = getSourceViewer();
 
2408       final IDocument document = viewer.getDocument();
 
2409       fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
 
2410       int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
 
2414       int previous = findPreviousPosition(position);
 
2415       if (previous != BreakIterator.DONE) {
 
2416         setCaretPosition(previous);
 
2417         getTextWidget().showSelection();
 
2418         fireSelectionChanged();
 
2424      * Finds the previous position before the given position.
 
2427      *          the current position
 
2428      * @return the previous position
 
2430     protected int findPreviousPosition(int position) {
 
2431       ISourceViewer viewer = getSourceViewer();
 
2433       while (position != BreakIterator.DONE && widget == -1) { // TODO: optimize
 
2434         position = fIterator.preceding(position);
 
2435         if (position != BreakIterator.DONE)
 
2436           widget = modelOffset2WidgetOffset(viewer, position);
 
2442      * Sets the caret position to the sub-word boundary given with <code>position</code>.
 
2445      *          Position where the action should move the caret
 
2447     protected abstract void setCaretPosition(int position);
 
2451    * Text navigation action to navigate to the previous sub-word.
 
2455   protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
 
2458      * Creates a new navigate previous sub-word action.
 
2460     public NavigatePreviousSubWordAction() {
 
2461       super(ST.WORD_PREVIOUS);
 
2465      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
 
2467     protected void setCaretPosition(final int position) {
 
2468       getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
 
2473    * Text operation action to delete the previous sub-word.
 
2477   protected class DeletePreviousSubWordAction extends PreviousSubWordAction implements IUpdate {
 
2480      * Creates a new delete previous sub-word action.
 
2482     public DeletePreviousSubWordAction() {
 
2483       super(ST.DELETE_WORD_PREVIOUS);
 
2487      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
 
2489     protected void setCaretPosition(final int position) {
 
2490       if (!validateEditorInputState())
 
2493       final ISourceViewer viewer = getSourceViewer();
 
2494       final int caret = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
 
2497         viewer.getDocument().replace(position, caret - position, ""); //$NON-NLS-1$
 
2498       } catch (BadLocationException exception) {
 
2499         // Should not happen
 
2504      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#findPreviousPosition(int)
 
2506     protected int findPreviousPosition(int position) {
 
2507       return fIterator.preceding(position);
 
2511      * @see org.eclipse.ui.texteditor.IUpdate#update()
 
2513     public void update() {
 
2514       setEnabled(isEditorInputModifiable());
 
2519    * Text operation action to select the previous sub-word.
 
2523   protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
 
2526      * Creates a new select previous sub-word action.
 
2528     public SelectPreviousSubWordAction() {
 
2529       super(ST.SELECT_WORD_PREVIOUS);
 
2533      * @see net.sourceforge.phpdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int)
 
2535     protected void setCaretPosition(final int position) {
 
2536       final ISourceViewer viewer = getSourceViewer();
 
2538       final StyledText text = viewer.getTextWidget();
 
2539       if (text != null && !text.isDisposed()) {
 
2541         final Point selection = text.getSelection();
 
2542         final int caret = text.getCaretOffset();
 
2543         final int offset = modelOffset2WidgetOffset(viewer, position);
 
2545         if (caret == selection.x)
 
2546           text.setSelectionRange(selection.y, offset - selection.y);
 
2548           text.setSelectionRange(selection.x, offset - selection.x);
 
2553   //  static protected class AnnotationAccess implements IAnnotationAccess {
 
2556   // org.eclipse.jface.text.source.IAnnotationAccess#getType(org.eclipse.jface.text.source.Annotation)
 
2558   //    public Object getType(Annotation annotation) {
 
2559   //      if (annotation instanceof IJavaAnnotation) {
 
2560   //        IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
 
2561   //   // if (javaAnnotation.isRelevant())
 
2562   //   // return javaAnnotation.getAnnotationType();
 
2569   // org.eclipse.jface.text.source.IAnnotationAccess#isMultiLine(org.eclipse.jface.text.source.Annotation)
 
2571   //    public boolean isMultiLine(Annotation annotation) {
 
2577   // org.eclipse.jface.text.source.IAnnotationAccess#isTemporary(org.eclipse.jface.text.source.Annotation)
 
2579   //    public boolean isTemporary(Annotation annotation) {
 
2580   //      if (annotation instanceof IJavaAnnotation) {
 
2581   //        IJavaAnnotation javaAnnotation = (IJavaAnnotation) annotation;
 
2582   //        if (javaAnnotation.isRelevant())
 
2583   //          return javaAnnotation.isTemporary();
 
2589   private class PropertyChangeListener implements org.eclipse.core.runtime.Preferences.IPropertyChangeListener {
 
2591      * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
 
2593     public void propertyChange(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
 
2594       handlePreferencePropertyChanged(event);
 
2599    * Finds and marks occurrence annotations.
 
2603   class OccurrencesFinderJob extends Job implements IDocumentListener {
 
2605     private IDocument fDocument;
 
2607     private boolean fCancelled = false;
 
2609     private IProgressMonitor fProgressMonitor;
 
2611     private Position[] fPositions;
 
2613     public OccurrencesFinderJob(IDocument document, Position[] positions) {
 
2614       super("Occurrences Marker"); //$NON-NLS-1$
 
2615       fDocument = document;
 
2616       fPositions = positions;
 
2617       fDocument.addDocumentListener(this);
 
2620     private boolean isCancelled() {
 
2621       return fCancelled || fProgressMonitor.isCanceled();
 
2625      * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
 
2627     public IStatus run(IProgressMonitor progressMonitor) {
 
2629       fProgressMonitor = progressMonitor;
 
2634           return Status.CANCEL_STATUS;
 
2636         ITextViewer textViewer = getViewer();
 
2637         if (textViewer == null)
 
2638           return Status.CANCEL_STATUS;
 
2640         IDocument document = textViewer.getDocument();
 
2641         if (document == null)
 
2642           return Status.CANCEL_STATUS;
 
2644         IDocumentProvider documentProvider = getDocumentProvider();
 
2645         if (documentProvider == null)
 
2646           return Status.CANCEL_STATUS;
 
2648         IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput());
 
2649         if (annotationModel == null)
 
2650           return Status.CANCEL_STATUS;
 
2652         // Add occurrence annotations
 
2653         int length = fPositions.length;
 
2654         Map annotationMap = new HashMap(length);
 
2655         for (int i = 0; i < length; i++) {
 
2658             return Status.CANCEL_STATUS;
 
2661           Position position = fPositions[i];
 
2663           // Create & add annotation
 
2665             message = document.get(position.offset, position.length);
 
2666           } catch (BadLocationException ex) {
 
2670           annotationMap.put(new Annotation("net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$
 
2675           return Status.CANCEL_STATUS;
 
2677         synchronized (annotationModel) {
 
2678           if (annotationModel instanceof IAnnotationModelExtension) {
 
2679             ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap);
 
2681             removeOccurrenceAnnotations();
 
2682             Iterator iter = annotationMap.entrySet().iterator();
 
2683             while (iter.hasNext()) {
 
2684               Map.Entry mapEntry = (Map.Entry) iter.next();
 
2685               annotationModel.addAnnotation((Annotation) mapEntry.getKey(), (Position) mapEntry.getValue());
 
2688           fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]);
 
2691         fDocument.removeDocumentListener(this);
 
2693       return Status.OK_STATUS;
 
2697      * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
 
2699     public void documentAboutToBeChanged(DocumentEvent event) {
 
2704      * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
 
2706     public void documentChanged(DocumentEvent event) {
 
2711    * Updates the selection in the editor's widget with the selection of the outline page.
 
2713   class OutlineSelectionChangedListener extends AbstractSelectionChangedListener {
 
2714     public void selectionChanged(SelectionChangedEvent event) {
 
2715       doSelectionChanged(event);
 
2720    * Holds the current occurrence annotations.
 
2724   private Annotation[] fOccurrenceAnnotations = null;
 
2726   private Job fOccurrencesFinderJob;
 
2728   /** Preference key for showing the line number ruler */
 
2729   //  private final static String LINE_NUMBER_RULER =
 
2730   // PreferenceConstants.EDITOR_LINE_NUMBER_RULER;
 
2731   /** Preference key for the foreground color of the line numbers */
 
2732   // private final static String LINE_NUMBER_COLOR =
 
2733   // PreferenceConstants.EDITOR_LINE_NUMBER_RULER_COLOR;
 
2734   /** Preference key for the link color */
 
2735   private final static String LINK_COLOR = PreferenceConstants.EDITOR_LINK_COLOR;
 
2737   /** Preference key for compiler task tags */
 
2738   private final static String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
 
2740   // protected PHPActionGroup fActionGroups;
 
2741   //  /** The outline page */
 
2742   //  private AbstractContentOutlinePage fOutlinePage;
 
2743   /** The outline page */
 
2744   protected JavaOutlinePage fOutlinePage;
 
2746   /** Outliner context menu Id */
 
2747   protected String fOutlinerContextMenuId;
 
2750    * Indicates whether this editor should react on outline page selection changes
 
2752   private int fIgnoreOutlinePageSelection;
 
2754   /** The outline page selection updater */
 
2755   //  private OutlinePageSelectionUpdater fUpdater;
 
2756   //  protected PHPSyntaxParserThread fValidationThread = null;
 
2757   // private IPreferenceStore fPHPPrefStore;
 
2758   /** The selection changed listener */
 
2759   //  protected ISelectionChangedListener fSelectionChangedListener = new
 
2760   // SelectionChangedListener();
 
2762    * The editor selection changed listener.
 
2766   private EditorSelectionChangedListener fEditorSelectionChangedListener;
 
2768   /** The selection changed listener */
 
2769   protected AbstractSelectionChangedListener fOutlineSelectionChangedListener = new OutlineSelectionChangedListener();
 
2771   /** The editor's bracket matcher */
 
2772   private PHPPairMatcher fBracketMatcher = new PHPPairMatcher(BRACKETS);
 
2774   /** The line number ruler column */
 
2775   //  private LineNumberRulerColumn fLineNumberRulerColumn;
 
2776   /** This editor's encoding support */
 
2777   private DefaultEncodingSupport fEncodingSupport;
 
2779   /** The mouse listener */
 
2780   private MouseClickListener fMouseListener;
 
2783    * Indicates whether this editor is about to update any annotation views.
 
2787   private boolean fIsUpdatingAnnotationViews = false;
 
2790    * The marker that served as last target for a goto marker request.
 
2794   private IMarker fLastMarkerTarget = null;
 
2796   protected CompositeActionGroup fActionGroups;
 
2798   protected CompositeActionGroup fContextMenuGroup;
 
2801    * This editor's projection support
 
2805   private ProjectionSupport fProjectionSupport;
 
2808    * This editor's projection model updater
 
2812   private IJavaFoldingStructureProvider fProjectionModelUpdater;
 
2815    * The override and implements indicator manager for this editor.
 
2819   //    protected OverrideIndicatorManager fOverrideIndicatorManager;
 
2821    * The action group for folding.
 
2825   private FoldingActionGroup fFoldingGroup;
 
2827   /** The information presenter. */
 
2828   private InformationPresenter fInformationPresenter;
 
2830   /** The annotation access */
 
2831   //  protected IAnnotationAccess fAnnotationAccess = new AnnotationAccess();
 
2832   /** The overview ruler */
 
2833   protected OverviewRuler isOverviewRulerVisible;
 
2835   /** The source viewer decoration support */
 
2836   //protected SourceViewerDecorationSupport fSourceViewerDecorationSupport;
 
2837   /** The overview ruler */
 
2838   //protected OverviewRuler fOverviewRuler;
 
2839   /** The preference property change listener for java core. */
 
2840   private org.eclipse.core.runtime.Preferences.IPropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
 
2843    * Returns the most narrow java element including the given offset
 
2846    *          the offset inside of the requested element
 
2848   abstract protected IJavaElement getElementAt(int offset);
 
2851    * Returns the java element of this editor's input corresponding to the given IJavaElement
 
2853   abstract protected IJavaElement getCorrespondingElement(IJavaElement element);
 
2856    * Sets the input of the editor's outline page.
 
2858   abstract protected void setOutlinePageInput(JavaOutlinePage page, IEditorInput input);
 
2861    * Default constructor.
 
2863   public PHPEditor() {
 
2868    * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeKeyBindingScopes()
 
2870   protected void initializeKeyBindingScopes() {
 
2871     setKeyBindingScopes(new String[] { "net.sourceforge.phpdt.ui.phpEditorScope" }); //$NON-NLS-1$
 
2875    * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
 
2877   protected void initializeEditor() {
 
2879     //    JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
 
2880     //    setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools, this, IPHPPartitions.PHP_PARTITIONING)); //,
 
2881     // IJavaPartitions.JAVA_PARTITIONING));
 
2882     IPreferenceStore store = createCombinedPreferenceStore(null);
 
2883     setPreferenceStore(store);
 
2884     JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
 
2885     setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools.getColorManager(), store, this,
 
2886         IPHPPartitions.PHP_PARTITIONING));
 
2887     // TODO changed in 3.x ?
 
2888     //    setRangeIndicator(new DefaultRangeIndicator());
 
2889     //    if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
 
2890     //      fUpdater = new OutlinePageSelectionUpdater();
 
2893     //          IPreferenceStore store= createCombinedPreferenceStore(null);
 
2894     //          setPreferenceStore(store);
 
2895     //          JavaTextTools textTools=
 
2896     // PHPeclipsePlugin.getDefault().getJavaTextTools();
 
2897     //          setSourceViewerConfiguration(new
 
2898     // JavaSourceViewerConfiguration(textTools.getColorManager(), store,
 
2899     // this, IJavaPartitions.JAVA_PARTITIONING));
 
2900     //          fMarkOccurrenceAnnotations=
 
2901     // store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES);
 
2902     //          fStickyOccurrenceAnnotations=
 
2903     // store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES);
 
2904     //          fMarkTypeOccurrences=
 
2905     // store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES);
 
2906     //          fMarkMethodOccurrences=
 
2907     // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES);
 
2908     //          fMarkConstantOccurrences=
 
2909     // store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES);
 
2910     //          fMarkFieldOccurrences=
 
2911     // store.getBoolean(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES);
 
2912     //          fMarkLocalVariableypeOccurrences=
 
2913     // store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES);
 
2914     //          fMarkExceptionOccurrences=
 
2915     // store.getBoolean(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES);
 
2916     //          fMarkMethodExitPoints=
 
2917     // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS);
 
2921    * @see org.eclipse.ui.texteditor.AbstractTextEditor#updatePropertyDependentActions()
 
2923   protected void updatePropertyDependentActions() {
 
2924     super.updatePropertyDependentActions();
 
2925     if (fEncodingSupport != null)
 
2926       fEncodingSupport.reset();
 
2930    * Update the hovering behavior depending on the preferences.
 
2932   private void updateHoverBehavior() {
 
2933     SourceViewerConfiguration configuration = getSourceViewerConfiguration();
 
2934     String[] types = configuration.getConfiguredContentTypes(getSourceViewer());
 
2936     for (int i = 0; i < types.length; i++) {
 
2938       String t = types[i];
 
2940       int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t);
 
2942       ISourceViewer sourceViewer = getSourceViewer();
 
2943       if (sourceViewer instanceof ITextViewerExtension2) {
 
2944         if (stateMasks != null) {
 
2945           for (int j = 0; j < stateMasks.length; j++) {
 
2946             int stateMask = stateMasks[j];
 
2947             ITextHover textHover = configuration.getTextHover(sourceViewer, t, stateMask);
 
2948             ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, stateMask);
 
2951           ITextHover textHover = configuration.getTextHover(sourceViewer, t);
 
2952           ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
 
2955         sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t);
 
2959   public void updatedTitleImage(Image image) {
 
2960     setTitleImage(image);
 
2964    * @see net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
 
2966   public Object getViewPartInput() {
 
2967     return getEditorInput().getAdapter(IResource.class);
 
2971    * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetSelection(ISelection)
 
2973   protected void doSetSelection(ISelection selection) {
 
2974     super.doSetSelection(selection);
 
2975     synchronizeOutlinePageSelection();
 
2978   boolean isFoldingEnabled() {
 
2979     return PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
 
2983    * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt. widgets.Composite)
 
2985   public void createPartControl(Composite parent) {
 
2986     super.createPartControl(parent);
 
2988     //fSourceViewerDecorationSupport.install(getPreferenceStore());
 
2990     ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
 
2992     fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
 
2993     fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
 
2994     fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
 
2995     fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
 
2996       public IInformationControl createInformationControl(Shell shell) {
 
2997         return new CustomSourceInformationControl(shell, IDocument.DEFAULT_CONTENT_TYPE);
 
3000     fProjectionSupport.install();
 
3002     fProjectionModelUpdater = PHPeclipsePlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider();
 
3003     if (fProjectionModelUpdater != null)
 
3004       fProjectionModelUpdater.install(this, projectionViewer);
 
3006     if (isFoldingEnabled())
 
3007       projectionViewer.doOperation(ProjectionViewer.TOGGLE);
 
3008     Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
 
3009     preferences.addPropertyChangeListener(fPropertyChangeListener);
 
3011     IInformationControlCreator informationControlCreator = new IInformationControlCreator() {
 
3012       public IInformationControl createInformationControl(Shell parent) {
 
3013         boolean cutDown = false;
 
3014         int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
 
3015         return new DefaultInformationControl(parent, SWT.RESIZE, style, new HTMLTextPresenter(cutDown));
 
3019     fInformationPresenter = new InformationPresenter(informationControlCreator);
 
3020     fInformationPresenter.setSizeConstraints(60, 10, true, true);
 
3021     fInformationPresenter.install(getSourceViewer());
 
3023     fEditorSelectionChangedListener = new EditorSelectionChangedListener();
 
3024     fEditorSelectionChangedListener.install(getSelectionProvider());
 
3026     if (isBrowserLikeLinks())
 
3027       enableBrowserLikeLinks();
 
3029     if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE))
 
3030       enableOverwriteMode(false);
 
3033     //    getEditorSite().getShell().addShellListener(fActivationListener);
 
3036   private void setWordWrap() {
 
3037     if (getSourceViewer() != null) {
 
3038       getSourceViewer().getTextWidget().setWordWrap(
 
3039           PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_WRAP_WORDS));
 
3043   protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
 
3045     support.setCharacterPairMatcher(fBracketMatcher);
 
3046     support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
 
3048     super.configureSourceViewerDecorationSupport(support);
 
3052    * @see org.eclipse.ui.texteditor.AbstractTextEditor#gotoMarker(org.eclipse.core.resources.IMarker)
 
3054   public void gotoMarker(IMarker marker) {
 
3055     fLastMarkerTarget = marker;
 
3056     if (!fIsUpdatingAnnotationViews) {
 
3057       super.gotoMarker(marker);
 
3062    * Jumps to the next enabled annotation according to the given direction. An annotation type is enabled if it is configured to be
 
3063    * in the Next/Previous tool bar drop down menu and if it is checked.
 
3066    *          <code>true</code> if search direction is forward, <code>false</code> if backward
 
3068   public void gotoAnnotation(boolean forward) {
 
3069     ITextSelection selection = (ITextSelection) getSelectionProvider().getSelection();
 
3070     Position position = new Position(0, 0);
 
3071     if (false /* delayed - see bug 18316 */) {
 
3072       getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
 
3073       selectAndReveal(position.getOffset(), position.getLength());
 
3074     } else /* no delay - see bug 18316 */{
 
3075       Annotation annotation = getNextAnnotation(selection.getOffset(), selection.getLength(), forward, position);
 
3076       setStatusLineErrorMessage(null);
 
3077       setStatusLineMessage(null);
 
3078       if (annotation != null) {
 
3079         updateAnnotationViews(annotation);
 
3080         selectAndReveal(position.getOffset(), position.getLength());
 
3081         setStatusLineMessage(annotation.getText());
 
3087    * Returns the lock object for the given annotation model.
 
3089    * @param annotationModel
 
3090    *          the annotation model
 
3091    * @return the annotation model's lock object
 
3094   private Object getLockObject(IAnnotationModel annotationModel) {
 
3095     if (annotationModel instanceof ISynchronizable)
 
3096       return ((ISynchronizable) annotationModel).getLockObject();
 
3098       return annotationModel;
 
3102    * Updates the annotation views that show the given annotation.
 
3107   private void updateAnnotationViews(Annotation annotation) {
 
3108     IMarker marker = null;
 
3109     if (annotation instanceof MarkerAnnotation)
 
3110       marker = ((MarkerAnnotation) annotation).getMarker();
 
3111     else if (annotation instanceof IJavaAnnotation) {
 
3112       Iterator e = ((IJavaAnnotation) annotation).getOverlaidIterator();
 
3114         while (e.hasNext()) {
 
3115           Object o = e.next();
 
3116           if (o instanceof MarkerAnnotation) {
 
3117             marker = ((MarkerAnnotation) o).getMarker();
 
3124     if (marker != null && !marker.equals(fLastMarkerTarget)) {
 
3126         boolean isProblem = marker.isSubtypeOf(IMarker.PROBLEM);
 
3127         IWorkbenchPage page = getSite().getPage();
 
3128         IViewPart view = page.findView(isProblem ? IPageLayout.ID_PROBLEM_VIEW : IPageLayout.ID_TASK_LIST); //$NON-NLS-1$  //$NON-NLS-2$
 
3130           Method method = view.getClass().getMethod("setSelection", new Class[] { IStructuredSelection.class, boolean.class }); //$NON-NLS-1$
 
3131           method.invoke(view, new Object[] { new StructuredSelection(marker), Boolean.TRUE });
 
3133       } catch (CoreException x) {
 
3134       } catch (NoSuchMethodException x) {
 
3135       } catch (IllegalAccessException x) {
 
3136       } catch (InvocationTargetException x) {
 
3138       // ignore exceptions, don't update any of the lists, just set status line
 
3143    * Returns this document's complete text.
 
3145    * @return the document's complete text
 
3147   public String get() {
 
3148     IDocument doc = this.getDocumentProvider().getDocument(this.getEditorInput());
 
3153    * Sets the outliner's context menu ID.
 
3155   protected void setOutlinerContextMenuId(String menuId) {
 
3156     fOutlinerContextMenuId = menuId;
 
3160    * Returns the standard action group of this editor.
 
3162   protected ActionGroup getActionGroup() {
 
3163     return fActionGroups;
 
3166   //  public JavaOutlinePage getfOutlinePage() {
 
3167   //    return fOutlinePage;
 
3171    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method extend the actions to add those
 
3172    * specific to the receiver
 
3174   protected void createActions() {
 
3175     super.createActions();
 
3177     ActionGroup oeg, ovg, jsg, sg;
 
3178     fActionGroups = new CompositeActionGroup(new ActionGroup[] { oeg = new OpenEditorActionGroup(this),
 
3179     //          sg= new ShowActionGroup(this),
 
3180         //              ovg= new OpenViewActionGroup(this),
 
3181         //              jsg= new JavaSearchActionGroup(this)
 
3183     fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { oeg });
 
3186     fFoldingGroup = new FoldingActionGroup(this, getViewer());
 
3188     ResourceAction resAction = new TextOperationAction(PHPEditorMessages.getResourceBundle(),
 
3189         "ShowJavaDoc.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$
 
3190     resAction = new InformationDispatchAction(PHPEditorMessages.getResourceBundle(),
 
3191         "ShowJavaDoc.", (TextOperationAction) resAction); //$NON-NLS-1$
 
3192     resAction.setActionDefinitionId(net.sourceforge.phpdt.ui.actions.PHPEditorActionDefinitionIds.SHOW_JAVADOC);
 
3193     setAction("ShowJavaDoc", resAction); //$NON-NLS-1$
 
3194     //  WorkbenchHelp.setHelp(resAction,
 
3195     // IJavaHelpContextIds.SHOW_JAVADOC_ACTION);
 
3197     Action action = new GotoMatchingBracketAction(this);
 
3198     action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_MATCHING_BRACKET);
 
3199     setAction(GotoMatchingBracketAction.GOTO_MATCHING_BRACKET, action);
 
3202     // TextOperationAction(PHPEditorMessages.getResourceBundle(),"ShowOutline.",
 
3203     // this, JavaSourceViewer.SHOW_OUTLINE, true); //$NON-NLS-1$
 
3204     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE);
 
3205     //  setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE, action);
 
3206     //// WorkbenchHelp.setHelp(action,
 
3207     // IJavaHelpContextIds.SHOW_OUTLINE_ACTION);
 
3210     // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenStructure.",
 
3211     // this, JavaSourceViewer.OPEN_STRUCTURE, true); //$NON-NLS-1$
 
3212     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE);
 
3213     //  setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_STRUCTURE,
 
3215     //// WorkbenchHelp.setHelp(action,
 
3216     // IJavaHelpContextIds.OPEN_STRUCTURE_ACTION);
 
3219     // TextOperationAction(PHPEditorMessages.getResourceBundle(),"OpenHierarchy.",
 
3220     // this, JavaSourceViewer.SHOW_HIERARCHY, true); //$NON-NLS-1$
 
3221     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY);
 
3222     //  setAction(PHPEditorActionDefinitionIds.SHOW_OUTLINE.OPEN_HIERARCHY,
 
3224     //// WorkbenchHelp.setHelp(action,
 
3225     // IJavaHelpContextIds.OPEN_HIERARCHY_ACTION);
 
3227     fEncodingSupport = new DefaultEncodingSupport();
 
3228     fEncodingSupport.initialize(this);
 
3230     //  fSelectionHistory= new SelectionHistory(this);
 
3232     //  action= new StructureSelectEnclosingAction(this, fSelectionHistory);
 
3233     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_ENCLOSING);
 
3234     //  setAction(StructureSelectionAction.ENCLOSING, action);
 
3236     //  action= new StructureSelectNextAction(this, fSelectionHistory);
 
3237     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_NEXT);
 
3238     //  setAction(StructureSelectionAction.NEXT, action);
 
3240     //  action= new StructureSelectPreviousAction(this, fSelectionHistory);
 
3241     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_PREVIOUS);
 
3242     //  setAction(StructureSelectionAction.PREVIOUS, action);
 
3244     //  StructureSelectHistoryAction historyAction= new
 
3245     // StructureSelectHistoryAction(this, fSelectionHistory);
 
3246     //  historyAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST);
 
3247     //  setAction(StructureSelectionAction.HISTORY, historyAction);
 
3248     //  fSelectionHistory.setHistoryAction(historyAction);
 
3250     //  action= GoToNextPreviousMemberAction.newGoToNextMemberAction(this);
 
3251     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER);
 
3252     //  setAction(GoToNextPreviousMemberAction.NEXT_MEMBER, action);
 
3255     // GoToNextPreviousMemberAction.newGoToPreviousMemberAction(this);
 
3256     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER);
 
3257     //  setAction(GoToNextPreviousMemberAction.PREVIOUS_MEMBER, action);
 
3259     //  action= new QuickFormatAction();
 
3260     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.QUICK_FORMAT);
 
3261     //  setAction(IJavaEditorActionDefinitionIds.QUICK_FORMAT, action);
 
3263     //  action= new RemoveOccurrenceAnnotations(this);
 
3264     //  action.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS);
 
3265     //  setAction("RemoveOccurrenceAnnotations", action); //$NON-NLS-1$
 
3267     // add annotation actions
 
3268     action = new JavaSelectMarkerRulerAction2(PHPEditorMessages.getResourceBundle(), "Editor.RulerAnnotationSelection.", this); //$NON-NLS-1$
 
3269     setAction("AnnotationAction", action); //$NON-NLS-1$
 
3272   private void internalDoSetInput(IEditorInput input) throws CoreException {
 
3273     super.doSetInput(input);
 
3275     if (getSourceViewer() instanceof JavaSourceViewer) {
 
3276       JavaSourceViewer viewer = (JavaSourceViewer) getSourceViewer();
 
3277       if (viewer.getReconciler() == null) {
 
3278         IReconciler reconciler = getSourceViewerConfiguration().getReconciler(viewer);
 
3279         if (reconciler != null) {
 
3280           reconciler.install(viewer);
 
3281           viewer.setReconciler(reconciler);
 
3286     if (fEncodingSupport != null)
 
3287       fEncodingSupport.reset();
 
3289     setOutlinePageInput(fOutlinePage, input);
 
3291     if (fProjectionModelUpdater != null)
 
3292       fProjectionModelUpdater.initialize();
 
3294     //        if (isShowingOverrideIndicators())
 
3295     //                  installOverrideIndicator(false);
 
3299    * @see org.eclipse.ui.texteditor.AbstractTextEditor#setPreferenceStore(org.eclipse.jface.preference.IPreferenceStore)
 
3302   protected void setPreferenceStore(IPreferenceStore store) {
 
3303     super.setPreferenceStore(store);
 
3304     if (getSourceViewerConfiguration() instanceof PHPSourceViewerConfiguration) {
 
3305       JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
 
3306       setSourceViewerConfiguration(new PHPSourceViewerConfiguration(textTools.getColorManager(), store, this,
 
3307           IPHPPartitions.PHP_PARTITIONING));
 
3309     if (getSourceViewer() instanceof JavaSourceViewer)
 
3310       ((JavaSourceViewer) getSourceViewer()).setPreferenceStore(store);
 
3314    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs any extra disposal
 
3315    * actions required by the php editor.
 
3317   public void dispose() {
 
3318     if (fProjectionModelUpdater != null) {
 
3319       fProjectionModelUpdater.uninstall();
 
3320       fProjectionModelUpdater = null;
 
3323     if (fProjectionSupport != null) {
 
3324       fProjectionSupport.dispose();
 
3325       fProjectionSupport = null;
 
3327     //   PHPEditorEnvironment.disconnect(this);
 
3328     if (fOutlinePage != null)
 
3329       fOutlinePage.setInput(null);
 
3331     if (fActionGroups != null)
 
3332       fActionGroups.dispose();
 
3334     if (isBrowserLikeLinks())
 
3335       disableBrowserLikeLinks();
 
3337     if (fEncodingSupport != null) {
 
3338       fEncodingSupport.dispose();
 
3339       fEncodingSupport = null;
 
3342     if (fPropertyChangeListener != null) {
 
3343       Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences();
 
3344       preferences.removePropertyChangeListener(fPropertyChangeListener);
 
3345       fPropertyChangeListener = null;
 
3348     //    if (fSourceViewerDecorationSupport != null) {
 
3349     //      fSourceViewerDecorationSupport.dispose();
 
3350     //      fSourceViewerDecorationSupport = null;
 
3353     if (fBracketMatcher != null) {
 
3354       fBracketMatcher.dispose();
 
3355       fBracketMatcher = null;
 
3358     if (fEditorSelectionChangedListener != null) {
 
3359       fEditorSelectionChangedListener.uninstall(getSelectionProvider());
 
3360       fEditorSelectionChangedListener = null;
 
3367    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs any extra revert behavior
 
3368    * required by the php editor.
 
3370   //  public void doRevertToSaved() {
 
3371   //    super.doRevertToSaved();
 
3372   //    if (fOutlinePage != null)
 
3373   //      fOutlinePage.update();
 
3376    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs any extra save behavior
 
3377    * required by the php editor.
 
3379   //  public void doSave(IProgressMonitor monitor) {
 
3380   //    super.doSave(monitor);
 
3381   // compile or not, according to the user preferences
 
3382   // IPreferenceStore store = getPreferenceStore();
 
3383   // the parse on save was changed to the eclipse "builders" concept
 
3384   //    if (store.getBoolean(PHPeclipsePlugin.PHP_PARSE_ON_SAVE)) {
 
3385   //      IAction a = PHPParserAction.getInstance();
 
3389   //    if (SWT.getPlatform().equals("win32")) {
 
3390   //      IAction a = ShowExternalPreviewAction.getInstance();
 
3394   //    if (fOutlinePage != null)
 
3395   //      fOutlinePage.update();
 
3398    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs any extra save as
 
3399    * behavior required by the php editor.
 
3401   //  public void doSaveAs() {
 
3402   //    super.doSaveAs();
 
3403   //    if (fOutlinePage != null)
 
3404   //      fOutlinePage.update();
 
3407    * @see StatusTextEditor#getStatusHeader(IStatus)
 
3409   protected String getStatusHeader(IStatus status) {
 
3410     if (fEncodingSupport != null) {
 
3411       String message = fEncodingSupport.getStatusHeader(status);
 
3412       if (message != null)
 
3415     return super.getStatusHeader(status);
 
3419    * @see StatusTextEditor#getStatusBanner(IStatus)
 
3421   protected String getStatusBanner(IStatus status) {
 
3422     if (fEncodingSupport != null) {
 
3423       String message = fEncodingSupport.getStatusBanner(status);
 
3424       if (message != null)
 
3427     return super.getStatusBanner(status);
 
3431    * @see StatusTextEditor#getStatusMessage(IStatus)
 
3433   protected String getStatusMessage(IStatus status) {
 
3434     if (fEncodingSupport != null) {
 
3435       String message = fEncodingSupport.getStatusMessage(status);
 
3436       if (message != null)
 
3439     return super.getStatusMessage(status);
 
3443    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs sets the input of the
 
3444    * outline page after AbstractTextEditor has set input.
 
3446   //  protected void doSetInput(IEditorInput input) throws CoreException {
 
3447   //    super.doSetInput(input);
 
3448   //    if (fEncodingSupport != null)
 
3449   //      fEncodingSupport.reset();
 
3450   //    setOutlinePageInput(fOutlinePage, input);
 
3453    * @see AbstractTextEditor#doSetInput
 
3455   protected void doSetInput(IEditorInput input) throws CoreException {
 
3456     ISourceViewer sourceViewer = getSourceViewer();
 
3457     if (!(sourceViewer instanceof ISourceViewerExtension2)) {
 
3458       setPreferenceStore(createCombinedPreferenceStore(input));
 
3459       internalDoSetInput(input);
 
3463     // uninstall & unregister preference store listener
 
3464     if (isBrowserLikeLinks())
 
3465       disableBrowserLikeLinks();
 
3466     getSourceViewerDecorationSupport(sourceViewer).uninstall();
 
3467     ((ISourceViewerExtension2) sourceViewer).unconfigure();
 
3469     setPreferenceStore(createCombinedPreferenceStore(input));
 
3471     // install & register preference store listener
 
3472     sourceViewer.configure(getSourceViewerConfiguration());
 
3473     getSourceViewerDecorationSupport(sourceViewer).install(getPreferenceStore());
 
3474     if (isBrowserLikeLinks())
 
3475       enableBrowserLikeLinks();
 
3477     internalDoSetInput(input);
 
3481    * @see org.phpeclipse.phpdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput()
 
3483   //  public Object getViewPartInput() {
 
3484   //    return getEditorInput().getAdapter(IFile.class);
 
3487    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method adds any PHPEditor specific
 
3490   public void editorContextMenuAboutToShow(MenuManager menu) {
 
3491     super.editorContextMenuAboutToShow(menu);
 
3492     menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO, new Separator(IContextMenuConstants.GROUP_OPEN));
 
3493     menu.insertAfter(IContextMenuConstants.GROUP_OPEN, new GroupMarker(IContextMenuConstants.GROUP_SHOW));
 
3495     ActionContext context = new ActionContext(getSelectionProvider().getSelection());
 
3496     fContextMenuGroup.setContext(context);
 
3497     fContextMenuGroup.fillContextMenu(menu);
 
3498     fContextMenuGroup.setContext(null);
 
3499     //    addAction(menu, ITextEditorActionConstants.GROUP_EDIT, "Format");
 
3502     //    ActionContext context =
 
3503     //      new ActionContext(getSelectionProvider().getSelection());
 
3504     //    fContextMenuGroup.setContext(context);
 
3505     //    fContextMenuGroup.fillContextMenu(menu);
 
3506     //    fContextMenuGroup.setContext(null);
 
3510    * Creates the outline page used with this editor.
 
3512   protected JavaOutlinePage createOutlinePage() {
 
3513     JavaOutlinePage page = new JavaOutlinePage(fOutlinerContextMenuId, this);
 
3514     fOutlineSelectionChangedListener.install(page);
 
3515     setOutlinePageInput(page, getEditorInput());
 
3520    * Informs the editor that its outliner has been closed.
 
3522   public void outlinePageClosed() {
 
3523     if (fOutlinePage != null) {
 
3524       fOutlineSelectionChangedListener.uninstall(fOutlinePage);
 
3525       fOutlinePage = null;
 
3526       resetHighlightRange();
 
3531    * Synchronizes the outliner selection with the given element position in the editor.
 
3534    *          the java element to select
 
3536   protected void synchronizeOutlinePage(ISourceReference element) {
 
3537     synchronizeOutlinePage(element, true);
 
3541    * Synchronizes the outliner selection with the given element position in the editor.
 
3544    *          the java element to select
 
3545    * @param checkIfOutlinePageActive
 
3546    *          <code>true</code> if check for active outline page needs to be done
 
3548   protected void synchronizeOutlinePage(ISourceReference element, boolean checkIfOutlinePageActive) {
 
3549     if (fOutlinePage != null && element != null && !(checkIfOutlinePageActive && isJavaOutlinePageActive())) {
 
3550       fOutlineSelectionChangedListener.uninstall(fOutlinePage);
 
3551       fOutlinePage.select(element);
 
3552       fOutlineSelectionChangedListener.install(fOutlinePage);
 
3557    * Synchronizes the outliner selection with the actual cursor position in the editor.
 
3559   public void synchronizeOutlinePageSelection() {
 
3560     synchronizeOutlinePage(computeHighlightRangeSourceReference());
 
3562     //    ISourceViewer sourceViewer = getSourceViewer();
 
3563     //    if (sourceViewer == null || fOutlinePage == null)
 
3566     //    StyledText styledText = sourceViewer.getTextWidget();
 
3567     //    if (styledText == null)
 
3571     //    if (sourceViewer instanceof ITextViewerExtension3) {
 
3572     //      ITextViewerExtension3 extension = (ITextViewerExtension3)
 
3575     // extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
 
3577     //      int offset = sourceViewer.getVisibleRegion().getOffset();
 
3578     //      caret = offset + styledText.getCaretOffset();
 
3581     //    IJavaElement element = getElementAt(caret);
 
3582     //    if (element instanceof ISourceReference) {
 
3583     //      fOutlinePage.removeSelectionChangedListener(fSelectionChangedListener);
 
3584     //      fOutlinePage.select((ISourceReference) element);
 
3585     //      fOutlinePage.addSelectionChangedListener(fSelectionChangedListener);
 
3589   protected void setSelection(ISourceReference reference, boolean moveCursor) {
 
3591     ISelection selection = getSelectionProvider().getSelection();
 
3592     if (selection instanceof TextSelection) {
 
3593       TextSelection textSelection = (TextSelection) selection;
 
3594       if (textSelection.getOffset() != 0 || textSelection.getLength() != 0)
 
3595         markInNavigationHistory();
 
3598     if (reference != null) {
 
3600       StyledText textWidget = null;
 
3602       ISourceViewer sourceViewer = getSourceViewer();
 
3603       if (sourceViewer != null)
 
3604         textWidget = sourceViewer.getTextWidget();
 
3606       if (textWidget == null)
 
3611         ISourceRange range = reference.getSourceRange();
 
3615         int offset = range.getOffset();
 
3616         int length = range.getLength();
 
3618         if (offset < 0 || length < 0)
 
3621         textWidget.setRedraw(false);
 
3623         setHighlightRange(offset, length, moveCursor);
 
3631         if (reference instanceof IMember) {
 
3632           range = ((IMember) reference).getNameRange();
 
3633           if (range != null) {
 
3634             offset = range.getOffset();
 
3635             length = range.getLength();
 
3638         //                                      else if (reference instanceof IImportDeclaration) {
 
3639         //                                              String name= ((IImportDeclaration)
 
3640         // reference).getElementName();
 
3641         //                                              if (name != null && name.length() > 0) {
 
3642         //                                                      String content= reference.getSource();
 
3643         //                                                      if (content != null) {
 
3644         //                                                              offset= range.getOffset() + content.indexOf(name);
 
3645         //                                                              length= name.length();
 
3648         //                                      } else if (reference instanceof IPackageDeclaration) {
 
3649         //                                              String name= ((IPackageDeclaration)
 
3650         // reference).getElementName();
 
3651         //                                              if (name != null && name.length() > 0) {
 
3652         //                                                      String content= reference.getSource();
 
3653         //                                                      if (content != null) {
 
3654         //                                                              offset= range.getOffset() + content.indexOf(name);
 
3655         //                                                              length= name.length();
 
3660         if (offset > -1 && length > 0) {
 
3661           sourceViewer.revealRange(offset, length);
 
3662           sourceViewer.setSelectedRange(offset, length);
 
3665       } catch (JavaModelException x) {
 
3666       } catch (IllegalArgumentException x) {
 
3668         if (textWidget != null)
 
3669           textWidget.setRedraw(true);
 
3672     } else if (moveCursor) {
 
3673       resetHighlightRange();
 
3676     markInNavigationHistory();
 
3679   public void setSelection(IJavaElement element) {
 
3680     if (element == null || element instanceof ICompilationUnit) { // ||
 
3686        * If the element is an ICompilationUnit this unit is either the input of this editor or not being displayed. In both cases,
 
3687        * nothing should happened. (http://dev.eclipse.org/bugs/show_bug.cgi?id=5128)
 
3692     IJavaElement corresponding = getCorrespondingElement(element);
 
3693     if (corresponding instanceof ISourceReference) {
 
3694       ISourceReference reference = (ISourceReference) corresponding;
 
3695       // set highlight range
 
3696       setSelection(reference, true);
 
3697       // set outliner selection
 
3698       if (fOutlinePage != null) {
 
3699         fOutlineSelectionChangedListener.uninstall(fOutlinePage);
 
3700         fOutlinePage.select(reference);
 
3701         fOutlineSelectionChangedListener.install(fOutlinePage);
 
3706   public synchronized void editingScriptStarted() {
 
3707     ++fIgnoreOutlinePageSelection;
 
3710   public synchronized void editingScriptEnded() {
 
3711     --fIgnoreOutlinePageSelection;
 
3714   public synchronized boolean isEditingScriptRunning() {
 
3715     return (fIgnoreOutlinePageSelection > 0);
 
3719    * The <code>PHPEditor</code> implementation of this <code>AbstractTextEditor</code> method performs gets the java content
 
3720    * outline page if request is for a an outline page.
 
3722   public Object getAdapter(Class required) {
 
3724     if (IContentOutlinePage.class.equals(required)) {
 
3725       if (fOutlinePage == null)
 
3726         fOutlinePage = createOutlinePage();
 
3727       return fOutlinePage;
 
3730     if (IEncodingSupport.class.equals(required))
 
3731       return fEncodingSupport;
 
3733     if (required == IShowInTargetList.class) {
 
3734       return new IShowInTargetList() {
 
3735         public String[] getShowInTargetIds() {
 
3736           return new String[] { JavaUI.ID_PACKAGES, IPageLayout.ID_OUTLINE, IPageLayout.ID_RES_NAV };
 
3741     if (fProjectionSupport != null) {
 
3742       Object adapter = fProjectionSupport.getAdapter(getSourceViewer(), required);
 
3743       if (adapter != null)
 
3747     return super.getAdapter(required);
 
3750   //  public Object getAdapter(Class required) {
 
3751   //    if (IContentOutlinePage.class.equals(required)) {
 
3752   //      if (fOutlinePage == null) {
 
3753   //        fOutlinePage = new PHPContentOutlinePage(getDocumentProvider(), this);
 
3754   //        if (getEditorInput() != null)
 
3755   //          fOutlinePage.setInput(getEditorInput());
 
3757   //      return fOutlinePage;
 
3760   //    if (IEncodingSupport.class.equals(required))
 
3761   //      return fEncodingSupport;
 
3763   //    return super.getAdapter(required);
 
3766   protected void doSelectionChanged(SelectionChangedEvent event) {
 
3767     ISourceReference reference = null;
 
3769     ISelection selection = event.getSelection();
 
3770     Iterator iter = ((IStructuredSelection) selection).iterator();
 
3771     while (iter.hasNext()) {
 
3772       Object o = iter.next();
 
3773       if (o instanceof ISourceReference) {
 
3774         reference = (ISourceReference) o;
 
3779     if (!isActivePart() && PHPeclipsePlugin.getActivePage() != null)
 
3780       PHPeclipsePlugin.getActivePage().bringToTop(this);
 
3783       editingScriptStarted();
 
3784       setSelection(reference, !isActivePart());
 
3786       editingScriptEnded();
 
3791    * @see AbstractTextEditor#adjustHighlightRange(int, int)
 
3793   protected void adjustHighlightRange(int offset, int length) {
 
3797       IJavaElement element = getElementAt(offset);
 
3798       while (element instanceof ISourceReference) {
 
3799         ISourceRange range = ((ISourceReference) element).getSourceRange();
 
3800         if (offset < range.getOffset() + range.getLength() && range.getOffset() < offset + length) {
 
3802           ISourceViewer viewer = getSourceViewer();
 
3803           if (viewer instanceof ITextViewerExtension5) {
 
3804             ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
3805             extension.exposeModelRange(new Region(range.getOffset(), range.getLength()));
 
3808           setHighlightRange(range.getOffset(), range.getLength(), true);
 
3809           if (fOutlinePage != null) {
 
3810             fOutlineSelectionChangedListener.uninstall(fOutlinePage);
 
3811             fOutlinePage.select((ISourceReference) element);
 
3812             fOutlineSelectionChangedListener.install(fOutlinePage);
 
3817         element = element.getParent();
 
3820     } catch (JavaModelException x) {
 
3821       PHPeclipsePlugin.log(x.getStatus());
 
3824     ISourceViewer viewer = getSourceViewer();
 
3825     if (viewer instanceof ITextViewerExtension5) {
 
3826       ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
 
3827       extension.exposeModelRange(new Region(offset, length));
 
3829       resetHighlightRange();
 
3834   protected boolean isActivePart() {
 
3835     IWorkbenchWindow window = getSite().getWorkbenchWindow();
 
3836     IPartService service = window.getPartService();
 
3837     IWorkbenchPart part = service.getActivePart();
 
3838     return part != null && part.equals(this);
 
3841   //  public void openContextHelp() {
 
3843   // this.getDocumentProvider().getDocument(this.getEditorInput());
 
3844   //    ITextSelection selection = (ITextSelection)
 
3845   // this.getSelectionProvider().getSelection();
 
3846   //    int pos = selection.getOffset();
 
3847   //    String word = getFunctionName(doc, pos);
 
3848   //    openContextHelp(word);
 
3851   //  private void openContextHelp(String word) {
 
3855   //  public static void open(String word) {
 
3856   //    IHelp help = WorkbenchHelp.getHelpSupport();
 
3857   //    if (help != null) {
 
3858   //      IHelpResource helpResource = new PHPFunctionHelpResource(word);
 
3859   //      WorkbenchHelp.getHelpSupport().displayHelpResource(helpResource);
 
3861   //      // showMessage(shell, dialogTitle, ActionMessages.getString("Open help
 
3862   // not available"), false); //$NON-NLS-1$
 
3866   //    private String getFunctionName(IDocument doc, int pos) {
 
3867   //            Point word = PHPWordExtractor.findWord(doc, pos);
 
3868   //            if (word != null) {
 
3870   //                            return doc.get(word.x, word.y).replace('_', '-');
 
3871   //                    } catch (BadLocationException e) {
 
3878    * @see AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
 
3880   protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
 
3884       ISourceViewer sourceViewer = getSourceViewer();
 
3885       if (sourceViewer == null)
 
3888       String property = event.getProperty();
 
3890       if (PreferenceConstants.EDITOR_TAB_WIDTH.equals(property)) {
 
3891         Object value = event.getNewValue();
 
3892         if (value instanceof Integer) {
 
3893           sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
 
3894         } else if (value instanceof String) {
 
3896             sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value));
 
3897           } catch (NumberFormatException e) {
 
3898             // bug #1038071 - set default tab:
 
3899             sourceViewer.getTextWidget().setTabs(80);
 
3905       //      if (OVERVIEW_RULER.equals(property)) {
 
3906       //        if (isOverviewRulerVisible())
 
3907       //          showOverviewRuler();
 
3909       //          hideOverviewRuler();
 
3913       //      if (LINE_NUMBER_RULER.equals(property)) {
 
3914       //        if (isLineNumberRulerVisible())
 
3915       //          showLineNumberRuler();
 
3917       //          hideLineNumberRuler();
 
3921       //      if (fLineNumberRulerColumn != null
 
3922       //        && (LINE_NUMBER_COLOR.equals(property) ||
 
3923       // PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property) ||
 
3924       // PREFERENCE_COLOR_BACKGROUND.equals(property))) {
 
3926       //        initializeLineNumberRulerColumn(fLineNumberRulerColumn);
 
3929       if (isJavaEditorHoverProperty(property))
 
3930         updateHoverBehavior();
 
3932       if (BROWSER_LIKE_LINKS.equals(property)) {
 
3933         if (isBrowserLikeLinks())
 
3934           enableBrowserLikeLinks();
 
3936           disableBrowserLikeLinks();
 
3940       if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE.equals(property)) {
 
3941         if ((event.getNewValue() instanceof Boolean) && ((Boolean) event.getNewValue()).booleanValue())
 
3946       if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE.equals(property)) {
 
3947         if (event.getNewValue() instanceof Boolean) {
 
3948           Boolean disable = (Boolean) event.getNewValue();
 
3949           enableOverwriteMode(!disable.booleanValue());
 
3954       //        if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property))
 
3956       //                if (event.getNewValue() instanceof Boolean) {
 
3957       //                        boolean markOccurrenceAnnotations=
 
3958       // ((Boolean)event.getNewValue()).booleanValue();
 
3959       //                        if (markOccurrenceAnnotations != fMarkOccurrenceAnnotations) {
 
3960       //                                fMarkOccurrenceAnnotations= markOccurrenceAnnotations;
 
3961       //                                if (!fMarkOccurrenceAnnotations)
 
3962       //                                        uninstallOccurrencesFinder();
 
3964       //                                        installOccurrencesFinder();
 
3969       // (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property))
 
3971       //                if (event.getNewValue() instanceof Boolean) {
 
3972       //                        boolean stickyOccurrenceAnnotations=
 
3973       // ((Boolean)event.getNewValue()).booleanValue();
 
3974       //                        if (stickyOccurrenceAnnotations != fStickyOccurrenceAnnotations)
 
3976       //                                fStickyOccurrenceAnnotations= stickyOccurrenceAnnotations;
 
3977       //// if (!fMarkOccurrenceAnnotations)
 
3978       //// uninstallOccurrencesFinder();
 
3980       //// installOccurrencesFinder();
 
3985       ((PHPSourceViewerConfiguration) getSourceViewerConfiguration()).handlePropertyChangeEvent(event);
 
3987       //                if (affectsOverrideIndicatorAnnotations(event)) {
 
3988       //                        if (isShowingOverrideIndicators()) {
 
3989       //                                if (fOverrideIndicatorManager == null)
 
3990       //                                        installOverrideIndicator(true);
 
3992       //                                if (fOverrideIndicatorManager != null)
 
3993       //                                        uninstallOverrideIndicator();
 
3998       if (PreferenceConstants.EDITOR_FOLDING_PROVIDER.equals(property)) {
 
3999         if (sourceViewer instanceof ProjectionViewer) {
 
4000           ProjectionViewer projectionViewer = (ProjectionViewer) sourceViewer;
 
4001           if (fProjectionModelUpdater != null)
 
4002             fProjectionModelUpdater.uninstall();
 
4003           // either freshly enabled or provider changed
 
4004           fProjectionModelUpdater = PHPeclipsePlugin.getDefault().getFoldingStructureProviderRegistry().getCurrentFoldingProvider();
 
4005           if (fProjectionModelUpdater != null) {
 
4006             fProjectionModelUpdater.install(this, projectionViewer);
 
4012       super.handlePreferenceStoreChanged(event);
 
4018   // AbstractTextEditor#handlePreferenceStoreChanged(PropertyChangeEvent)
 
4020   //  protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
 
4024   //      ISourceViewer sourceViewer = getSourceViewer();
 
4025   //      if (sourceViewer == null)
 
4028   //      String property = event.getProperty();
 
4031   // (JavaSourceViewerConfiguration.PREFERENCE_TAB_WIDTH.equals(property)) {
 
4032   //      // Object value= event.getNewValue();
 
4033   //      // if (value instanceof Integer) {
 
4034   //      // sourceViewer.getTextWidget().setTabs(((Integer) value).intValue());
 
4035   //      // } else if (value instanceof String) {
 
4036   //      // sourceViewer.getTextWidget().setTabs(Integer.parseInt((String)
 
4042   //      if (IPreferenceConstants.LINE_NUMBER_RULER.equals(property)) {
 
4043   //        if (isLineNumberRulerVisible())
 
4044   //          showLineNumberRuler();
 
4046   //          hideLineNumberRuler();
 
4050   //      if (fLineNumberRulerColumn != null
 
4051   //        && (IPreferenceConstants.LINE_NUMBER_COLOR.equals(property)
 
4052   //          || PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT.equals(property)
 
4053   //          || PREFERENCE_COLOR_BACKGROUND.equals(property))) {
 
4055   //        initializeLineNumberRulerColumn(fLineNumberRulerColumn);
 
4059   //      super.handlePreferenceStoreChanged(event);
 
4063   //  private boolean isJavaEditorHoverProperty(String property) {
 
4064   //    return PreferenceConstants.EDITOR_DEFAULT_HOVER.equals(property)
 
4065   //      || PreferenceConstants.EDITOR_NONE_HOVER.equals(property)
 
4066   //      || PreferenceConstants.EDITOR_CTRL_HOVER.equals(property)
 
4067   //      || PreferenceConstants.EDITOR_SHIFT_HOVER.equals(property)
 
4068   //      || PreferenceConstants.EDITOR_CTRL_ALT_HOVER.equals(property)
 
4069   //      || PreferenceConstants.EDITOR_CTRL_SHIFT_HOVER.equals(property)
 
4070   //      || PreferenceConstants.EDITOR_CTRL_ALT_SHIFT_HOVER.equals(property)
 
4071   //      || PreferenceConstants.EDITOR_ALT_SHIFT_HOVER.equals(property);
 
4075    * Shows the line number ruler column.
 
4077   //  private void showLineNumberRuler() {
 
4078   //    IVerticalRuler v = getVerticalRuler();
 
4079   //    if (v instanceof CompositeRuler) {
 
4080   //      CompositeRuler c = (CompositeRuler) v;
 
4081   //      c.addDecorator(1, createLineNumberRulerColumn());
 
4084   private boolean isJavaEditorHoverProperty(String property) {
 
4085     return PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property);
 
4089    * Return whether the browser like links should be enabled according to the preference store settings.
 
4091    * @return <code>true</code> if the browser like links should be enabled
 
4093   private boolean isBrowserLikeLinks() {
 
4094     IPreferenceStore store = getPreferenceStore();
 
4095     return store.getBoolean(BROWSER_LIKE_LINKS);
 
4099    * Enables browser like links.
 
4101   private void enableBrowserLikeLinks() {
 
4102     if (fMouseListener == null) {
 
4103       fMouseListener = new MouseClickListener();
 
4104       fMouseListener.install();
 
4109    * Disables browser like links.
 
4111   private void disableBrowserLikeLinks() {
 
4112     if (fMouseListener != null) {
 
4113       fMouseListener.uninstall();
 
4114       fMouseListener = null;
 
4119    * Handles a property change event describing a change of the java core's preferences and updates the preference related editor
 
4123    *          the property change event
 
4125   protected void handlePreferencePropertyChanged(org.eclipse.core.runtime.Preferences.PropertyChangeEvent event) {
 
4126     if (COMPILER_TASK_TAGS.equals(event.getProperty())) {
 
4127       ISourceViewer sourceViewer = getSourceViewer();
 
4128       if (sourceViewer != null
 
4129           && affectsTextPresentation(new PropertyChangeEvent(event.getSource(), event.getProperty(), event.getOldValue(), event
 
4131         sourceViewer.invalidateTextPresentation();
 
4133     if (PreferenceConstants.EDITOR_WRAP_WORDS.equals(event.getProperty())) {
 
4139    * Return whether the line number ruler column should be visible according to the preference store settings.
 
4141    * @return <code>true</code> if the line numbers should be visible
 
4143   //  protected boolean isLineNumberRulerVisible() {
 
4144   //    IPreferenceStore store = getPreferenceStore();
 
4145   //    return store.getBoolean(LINE_NUMBER_RULER);
 
4148    * Hides the line number ruler column.
 
4150   //  private void hideLineNumberRuler() {
 
4151   //    IVerticalRuler v = getVerticalRuler();
 
4152   //    if (v instanceof CompositeRuler) {
 
4153   //      CompositeRuler c = (CompositeRuler) v;
 
4155   //        c.removeDecorator(1);
 
4156   //      } catch (Throwable e) {
 
4161    * @see AbstractTextEditor#handleCursorPositionChanged()
 
4163   //  protected void handleCursorPositionChanged() {
 
4164   //    super.handleCursorPositionChanged();
 
4165   //    if (!isEditingScriptRunning() && fUpdater != null)
 
4169    * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleElementContentReplaced()
 
4171   protected void handleElementContentReplaced() {
 
4172     super.handleElementContentReplaced();
 
4173     if (fProjectionModelUpdater != null)
 
4174       fProjectionModelUpdater.initialize();
 
4178    * Initializes the given line number ruler column from the preference store.
 
4180    * @param rulerColumn
 
4181    *          the ruler column to be initialized
 
4183   //  protected void initializeLineNumberRulerColumn(LineNumberRulerColumn
 
4185   //    JavaTextTools textTools =
 
4186   // PHPeclipsePlugin.getDefault().getJavaTextTools();
 
4187   //    IColorManager manager = textTools.getColorManager();
 
4189   //    IPreferenceStore store = getPreferenceStore();
 
4190   //    if (store != null) {
 
4193   //      // foreground color
 
4194   //      if (store.contains(LINE_NUMBER_COLOR)) {
 
4195   //        if (store.isDefault(LINE_NUMBER_COLOR))
 
4196   //          rgb = PreferenceConverter.getDefaultColor(store, LINE_NUMBER_COLOR);
 
4198   //          rgb = PreferenceConverter.getColor(store, LINE_NUMBER_COLOR);
 
4200   //      rulerColumn.setForeground(manager.getColor(rgb));
 
4203   //      // background color
 
4204   //      if (!store.getBoolean(PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT)) {
 
4205   //        if (store.contains(PREFERENCE_COLOR_BACKGROUND)) {
 
4206   //          if (store.isDefault(PREFERENCE_COLOR_BACKGROUND))
 
4207   //            rgb = PreferenceConverter.getDefaultColor(store,
 
4208   // PREFERENCE_COLOR_BACKGROUND);
 
4210   //            rgb = PreferenceConverter.getColor(store, PREFERENCE_COLOR_BACKGROUND);
 
4213   //      rulerColumn.setBackground(manager.getColor(rgb));
 
4217    * Creates a new line number ruler column that is appropriately initialized.
 
4219   //  protected IVerticalRulerColumn createLineNumberRulerColumn() {
 
4220   //    fLineNumberRulerColumn = new LineNumberRulerColumn();
 
4221   //    initializeLineNumberRulerColumn(fLineNumberRulerColumn);
 
4222   //    return fLineNumberRulerColumn;
 
4225    * @see AbstractTextEditor#createVerticalRuler()
 
4227   //  protected IVerticalRuler createVerticalRuler() {
 
4228   //    CompositeRuler ruler = new CompositeRuler();
 
4229   //    ruler.addDecorator(0, new AnnotationRulerColumn(VERTICAL_RULER_WIDTH));
 
4230   //    if (isLineNumberRulerVisible())
 
4231   //      ruler.addDecorator(1, createLineNumberRulerColumn());
 
4234   //  private static IRegion getSignedSelection(ITextViewer viewer) {
 
4236   //    StyledText text = viewer.getTextWidget();
 
4237   //    int caretOffset = text.getCaretOffset();
 
4238   //    Point selection = text.getSelection();
 
4241   //    int offset, length;
 
4242   //    if (caretOffset == selection.x) {
 
4243   //      offset = selection.y;
 
4244   //      length = selection.x - selection.y;
 
4248   //      offset = selection.x;
 
4249   //      length = selection.y - selection.x;
 
4252   //    return new Region(offset, length);
 
4254   protected IRegion getSignedSelection(ISourceViewer sourceViewer) {
 
4255     StyledText text = sourceViewer.getTextWidget();
 
4256     Point selection = text.getSelectionRange();
 
4258     if (text.getCaretOffset() == selection.x) {
 
4259       selection.x = selection.x + selection.y;
 
4260       selection.y = -selection.y;
 
4263     selection.x = widgetOffset2ModelOffset(sourceViewer, selection.x);
 
4265     return new Region(selection.x, selection.y);
 
4268   /** Preference key for matching brackets */
 
4269   protected final static String MATCHING_BRACKETS = PreferenceConstants.EDITOR_MATCHING_BRACKETS;
 
4271   /** Preference key for matching brackets color */
 
4272   protected final static String MATCHING_BRACKETS_COLOR = PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR;
 
4274   /** Preference key for highlighting current line */
 
4275   //  protected final static String CURRENT_LINE = PreferenceConstants.EDITOR_CURRENT_LINE;
 
4276   /** Preference key for highlight color of current line */
 
4277   //  protected final static String CURRENT_LINE_COLOR = PreferenceConstants.EDITOR_CURRENT_LINE_COLOR;
 
4278   /** Preference key for showing print marging ruler */
 
4279   //  protected final static String PRINT_MARGIN = PreferenceConstants.EDITOR_PRINT_MARGIN;
 
4280   /** Preference key for print margin ruler color */
 
4281   //  protected final static String PRINT_MARGIN_COLOR = PreferenceConstants.EDITOR_PRINT_MARGIN_COLOR;
 
4282   /** Preference key for print margin ruler column */
 
4283   //  protected final static String PRINT_MARGIN_COLUMN = PreferenceConstants.EDITOR_PRINT_MARGIN_COLUMN;
 
4284   /** Preference key for error indication */
 
4285   //  protected final static String ERROR_INDICATION =
 
4286   // PreferenceConstants.EDITOR_PROBLEM_INDICATION;
 
4287   /** Preference key for error color */
 
4288   //  protected final static String ERROR_INDICATION_COLOR =
 
4289   // PreferenceConstants.EDITOR_PROBLEM_INDICATION_COLOR;
 
4290   /** Preference key for warning indication */
 
4291   //  protected final static String WARNING_INDICATION =
 
4292   // PreferenceConstants.EDITOR_WARNING_INDICATION;
 
4293   /** Preference key for warning color */
 
4294   //  protected final static String WARNING_INDICATION_COLOR =
 
4295   // PreferenceConstants.EDITOR_WARNING_INDICATION_COLOR;
 
4296   /** Preference key for task indication */
 
4297   protected final static String TASK_INDICATION = PreferenceConstants.EDITOR_TASK_INDICATION;
 
4299   /** Preference key for task color */
 
4300   protected final static String TASK_INDICATION_COLOR = PreferenceConstants.EDITOR_TASK_INDICATION_COLOR;
 
4302   /** Preference key for bookmark indication */
 
4303   protected final static String BOOKMARK_INDICATION = PreferenceConstants.EDITOR_BOOKMARK_INDICATION;
 
4305   /** Preference key for bookmark color */
 
4306   protected final static String BOOKMARK_INDICATION_COLOR = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_COLOR;
 
4308   /** Preference key for search result indication */
 
4309   protected final static String SEARCH_RESULT_INDICATION = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION;
 
4311   /** Preference key for search result color */
 
4312   protected final static String SEARCH_RESULT_INDICATION_COLOR = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_COLOR;
 
4314   /** Preference key for unknown annotation indication */
 
4315   protected final static String UNKNOWN_INDICATION = PreferenceConstants.EDITOR_UNKNOWN_INDICATION;
 
4317   /** Preference key for unknown annotation color */
 
4318   protected final static String UNKNOWN_INDICATION_COLOR = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_COLOR;
 
4320   /** Preference key for shwoing the overview ruler */
 
4321   protected final static String OVERVIEW_RULER = PreferenceConstants.EDITOR_OVERVIEW_RULER;
 
4323   /** Preference key for error indication in overview ruler */
 
4324   protected final static String ERROR_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_ERROR_INDICATION_IN_OVERVIEW_RULER;
 
4326   /** Preference key for warning indication in overview ruler */
 
4327   protected final static String WARNING_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_WARNING_INDICATION_IN_OVERVIEW_RULER;
 
4329   /** Preference key for task indication in overview ruler */
 
4330   protected final static String TASK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER;
 
4332   /** Preference key for bookmark indication in overview ruler */
 
4333   protected final static String BOOKMARK_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_BOOKMARK_INDICATION_IN_OVERVIEW_RULER;
 
4335   /** Preference key for search result indication in overview ruler */
 
4336   protected final static String SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER;
 
4338   /** Preference key for unknown annotation indication in overview ruler */
 
4339   protected final static String UNKNOWN_INDICATION_IN_OVERVIEW_RULER = PreferenceConstants.EDITOR_UNKNOWN_INDICATION_IN_OVERVIEW_RULER;
 
4341   //            /** Preference key for compiler task tags */
 
4342   //            private final static String COMPILER_TASK_TAGS=
 
4343   // JavaCore.COMPILER_TASK_TAGS;
 
4344   /** Preference key for browser like links */
 
4345   private final static String BROWSER_LIKE_LINKS = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS;
 
4347   /** Preference key for key modifier of browser like links */
 
4348   private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER;
 
4351    * Preference key for key modifier mask of browser like links. The value is only used if the value of
 
4352    * <code>EDITOR_BROWSER_LIKE_LINKS</code> cannot be resolved to valid SWT modifier bits.
 
4356   private final static String BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK = PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK;
 
4358   private final static char[] BRACKETS = { '{', '}', '(', ')', '[', ']' };
 
4360   private static boolean isBracket(char character) {
 
4361     for (int i = 0; i != BRACKETS.length; ++i)
 
4362       if (character == BRACKETS[i])
 
4367   private static boolean isSurroundedByBrackets(IDocument document, int offset) {
 
4368     if (offset == 0 || offset == document.getLength())
 
4372       return isBracket(document.getChar(offset - 1)) && isBracket(document.getChar(offset));
 
4374     } catch (BadLocationException e) {
 
4379   //  protected void configureSourceViewerDecorationSupport() {
 
4381   //    fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher);
 
4383   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4384   //      AnnotationType.UNKNOWN,
 
4385   //      UNKNOWN_INDICATION_COLOR,
 
4386   //      UNKNOWN_INDICATION,
 
4387   //      UNKNOWN_INDICATION_IN_OVERVIEW_RULER,
 
4389   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4390   //      AnnotationType.BOOKMARK,
 
4391   //      BOOKMARK_INDICATION_COLOR,
 
4392   //      BOOKMARK_INDICATION,
 
4393   //      BOOKMARK_INDICATION_IN_OVERVIEW_RULER,
 
4395   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4396   //      AnnotationType.TASK,
 
4397   //      TASK_INDICATION_COLOR,
 
4399   //      TASK_INDICATION_IN_OVERVIEW_RULER,
 
4401   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4402   //      AnnotationType.SEARCH,
 
4403   //      SEARCH_RESULT_INDICATION_COLOR,
 
4404   //      SEARCH_RESULT_INDICATION,
 
4405   //      SEARCH_RESULT_INDICATION_IN_OVERVIEW_RULER,
 
4407   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4408   //      AnnotationType.WARNING,
 
4409   //      WARNING_INDICATION_COLOR,
 
4410   //      WARNING_INDICATION,
 
4411   //      WARNING_INDICATION_IN_OVERVIEW_RULER,
 
4413   //    fSourceViewerDecorationSupport.setAnnotationPainterPreferenceKeys(
 
4414   //      AnnotationType.ERROR,
 
4415   //      ERROR_INDICATION_COLOR,
 
4416   //      ERROR_INDICATION,
 
4417   //      ERROR_INDICATION_IN_OVERVIEW_RULER,
 
4420   //    fSourceViewerDecorationSupport.setCursorLinePainterPreferenceKeys(CURRENT_LINE,
 
4421   // CURRENT_LINE_COLOR);
 
4422   //    fSourceViewerDecorationSupport.setMarginPainterPreferenceKeys(PRINT_MARGIN,
 
4423   // PRINT_MARGIN_COLOR, PRINT_MARGIN_COLUMN);
 
4424   //    fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS,
 
4425   // MATCHING_BRACKETS_COLOR);
 
4427   //    fSourceViewerDecorationSupport.setSymbolicFontName(getFontPropertyPreferenceKey());
 
4431    * Returns the Java element wrapped by this editors input.
 
4433    * @return the Java element wrapped by this editors input.
 
4436   abstract protected IJavaElement getInputJavaElement();
 
4438   protected void updateStatusLine() {
 
4439     ITextSelection selection = (ITextSelection) getSelectionProvider().getSelection();
 
4440     Annotation annotation = getAnnotation(selection.getOffset(), selection.getLength());
 
4441     setStatusLineErrorMessage(null);
 
4442     setStatusLineMessage(null);
 
4443     if (annotation != null) {
 
4445         fIsUpdatingAnnotationViews = true;
 
4446         updateAnnotationViews(annotation);
 
4448         fIsUpdatingAnnotationViews = false;
 
4450       if (annotation instanceof IJavaAnnotation && ((IJavaAnnotation) annotation).isProblem())
 
4451         setStatusLineMessage(annotation.getText());
 
4456    * Jumps to the matching bracket.
 
4458   public void gotoMatchingBracket() {
 
4460     ISourceViewer sourceViewer = getSourceViewer();
 
4461     IDocument document = sourceViewer.getDocument();
 
4462     if (document == null)
 
4465     IRegion selection = getSignedSelection(sourceViewer);
 
4467     int selectionLength = Math.abs(selection.getLength());
 
4468     if (selectionLength > 1) {
 
4469       setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.invalidSelection")); //$NON-NLS-1$               
 
4470       sourceViewer.getTextWidget().getDisplay().beep();
 
4475     int sourceCaretOffset = selection.getOffset() + selection.getLength();
 
4476     if (isSurroundedByBrackets(document, sourceCaretOffset))
 
4477       sourceCaretOffset -= selection.getLength();
 
4479     IRegion region = fBracketMatcher.match(document, sourceCaretOffset);
 
4480     if (region == null) {
 
4481       setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.noMatchingBracket")); //$NON-NLS-1$              
 
4482       sourceViewer.getTextWidget().getDisplay().beep();
 
4486     int offset = region.getOffset();
 
4487     int length = region.getLength();
 
4492     int anchor = fBracketMatcher.getAnchor();
 
4493     int targetOffset = (PHPPairMatcher.RIGHT == anchor) ? offset : offset + length - 1;
 
4495     boolean visible = false;
 
4496     if (sourceViewer instanceof ITextViewerExtension3) {
 
4497       ITextViewerExtension3 extension = (ITextViewerExtension3) sourceViewer;
 
4498       visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1);
 
4500       IRegion visibleRegion = sourceViewer.getVisibleRegion();
 
4501       visible = (targetOffset >= visibleRegion.getOffset() && targetOffset < visibleRegion.getOffset() + visibleRegion.getLength());
 
4505       setStatusLineErrorMessage(PHPEditorMessages.getString("GotoMatchingBracket.error.bracketOutsideSelectedElement")); //$NON-NLS-1$          
 
4506       sourceViewer.getTextWidget().getDisplay().beep();
 
4510     if (selection.getLength() < 0)
 
4511       targetOffset -= selection.getLength();
 
4513     sourceViewer.setSelectedRange(targetOffset, selection.getLength());
 
4514     sourceViewer.revealRange(targetOffset, selection.getLength());
 
4518    * Ses the given message as error message to this editor's status line.
 
4523   protected void setStatusLineErrorMessage(String msg) {
 
4524     IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
 
4525     if (statusLine != null)
 
4526       statusLine.setMessage(true, msg, null);
 
4530    * Sets the given message as message to this editor's status line.
 
4536   protected void setStatusLineMessage(String msg) {
 
4537     IEditorStatusLine statusLine = (IEditorStatusLine) getAdapter(IEditorStatusLine.class);
 
4538     if (statusLine != null)
 
4539       statusLine.setMessage(false, msg, null);
 
4543    * Returns the annotation closest to the given range respecting the given direction. If an annotation is found, the annotations
 
4544    * current position is copied into the provided annotation position.
 
4551    *          <code>true</code> for forwards, <code>false</code> for backward
 
4552    * @param annotationPosition
 
4553    *          the position of the found annotation
 
4554    * @return the found annotation
 
4556   private Annotation getNextAnnotation(final int offset, final int length, boolean forward, Position annotationPosition) {
 
4558     Annotation nextAnnotation = null;
 
4559     Position nextAnnotationPosition = null;
 
4560     Annotation containingAnnotation = null;
 
4561     Position containingAnnotationPosition = null;
 
4562     boolean currentAnnotation = false;
 
4564     IDocument document = getDocumentProvider().getDocument(getEditorInput());
 
4565     int endOfDocument = document.getLength();
 
4566     int distance = Integer.MAX_VALUE;
 
4568     IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
 
4569     Iterator e = new JavaAnnotationIterator(model, true, true);
 
4570     while (e.hasNext()) {
 
4571       Annotation a = (Annotation) e.next();
 
4572       if ((a instanceof IJavaAnnotation) && ((IJavaAnnotation) a).hasOverlay() || !isNavigationTarget(a))
 
4575       Position p = model.getPosition(a);
 
4579       if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {// || p.includes(offset)) {
 
4580         if (containingAnnotation == null
 
4581             || (forward && p.length >= containingAnnotationPosition.length || !forward
 
4582                 && p.length >= containingAnnotationPosition.length)) {
 
4583           containingAnnotation = a;
 
4584           containingAnnotationPosition = p;
 
4585           currentAnnotation = p.length == length;
 
4588         int currentDistance = 0;
 
4591           currentDistance = p.getOffset() - offset;
 
4592           if (currentDistance < 0)
 
4593             currentDistance = endOfDocument + currentDistance;
 
4595           if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
 
4596             distance = currentDistance;
 
4598             nextAnnotationPosition = p;
 
4601           currentDistance = offset + length - (p.getOffset() + p.length);
 
4602           if (currentDistance < 0)
 
4603             currentDistance = endOfDocument + currentDistance;
 
4605           if (currentDistance < distance || currentDistance == distance && p.length < nextAnnotationPosition.length) {
 
4606             distance = currentDistance;
 
4608             nextAnnotationPosition = p;
 
4613     if (containingAnnotationPosition != null && (!currentAnnotation || nextAnnotation == null)) {
 
4614       annotationPosition.setOffset(containingAnnotationPosition.getOffset());
 
4615       annotationPosition.setLength(containingAnnotationPosition.getLength());
 
4616       return containingAnnotation;
 
4618     if (nextAnnotationPosition != null) {
 
4619       annotationPosition.setOffset(nextAnnotationPosition.getOffset());
 
4620       annotationPosition.setLength(nextAnnotationPosition.getLength());
 
4623     return nextAnnotation;
 
4627    * Returns the annotation overlapping with the given range or <code>null</code>.
 
4633    * @return the found annotation or <code>null</code>
 
4636   private Annotation getAnnotation(int offset, int length) {
 
4637     IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
 
4638     Iterator e = new JavaAnnotationIterator(model, true, true);
 
4639     while (e.hasNext()) {
 
4640       Annotation a = (Annotation) e.next();
 
4641       if (!isNavigationTarget(a))
 
4644       Position p = model.getPosition(a);
 
4645       if (p != null && p.overlapsWith(offset, length))
 
4653    * Returns whether the given annotation is configured as a target for the "Go to Next/Previous Annotation" actions
 
4657    * @return <code>true</code> if this is a target, <code>false</code> otherwise
 
4660   private boolean isNavigationTarget(Annotation annotation) {
 
4661     Preferences preferences = EditorsUI.getPluginPreferences();
 
4662     AnnotationPreference preference = getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
 
4664     //          String key= forward ? preference.getIsGoToNextNavigationTargetKey() : preference.getIsGoToPreviousNavigationTargetKey();
 
4665     String key = preference == null ? null : preference.getIsGoToNextNavigationTargetKey();
 
4666     return (key != null && preferences.getBoolean(key));
 
4670    * Returns a segmentation of the line of the given document appropriate for bidi rendering. The default implementation returns
 
4671    * only the string literals of a php code line as segments.
 
4676    *          the offset of the line
 
4677    * @return the line's bidi segmentation
 
4678    * @throws BadLocationException
 
4679    *           in case lineOffset is not valid in document
 
4681   public static int[] getBidiLineSegments(IDocument document, int lineOffset) throws BadLocationException {
 
4683     IRegion line = document.getLineInformationOfOffset(lineOffset);
 
4684     ITypedRegion[] linePartitioning = document.computePartitioning(lineOffset, line.getLength());
 
4686     List segmentation = new ArrayList();
 
4687     for (int i = 0; i < linePartitioning.length; i++) {
 
4688       if (IPHPPartitions.PHP_STRING_DQ.equals(linePartitioning[i].getType()))
 
4689         segmentation.add(linePartitioning[i]);
 
4692     if (segmentation.size() == 0)
 
4695     int size = segmentation.size();
 
4696     int[] segments = new int[size * 2 + 1];
 
4699     for (int i = 0; i < size; i++) {
 
4700       ITypedRegion segment = (ITypedRegion) segmentation.get(i);
 
4705       int offset = segment.getOffset() - lineOffset;
 
4706       if (offset > segments[j - 1])
 
4707         segments[j++] = offset;
 
4709       if (offset + segment.getLength() >= line.getLength())
 
4712       segments[j++] = offset + segment.getLength();
 
4715     if (j < segments.length) {
 
4716       int[] result = new int[j];
 
4717       System.arraycopy(segments, 0, result, 0, j);
 
4725    * Returns a segmentation of the given line appropriate for bidi rendering. The default implementation returns only the string
 
4726    * literals of a php code line as segments.
 
4729    *          the offset of the line
 
4731    *          the content of the line
 
4732    * @return the line's bidi segmentation
 
4734   protected int[] getBidiLineSegments(int lineOffset, String line) {
 
4735     IDocumentProvider provider = getDocumentProvider();
 
4736     if (provider != null && line != null && line.length() > 0) {
 
4737       IDocument document = provider.getDocument(getEditorInput());
 
4738       if (document != null)
 
4740           return getBidiLineSegments(document, lineOffset);
 
4741         } catch (BadLocationException x) {
 
4749    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
 
4751   //  protected final ISourceViewer createSourceViewer(
 
4752   //    Composite parent,
 
4753   //    IVerticalRuler ruler,
 
4755   //    ISourceViewer viewer = createJavaSourceViewer(parent, ruler, styles);
 
4756   //    StyledText text = viewer.getTextWidget();
 
4757   //    text.addBidiSegmentListener(new BidiSegmentListener() {
 
4758   //      public void lineGetSegments(BidiSegmentEvent event) {
 
4759   //        event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
 
4762   //    // JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
 
4765   public final ISourceViewer getViewer() {
 
4766     return getSourceViewer();
 
4769   //  protected void showOverviewRuler() {
 
4770   //    if (fOverviewRuler != null) {
 
4771   //      if (getSourceViewer() instanceof ISourceViewerExtension) {
 
4772   //        ((ISourceViewerExtension)
 
4773   // getSourceViewer()).showAnnotationsOverview(true);
 
4774   //        fSourceViewerDecorationSupport.updateOverviewDecorations();
 
4779   //  protected void hideOverviewRuler() {
 
4780   //    if (getSourceViewer() instanceof ISourceViewerExtension) {
 
4781   //      fSourceViewerDecorationSupport.hideAnnotationOverview();
 
4782   //      ((ISourceViewerExtension)
 
4783   // getSourceViewer()).showAnnotationsOverview(false);
 
4787   //  protected boolean isOverviewRulerVisible() {
 
4788   //    IPreferenceStore store = getPreferenceStore();
 
4789   //    return store.getBoolean(OVERVIEW_RULER);
 
4792    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
 
4794   //  protected ISourceViewer createJavaSourceViewer(
 
4795   //    Composite parent,
 
4796   //    IVerticalRuler ruler,
 
4797   //    IOverviewRuler overviewRuler,
 
4798   //    boolean isOverviewRulerVisible,
 
4800   //    return new SourceViewer(parent, ruler, overviewRuler,
 
4801   // isOverviewRulerVisible(), styles);
 
4804    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
 
4806   protected ISourceViewer createJavaSourceViewer(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler,
 
4807       boolean isOverviewRulerVisible, int styles, IPreferenceStore store) {
 
4808     return new JavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles, store);
 
4812    * @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int)
 
4814   protected final ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
 
4816     ISourceViewer viewer = createJavaSourceViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles,
 
4817         getPreferenceStore());
 
4819     StyledText text = viewer.getTextWidget();
 
4820     text.addBidiSegmentListener(new BidiSegmentListener() {
 
4821       public void lineGetSegments(BidiSegmentEvent event) {
 
4822         event.segments = getBidiLineSegments(event.lineOffset, event.lineText);
 
4826     //          JavaUIHelp.setHelp(this, text, IJavaHelpContextIds.JAVA_EDITOR);
 
4828     // ensure source viewer decoration support has been created and
 
4830     getSourceViewerDecorationSupport(viewer);
 
4836    * @see AbstractTextEditor#affectsTextPresentation(PropertyChangeEvent)
 
4838   protected boolean affectsTextPresentation(PropertyChangeEvent event) {
 
4839     return ((PHPSourceViewerConfiguration) getSourceViewerConfiguration()).affectsTextPresentation(event)
 
4840         || super.affectsTextPresentation(event);
 
4844   //      protected boolean affectsTextPresentation(PropertyChangeEvent event) {
 
4845   //        JavaTextTools textTools = PHPeclipsePlugin.getDefault().getJavaTextTools();
 
4846   //        return textTools.affectsBehavior(event);
 
4849    * Creates and returns the preference store for this Java editor with the given input.
 
4852    *          The editor input for which to create the preference store
 
4853    * @return the preference store for this editor
 
4857   private IPreferenceStore createCombinedPreferenceStore(IEditorInput input) {
 
4858     List stores = new ArrayList(3);
 
4860     IJavaProject project = EditorUtility.getJavaProject(input);
 
4861     if (project != null)
 
4862       stores.add(new OptionsAdapter(project.getOptions(false), PHPeclipsePlugin.getDefault().getMockupPreferenceStore(),
 
4863           new OptionsAdapter.IPropertyChangeEventFilter() {
 
4865             public boolean isFiltered(PropertyChangeEvent event) {
 
4866               IJavaElement inputJavaElement = getInputJavaElement();
 
4867               IJavaProject javaProject = inputJavaElement != null ? inputJavaElement.getJavaProject() : null;
 
4868               if (javaProject == null)
 
4871               return !javaProject.getProject().equals(event.getSource());
 
4876     stores.add(PHPeclipsePlugin.getDefault().getPreferenceStore());
 
4877     stores.add(new PreferencesAdapter(JavaCore.getPlugin().getPluginPreferences()));
 
4878     stores.add(EditorsUI.getPreferenceStore());
 
4880     return new ChainedPreferenceStore((IPreferenceStore[]) stores.toArray(new IPreferenceStore[stores.size()]));
 
4884    * Jumps to the error next according to the given direction.
 
4886   public void gotoError(boolean forward) {
 
4888     ISelectionProvider provider = getSelectionProvider();
 
4890     ITextSelection s = (ITextSelection) provider.getSelection();
 
4891     Position errorPosition = new Position(0, 0);
 
4892     IJavaAnnotation nextError = getNextError(s.getOffset(), forward, errorPosition);
 
4894     if (nextError != null) {
 
4896       IMarker marker = null;
 
4897       if (nextError instanceof MarkerAnnotation)
 
4898         marker = ((MarkerAnnotation) nextError).getMarker();
 
4900         Iterator e = nextError.getOverlaidIterator();
 
4902           while (e.hasNext()) {
 
4903             Object o = e.next();
 
4904             if (o instanceof MarkerAnnotation) {
 
4905               marker = ((MarkerAnnotation) o).getMarker();
 
4912       if (marker != null) {
 
4913         IWorkbenchPage page = getSite().getPage();
 
4914         IViewPart view = view = page.findView("org.eclipse.ui.views.TaskList"); //$NON-NLS-1$
 
4915         if (view instanceof TaskList) {
 
4916           StructuredSelection ss = new StructuredSelection(marker);
 
4917           ((TaskList) view).setSelection(ss, true);
 
4921       selectAndReveal(errorPosition.getOffset(), errorPosition.getLength());
 
4922       //      setStatusLineErrorMessage(nextError.getMessage());
 
4926       setStatusLineErrorMessage(null);
 
4931   private IJavaAnnotation getNextError(int offset, boolean forward, Position errorPosition) {
 
4933     IJavaAnnotation nextError = null;
 
4934     Position nextErrorPosition = null;
 
4936     IDocument document = getDocumentProvider().getDocument(getEditorInput());
 
4937     int endOfDocument = document.getLength();
 
4940     IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
 
4941     Iterator e = new JavaAnnotationIterator(model, false);
 
4942     while (e.hasNext()) {
 
4944       IJavaAnnotation a = (IJavaAnnotation) e.next();
 
4945       if (a.hasOverlay() || !a.isProblem())
 
4948       Position p = model.getPosition((Annotation) a);
 
4949       if (!p.includes(offset)) {
 
4951         int currentDistance = 0;
 
4954           currentDistance = p.getOffset() - offset;
 
4955           if (currentDistance < 0)
 
4956             currentDistance = endOfDocument - offset + p.getOffset();
 
4958           currentDistance = offset - p.getOffset();
 
4959           if (currentDistance < 0)
 
4960             currentDistance = offset + endOfDocument - p.getOffset();
 
4963         if (nextError == null || currentDistance < distance) {
 
4964           distance = currentDistance;
 
4966           nextErrorPosition = p;
 
4971     if (nextErrorPosition != null) {
 
4972       errorPosition.setOffset(nextErrorPosition.getOffset());
 
4973       errorPosition.setLength(nextErrorPosition.getLength());
 
4979   void removeOccurrenceAnnotations() {
 
4980     IDocumentProvider documentProvider = getDocumentProvider();
 
4981     if (documentProvider == null)
 
4984     IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput());
 
4985     if (annotationModel == null || fOccurrenceAnnotations == null)
 
4988     synchronized (annotationModel) {
 
4989       if (annotationModel instanceof IAnnotationModelExtension) {
 
4990         ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, null);
 
4992         for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++)
 
4993           annotationModel.removeAnnotation(fOccurrenceAnnotations[i]);
 
4995       fOccurrenceAnnotations = null;
 
4999   protected void uninstallOverrideIndicator() {
 
5000     //          if (fOverrideIndicatorManager != null) {
 
5001     //                  fOverrideIndicatorManager.removeAnnotations();
 
5002     //                  fOverrideIndicatorManager= null;
 
5006   protected void installOverrideIndicator(boolean waitForReconcilation) {
 
5007     uninstallOverrideIndicator();
 
5008     IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
 
5009     final IJavaElement inputElement = getInputJavaElement();
 
5011     if (model == null || inputElement == null)
 
5014     //  fOverrideIndicatorManager= new OverrideIndicatorManager(model, inputElement, null);
 
5016     //  if (provideAST) {
 
5017     //          Job job= new Job(JavaEditorMessages.getString("OverrideIndicatorManager.intallJob")) { //$NON-NLS-1$
 
5019     //                   * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
 
5022     //                  protected IStatus run(IProgressMonitor monitor) {
 
5023     //                          CompilationUnit ast= JavaPlugin.getDefault().getASTProvider().getAST(inputElement, true, null);
 
5024     //                          if (fOverrideIndicatorManager != null) // editor might have been closed in the meanwhile
 
5025     //                                  fOverrideIndicatorManager.reconciled(ast, true, monitor);
 
5026     //                          return Status.OK_STATUS;
 
5029     //          job.setPriority(Job.DECORATE);
 
5030     //          job.setSystem(true);
 
5036    * Tells whether override indicators are shown.
 
5038    * @return <code>true</code> if the override indicators are shown
 
5041   //    protected boolean isShowingOverrideIndicators() {
 
5042   //            AnnotationPreference preference=
 
5043   // getAnnotationPreferenceLookup().getAnnotationPreference(OverrideIndicatorManager.ANNOTATION_TYPE);
 
5044   //            IPreferenceStore store= getPreferenceStore();
 
5045   //            return getBoolean(store, preference.getHighlightPreferenceKey())
 
5046   //                    || getBoolean(store, preference.getVerticalRulerPreferenceKey())
 
5047   //                    || getBoolean(store, preference.getOverviewRulerPreferenceKey())
 
5048   //                    || getBoolean(store, preference.getTextPreferenceKey());
 
5051    * Returns the boolean preference for the given key.
 
5054    *          the preference store
 
5056    *          the preference key
 
5057    * @return <code>true</code> if the key exists in the store and its value is <code>true</code>
 
5060   private boolean getBoolean(IPreferenceStore store, String key) {
 
5061     return key != null && store.getBoolean(key);
 
5064   protected boolean isPrefQuickDiffAlwaysOn() {
 
5065     return false; // never show change ruler for the non-editable java editor. Overridden in subclasses like PHPUnitEditor
 
5069    * @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions()
 
5071   protected void createNavigationActions() {
 
5072     super.createNavigationActions();
 
5074     final StyledText textWidget = getSourceViewer().getTextWidget();
 
5076     IAction action = new SmartLineStartAction(textWidget, false);
 
5077     action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START);
 
5078     setAction(ITextEditorActionDefinitionIds.LINE_START, action);
 
5080     action = new SmartLineStartAction(textWidget, true);
 
5081     action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START);
 
5082     setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action);
 
5084     action = new NavigatePreviousSubWordAction();
 
5085     action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS);
 
5086     setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action);
 
5087     textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL);
 
5089     action = new NavigateNextSubWordAction();
 
5090     action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT);
 
5091     setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action);
 
5092     textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL);
 
5094     action = new SelectPreviousSubWordAction();
 
5095     action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS);
 
5096     setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action);
 
5097     textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT, SWT.NULL);
 
5099     action = new SelectNextSubWordAction();
 
5100     action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT);
 
5101     setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action);
 
5102     textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT, SWT.NULL);
 
5106    * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler()
 
5108   protected CompositeRuler createCompositeRuler() {
 
5109     if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER))
 
5110       return super.createCompositeRuler();
 
5112     CompositeRuler ruler = new CompositeRuler();
 
5113     AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess());
 
5114     column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() {
 
5116       public void doubleClick(DoubleClickEvent event) {
 
5117         // for now: just invoke ruler double click action
 
5118         triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK);
 
5121       private void triggerAction(String actionID) {
 
5122         IAction action = getAction(actionID);
 
5123         if (action != null) {
 
5124           if (action instanceof IUpdate)
 
5125             ((IUpdate) action).update();
 
5126           // hack to propagate line change
 
5127           if (action instanceof ISelectionListener) {
 
5128             ((ISelectionListener) action).selectionChanged(null, null);
 
5130           if (action.isEnabled())
 
5136     ruler.addDecorator(0, column);
 
5138     if (isLineNumberRulerVisible())
 
5139       ruler.addDecorator(1, createLineNumberRulerColumn());
 
5140     else if (isPrefQuickDiffAlwaysOn())
 
5141       ruler.addDecorator(1, createChangeRulerColumn());
 
5147    * Returns the folding action group, or <code>null</code> if there is none.
 
5149    * @return the folding action group, or <code>null</code> if there is none
 
5152   protected FoldingActionGroup getFoldingActionGroup() {
 
5153     return fFoldingGroup;
 
5157    * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
 
5159   protected void performRevert() {
 
5160     ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
 
5161     projectionViewer.setRedraw(false);
 
5164       boolean projectionMode = projectionViewer.isProjectionMode();
 
5165       if (projectionMode) {
 
5166         projectionViewer.disableProjection();
 
5167         if (fProjectionModelUpdater != null)
 
5168           fProjectionModelUpdater.uninstall();
 
5171       super.performRevert();
 
5173       if (projectionMode) {
 
5174         if (fProjectionModelUpdater != null)
 
5175           fProjectionModelUpdater.install(this, projectionViewer);
 
5176         projectionViewer.enableProjection();
 
5180       projectionViewer.setRedraw(true);
 
5185    * React to changed selection.
 
5189   protected void selectionChanged() {
 
5190     if (getSelectionProvider() == null)
 
5192     ISourceReference element = computeHighlightRangeSourceReference();
 
5193     if (getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE))
 
5194       synchronizeOutlinePage(element);
 
5195     setSelection(element, false);
 
5199   private boolean isJavaOutlinePageActive() {
 
5200     IWorkbenchPart part = getActivePart();
 
5201     return part instanceof ContentOutline && ((ContentOutline) part).getCurrentPage() == fOutlinePage;
 
5204   private IWorkbenchPart getActivePart() {
 
5205     IWorkbenchWindow window = getSite().getWorkbenchWindow();
 
5206     IPartService service = window.getPartService();
 
5207     IWorkbenchPart part = service.getActivePart();
 
5212    * Computes and returns the source reference that includes the caret and serves as provider for the outline page selection and the
 
5213    * editor range indication.
 
5215    * @return the computed source reference
 
5218   protected ISourceReference computeHighlightRangeSourceReference() {
 
5219     ISourceViewer sourceViewer = getSourceViewer();
 
5220     if (sourceViewer == null)
 
5223     StyledText styledText = sourceViewer.getTextWidget();
 
5224     if (styledText == null)
 
5228     if (sourceViewer instanceof ITextViewerExtension5) {
 
5229       ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer;
 
5230       caret = extension.widgetOffset2ModelOffset(styledText.getCaretOffset());
 
5232       int offset = sourceViewer.getVisibleRegion().getOffset();
 
5233       caret = offset + styledText.getCaretOffset();
 
5236     IJavaElement element = getElementAt(caret, false);
 
5238     if (!(element instanceof ISourceReference))
 
5241     if (element.getElementType() == IJavaElement.IMPORT_DECLARATION) {
 
5243       IImportDeclaration declaration = (IImportDeclaration) element;
 
5244       IImportContainer container = (IImportContainer) declaration.getParent();
 
5245       ISourceRange srcRange = null;
 
5248         srcRange = container.getSourceRange();
 
5249       } catch (JavaModelException e) {
 
5252       if (srcRange != null && srcRange.getOffset() == caret)
 
5256     return (ISourceReference) element;
 
5260    * Returns the most narrow java element including the given offset.
 
5263    *          the offset inside of the requested element
 
5265    *          <code>true</code> if editor input should be reconciled in advance
 
5266    * @return the most narrow java element
 
5269   protected IJavaElement getElementAt(int offset, boolean reconcile) {
 
5270     return getElementAt(offset);