From 61eb503de1c21c1467630c551c2ff1b065d493d1 Mon Sep 17 00:00:00 2001 From: axelcl Date: Wed, 5 Oct 2005 21:04:53 +0000 Subject: [PATCH] Implemented a simple occurrences finder for Variables ($...) and Identifiers; No prference dialog available at the moment --- .../phpdt/internal/compiler/parser/Scanner.java | 12 + .../phpdt/internal/ui/text/JavaWordFinder.java | 55 +- .../java/hover/AbstractJavaEditorTextHover.java | 46 +- .../ui/viewsupport/ISelectionListenerWithAST.java | 35 ++ .../SelectionListenerWithASTManager.java | 233 ++++++++ .../sourceforge/phpdt/ui/PreferenceConstants.java | 12 + .../phpeclipse/phpeditor/PHPEditor.java | 582 +++++++++++++++----- .../phpeclipse/phpeditor/PHPEditorMessages.java | 32 +- .../phpeditor/PHPEditorMessages.properties | 6 +- 9 files changed, 819 insertions(+), 194 deletions(-) create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java index e4ed1ce..ce16744 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java @@ -419,6 +419,18 @@ public class Scanner implements IScanner, ITerminalSymbols { return result; } + public final boolean equalsCurrentTokenSource(char[] word) { + if (word.length != currentPosition - startPosition) { + return false; + } + for (int i = 0; i < word.length; i++) { + if (word[i]!=source[startPosition+i]){ + return false; + } + } + return true; + } + public final char[] getRawTokenSourceEnd() { int length = this.eofPosition - this.currentPosition - 1; char[] sourceEnd = new char[length]; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java index 63934fa..37944fb 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordFinder.java @@ -1,16 +1,15 @@ /******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html - * + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.text; - import net.sourceforge.phpdt.internal.compiler.parser.Scanner; import org.eclipse.jface.text.BadLocationException; @@ -19,42 +18,46 @@ import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Region; public class JavaWordFinder { - + public static IRegion findWord(IDocument document, int offset) { - - int start= -1; - int end= -1; - - + + int start = -1; + int end = -1; + try { - - int pos= offset; - char c; - + + int pos = offset; + char c = ' '; + while (pos >= 0) { - c= document.getChar(pos); + c = document.getChar(pos); + if (c == '$') { + --pos; + break; + } if (!Scanner.isPHPIdentifierPart(c)) break; + --pos; } - - start= pos; - - pos= offset; - int length= document.getLength(); - + + start = pos; + + pos = offset; + int length = document.getLength(); + while (pos < length) { - c= document.getChar(pos); + c = document.getChar(pos); if (!Scanner.isPHPIdentifierPart(c)) break; ++pos; } - - end= pos; - + + end = pos; + } catch (BadLocationException x) { } - + if (start > -1 && end > -1) { if (start == offset && end == offset) return new Region(offset, 0); @@ -63,7 +66,7 @@ public class JavaWordFinder { else return new Region(start + 1, end - start - 1); } - + return null; } } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java index f86494b..ce9fe79 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/hover/AbstractJavaEditorTextHover.java @@ -1,10 +1,10 @@ /******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html - * + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -36,7 +36,7 @@ import org.eclipse.ui.keys.KeySequence; /** * Abstract class for providing hover information for Java elements. - * + * * @since 2.1 */ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHover { @@ -69,44 +69,44 @@ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHove // IClassFileEditorInput cfeInput= (IClassFileEditorInput) input; // return cfeInput.getClassFile(); // } -// -// IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager(); +// +// IWorkingCopyManager manager= PHPeclipsePlugin.getDefault().getWorkingCopyManager(); // return manager.getWorkingCopy(input); // } -// +// // return null; // } - + /* * @see ITextHover#getHoverRegion(ITextViewer, int) */ public IRegion getHoverRegion(ITextViewer textViewer, int offset) { return JavaWordFinder.findWord(textViewer.getDocument(), offset); } - + /* * @see ITextHover#getHoverInfo(ITextViewer, IRegion) */ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { - + // ICodeAssist resolve= getCodeAssist(); // if (resolve != null) { // try { // IJavaElement[] result= null; -// +// // synchronized (resolve) { // result= resolve.codeSelect(hoverRegion.getOffset(), hoverRegion.getLength()); // } -// +// // if (result == null) // return null; -// -// int nResults= result.length; +// +// int nResults= result.length; // if (nResults == 0) // return null; -// +// // return getHoverInfo(result); -// +// // } catch (JavaModelException x) { // PHPeclipsePlugin.log(x.getStatus()); // } @@ -116,7 +116,7 @@ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHove /** * Provides hover information for the given Java elements. - * + * * @return the hover information string * @since 2.1 */ @@ -134,21 +134,21 @@ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHove } }; } - + /** * Returns the tool tip affordance string. - * + * * @return the affordance string or null if disabled or no key binding is defined * @since 3.0 */ protected String getTooltipAffordanceString() { if (!PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE)) return null; - + KeySequence[] sequences= getKeySequences(); if (sequences == null) return null; - + String keySequence= sequences[0].format(); return JavaHoverMessages.getFormattedString("JavaTextHover.makeStickyHint", keySequence); //$NON-NLS-1$ } @@ -156,9 +156,9 @@ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHove /** * Returns the array of valid key sequence bindings for the * show tool tip description command. - * + * * @return the array with the {@link KeySequence}s - * + * * @since 3.0 */ private KeySequence[] getKeySequences() { @@ -170,7 +170,7 @@ public abstract class AbstractJavaEditorTextHover implements IJavaEditorTextHove keySequences[i]= ((IKeySequenceBinding) list.get(i)).getKeySequence(); } return keySequences; - } + } } return null; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java new file mode 100644 index 0000000..d470a99 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/ISelectionListenerWithAST.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import org.eclipse.jface.text.ITextSelection; + +import org.eclipse.ui.IEditorPart; + +/** + * Listener to be informed on text selection changes in an editor (post selection), including the corresponding AST. + * The AST is shared and must not be modified. + * Listeners can be registered in a SelectionListenerWithASTManager. + */ +public interface ISelectionListenerWithAST { + + /** + * Called when a selection has changed. The method is called in a post selection event in an background + * thread. + * @param part The editor part in which the selection change has occured. + * @param selection The new text selection + * @param astRoot The AST tree corresponding to the editor's input. This AST is shared and must + * not be modified. + */ + void selectionChanged(IEditorPart part, ITextSelection selection); +// void selectionChanged(IEditorPart part, ITextSelection selection, CompilationUnit astRoot); + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java new file mode 100644 index 0000000..a08966a --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.viewsupport; + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpdt.core.IJavaElement; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.util.ListenerList; +import org.eclipse.jface.viewers.IPostSelectionProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Infrastructure to share an AST for editor post selection listeners. + */ +public class SelectionListenerWithASTManager { + + private static SelectionListenerWithASTManager fgDefault; + + /** + * @return Returns the default manager instance. + */ + public static SelectionListenerWithASTManager getDefault() { + if (fgDefault == null) { + fgDefault= new SelectionListenerWithASTManager(); + } + return fgDefault; + } + + + private final static class PartListenerGroup { + private ITextEditor fPart; + private ISelectionChangedListener fSelectionListener, fPostSelectionListener; + private Job fCurrentJob; + private ListenerList fAstListeners; + /** + * Lock to avoid having more than one calculateAndInform job in parallel. + * Only jobs may synchronize on this as otherwise deadlocks are possible. + */ + private final Object fJobLock= new Object(); + + public PartListenerGroup(ITextEditor part) { + fPart= part; + fCurrentJob= null; + fAstListeners= new ListenerList(); + + fSelectionListener= new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection= event.getSelection(); + if (selection instanceof ITextSelection) { + fireSelectionChanged((ITextSelection) selection); + } + } + }; + + fPostSelectionListener= new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection= event.getSelection(); + if (selection instanceof ITextSelection) { + firePostSelectionChanged((ITextSelection) selection); + } + } + }; + } + + public boolean isEmpty() { + return fAstListeners.isEmpty(); + } + + public void install(ISelectionListenerWithAST listener) { + if (isEmpty()) { + ISelectionProvider selectionProvider= fPart.getSelectionProvider(); + if (selectionProvider instanceof IPostSelectionProvider) { + ((IPostSelectionProvider) selectionProvider).addPostSelectionChangedListener(fPostSelectionListener); + selectionProvider.addSelectionChangedListener(fSelectionListener); + } + } + fAstListeners.add(listener); + } + + public void uninstall(ISelectionListenerWithAST listener) { + fAstListeners.remove(listener); + if (isEmpty()) { + ISelectionProvider selectionProvider= fPart.getSelectionProvider(); + if (selectionProvider instanceof IPostSelectionProvider) { + ((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(fPostSelectionListener); + selectionProvider.removeSelectionChangedListener(fSelectionListener); + } + } + } + + public void fireSelectionChanged(final ITextSelection selection) { + if (fCurrentJob != null) { + fCurrentJob.cancel(); + } + } + + public void firePostSelectionChanged(final ITextSelection selection) { + if (fCurrentJob != null) { + fCurrentJob.cancel(); + } + final IJavaElement input= getJavaElement(); + if (input == null) { + return; + } + + fCurrentJob= new Job("SelectionListenerWithASTManager Job") {//JavaUIMessages.SelectionListenerWithASTManager_job_title) { + public IStatus run(IProgressMonitor monitor) { + if (monitor == null) { + monitor= new NullProgressMonitor(); + } + synchronized (fJobLock) { + return calculateASTandInform(input, selection, monitor); + } + } + }; + fCurrentJob.setPriority(Job.DECORATE); + fCurrentJob.setSystem(true); + fCurrentJob.schedule(); + } + + private IJavaElement getJavaElement() { + IEditorInput editorInput= fPart.getEditorInput(); + if (editorInput != null) + return (IJavaElement)editorInput.getAdapter(IJavaElement.class); + + return null; + } + + protected IStatus calculateASTandInform(IJavaElement input, ITextSelection selection, IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + // create AST + try { +// CompilationUnit astRoot= PHPeclipsePlugin.getDefault().getASTProvider().getAST(input, ASTProvider.WAIT_ACTIVE_ONLY, monitor); + +// if (astRoot != null && !monitor.isCanceled()) { + Object[] listeners; + synchronized (PartListenerGroup.this) { + listeners= fAstListeners.getListeners(); + } + for (int i= 0; i < listeners.length; i++) { + ((ISelectionListenerWithAST) listeners[i]).selectionChanged(fPart, selection);//, astRoot); + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + } + return Status.OK_STATUS; +// } + } catch (OperationCanceledException e) { + // thrown when cancelling the AST creation + } + return Status.CANCEL_STATUS; + } + } + + + private Map fListenerGroups; + + private SelectionListenerWithASTManager() { + fListenerGroups= new HashMap(); + } + + /** + * Registers a selection listener for the given editor part. + * @param part The editor part to listen to. + * @param listener The listener to register. + */ + public void addListener(ITextEditor part, ISelectionListenerWithAST listener) { + synchronized (this) { + PartListenerGroup partListener= (PartListenerGroup) fListenerGroups.get(part); + if (partListener == null) { + partListener= new PartListenerGroup(part); + fListenerGroups.put(part, partListener); + } + partListener.install(listener); + } + } + + /** + * Unregisters a selection listener. + * @param part The editor part the listener was registered. + * @param listener The listener to unregister. + */ + public void removeListener(ITextEditor part, ISelectionListenerWithAST listener) { + synchronized (this) { + PartListenerGroup partListener= (PartListenerGroup) fListenerGroups.get(part); + if (partListener != null) { + partListener.uninstall(listener); + if (partListener.isEmpty()) { + fListenerGroups.remove(part); + } + } + } + } + + /** + * Forces a selection changed event that is sent to all listeners registered to the given editor + * part. The event is sent from a background thread: this method call can return before the listeners + * are informed. + * @param part The editor part that has a changed selection + * @param selection The new text selection + */ + public void forceSelectionChange(ITextEditor part, ITextSelection selection) { + synchronized (this) { + PartListenerGroup partListener= (PartListenerGroup) fListenerGroups.get(part); + if (partListener != null) { + partListener.firePostSelectionChanged(selection); + } + } + }} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java index 9aa8ef0..0ff3193 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java @@ -2523,6 +2523,18 @@ public class PreferenceConstants { store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER, ctrl); store.setDefault(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK, SWT.CTRL); +// mark occurrences + store.setDefault(PreferenceConstants.EDITOR_MARK_OCCURRENCES, true); + store.setDefault(PreferenceConstants.EDITOR_STICKY_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS, true); +// store.setDefault(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, true); + // spell checking store.setDefault(PreferenceConstants.SPELLING_CHECK_SPELLING, false); store.setDefault(PreferenceConstants.SPELLING_LOCALE, SpellCheckEngine.getDefaultLocale().toString()); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java index 5f57887..7ecba2c 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -33,7 +33,11 @@ import net.sourceforge.phpdt.core.ISourceRange; import net.sourceforge.phpdt.core.ISourceReference; import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; +import net.sourceforge.phpdt.core.compiler.InvalidInputException; import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError; +import net.sourceforge.phpdt.internal.core.CompilationUnit; import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup; import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter; @@ -41,11 +45,14 @@ import net.sourceforge.phpdt.internal.ui.text.CustomSourceInformationControl; import net.sourceforge.phpdt.internal.ui.text.DocumentCharacterIterator; import net.sourceforge.phpdt.internal.ui.text.HTMLTextPresenter; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; +import net.sourceforge.phpdt.internal.ui.text.JavaWordFinder; import net.sourceforge.phpdt.internal.ui.text.JavaWordIterator; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; import net.sourceforge.phpdt.internal.ui.text.PreferencesAdapter; import net.sourceforge.phpdt.internal.ui.text.java.JavaExpandHover; +import net.sourceforge.phpdt.internal.ui.viewsupport.ISelectionListenerWithAST; import net.sourceforge.phpdt.internal.ui.viewsupport.IViewPartInputProvider; +import net.sourceforge.phpdt.internal.ui.viewsupport.SelectionListenerWithASTManager; import net.sourceforge.phpdt.ui.IContextMenuConstants; import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpdt.ui.PreferenceConstants; @@ -63,6 +70,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; @@ -77,10 +85,12 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DefaultInformationControl; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IDocumentExtension4; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.text.IInformationControl; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ISelectionValidator; import org.eclipse.jface.text.ISynchronizable; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.ITextInputListener; @@ -99,6 +109,7 @@ import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.information.IInformationProvider; import org.eclipse.jface.text.information.InformationPresenter; +import org.eclipse.jface.text.link.LinkedModeModel; import org.eclipse.jface.text.reconciler.IReconciler; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.AnnotationRulerColumn; @@ -151,13 +162,16 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPartService; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.editors.text.DefaultEncodingSupport; @@ -2305,7 +2319,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I ISourceViewer viewer = getSourceViewer(); int widget = -1; while (position != BreakIterator.DONE && widget == -1) { // TODO: - // optimize + // optimize position = fIterator.following(position); if (position != BreakIterator.DONE) widget = modelOffset2WidgetOffset(viewer, position); @@ -2486,7 +2500,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I ISourceViewer viewer = getSourceViewer(); int widget = -1; while (position != BreakIterator.DONE && widget == -1) { // TODO: - // optimize + // optimize position = fIterator.preceding(position); if (position != BreakIterator.DONE) widget = modelOffset2WidgetOffset(viewer, position); @@ -2657,25 +2671,40 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I * * @since 3.0 */ - class OccurrencesFinderJob extends Job implements IDocumentListener { + class OccurrencesFinderJob extends Job { private IDocument fDocument; - private boolean fCancelled = false; + private ISelection fSelection; + + private ISelectionValidator fPostSelectionValidator; + + private boolean fCanceled = false; private IProgressMonitor fProgressMonitor; private Position[] fPositions; - public OccurrencesFinderJob(IDocument document, Position[] positions) { - super("Occurrences Marker"); //$NON-NLS-1$ + public OccurrencesFinderJob(IDocument document, Position[] positions, ISelection selection) { + super(PHPEditorMessages.JavaEditor_markOccurrences_job_name); fDocument = document; + fSelection = selection; fPositions = positions; - fDocument.addDocumentListener(this); + + if (getSelectionProvider() instanceof ISelectionValidator) + fPostSelectionValidator = (ISelectionValidator) getSelectionProvider(); + } + + // cannot use cancel() because it is declared final + void doCancel() { + fCanceled = true; + cancel(); } - private boolean isCancelled() { - return fCancelled || fProgressMonitor.isCanceled(); + private boolean isCanceled() { + return fCanceled || fProgressMonitor.isCanceled() || fPostSelectionValidator != null + && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection) + || LinkedModeModel.hasInstalledModel(fDocument); } /* @@ -2685,76 +2714,110 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I fProgressMonitor = progressMonitor; - try { - - if (isCancelled()) - return Status.CANCEL_STATUS; + if (isCanceled()) + return Status.CANCEL_STATUS; - ITextViewer textViewer = getViewer(); - if (textViewer == null) - return Status.CANCEL_STATUS; + ITextViewer textViewer = getViewer(); + if (textViewer == null) + return Status.CANCEL_STATUS; - IDocument document = textViewer.getDocument(); - if (document == null) - return Status.CANCEL_STATUS; + IDocument document = textViewer.getDocument(); + if (document == null) + return Status.CANCEL_STATUS; - IDocumentProvider documentProvider = getDocumentProvider(); - if (documentProvider == null) - return Status.CANCEL_STATUS; + IDocumentProvider documentProvider = getDocumentProvider(); + if (documentProvider == null) + return Status.CANCEL_STATUS; - IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput()); - if (annotationModel == null) - return Status.CANCEL_STATUS; + IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput()); + if (annotationModel == null) + return Status.CANCEL_STATUS; - // Add occurrence annotations - int length = fPositions.length; - Map annotationMap = new HashMap(length); - for (int i = 0; i < length; i++) { + // Add occurrence annotations + int length = fPositions.length; + Map annotationMap = new HashMap(length); + for (int i = 0; i < length; i++) { - if (isCancelled()) - return Status.CANCEL_STATUS; + if (isCanceled()) + return Status.CANCEL_STATUS; - String message; - Position position = fPositions[i]; + String message; + Position position = fPositions[i]; - // Create & add annotation - try { - message = document.get(position.offset, position.length); - } catch (BadLocationException ex) { - // Skip this match - continue; - } - annotationMap.put(new Annotation("net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$ - position); + // Create & add annotation + try { + message = document.get(position.offset, position.length); + } catch (BadLocationException ex) { + // Skip this match + continue; } + annotationMap.put(new Annotation("net.sourceforge.phpdt.ui.occurrences", false, message), //$NON-NLS-1$ + position); + } - if (isCancelled()) - return Status.CANCEL_STATUS; + if (isCanceled()) + return Status.CANCEL_STATUS; - synchronized (annotationModel) { - if (annotationModel instanceof IAnnotationModelExtension) { - ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap); - } else { - removeOccurrenceAnnotations(); - Iterator iter = annotationMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry mapEntry = (Map.Entry) iter.next(); - annotationModel.addAnnotation((Annotation) mapEntry.getKey(), (Position) mapEntry.getValue()); - } + synchronized (getLockObject(annotationModel)) { + if (annotationModel instanceof IAnnotationModelExtension) { + ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, annotationMap); + } else { + removeOccurrenceAnnotations(); + Iterator iter = annotationMap.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry mapEntry = (Map.Entry) iter.next(); + annotationModel.addAnnotation((Annotation) mapEntry.getKey(), (Position) mapEntry.getValue()); } - fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]); } - } finally { - fDocument.removeDocumentListener(this); + fOccurrenceAnnotations = (Annotation[]) annotationMap.keySet().toArray(new Annotation[annotationMap.keySet().size()]); } + return Status.OK_STATUS; } + } + + /** + * Cancels the occurrences finder job upon document changes. + * + * @since 3.0 + */ + class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener { + + public void install() { + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer == null) + return; + + StyledText text = sourceViewer.getTextWidget(); + if (text == null || text.isDisposed()) + return; + + sourceViewer.addTextInputListener(this); + + IDocument document = sourceViewer.getDocument(); + if (document != null) + document.addDocumentListener(this); + } + + public void uninstall() { + ISourceViewer sourceViewer = getSourceViewer(); + if (sourceViewer != null) + sourceViewer.removeTextInputListener(this); + + IDocumentProvider documentProvider = getDocumentProvider(); + if (documentProvider != null) { + IDocument document = documentProvider.getDocument(getEditorInput()); + if (document != null) + document.removeDocumentListener(this); + } + } /* * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentAboutToBeChanged(DocumentEvent event) { - fCancelled = true; + if (fOccurrencesFinderJob != null) + fOccurrencesFinderJob.doCancel(); } /* @@ -2762,6 +2825,70 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I */ public void documentChanged(DocumentEvent event) { } + + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, + * org.eclipse.jface.text.IDocument) + */ + public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) { + if (oldInput == null) + return; + + oldInput.removeDocumentListener(this); + } + + /* + * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, + * org.eclipse.jface.text.IDocument) + */ + public void inputDocumentChanged(IDocument oldInput, IDocument newInput) { + if (newInput == null) + return; + newInput.addDocumentListener(this); + } + } + + /** + * Internal activation listener. + * + * @since 3.0 + */ + private class ActivationListener implements IWindowListener { + + /* + * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) + * @since 3.1 + */ + public void windowActivated(IWorkbenchWindow window) { + if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations && isActivePart()) { + fForcedMarkOccurrencesSelection = getSelectionProvider().getSelection(); + SelectionListenerWithASTManager.getDefault().forceSelectionChange(PHPEditor.this, + (ITextSelection) fForcedMarkOccurrencesSelection); + } + } + + /* + * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) + * @since 3.1 + */ + public void windowDeactivated(IWorkbenchWindow window) { + if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations && isActivePart()) + removeOccurrenceAnnotations(); + } + + /* + * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) + * @since 3.1 + */ + public void windowClosed(IWorkbenchWindow window) { + } + + /* + * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) + * @since 3.1 + */ + public void windowOpened(IWorkbenchWindow window) { + } } /** @@ -2773,7 +2900,15 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I doSelectionChanged(event); } } - + /** + * The internal shell activation listener for updating occurrences. + * @since 3.0 + */ + private ActivationListener fActivationListener= new ActivationListener(); + private ISelectionListenerWithAST fPostSelectionListenerWithAST; + private OccurrencesFinderJob fOccurrencesFinderJob; + /** The occurrences finder job canceler */ + private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler; /** * Holds the current occurrence annotations. * @@ -2781,7 +2916,45 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I */ private Annotation[] fOccurrenceAnnotations = null; - private Job fOccurrencesFinderJob; + /** + * Tells whether all occurrences of the element at the current caret location + * are automatically marked in this editor. + * + * @since 3.0 + */ + private boolean fMarkOccurrenceAnnotations; + + /** + * The selection used when forcing occurrence marking through code. + * + * @since 3.0 + */ + private ISelection fForcedMarkOccurrencesSelection; + + /** + * The document modification stamp at the time when the last occurrence + * marking took place. + * + * @since 3.1 + */ + private long fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + + /** + * The region of the word under the caret used to when computing the current + * occurrence markings. + * + * @since 3.1 + */ + private IRegion fMarkOccurrenceTargetRegion; + + /** + * Tells whether the occurrence annotations are sticky i.e. whether they stay + * even if there's no valid Java element at the current caret position. Only + * valid if {@link #fMarkOccurrenceAnnotations} is true. + * + * @since 3.0 + */ + private boolean fStickyOccurrenceAnnotations; /** Preference key for showing the line number ruler */ // private final static String LINE_NUMBER_RULER = @@ -2961,24 +3134,17 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I // setSourceViewerConfiguration(new // JavaSourceViewerConfiguration(textTools.getColorManager(), store, // this, IJavaPartitions.JAVA_PARTITIONING)); - // fMarkOccurrenceAnnotations= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES); - // fStickyOccurrenceAnnotations= - // store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES); - // fMarkTypeOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES); - // fMarkMethodOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES); - // fMarkConstantOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES); - // fMarkFieldOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES); - // fMarkLocalVariableypeOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES); - // fMarkExceptionOccurrences= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES); - // fMarkMethodExitPoints= - // store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS); + fMarkOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES); + fStickyOccurrenceAnnotations= store.getBoolean(PreferenceConstants.EDITOR_STICKY_OCCURRENCES); +// fMarkTypeOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_TYPE_OCCURRENCES); +// fMarkMethodOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_OCCURRENCES); +// fMarkConstantOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_CONSTANT_OCCURRENCES); +// fMarkFieldOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_FIELD_OCCURRENCES); +// fMarkLocalVariableypeOccurrences= store.getBoolean(PreferenceConstants.EDITOR_MARK_LOCAL_VARIABLE_OCCURRENCES); +// fMarkExceptions= store.getBoolean(PreferenceConstants.EDITOR_MARK_EXCEPTION_OCCURRENCES); +// fMarkImplementors= store.getBoolean(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS); +// fMarkMethodExitPoints= store.getBoolean(PreferenceConstants.EDITOR_MARK_METHOD_EXIT_POINTS); + } /* @@ -3094,8 +3260,12 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE)) enableOverwriteMode(false); + if (fMarkOccurrenceAnnotations) + installOccurrencesFinder(); + + PlatformUI.getWorkbench().addWindowListener(fActivationListener); + setWordWrap(); - // getEditorSite().getShell().addShellListener(fActivationListener); } private void setWordWrap() { @@ -3406,6 +3576,17 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I if (isBrowserLikeLinks()) disableBrowserLikeLinks(); +// cancel possible running computation + fMarkOccurrenceAnnotations= false; + uninstallOccurrencesFinder(); + + uninstallOverrideIndicator(); + + if (fActivationListener != null) { + PlatformUI.getWorkbench().removeWindowListener(fActivationListener); + fActivationListener= null; + } + if (fEncodingSupport != null) { fEncodingSupport.dispose(); fEncodingSupport = null; @@ -4020,32 +4201,40 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I return; } + if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE.equals(property)) { + if (event.getNewValue() instanceof Boolean) { + Boolean disable = (Boolean) event.getNewValue(); + enableOverwriteMode(!disable.booleanValue()); + } + return; + } + + boolean newBooleanValue= false; + Object newValue= event.getNewValue(); + if (newValue != null) + newBooleanValue= Boolean.valueOf(newValue.toString()).booleanValue(); + if (PreferenceConstants.EDITOR_SYNC_OUTLINE_ON_CURSOR_MOVE.equals(property)) { - if ((event.getNewValue() instanceof Boolean) && ((Boolean) event.getNewValue()).booleanValue()) + if (newBooleanValue) selectionChanged(); return; } - if (PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE.equals(property)) { - if (event.getNewValue() instanceof Boolean) { - Boolean disable = (Boolean) event.getNewValue(); - enableOverwriteMode(!disable.booleanValue()); + if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) { + if (newBooleanValue != fMarkOccurrenceAnnotations) { + fMarkOccurrenceAnnotations= newBooleanValue; + if (!fMarkOccurrenceAnnotations) + uninstallOccurrencesFinder(); + else + installOccurrencesFinder(); } return; } - // if (PreferenceConstants.EDITOR_MARK_OCCURRENCES.equals(property)) - // { - // if (event.getNewValue() instanceof Boolean) { - // boolean markOccurrenceAnnotations= - // ((Boolean)event.getNewValue()).booleanValue(); - // if (markOccurrenceAnnotations != fMarkOccurrenceAnnotations) { - // fMarkOccurrenceAnnotations= markOccurrenceAnnotations; - // if (!fMarkOccurrenceAnnotations) - // uninstallOccurrencesFinder(); - // else - // installOccurrencesFinder(); - // } + if (PreferenceConstants.EDITOR_STICKY_OCCURRENCES.equals(property)) { + fStickyOccurrenceAnnotations= newBooleanValue; + return; + } // } // } // if @@ -4056,14 +4245,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I // ((Boolean)event.getNewValue()).booleanValue(); // if (stickyOccurrenceAnnotations != fStickyOccurrenceAnnotations) // { - // fStickyOccurrenceAnnotations= stickyOccurrenceAnnotations; - // // if (!fMarkOccurrenceAnnotations) - // // uninstallOccurrencesFinder(); - // // else - // // installOccurrencesFinder(); - // } - // } - // } + ((PHPSourceViewerConfiguration) getSourceViewerConfiguration()).handlePropertyChangeEvent(event); @@ -4670,8 +4852,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I continue; if (forward && p.offset == offset || !forward && p.offset + p.getLength() == offset + length) {// || - // p.includes(offset)) - // { + // p.includes(offset)) + // { if (containingAnnotation == null || (forward && p.length >= containingAnnotationPosition.length || !forward && p.length >= containingAnnotationPosition.length)) { @@ -5078,26 +5260,6 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I return nextError; } - void removeOccurrenceAnnotations() { - IDocumentProvider documentProvider = getDocumentProvider(); - if (documentProvider == null) - return; - - IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput()); - if (annotationModel == null || fOccurrenceAnnotations == null) - return; - - synchronized (annotationModel) { - if (annotationModel instanceof IAnnotationModelExtension) { - ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, null); - } else { - for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++) - annotationModel.removeAnnotation(fOccurrenceAnnotations[i]); - } - fOccurrenceAnnotations = null; - } - } - protected void uninstallOverrideIndicator() { // if (fOverrideIndicatorManager != null) { // fOverrideIndicatorManager.removeAnnotations(); @@ -5173,7 +5335,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I protected boolean isPrefQuickDiffAlwaysOn() { return false; // never show change ruler for the non-editable java editor. - // Overridden in subclasses like PHPUnitEditor + // Overridden in subclasses like PHPUnitEditor } /* @@ -5386,7 +5548,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I public ShowInContext getShowInContext() { FileEditorInput fei = (FileEditorInput) getEditorInput(); ShowInContext context = BrowserUtil.getShowInContext(fei.getFile(), false, ""); - if (context!=null) { + if (context != null) { return context; } return new ShowInContext(fei.getFile(), null); @@ -5395,4 +5557,168 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I public String[] getShowInTargetIds() { return new String[] { BrowserView.ID_BROWSER }; } + + /** + * Updates the occurrences annotations based on the current selection. + * + * @param selection + * the text selection + * @param astRoot + * the compilation unit AST + * @since 3.0 + */ + protected void updateOccurrenceAnnotations(ITextSelection selection) {//, CompilationUnit astRoot) { + + if (fOccurrencesFinderJob != null) + fOccurrencesFinderJob.cancel(); + + if (!fMarkOccurrenceAnnotations) + return; + +// if (astRoot == null || selection == null) + if (selection == null) + return; + + IDocument document = getSourceViewer().getDocument(); + if (document == null) + return; + + if (document instanceof IDocumentExtension4) { + int offset = selection.getOffset(); + long currentModificationStamp = ((IDocumentExtension4) document).getModificationStamp(); + if (fMarkOccurrenceTargetRegion != null && currentModificationStamp == fMarkOccurrenceModificationStamp) { + if (fMarkOccurrenceTargetRegion.getOffset() <= offset + && offset <= fMarkOccurrenceTargetRegion.getOffset() + fMarkOccurrenceTargetRegion.getLength()) + return; + } + fMarkOccurrenceTargetRegion = JavaWordFinder.findWord(document, offset); + fMarkOccurrenceModificationStamp = currentModificationStamp; + } + + List matches = null; + + if (matches == null) { + try { + matches = new ArrayList(); + + Scanner fScanner = new Scanner(); + fScanner.setSource(document.get().toCharArray()); + fScanner.setPHPMode(false); + char[] word; + + word = document.get(fMarkOccurrenceTargetRegion.getOffset(), fMarkOccurrenceTargetRegion.getLength()).toCharArray(); + + int fToken = ITerminalSymbols.TokenNameEOF; + try { + fToken = fScanner.getNextToken(); + while (fToken != ITerminalSymbols.TokenNameEOF) { // && fToken != + // TokenNameERROR) { + if (fToken == ITerminalSymbols.TokenNameVariable || fToken == ITerminalSymbols.TokenNameIdentifier) { + // global variable + if (fScanner.equalsCurrentTokenSource(word)) { + matches.add(new Region(fScanner.getCurrentTokenStartPosition(), fScanner.getCurrentTokenEndPosition() + - fScanner.getCurrentTokenStartPosition()+1)); + } + } + fToken = fScanner.getNextToken(); + } + } catch (InvalidInputException e) { + // ignore errors + } catch (SyntaxError e) { + // ignore errors + } + + } catch (BadLocationException e1) { + // ignore errors + } + + } + + if (matches == null || matches.size() == 0) { + if (!fStickyOccurrenceAnnotations) + removeOccurrenceAnnotations(); + return; + } + + Position[] positions = new Position[matches.size()]; + int i = 0; + for (Iterator each = matches.iterator(); each.hasNext();) { + IRegion currentNode = (IRegion) each.next(); + positions[i++] = new Position(currentNode.getOffset(), currentNode.getLength()); + } + + fOccurrencesFinderJob = new OccurrencesFinderJob(document, positions, selection); + // fOccurrencesFinderJob.setPriority(Job.DECORATE); + // fOccurrencesFinderJob.setSystem(true); + // fOccurrencesFinderJob.schedule(); + fOccurrencesFinderJob.run(new NullProgressMonitor()); + } + + protected void installOccurrencesFinder() { + fMarkOccurrenceAnnotations = true; + + fPostSelectionListenerWithAST = new ISelectionListenerWithAST() { + public void selectionChanged(IEditorPart part, ITextSelection selection) { //, CompilationUnit astRoot) { + updateOccurrenceAnnotations(selection);//, astRoot); + } + }; + SelectionListenerWithASTManager.getDefault().addListener(this, fPostSelectionListenerWithAST); + if (getSelectionProvider() != null) { + fForcedMarkOccurrencesSelection = getSelectionProvider().getSelection(); + SelectionListenerWithASTManager.getDefault().forceSelectionChange(this, (ITextSelection) fForcedMarkOccurrencesSelection); + } + + if (fOccurrencesFinderJobCanceler == null) { + fOccurrencesFinderJobCanceler = new OccurrencesFinderJobCanceler(); + fOccurrencesFinderJobCanceler.install(); + } + } + + protected void uninstallOccurrencesFinder() { + fMarkOccurrenceAnnotations = false; + + if (fOccurrencesFinderJob != null) { + fOccurrencesFinderJob.cancel(); + fOccurrencesFinderJob = null; + } + + if (fOccurrencesFinderJobCanceler != null) { + fOccurrencesFinderJobCanceler.uninstall(); + fOccurrencesFinderJobCanceler = null; + } + + if (fPostSelectionListenerWithAST != null) { + SelectionListenerWithASTManager.getDefault().removeListener(this, fPostSelectionListenerWithAST); + fPostSelectionListenerWithAST = null; + } + + removeOccurrenceAnnotations(); + } + + protected boolean isMarkingOccurrences() { + return fMarkOccurrenceAnnotations; + } + + void removeOccurrenceAnnotations() { + fMarkOccurrenceModificationStamp = IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; + fMarkOccurrenceTargetRegion = null; + + IDocumentProvider documentProvider = getDocumentProvider(); + if (documentProvider == null) + return; + + IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput()); + if (annotationModel == null || fOccurrenceAnnotations == null) + return; + + synchronized (getLockObject(annotationModel)) { + if (annotationModel instanceof IAnnotationModelExtension) { + ((IAnnotationModelExtension) annotationModel).replaceAnnotations(fOccurrenceAnnotations, null); + } else { + for (int i = 0, length = fOccurrenceAnnotations.length; i < length; i++) + annotationModel.removeAnnotation(fOccurrenceAnnotations[i]); + } + fOccurrenceAnnotations = null; + } + } } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java index 4350d51..8260ce6 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.java @@ -1,14 +1,14 @@ /********************************************************************** -Copyright (c) 2000, 2002 IBM Corp. and others. -All rights reserved. This program and the accompanying materials -are made available under the terms of the Common Public License v1.0 -which accompanies this distribution, and is available at -http://www.eclipse.org/legal/cpl-v10.html - -Contributors: - IBM Corporation - Initial implementation - www.phpeclipse.de -**********************************************************************/ + Copyright (c) 2000, 2002 IBM Corp. and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Common Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/cpl-v10.html + + Contributors: + IBM Corporation - Initial implementation + www.phpeclipse.de + **********************************************************************/ package net.sourceforge.phpeclipse.phpeditor; import java.text.MessageFormat; @@ -17,9 +17,11 @@ import java.util.ResourceBundle; public class PHPEditorMessages { - private static final String RESOURCE_BUNDLE= "net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages";//$NON-NLS-1$ + private static final String RESOURCE_BUNDLE = "net.sourceforge.phpeclipse.phpeditor.PHPEditorMessages";//$NON-NLS-1$ + + private static ResourceBundle fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE); - private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + public static String JavaEditor_markOccurrences_job_name = "JavaEditor.markOccurrences.job.name"; private PHPEditorMessages() { } @@ -31,14 +33,14 @@ public class PHPEditorMessages { return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ } } - + /** * Gets a string from the resource bundle and formats it with arguments - */ + */ public static String getFormattedString(String key, Object[] args) { return MessageFormat.format(getString(key), args); } - + public static ResourceBundle getResourceBundle() { return fgResourceBundle; } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties index d2dae94..5f8dffc 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorMessages.properties @@ -88,7 +88,7 @@ EditorUtility.concatModifierStrings= {0} + {1} PHPUnitEditor.error.saving.message1=File has been deleted. PHPUnitEditor.error.saving.message2=Could not save file. -PHPUnitEditor.error.saving.message3=Could not save file. +PHPUnitEditor.error.saving.message3=Could not save file. PHPUnitEditor.error.saving.title1=Cannot Save PHPUnitEditor.error.saving.title2=Save Problems PHPUnitEditor.error.saving.title3=Save Problems @@ -122,4 +122,6 @@ JavaOutlinePage.GoIntoTopLevelType.tooltip=Go Into Top Level Type JavaOutlinePage.GoIntoTopLevelType.description=Show children of top level type only JavaOutlinePage.error.ChildrenProvider.getChildren.message1=JavaOutlinePage.ChildrenProvider.getChildren JavaOutlinePage.error.ChildrenProvider.hasChildren.message1=JavaOutlinePage.ChildrenProvider.hasChildren -JavaOutlinePage.error.NoTopLevelType=Top level type not defined \ No newline at end of file +JavaOutlinePage.error.NoTopLevelType=Top level type not defined + +JavaEditor.markOccurrences.job.name= Occurrences Marker \ No newline at end of file -- 1.7.1