From ffe35f8fc0062f4e62477bd848906b73aa9894e1 Mon Sep 17 00:00:00 2001 From: axelcl Date: Wed, 26 Jan 2005 22:47:47 +0000 Subject: [PATCH] * Added browser like links (Ctrl+Mouseclick on identifier; same as F3 shortcut) * Added pref page for PHP Editor-Navigation (i.e. browser like links) * search for task-tags now in multi line comments * fixed bug #996193 (wrong Display.synExec() at startup) * improved handling for subword shortcuts (ARROW_KEY_LEFT, ARROW_KEY_RIGHT, CTRL+ARROW_KEY_LEFT, CTRL+ARROW_KEY_RIGHT) --- net.sourceforge.phpeclipse/plugin.properties | 2 + net.sourceforge.phpeclipse/plugin.xml | 91 ++- .../sourceforge/phpdt/core/CompletionProposal.java | 905 ++++++++++++ .../phpdt/core/CompletionRequestor.java | 165 +++ .../src/net/sourceforge/phpdt/core/Flags.java | 6 +- .../net/sourceforge/phpdt/core/ICodeAssist.java | 198 +++ .../phpdt/core/ICodeCompletionRequestor.java | 263 ++++ .../phpdt/internal/compiler/parser/Parser.java | 12 +- .../phpdt/internal/compiler/parser/Scanner.java | 303 +++-- .../internal/core/util/CommentRecorderScanner.java | 2 +- .../corext/refactoring/util/ResourceUtil.java | 86 ++ .../phpdt/internal/formatter/CodeFormatter.java | 12 +- .../phpdt/internal/ui/actions/ActionUtil.java | 97 ++ .../internal/ui/actions/AddBlockCommentAction.java | 350 +++--- .../internal/ui/actions/BlockCommentAction.java | 21 +- .../phpdt/internal/ui/actions/IndentAction.java | 499 +++++++ .../ui/actions/RemoveBlockCommentAction.java | 26 +- .../ui/preferences/JavaEditorPreferencePage.java | 246 ++-- .../ui/text/DocumentCharacterIterator.java | 200 +++ .../phpdt/internal/ui/text/JavaBreakIterator.java | 418 ++++++ .../phpdt/internal/ui/text/JavaWordIterator.java | 221 +++ .../ui/text/SequenceCharacterIterator.java | 166 +++ .../internal/ui/text/java/JavaExpandHover.java | 188 +++ .../internal/ui/text/java/JavaHoverMessages.java | 85 ++ .../ui/text/java/JavaHoverMessages.properties | 18 + .../sourceforge/phpdt/ui/PreferenceConstants.java | 35 +- .../phpdt/ui/actions/OpenEditorActionGroup.java | 155 ++ .../ui/actions/PHPEditorActionDefinitionIds.java | 2 +- .../phpeclipse/actions/IncludesScanner.java | 2 +- .../actions/OpenDeclarationEditorAction.java | 263 ++++ .../actions/PHPOpenDeclarationAction.java | 103 ++ .../actions/PHPOpenDeclarationEditorAction.java | 293 +---- .../phpeclipse/builder/IdentifierIndexManager.java | 2 +- .../compiler/ast/CompilationUnitDeclaration.java | 2 +- .../BasicJavaEditorActionContributor.java | 17 +- .../CompilationUnitEditorActionContributor.java | 8 +- .../phpeclipse/phpeditor/PHPEditor.java | 1540 ++++++++++++++++++-- .../phpeditor/PHPEditorActionDefinitionIds.java | 16 +- .../phpeclipse/phpeditor/PHPUnitEditor.java | 148 +-- 39 files changed, 6161 insertions(+), 1005 deletions(-) create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionProposal.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestor.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeAssist.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeCompletionRequestor.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/refactoring/util/ResourceUtil.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java create mode 100644 net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java diff --git a/net.sourceforge.phpeclipse/plugin.properties b/net.sourceforge.phpeclipse/plugin.properties index dab4d83..ae1bd78 100644 --- a/net.sourceforge.phpeclipse/plugin.properties +++ b/net.sourceforge.phpeclipse/plugin.properties @@ -23,6 +23,8 @@ newWizardHTMLFile.name=HTML file NewPHPClass.label= Class NewPHPClass.description=Create a PHP class +OpenActionSet.label=Open Declaration/Include +OpenActionSet.description=Open a PHP Declaration or Include OpenDeclaration=Open Declaration/Include ExportWizards.Obfuscator = Obfuscate PHP Project to File system ExportWizards.ObfuscatorDescription = Obfuscate PHP resources to the local file system diff --git a/net.sourceforge.phpeclipse/plugin.xml b/net.sourceforge.phpeclipse/plugin.xml index 57699a0..663efab 100644 --- a/net.sourceforge.phpeclipse/plugin.xml +++ b/net.sourceforge.phpeclipse/plugin.xml @@ -666,14 +666,14 @@ id="net.sourceforge.phpeclipse.phpeditor.ShiftRight"> - @@ -1049,7 +1048,24 @@ - + + + + + + - + @@ -1211,7 +1227,7 @@ platform="carbon" string="Ctrl+/" scope="net.sourceforge.phpdt.ui.phpEditorScope" - command="" + command="net.sourceforge.phpeclipse.phpeditor.toggle.comment" configuration="org.eclipse.ui.defaultAcceleratorConfiguration"> + + + + + + + + + + + + + + + + + + - - - + + + * In typical usage, the user working in a Java code editor issues + * a code assist command. This command results in a call to + * ICodeAssist.codeComplete(position, completionRequestor) + * passing the current position in the source code. The code assist + * engine analyzes the code in the buffer, determines what kind of + * Java language construct is at that position, and proposes ways + * to complete that construct. These proposals are instances of + * subclasses of CompletionProposal. These proposals, + * perhaps after sorting and filtering, are presented to the user + * to make a choice. + *

+ *

+ * The proposal is as follows: insert + * the {@linkplain #getCompletion() completion string} into the + * source file buffer, replacing the characters between + * {@linkplain #getReplaceStart() the start} + * and {@linkplain #getReplaceEnd() end}. The string + * can be arbitrary; for example, it might include not only the + * name of a method but a set of parentheses. Moreover, the source + * range may include source positions before or after the source + * position where ICodeAssist.codeComplete was invoked. + * The rest of the information associated with the proposal is + * to provide context that may help a user to choose from among + * competing proposals. + *

+ *

+ * The completion engine creates instances of this class; it is not + * intended to be used by other clients. + *

+ * + * @see ICodeAssist#codeComplete(int, CompletionRequestor) + * @since 3.0 + */ +public final class CompletionProposal { + + /** + * Completion is a declaration of an anonymous class. + * This kind of completion might occur in a context like + * "new List^;" and complete it to + * "new List() {}". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int ANONYMOUS_CLASS_DECLARATION = 1; + + /** + * Completion is a reference to a field. + * This kind of completion might occur in a context like + * "this.ref^ = 0;" and complete it to + * "this.refcount = 0;". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int FIELD_REF = 2; + + /** + * Completion is a keyword. + * This kind of completion might occur in a context like + * "public cl^ Foo {}" and complete it to + * "public class Foo {}". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int KEYWORD = 3; + + /** + * Completion is a reference to a label. + * This kind of completion might occur in a context like + * "break lo^;" and complete it to + * "break loop;". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int LABEL_REF = 4; + + /** + * Completion is a reference to a local variable. + * This kind of completion might occur in a context like + * "ke^ = 4;" and complete it to + * "keys = 4;". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int LOCAL_VARIABLE_REF = 5; + + /** + * Completion is a reference to a method. + * This kind of completion might occur in a context like + * "System.out.pr^();" and complete it to + * ""System.out.println();". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int METHOD_REF = 6; + + /** + * Completion is a declaration of a method. + * This kind of completion might occur in a context like + * "new List() {si^};" and complete it to + * "new List() {public int size() {} };". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int METHOD_DECLARATION = 7; + + /** + * Completion is a reference to a package. + * This kind of completion might occur in a context like + * "import java.u^.*;" and complete it to + * "import java.util.*;". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int PACKAGE_REF = 8; + + /** + * Completion is a reference to a type. Any kind of type + * is allowed, including primitive types, reference types, + * array types, parameterized types, and type variables. + * This kind of completion might occur in a context like + * "public static Str^ key;" and complete it to + * "public static String key;". + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * + * @see #getKind() + */ + public static final int TYPE_REF = 9; + + /** + * Completion is a declaration of a variable (locals, parameters, + * fields, etc.). + *

+ * The following additional context information is available + * for this kind of completion proposal at little extra cost: + *

+ *

+ * @see #getKind() + */ + public static final int VARIABLE_DECLARATION = 10; + + /** + * Kind of completion request. + */ + private int completionKind; + + /** + * Offset in original buffer where ICodeAssist.codeComplete() was + * requested. + */ + private int completionLocation; + + /** + * Start position (inclusive) of source range in original buffer + * containing the relevant token + * defaults to empty subrange at [0,0). + */ + private int tokenStart = 0; + + /** + * End position (exclusive) of source range in original buffer + * containing the relevant token; + * defaults to empty subrange at [0,0). + */ + private int tokenEnd = 0; + + /** + * Completion string; defaults to empty string. + */ + private char[] completion = CharOperation.NO_CHAR; + + /** + * Start position (inclusive) of source range in original buffer + * to be replaced by completion string; + * defaults to empty subrange at [0,0). + */ + private int replaceStart = 0; + + /** + * End position (exclusive) of source range in original buffer + * to be replaced by completion string; + * defaults to empty subrange at [0,0). + */ + private int replaceEnd = 0; + + /** + * Relevance rating; positive; higher means better; + * defaults to minimum rating. + */ + private int relevance = 1; + + /** + * Signature of the relevant package or type declaration + * in the context, or null if none. + * Defaults to null. + */ + private char[] declarationSignature = null; + + /** + * Simple name of the method, field, + * member, or variable relevant in the context, or + * null if none. + * Defaults to null. + */ + private char[] name = null; + + /** + * Signature of the method, field type, member type, + * relevant in the context, or null if none. + * Defaults to null. + */ + private char[] signature = null; + + /** + * Modifier flags relevant in the context, or + * Flags.AccDefault if none. + * Defaults to Flags.AccDefault. + */ + private int flags = Flags.AccDefault; + + /** + * Parameter names (for method completions), or + * null if none. Lazily computed. + * Defaults to null. + */ + private char[][] parameterNames = null; + + /** + * Indicates whether parameter names have been computed. + */ + private boolean parameterNamesComputed = false; + + /** + * Creates a basic completion proposal. All instance + * field have plausible default values unless otherwise noted. + *

+ * Note that the constructors for this class are internal to the + * Java model implementation. Clients cannot directly create + * CompletionProposal objects. + *

+ * + * @param kind one of the kind constants declared on this class + * @param completionOffset original offset of code completion request + * @return a new completion proposal + */ + public static CompletionProposal create(int kind, int completionOffset) { + return new CompletionProposal(kind, completionOffset); + } + + /** + * Creates a basic completion proposal. All instance + * field have plausible default values unless otherwise noted. + *

+ * Note that the constructors for this class are internal to the + * Java model implementation. Clients cannot directly create + * CompletionProposal objects. + *

+ * + * @param kind one of the kind constants declared on this class + * @param completionLocation original offset of code completion request + */ + CompletionProposal(int kind, int completionLocation) { + if ((kind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION) + || (kind > CompletionProposal.VARIABLE_DECLARATION)) { + throw new IllegalArgumentException(); + } + if (this.completion == null || completionLocation < 0) { + throw new IllegalArgumentException(); + } + this.completionKind = kind; + this.completionLocation = completionLocation; + } + + /** + * Returns the kind of completion being proposed. + *

+ * The set of different kinds of completion proposals is + * expected to change over time. It is strongly recommended + * that clients do not assume that the kind is one of the + * ones they know about, and code defensively for the + * possibility of unexpected future growth. + *

+ * + * @return the kind; one of the kind constants + * declared on this class, or possibly a kind unknown + * to the caller + */ + public int getKind() { + return this.completionKind; + } + + /** + * Returns the character index in the source file buffer + * where source completion was requested (the + * offsetparameter to + * ICodeAssist.codeComplete. + * + * @return character index in source file buffer + * @see ICodeAssist#codeComplete(int,CompletionRequestor) + */ + public int getCompletionLocation() { + return this.completionLocation; + } + + /** + * Returns the character index of the start of the + * subrange in the source file buffer containing the + * relevant token being completed. This + * token is either the identifier or Java language keyword + * under, or immediately preceding, the original request + * offset. If the original request offset is not within + * or immediately after an identifier or keyword, then the + * position returned is original request offset and the + * token range is empty. + * + * @return character index of token start position (inclusive) + */ + public int getTokenStart() { + return this.tokenStart; + } + + /** + * Returns the character index of the end (exclusive) of the subrange + * in the source file buffer containing the + * relevant token. When there is no relevant token, the + * range is empty + * (getEndToken() == getStartToken()). + * + * @return character index of token end position (exclusive) + */ + public int getTokenEnd() { + return this.tokenEnd; + } + + /** + * Sets the character indices of the subrange in the + * source file buffer containing the relevant token being + * completed. This token is either the identifier or + * Java language keyword under, or immediately preceding, + * the original request offset. If the original request + * offset is not within or immediately after an identifier + * or keyword, then the source range begins at original + * request offset and is empty. + *

+ * If not set, defaults to empty subrange at [0,0). + *

+ * + * @param startIndex character index of token start position (inclusive) + * @param endIndex character index of token end position (exclusive) + */ + public void setTokenRange(int startIndex, int endIndex) { + if (startIndex < 0 || endIndex < startIndex) { + throw new IllegalArgumentException(); + } + this.tokenStart = startIndex; + this.tokenEnd = endIndex; + } + + /** + * Returns the proposed sequence of characters to insert into the + * source file buffer, replacing the characters at the specified + * source range. The string can be arbitrary; for example, it might + * include not only the name of a method but a set of parentheses. + *

+ * The client must not modify the array returned. + *

+ * + * @return the completion string + */ + public char[] getCompletion() { + return this.completion; + } + + /** + * Sets the proposed sequence of characters to insert into the + * source file buffer, replacing the characters at the specified + * source range. The string can be arbitrary; for example, it might + * include not only the name of a method but a set of parentheses. + *

+ * If not set, defaults to an empty character array. + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param completion the completion string + */ + public void setCompletion(char[] completion) { + this.completion = completion; + } + + /** + * Returns the character index of the start of the + * subrange in the source file buffer to be replaced + * by the completion string. If the subrange is empty + * (getReplaceEnd() == getReplaceStart()), + * the completion string is to be inserted at this + * index. + *

+ * Note that while the token subrange is precisely + * specified, the replacement range is loosely + * constrained and may not bear any direct relation + * to the original request offset. For example, a + * it would be possible for a type completion to + * propose inserting an import declaration at the + * top of the compilation unit; or the completion + * might include trailing parentheses and + * punctuation for a method completion. + *

+ * + * @return replacement start position (inclusive) + */ + public int getReplaceStart() { + return this.replaceStart; + } + + /** + * Returns the character index of the end of the + * subrange in the source file buffer to be replaced + * by the completion string. If the subrange is empty + * (getReplaceEnd() == getReplaceStart()), + * the completion string is to be inserted at this + * index. + * + * @return replacement end position (exclusive) + */ + public int getReplaceEnd() { + return this.replaceEnd; + } + + /** + * Sets the character indices of the subrange in the + * source file buffer to be replaced by the completion + * string. If the subrange is empty + * (startIndex == endIndex), + * the completion string is to be inserted at this + * index. + *

+ * If not set, defaults to empty subrange at [0,0). + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param startIndex character index of replacement start position (inclusive) + * @param endIndex character index of replacement end position (exclusive) + */ + public void setReplaceRange(int startIndex, int endIndex) { + if (startIndex < 0 || endIndex < startIndex) { + throw new IllegalArgumentException(); + } + this.replaceStart = startIndex; + this.replaceEnd = endIndex; + } + + /** + * Returns the relative relevance rating of this proposal. + * + * @return relevance rating of this proposal; ratings are positive; higher means better + */ + public int getRelevance() { + return this.relevance; + } + + /** + * Sets the relative relevance rating of this proposal. + *

+ * If not set, defaults to the lowest possible rating (1). + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param rating relevance rating of this proposal; ratings are positive; higher means better + */ + public void setRelevance(int rating) { + if (rating <= 0) { + throw new IllegalArgumentException(); + } + this.relevance = rating; + } + + /** + * Returns the type or package signature of the relevant + * declaration in the context, or null if none. + *

+ * This field is available for the following kinds of + * completion proposals: + *

+ * For kinds of completion proposals, this method returns + * null. Clients must not modify the array + * returned. + *

+ * + * @return the declaration signature, or + * null if none + * @see Signature + */ + public char[] getDeclarationSignature() { + return this.declarationSignature; + } + + /** + * Sets the type or package signature of the relevant + * declaration in the context, or null if none. + *

+ * If not set, defaults to none. + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param signature the type or package signature, or + * null if none + */ + public void setDeclarationSignature(char[] signature) { + this.declarationSignature = signature; + } + + /** + * Returns the simple name of the method, field, + * member, or variable relevant in the context, or + * null if none. + *

+ * This field is available for the following kinds of + * completion proposals: + *

+ * For kinds of completion proposals, this method returns + * null. Clients must not modify the array + * returned. + *

+ * + * @return the keyword, field, method, local variable, or member + * name, or null if none + */ + public char[] getName() { + return this.name; + } + + + /** + * Sets the simple name of the method, field, + * member, or variable relevant in the context, or + * null if none. + *

+ * If not set, defaults to none. + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param name the keyword, field, method, local variable, + * or member name, or null if none + */ + public void setName(char[] name) { + this.name = name; + } + + /** + * Returns the signature of the method or type + * relevant in the context, or null if none. + *

+ * This field is available for the following kinds of + * completion proposals: + *

+ * For kinds of completion proposals, this method returns + * null. Clients must not modify the array + * returned. + *

+ * + * @return the signature, or null if none + * @see Signature + */ + public char[] getSignature() { + return this.signature; + } + + /** + * Sets the signature of the method, field type, member type, + * relevant in the context, or null if none. + *

+ * If not set, defaults to none. + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param signature the signature, or null if none + */ + public void setSignature(char[] signature) { + this.signature = signature; + } + + /** + * Returns the modifier flags relevant in the context, or + * Flags.AccDefault if none. + *

+ * This field is available for the following kinds of + * completion proposals: + *

+ * For kinds of completion proposals, this method returns + * Flags.AccDefault. + *

+ * + * @return the modifier flags, or + * Flags.AccDefault if none + * @see Flags + */ + public int getFlags() { + return this.flags; + } + + /** + * Sets the modifier flags relevant in the context. + *

+ * If not set, defaults to none. + *

+ *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param flags the modifier flags, or + * Flags.AccDefault if none + */ + public void setFlags(int flags) { + this.flags = flags; + } + + /** + * Finds the method parameter names. + * This information is relevant to method reference (and + * method declaration proposals). Returns null + * if not available or not relevant. + *

+ * The client must not modify the array returned. + *

+ *

+ * Note that this is an expensive thing to compute, which may require + * parsing Java source files, etc. Use sparingly. + *

+ * + * @param monitor the progress monitor, or null if none + * @return the parameter names, or null if none + * or not available or not relevant + */ + public char[][] findParameterNames(IProgressMonitor monitor) { + if (!this.parameterNamesComputed) { + this.parameterNamesComputed = true; + // TODO (jerome) - Missing implementation + } + return this.parameterNames; + } + + /** + * Sets the method parameter names. + * This information is relevant to method reference (and + * method declaration proposals). + *

+ * The completion engine creates instances of this class and sets + * its properties; this method is not intended to be used by other clients. + *

+ * + * @param parameterNames the parameter names, or null if none + */ + public void setParameterNames(char[][] parameterNames) { + this.parameterNames = parameterNames; + this.parameterNamesComputed = true; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestor.java new file mode 100644 index 0000000..2195c82 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/CompletionRequestor.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +import net.sourceforge.phpdt.core.compiler.IProblem; + +/** + * Abstract base class for a completion requestor which is passed completion + * proposals as they are generated in response to a code assist request. + *

+ * This class is intended to be subclassed by clients. + *

+ *

+ * The code assist engine normally invokes methods on completion + * requestors in the following sequence: + *

+ * requestor.beginReporting();
+ * requestor.accept(proposal_1);
+ * requestor.accept(proposal_2);
+ * ...
+ * requestor.endReporting();
+ * 
+ * If, however, the engine is unable to offer completion proposals + * for whatever reason, completionFailure is called + * with a problem object describing why completions were unavailable. + * In this case, the sequence of calls is: + *
+ * requestor.beginReporting();
+ * requestor.completionFailure(problem);
+ * requestor.endReporting();
+ * 
+ * In either case, the bracketing beginReporting + * endReporting calls are always made. + *

+ *

+ * The class was introduced in 3.0 as a more evolvable replacement + * for the ICompletionRequestor interface. + *

+ * + * @see ICodeAssist + * @since 3.0 + */ +public abstract class CompletionRequestor { + + /** + * The set of CompletionProposal kinds that this requestor + * ignores; 0 means the set is empty. + * 1 << completionProposalKind + */ + private int ignoreSet = 0; + + /** + * Creates a new completion requestor. + * The requestor is interested in all kinds of completion + * proposals; none will be ignored. + */ + public CompletionRequestor() { + // do nothing + } + + /** + * Returns whether the given kind of completion proposal is ignored. + * + * @param completionProposalKind one of the kind constants declared + * on CompletionProposal + * @return true if the given kind of completion proposal + * is ignored by this requestor, and false if it is of + * interest + * @see #setIgnored(int, boolean) + * @see CompletionProposal#getKind() + */ + public final boolean isIgnored(int completionProposalKind) { + if (completionProposalKind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION + || completionProposalKind > CompletionProposal.VARIABLE_DECLARATION) { + throw new IllegalArgumentException(); + } + return 0 != (this.ignoreSet & (1 << completionProposalKind)); + } + + /** + * Sets whether the given kind of completion proposal is ignored. + * + * @param completionProposalKind one of the kind constants declared + * on CompletionProposal + * @param ignore true if the given kind of completion proposal + * is ignored by this requestor, and false if it is of + * interest + * @see #isIgnored(int) + * @see CompletionProposal#getKind() + */ + public final void setIgnored(int completionProposalKind, boolean ignore) { + if (completionProposalKind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION + || completionProposalKind > CompletionProposal.VARIABLE_DECLARATION) { + throw new IllegalArgumentException(); + } + if (ignore) { + this.ignoreSet |= (1 << completionProposalKind); + } else { + this.ignoreSet &= ~(1 << completionProposalKind); + } + } + + /** + * Pro forma notification sent before reporting a batch of + * completion proposals. + *

+ * The default implementation of this method does nothing. + * Clients may override. + *

+ */ + public void beginReporting() { + // do nothing + } + + /** + * Pro forma notification sent after reporting a batch of + * completion proposals. + *

+ * The default implementation of this method does nothing. + * Clients may override. + *

+ */ + public void endReporting() { + // do nothing + } + + /** + * Notification of failure to produce any completions. + * The problem object explains what prevented completing. + *

+ * The default implementation of this method does nothing. + * Clients may override to receive this kind of notice. + *

+ * + * @param problem the problem object + */ + public void completionFailure(IProblem problem) { + // default behavior is to ignore + } + + /** + * Proposes a completion. Has no effect if the kind of proposal + * is being ignored by this requestor. Callers should consider + * checking {@link #isIgnored(int)} before avoid creating proposal + * objects that would only be ignored. + *

+ * Similarly, implementers should check + * {@link #isIgnored(int) isIgnored(proposal.getKind())} + * and ignore proposals that have been declared as uninteresting. + * The proposal object passed in only valid for the duration of + * this call; implementors must not hang on to these objects. + * + * @param proposal the completion proposal + * @exception IllegalArgumentException if the proposal is null + */ + public abstract void accept(CompletionProposal proposal); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java index fefe486..a9ccaae 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/Flags.java @@ -30,7 +30,11 @@ import net.sourceforge.phpdt.internal.compiler.env.IConstants; * @see IMember#getFlags */ public final class Flags { - + /** + * Constant representing the absence of any flag + * @since 3.0 + */ + public static final int AccDefault = 0; /** * Public access flag. See The Java Virtual Machine Specification for more details. * @since 2.0 diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeAssist.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeAssist.java new file mode 100644 index 0000000..a0d7654 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeAssist.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +/** + * Common protocol for Java elements that support source code assist and code + * resolve. + *

+ * This interface is not intended to be implemented by clients. + *

+ */ +public interface ICodeAssist { + + /** + * Performs code completion at the given offset position in this compilation unit, + * reporting results to the given completion requestor. The offset + * is the 0-based index of the character, after which code assist is desired. + * An offset of -1 indicates to code assist at the beginning of this + * compilation unit. + * + * @param offset the given offset position + * @param requestor the given completion requestor + * + * @exception JavaModelException if code assist could not be performed. Reasons include:
    + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The position specified is < -1 or is greater than this compilation unit's + * source length (INDEX_OUT_OF_BOUNDS) + *
+ * + * @exception IllegalArgumentException if requestor is null + * @deprecated Use {@link #codeComplete(int, ICompletionRequestor)} instead. + */ + void codeComplete(int offset, ICodeCompletionRequestor requestor) + throws JavaModelException; + /** + * Performs code completion at the given offset position in this compilation unit, + * reporting results to the given completion requestor. The offset + * is the 0-based index of the character, after which code assist is desired. + * An offset of -1 indicates to code assist at the beginning of this + * compilation unit. + * + * @param offset the given offset position + * @param requestor the given completion requestor + * @exception JavaModelException if code assist could not be performed. Reasons include:
    + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The position specified is < -1 or is greater than this compilation unit's + * source length (INDEX_OUT_OF_BOUNDS) + *
+ * + * @exception IllegalArgumentException if requestor is null + * @since 2.0 + */ + // TODO (jerome - once CompletionRequestor is working) @ deprecated Use {@link #codeComplete(int, CompletionRequestor)} instead. + void codeComplete(int offset, ICompletionRequestor requestor) + throws JavaModelException; + + /** + * DO NOT USE: This API element was added in anticipation of J2SE + * 1.5 support, which is planned for the next release of Eclipse after 3.0. + * It is currently unimplemented, and the API may change slightly before + * reaching its final form. + *

+ * Performs code completion at the given offset position in this compilation unit, + * reporting results to the given completion requestor. The offset + * is the 0-based index of the character, after which code assist is desired. + * An offset of -1 indicates to code assist at the beginning of this + * compilation unit. + *

+ * + * @param offset the given offset position + * @param requestor the given completion requestor + * @exception JavaModelException if code assist could not be performed. Reasons include:

    + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The position specified is < -1 or is greater than this compilation unit's + * source length (INDEX_OUT_OF_BOUNDS) + *
+ * + * @exception IllegalArgumentException if requestor is null + * @since 3.0 + */ + void codeComplete(int offset, CompletionRequestor requestor) + throws JavaModelException; + + /** + * Performs code completion at the given offset position in this compilation unit, + * reporting results to the given completion requestor. The offset + * is the 0-based index of the character, after which code assist is desired. + * An offset of -1 indicates to code assist at the beginning of this + * compilation unit. + * It considers types in the working copies with the given owner first. In other words, + * the owner's working copies will take precedence over their original compilation units + * in the workspace. + *

+ * Note that if a working copy is empty, it will be as if the original compilation + * unit had been deleted. + *

+ * + * @param offset the given offset position + * @param requestor the given completion requestor + * @param owner the owner of working copies that take precedence over their original compilation units + * @exception JavaModelException if code assist could not be performed. Reasons include:
    + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The position specified is < -1 or is greater than this compilation unit's + * source length (INDEX_OUT_OF_BOUNDS) + *
+ * + * @exception IllegalArgumentException if requestor is null + * @since 3.0 + */ + // TODO (jerome - once CompletionRequestor is working) @ deprecated Use {@link #codeComplete(int, CompletionRequestor, WorkingCopyOwner)} instead. + void codeComplete(int offset, ICompletionRequestor requestor, WorkingCopyOwner owner) + throws JavaModelException; + + /** + * DO NOT USE: This API element was added in anticipation of J2SE + * 1.5 support, which is planned for the next release of Eclipse after 3.0. + * It is currently unimplemented, and the API may change slightly before + * reaching its final form. + *

+ * Performs code completion at the given offset position in this compilation unit, + * reporting results to the given completion requestor. The offset + * is the 0-based index of the character, after which code assist is desired. + * An offset of -1 indicates to code assist at the beginning of this + * compilation unit. + * It considers types in the working copies with the given owner first. In other words, + * the owner's working copies will take precedence over their original compilation units + * in the workspace. + *

+ * Note that if a working copy is empty, it will be as if the original compilation + * unit had been deleted. + *

+ * + * @param offset the given offset position + * @param requestor the given completion requestor + * @param owner the owner of working copies that take precedence over their original compilation units + * @exception JavaModelException if code assist could not be performed. Reasons include:
    + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The position specified is < -1 or is greater than this compilation unit's + * source length (INDEX_OUT_OF_BOUNDS) + *
+ * + * @exception IllegalArgumentException if requestor is null + * @since 3.0 + */ + void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner) + throws JavaModelException; + + /** + * Returns the Java elements correspondiing to the given selected text in this compilation unit. + * The offset is the 0-based index of the first selected character. + * The length is the number of selected characters. + * + * @param offset the given offset position + * @param length the number of selected characters + * @return the Java elements correspondiing to the given selected text + * + * @exception JavaModelException if code resolve could not be performed. Reasons include: + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The range specified is not within this element's + * source range (INDEX_OUT_OF_BOUNDS) + * + * + */ + IJavaElement[] codeSelect(int offset, int length) throws JavaModelException; + /** + * Returns the Java elements correspondiing to the given selected text in this compilation unit. + * The offset is the 0-based index of the first selected character. + * The length is the number of selected characters. + * It considers types in the working copies with the given owner first. In other words, + * the owner's working copies will take precedence over their original compilation units + * in the workspace. + *

    + * Note that if a working copy is empty, it will be as if the original compilation + * unit had been deleted. + *

    + * + * @param offset the given offset position + * @param length the number of selected characters + * @param owner the owner of working copies that take precedence over their original compilation units + * @return the Java elements correspondiing to the given selected text + * + * @exception JavaModelException if code resolve could not be performed. Reasons include: + *
  • This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  • + *
  • The range specified is not within this element's + * source range (INDEX_OUT_OF_BOUNDS) + * + * @since 3.0 + */ + IJavaElement[] codeSelect(int offset, int length, WorkingCopyOwner owner) throws JavaModelException; +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeCompletionRequestor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeCompletionRequestor.java new file mode 100644 index 0000000..26a923f --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/core/ICodeCompletionRequestor.java @@ -0,0 +1,263 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.core; + +import org.eclipse.core.resources.IMarker; + +/** + * A completion requestor accepts results as they are computed and is aware + * of source positions to complete the various different results. + *

    + * This interface may be implemented by clients. + *

    + * + * @see ICodeAssist + * @deprecated Use {@link CompletionRequestor} instead. + */ +public interface ICodeCompletionRequestor { +/** + * Code assist notification of a class completion. + * + * @param packageName Declaring package name of the class. + * @param className Name of the class. + * @param completionName The completion for the class. + * Can include ';' for imported classes. + * @param modifiers The modifiers of the class. + * @param completionStart The start position of insertion of the name of the class. + * @param completionEnd The end position of insertion of the name of the class. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + */ +void acceptClass( + char[] packageName, + char[] className, + char[] completionName, + int modifiers, + int completionStart, + int completionEnd); +/** + * Code assist notification of a compilation error detected during completion. + * @param marker Only problems which are categorized as errors are notified to the requestor, + * warnings are silently ignored. + * In case an error got signaled, no other completions might be available, + * therefore the problem message should be presented to the user. + * The source positions of the problem are related to the source where it was + * detected (might be in another compilation unit, if it was indirectly requested + * during the code assist process). + * Note: the problem knows its originating file name. + */ +void acceptError(IMarker marker); +/** + * Code assist notification of a field completion. + * + * @param declaringTypePackageName Name of the package in which the type that contains this field is declared. + * + * @param declaringTypeName Name of the type declaring this new field. + * + * @param name Name of the field. + * + * @param typePackageName Name of the package in which the type of this field is declared. + * + * @param typeName Name of the type of this field. + * + * @param completionName The completion for the field. + * + * @param modifiers The modifiers of this field. + * + * @param completionStart The start position of insertion of the name of this field. + * + * @param completionEnd The end position of insertion of the name of this field. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Base types are in the form "int" or "boolean". + * Array types are in the qualified form "M[]" or "int[]". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + */ +void acceptField( + char[] declaringTypePackageName, + char[] declaringTypeName, + char[] name, + char[] typePackageName, + char[] typeName, + char[] completionName, + int modifiers, + int completionStart, + int completionEnd); +/** + * Code assist notification of an interface completion. + * + * @param packageName Declaring package name of the interface. + * @param interfaceName Name of the interface. + * @param completionName The completion for the interface. + * Can include ';' for imported interfaces. + * @param modifiers The modifiers of the interface. + * @param completionStart The start position of insertion of the name of the interface. + * @param completionEnd The end position of insertion of the name of the interface. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + */ +void acceptInterface( + char[] packageName, + char[] interfaceName, + char[] completionName, + int modifiers, + int completionStart, + int completionEnd); +/** + * Code assist notification of a keyword completion. + * + * @param keywordName The keyword source. + * @param completionStart The start position of insertion of the name of this keyword. + * @param completionEnd The end position of insertion of the name of this keyword. + */ +void acceptKeyword(char[] keywordName, int completionStart, int completionEnd); +/** + * Code assist notification of a label completion. + * + * @param labelName The label source. + * @param completionStart The start position of insertion of the name of this label. + * @param completionEnd The end position of insertion of the name of this label. + */ +void acceptLabel(char[] labelName, int completionStart, int completionEnd); +/** + * Code assist notification of a local variable completion. + * + * @param name Name of the new local variable. + * + * @param typePackageName Name of the package in which the type of this new local variable is declared. + * + * @param typeName Name of the type of this new local variable. + * + * @param modifiers The modifiers of this new local variable. + * + * @param completionStart The start position of insertion of the name of this new local variable. + * + * @param completionEnd The end position of insertion of the name of this new local variable. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Base types are in the form "int" or "boolean". + * Array types are in the qualified form "M[]" or "int[]". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + */ +void acceptLocalVariable( + char[] name, + char[] typePackageName, + char[] typeName, + int modifiers, + int completionStart, + int completionEnd); +/** + * Code assist notification of a method completion. + * + * @param declaringTypePackageName Name of the package in which the type that contains this new method is declared. + * + * @param declaringTypeName Name of the type declaring this new method. + * + * @param selector Name of the new method. + * + * @param parameterPackageNames Names of the packages in which the parameter types are declared. + * Should contain as many elements as parameterTypeNames. + * + * @param parameterTypeNames Names of the parameters types. + * Should contain as many elements as parameterPackageNames. + * + * @param returnTypePackageName Name of the package in which the return type is declared. + * + * @param returnTypeName Name of the return type of this new method, should be null for a constructor. + * + * @param completionName The completion for the method. + * Can include zero, one or two brackets. If the closing bracket is included, then the cursor should be placed before it. + * + * @param modifiers The modifiers of this new method. + * + * @param completionStart The start position of insertion of the name of this new method. + * + * @param completionEnd The end position of insertion of the name of this new method. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Base types are in the form "int" or "boolean". + * Array types are in the qualified form "M[]" or "int[]". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + * + * NOTE: parameter names can be retrieved from the source model after the user selects a specific method. + */ +void acceptMethod( + char[] declaringTypePackageName, + char[] declaringTypeName, + char[] selector, + char[][] parameterPackageNames, + char[][] parameterTypeNames, + char[] returnTypePackageName, + char[] returnTypeName, + char[] completionName, + int modifiers, + int completionStart, + int completionEnd); +/** + * Code assist notification of a modifier completion. + * + * @param modifierName The new modifier. + * @param completionStart The start position of insertion of the name of this new modifier. + * @param completionEnd The end position of insertion of the name of this new modifier. + */ +void acceptModifier(char[] modifierName, int completionStart, int completionEnd); +/** + * Code assist notification of a package completion. + * + * @param packageName The package name. + * @param completionName The completion for the package. + * Can include '.*;' for imports. + * @param completionStart The start position of insertion of the name of this new package. + * @param completionEnd The end position of insertion of the name of this new package. + * + * NOTE - All package names are presented in their readable form: + * Package names are in the form "a.b.c". + * The default package is represented by an empty array. + */ +void acceptPackage( + char[] packageName, + char[] completionName, + int completionStart, + int completionEnd); +/** + * Code assist notification of a type completion. + * + * @param packageName Declaring package name of the type. + * @param typeName Name of the type. + * @param completionName The completion for the type. + * Can include ';' for imported types. + * @param completionStart The start position of insertion of the name of the type. + * @param completionEnd The end position of insertion of the name of the type. + * + * NOTE - All package and type names are presented in their readable form: + * Package names are in the form "a.b.c". + * Nested type names are in the qualified form "A.M". + * The default package is represented by an empty array. + */ +void acceptType( + char[] packageName, + char[] typeName, + char[] completionName, + int completionStart, + int completionEnd); +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index abb27ea..cc9ce7a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -167,7 +167,9 @@ public class Parser //extends PHPParserSuperclass public void initializeScanner() { this.scanner = new Scanner(false /* comment */, false /* whitespace */, this.options .getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /* nls */, false, false, - this.options.taskTags/* taskTags */, this.options.taskPriorites/* taskPriorities */); + this.options.taskTags/* taskTags */, + this.options.taskPriorites/* taskPriorities */, + true/*isTaskCaseSensitive*/); } /** @@ -208,6 +210,12 @@ public class Parser //extends PHPParserSuperclass throw new SyntaxError(1, 0, " ", error); } + private void reportSyntaxError(String error) { + int problemStartPosition = scanner.getCurrentTokenStartPosition(); + int problemEndPosition = scanner.getCurrentTokenEndPosition(); + reportSyntaxError(error, problemStartPosition, problemEndPosition + 1); + } + private void reportSyntaxError(String error, int problemStartPosition, int problemEndPosition) { problemReporter.phpParsingError(new String[] { error }, problemStartPosition, problemEndPosition, referenceContext, compilationUnit.compilationResult); @@ -1682,7 +1690,7 @@ public class Parser //extends PHPParserSuperclass } } else { // TokenNamedefault getNextToken(); - if (token == TokenNameCOLON) { + if (token == TokenNameCOLON || token == TokenNameSEMICOLON) { getNextToken(); if (token == TokenNameRBRACE) { // empty default case 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 655dcef..a1127f5 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 @@ -192,21 +192,25 @@ public class Scanner implements IScanner, ITerminalSymbols { public char[][] taskTags = null; public char[][] taskPriorities = null; - + public boolean isTaskCaseSensitive = true; public static final boolean DEBUG = false; public static final boolean TRACE = false; public ICompilationUnit compilationUnit = null; /** - * Determines if the specified character is permissible as the first character in a PHP identifier + * Determines if the specified character is permissible + * as the first character in a PHP identifier. + * + * The '$' character for HP variables isn't regarded as the first character ! */ public static boolean isPHPIdentifierStart(char ch) { return Character.isLetter(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF); } /** - * Determines if the specified character may be part of a PHP identifier as other than the first character + * Determines if the specified character may be part of a PHP + * identifier as other than the first character */ public static boolean isPHPIdentifierPart(char ch) { return Character.isLetterOrDigit(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF); @@ -1751,6 +1755,10 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameCOMMENT_PHPDOC; return TokenNameCOMMENT_BLOCK; } + + if (this.taskTags != null) { + checkTaskTag(this.startPosition, this.currentPosition); + } } catch (IndexOutOfBoundsException e) { // reset end position for error reporting currentPosition -= 2; @@ -3984,11 +3992,15 @@ public class Scanner implements IScanner, ITerminalSymbols { public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean checkNonExternalizedStringLiterals, boolean assertMode) { - this(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, assertMode, false, null, null); + this(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, assertMode, false, null, null,true); } - public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean checkNonExternalizedStringLiterals, - boolean assertMode, boolean tokenizeStrings, char[][] taskTags, char[][] taskPriorities) { + public Scanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, + boolean checkNonExternalizedStringLiterals, + boolean assertMode, boolean tokenizeStrings, + char[][] taskTags, + char[][] taskPriorities, + boolean isTaskCaseSensitive) { this.eofPosition = Integer.MAX_VALUE; this.tokenizeComments = tokenizeComments; this.tokenizeWhiteSpace = tokenizeWhiteSpace; @@ -4132,86 +4144,203 @@ public class Scanner implements IScanner, ITerminalSymbols { } } +//chech presence of task: tags +//TODO (frederic) see if we need to take unicode characters into account... +public void checkTaskTag(int commentStart, int commentEnd) { + char[] src = this.source; + + // only look for newer task: tags + if (this.foundTaskCount > 0 + && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) { + return; + } + int foundTaskIndex = this.foundTaskCount; + char previous = src[commentStart+1]; // should be '*' or '/' + nextChar : for ( + int i = commentStart + 2; i < commentEnd && i < this.eofPosition; i++) { + char[] tag = null; + char[] priority = null; + // check for tag occurrence only if not ambiguous with javadoc tag + if (previous != '@') { + nextTag : for (int itag = 0; itag < this.taskTags.length; itag++) { + tag = this.taskTags[itag]; + int tagLength = tag.length; + if (tagLength == 0) continue nextTag; + + // ensure tag is not leaded with letter if tag starts with a letter + if (Character.isJavaIdentifierStart(tag[0])) { + if (Character.isJavaIdentifierPart(previous)) { + continue nextTag; + } + } + + for (int t = 0; t < tagLength; t++) { + char sc, tc; + int x = i+t; + if (x >= this.eofPosition || x >= commentEnd) continue nextTag; + if ((sc = src[i + t]) != (tc = tag[t])) { // case sensitive check + if (this.isTaskCaseSensitive || (Character.toLowerCase(sc) != Character.toLowerCase(tc))) { // case insensitive check + continue nextTag; + } + } + } + // ensure tag is not followed with letter if tag finishes with a letter + if (i+tagLength < commentEnd && Character.isJavaIdentifierPart(src[i+tagLength-1])) { + if (Character.isJavaIdentifierPart(src[i + tagLength])) + continue nextTag; + } + if (this.foundTaskTags == null) { + this.foundTaskTags = new char[5][]; + this.foundTaskMessages = new char[5][]; + this.foundTaskPriorities = new char[5][]; + this.foundTaskPositions = new int[5][]; + } else if (this.foundTaskCount == this.foundTaskTags.length) { + System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); + System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, this.foundTaskCount); + } + + priority = this.taskPriorities != null && itag < this.taskPriorities.length + ? this.taskPriorities[itag] + : null; + + this.foundTaskTags[this.foundTaskCount] = tag; + this.foundTaskPriorities[this.foundTaskCount] = priority; + this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 }; + this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; + this.foundTaskCount++; + i += tagLength - 1; // will be incremented when looping + break nextTag; + } + } + previous = src[i]; + } + for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { + // retrieve message start and end positions + int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; + int max_value = i + 1 < this.foundTaskCount + ? this.foundTaskPositions[i + 1][0] - 1 + : commentEnd - 1; + // at most beginning of next task + if (max_value < msgStart) { + max_value = msgStart; // would only occur if tag is before EOF. + } + int end = -1; + char c; + for (int j = msgStart; j < max_value; j++) { + if ((c = src[j]) == '\n' || c == '\r') { + end = j - 1; + break; + } + } + if (end == -1) { + for (int j = max_value; j > msgStart; j--) { + if ((c = src[j]) == '*') { + end = j - 1; + break; + } + } + if (end == -1) + end = max_value; + } + if (msgStart == end) + continue; // empty + // trim the message + while (CharOperation.isWhitespace(src[end]) && msgStart <= end) + end--; + while (CharOperation.isWhitespace(src[msgStart]) && msgStart <= end) + msgStart++; + // update the end position of the task + this.foundTaskPositions[i][1] = end; + // get the message source + final int messageLength = end - msgStart + 1; + char[] message = new char[messageLength]; + System.arraycopy(src, msgStart, message, 0, messageLength); + this.foundTaskMessages[i] = message; + } +} + // chech presence of task: tags - public void checkTaskTag(int commentStart, int commentEnd) { - // only look for newer task: tags - if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) { - return; - } - int foundTaskIndex = this.foundTaskCount; - nextChar: for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) { - char[] tag = null; - char[] priority = null; - // check for tag occurrence - nextTag: for (int itag = 0; itag < this.taskTags.length; itag++) { - tag = this.taskTags[itag]; - priority = this.taskPriorities != null && itag < this.taskPriorities.length ? this.taskPriorities[itag] : null; - int tagLength = tag.length; - for (int t = 0; t < tagLength; t++) { - if (this.source[i + t] != tag[t]) - continue nextTag; - } - if (this.foundTaskTags == null) { - this.foundTaskTags = new char[5][]; - this.foundTaskMessages = new char[5][]; - this.foundTaskPriorities = new char[5][]; - this.foundTaskPositions = new int[5][]; - } else if (this.foundTaskCount == this.foundTaskTags.length) { - System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); - System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, - this.foundTaskCount); - System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, - this.foundTaskCount); - System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, - this.foundTaskCount); - } - this.foundTaskTags[this.foundTaskCount] = tag; - this.foundTaskPriorities[this.foundTaskCount] = priority; - this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 }; - this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; - this.foundTaskCount++; - i += tagLength - 1; // will be incremented when looping - } - } - for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { - // retrieve message start and end positions - int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; - int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd - 1; - // at most beginning of next task - if (max_value < msgStart) - max_value = msgStart; // would only occur if tag is before EOF. - int end = -1; - char c; - for (int j = msgStart; j < max_value; j++) { - if ((c = this.source[j]) == '\n' || c == '\r') { - end = j - 1; - break; - } - } - if (end == -1) { - for (int j = max_value; j > msgStart; j--) { - if ((c = this.source[j]) == '*') { - end = j - 1; - break; - } - } - if (end == -1) - end = max_value; - } - if (msgStart == end) - continue; // empty - // trim the message - while (CharOperation.isWhitespace(source[end]) && msgStart <= end) - end--; - while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end) - msgStart++; - // update the end position of the task - this.foundTaskPositions[i][1] = end; - // get the message source - final int messageLength = end - msgStart + 1; - char[] message = new char[messageLength]; - System.arraycopy(source, msgStart, message, 0, messageLength); - this.foundTaskMessages[i] = message; - } - } +// public void checkTaskTag(int commentStart, int commentEnd) { +// // only look for newer task: tags +// if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) { +// return; +// } +// int foundTaskIndex = this.foundTaskCount; +// nextChar: for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) { +// char[] tag = null; +// char[] priority = null; +// // check for tag occurrence +// nextTag: for (int itag = 0; itag < this.taskTags.length; itag++) { +// tag = this.taskTags[itag]; +// priority = this.taskPriorities != null && itag < this.taskPriorities.length ? this.taskPriorities[itag] : null; +// int tagLength = tag.length; +// for (int t = 0; t < tagLength; t++) { +// if (this.source[i + t] != tag[t]) +// continue nextTag; +// } +// if (this.foundTaskTags == null) { +// this.foundTaskTags = new char[5][]; +// this.foundTaskMessages = new char[5][]; +// this.foundTaskPriorities = new char[5][]; +// this.foundTaskPositions = new int[5][]; +// } else if (this.foundTaskCount == this.foundTaskTags.length) { +// System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); +// System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount * 2][], 0, +// this.foundTaskCount); +// System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount * 2][], 0, +// this.foundTaskCount); +// System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount * 2][], 0, +// this.foundTaskCount); +// } +// this.foundTaskTags[this.foundTaskCount] = tag; +// this.foundTaskPriorities[this.foundTaskCount] = priority; +// this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 }; +// this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; +// this.foundTaskCount++; +// i += tagLength - 1; // will be incremented when looping +// } +// } +// for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { +// // retrieve message start and end positions +// int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; +// int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd - 1; +// // at most beginning of next task +// if (max_value < msgStart) +// max_value = msgStart; // would only occur if tag is before EOF. +// int end = -1; +// char c; +// for (int j = msgStart; j < max_value; j++) { +// if ((c = this.source[j]) == '\n' || c == '\r') { +// end = j - 1; +// break; +// } +// } +// if (end == -1) { +// for (int j = max_value; j > msgStart; j--) { +// if ((c = this.source[j]) == '*') { +// end = j - 1; +// break; +// } +// } +// if (end == -1) +// end = max_value; +// } +// if (msgStart == end) +// continue; // empty +// // trim the message +// while (CharOperation.isWhitespace(source[end]) && msgStart <= end) +// end--; +// while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end) +// msgStart++; +// // update the end position of the task +// this.foundTaskPositions[i][1] = end; +// // get the message source +// final int messageLength = end - msgStart + 1; +// char[] message = new char[messageLength]; +// System.arraycopy(source, msgStart, message, 0, messageLength); +// this.foundTaskMessages[i] = message; +// } +// } } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CommentRecorderScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CommentRecorderScanner.java index 7f74c39..ce634b8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CommentRecorderScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/util/CommentRecorderScanner.java @@ -33,7 +33,7 @@ public class CommentRecorderScanner extends Scanner { // taskTags, taskPriorities, isTaskCaseSensitive); super(tokenizeComments, tokenizeWhiteSpace, checkNonExternalizedStringLiterals, false, false, - taskTags, taskPriorities); + taskTags, taskPriorities, true /*taskCaseSensitive*/); } /** diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/refactoring/util/ResourceUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/refactoring/util/ResourceUtil.java new file mode 100644 index 0000000..673326c --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/refactoring/util/ResourceUtil.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.corext.refactoring.util; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; + +import net.sourceforge.phpdt.core.ICompilationUnit; +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IMember; +import net.sourceforge.phpdt.core.IOpenable; + +import net.sourceforge.phpdt.internal.corext.Assert; + +public class ResourceUtil { + + private ResourceUtil(){ + } + + public static IFile[] getFiles(ICompilationUnit[] cus) { + List files= new ArrayList(cus.length); + for (int i= 0; i < cus.length; i++) { + IResource resource= ResourceUtil.getResource(cus[i]); + if (resource != null && resource.getType() == IResource.FILE) + files.add(resource); + } + return (IFile[]) files.toArray(new IFile[files.size()]); + } + + public static IFile getFile(ICompilationUnit cu) { + IResource resource= ResourceUtil.getResource(cu); + if (resource != null && resource.getType() == IResource.FILE) + return (IFile)resource; + else + return null; + } + + //----- other ------------------------------ + + /** + * Finds an IResource for a given ICompilationUnit. + * If the parameter is a working copy then the IResource for + * the original element is returned. + */ + public static IResource getResource(ICompilationUnit cu) { + return cu.getResource(); + } + + + /** + * Returns the IResource that the given IMember is defined in. + * @see #getResource + */ + public static IResource getResource(IMember member) { + Assert.isTrue(!member.isBinary()); + return getResource(member.getCompilationUnit()); + } + + public static IResource getResource(Object o){ + if (o instanceof IResource) + return (IResource)o; + if (o instanceof IJavaElement) + return getResource((IJavaElement)o); + return null; + } + + private static IResource getResource(IJavaElement element){ + if (element.getElementType() == IJavaElement.COMPILATION_UNIT) + return getResource((ICompilationUnit) element); + else if (element instanceof IOpenable) + return element.getResource(); + else + return null; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java index 7caa523..fe61f5a 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/formatter/CodeFormatter.java @@ -2,6 +2,7 @@ * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v0.5 + * * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v05.html * @@ -23,15 +24,8 @@ import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; import net.sourceforge.phpdt.internal.compiler.ConfigurableOption; import net.sourceforge.phpdt.internal.compiler.parser.Scanner; -import net.sourceforge.phpdt.internal.corext.codemanipulation.StubUtility; -import net.sourceforge.phpdt.internal.corext.util.Strings; import net.sourceforge.phpdt.internal.formatter.impl.FormatterOptions; import net.sourceforge.phpdt.internal.formatter.impl.SplitLine; -import net.sourceforge.phpdt.internal.ui.preferences.CodeFormatterPreferencePage; - -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.formatter.IContentFormatterExtension; -import org.eclipse.jface.text.formatter.IFormattingContext; /** *

    How to format a piece of code ?

    @@ -166,7 +160,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { , false /* nls */ , false /* assert */ , true, /* tokenizeStrings */ - null, null); // regular scanner for forming lines + null, null, true /*taskCaseSensitive*/); // regular scanner for forming lines scanner.recordLineSeparator = true; scanner.ignorePHPOneLiner = true; // to remind of the position of the beginning of the line. @@ -175,7 +169,7 @@ public class CodeFormatter implements ITerminalSymbols, ICodeFormatter { , false /* nls */ , false /* assert */ , true, /* tokenizeStrings */ - null, null); + null, null, true /*taskCaseSensitive*/); splitScanner.ignorePHPOneLiner = true; // secondary scanner to split long lines formed by primary scanning // initialize current line buffer diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java new file mode 100644 index 0000000..d526b77 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/ActionUtil.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.actions; + +import net.sourceforge.phpdt.core.IJavaElement; +import net.sourceforge.phpdt.core.IJavaProject; +import net.sourceforge.phpdt.core.IPackageFragment; +import net.sourceforge.phpdt.core.IPackageFragmentRoot; +import net.sourceforge.phpdt.internal.corext.refactoring.util.ResourceUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectNature; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.widgets.Shell; + +/* + * http://dev.eclipse.org/bugs/show_bug.cgi?id=19104 + */ +public class ActionUtil { + + private ActionUtil(){ + } + + //bug 31998 we will have to disable renaming of linked packages (and cus) + public static boolean mustDisableJavaModelAction(Shell shell, Object element) { + if (!(element instanceof IPackageFragment) && !(element instanceof IPackageFragmentRoot)) + return false; + + IResource resource= ResourceUtil.getResource(element); + if ((resource == null) || (! (resource instanceof IFolder)) || (! resource.isLinked())) + return false; + + MessageDialog.openInformation(shell, ActionMessages.getString("ActionUtil.not_possible"), ActionMessages.getString("ActionUtil.no_linked")); //$NON-NLS-1$ //$NON-NLS-2$ + return true; + } + + public static boolean isProcessable(Shell shell, PHPEditor editor) { + if (editor == null) + return true; + IJavaElement input= SelectionConverter.getInput(editor); + // if a Java editor doesn't have an input of type Java element + // then it is for sure not on the build path + if (input == null) { + MessageDialog.openInformation(shell, + ActionMessages.getString("ActionUtil.notOnBuildPath.title"), //$NON-NLS-1$ + ActionMessages.getString("ActionUtil.notOnBuildPath.message")); //$NON-NLS-1$ + return false; + } + return isProcessable(shell, input); + } + + public static boolean isProcessable(Shell shell, Object element) { + if (!(element instanceof IJavaElement)) + return true; + + if (isOnBuildPath((IJavaElement)element)) + return true; + MessageDialog.openInformation(shell, + ActionMessages.getString("ActionUtil.notOnBuildPath.title"), //$NON-NLS-1$ + ActionMessages.getString("ActionUtil.notOnBuildPath.message")); //$NON-NLS-1$ + return false; + } + + public static boolean isOnBuildPath(IJavaElement element) { + //fix for bug http://dev.eclipse.org/bugs/show_bug.cgi?id=20051 + if (element.getElementType() == IJavaElement.JAVA_PROJECT) + return true; + IJavaProject project= element.getJavaProject(); + try { +// if (!project.isOnClasspath(element)) +// return false; + IProject resourceProject= project.getProject(); + if (resourceProject == null) + return false; + IProjectNature nature= resourceProject.getNature(PHPeclipsePlugin.PHP_NATURE_ID); + // We have a Java project + if (nature != null) + return true; + } catch (CoreException e) { + } + return false; + } +} + diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java index 28fc336..68c90df 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/AddBlockCommentAction.java @@ -1,10 +1,10 @@ /******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation *******************************************************************************/ @@ -14,9 +14,10 @@ import java.util.LinkedList; import java.util.List; import java.util.ResourceBundle; -import net.sourceforge.phpdt.internal.corext.Assert; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; +import net.sourceforge.phpeclipse.phpeditor.php.PHPDocumentPartitioner; +import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPartitioningException; import org.eclipse.jface.text.IDocument; @@ -26,174 +27,181 @@ import org.eclipse.jface.text.ITypedRegion; import org.eclipse.ui.texteditor.ITextEditor; /** - * Action that encloses the editor's current selection with Java block comment terminators - * (/* and */). + * Action that encloses the editor's current selection with Java block comment terminators (/* and + * */). * * @since 3.0 - */ + */ public class AddBlockCommentAction extends BlockCommentAction { - /** - * Creates a new instance. - * - * @param bundle the resource bundle - * @param prefix a prefix to be prepended to the various resource keys - * (described in ResourceAction constructor), or - * null if none - * @param editor the text editor - */ - public AddBlockCommentAction(ResourceBundle bundle, String prefix, ITextEditor editor) { - super(bundle, prefix, editor); - } - - /* - * @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection, org.eclipse.jface.text.IDocumentExtension3, org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory) - */ - protected void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) throws BadLocationException, BadPartitioningException { - int selectionOffset= selection.getOffset(); - int selectionEndOffset= selectionOffset + selection.getLength(); - List edits= new LinkedList(); - //ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, selectionOffset, false); - ITypedRegion partition= docExtension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, selectionOffset, false); - - handleFirstPartition(partition, edits, factory, selectionOffset); - - while (partition.getOffset() + partition.getLength() < selectionEndOffset) { - partition= handleInteriorPartition(partition, edits, factory, docExtension); - } - - handleLastPartition(partition, edits, factory, selectionEndOffset); - - executeEdits(edits); - } - - /** - * Handle the first partition of the selected text. - * - * @param partition - * @param edits - * @param factory - * @param offset - */ - private void handleFirstPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, int offset) throws BadLocationException { - - int partOffset= partition.getOffset(); - String partType= partition.getType(); - - Assert.isTrue(partOffset <= offset, "illegal partition"); //$NON-NLS-1$ - - // first partition: mark start of comment -// if (partType == IDocument.DEFAULT_CONTENT_TYPE) - if (partType == IPHPPartitions.PHP_PARTITIONING) { - // Java code: right where selection starts - edits.add(factory.createEdit(offset, 0, getCommentStart())); - } else if (isSpecialPartition(partType)) { - // special types: include the entire partition - edits.add(factory.createEdit(partOffset, 0, getCommentStart())); - } // javadoc: no mark, will only start after comment - - } - - /** - * Handles the end of the given partition and the start of the next partition, which is returned. - * - * @param partition - * @param edits - * @param factory - * @param docExtension - * @return - * @throws BadLocationException - * @throws BadPartitioningException - */ - private ITypedRegion handleInteriorPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, IDocumentExtension3 docExtension) throws BadPartitioningException, BadLocationException { - - // end of previous partition - String partType= partition.getType(); - int partEndOffset= partition.getOffset() + partition.getLength(); - int tokenLength= getCommentStart().length(); - - boolean wasJavadoc= false; // true if the previous partition is javadoc - - if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) { - - wasJavadoc= true; - -// } else if (partType == IPHPPartitions.JAVA_MULTI_LINE_COMMENT) { -// -// // already in a comment - remove ending mark -// edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$ -// - } - - // advance to next partition - partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false); - partType= partition.getType(); - - // start of next partition - if (wasJavadoc) { - - // if previous was javadoc, and the current one is not, then add block comment start - if (partType == IDocument.DEFAULT_CONTENT_TYPE - || isSpecialPartition(partType)) { - edits.add(factory.createEdit(partition.getOffset(), 0, getCommentStart())); - } - - } else { // !wasJavadoc - - if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) { - // if next is javadoc, end block comment before - edits.add(factory.createEdit(partition.getOffset(), 0, getCommentEnd())); -// } else if (partType == IJavaPartitions.JAVA_MULTI_LINE_COMMENT) { -// // already in a comment - remove startToken -// edits.add(factory.createEdit(partition.getOffset(), getCommentStart().length(), "")); //$NON-NLS-1$ - } - } - - return partition; - } - - /** - * Handles the end of the last partition. - * - * @param partition - * @param edits - * @param factory - * @param endOffset - */ - private void handleLastPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, int endOffset) throws BadLocationException { - - String partType= partition.getType(); - -// if (partType == IDocument.DEFAULT_CONTENT_TYPE) { - if (partType == IPHPPartitions.PHP_PARTITIONING) { - // normal java: end comment where selection ends - edits.add(factory.createEdit(endOffset, 0, getCommentEnd())); - } else if (isSpecialPartition(partType)) { - // special types: consume entire partition - edits.add(factory.createEdit(partition.getOffset() + partition.getLength(), 0, getCommentEnd())); - } - - } - - /** - * Returns whether partType is special, i.e. a Java String, - * Character, or Line End Comment partition. - * - * @param partType the partition type to check - * @return true if partType is special, false otherwise - */ - private boolean isSpecialPartition(String partType) { - return// partType == IPHPPartitions.PHP_CHARACTER - //|| - partType == IPHPPartitions.PHP_STRING_DQ; - //|| partType == IPHPPartitions.PHP_SINGLE_LINE_COMMENT; - } - - /* - * @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#validSelection(org.eclipse.jface.text.ITextSelection) - */ - protected boolean isValidSelection(ITextSelection selection) { - return selection != null && !selection.isEmpty() && selection.getLength() > 0; - } - -} + /** + * Creates a new instance. + * + * @param bundle + * the resource bundle + * @param prefix + * a prefix to be prepended to the various resource keys (described in ResourceAction constructor), or + * null if none + * @param editor + * the text editor + */ + public AddBlockCommentAction(ResourceBundle bundle, String prefix, ITextEditor editor) { + super(bundle, prefix, editor); + } + + /* + * @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection, + * org.eclipse.jface.text.IDocumentExtension3, org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory) + */ + protected void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) + throws BadLocationException, BadPartitioningException { + int selectionOffset = selection.getOffset(); + int selectionEndOffset = selectionOffset + selection.getLength(); + List edits = new LinkedList(); + ITypedRegion partition = docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, selectionOffset, false); + + handleFirstPartition(partition, edits, factory, selectionOffset); + + while (partition.getOffset() + partition.getLength() < selectionEndOffset) { + partition = handleInteriorPartition(partition, edits, factory, docExtension); + } + + handleLastPartition(partition, edits, factory, selectionEndOffset); + + executeEdits(edits); + } + + /** + * Handle the first partition of the selected text. + * + * @param partition + * @param edits + * @param factory + * @param offset + */ + private void handleFirstPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, int offset) + throws BadLocationException { + + int partOffset = partition.getOffset(); + String partType = partition.getType(); + + Assert.isTrue(partOffset <= offset, "illegal partition"); //$NON-NLS-1$ + + // first partition: mark start of comment + if (partType == IDocument.DEFAULT_CONTENT_TYPE || + partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) { + // Java code: right where selection starts + edits.add(factory.createEdit(offset, 0, getCommentStart())); + } else if (isSpecialPartition(partType)) { + // special types: include the entire partition + edits.add(factory.createEdit(partOffset, 0, getCommentStart())); + } // javadoc: no mark, will only start after comment + + } + + /** + * Handles the end of the given partition and the start of the next partition, which is returned. + * + * @param partition + * @param edits + * @param factory + * @param docExtension + * @return + * @throws BadLocationException + * @throws BadPartitioningException + */ + private ITypedRegion handleInteriorPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, + IDocumentExtension3 docExtension) throws BadPartitioningException, BadLocationException { + + // end of previous partition + String partType = partition.getType(); + int partEndOffset = partition.getOffset() + partition.getLength(); + int tokenLength = getCommentStart().length(); + + boolean wasJavadoc = false; // true if the previous partition is javadoc + + if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) { + + wasJavadoc = true; + + } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) { + + // already in a comment - remove ending mark + edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$ + + } + + // advance to next partition + partition = docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false); + partType = partition.getType(); + + // start of next partition + if (wasJavadoc) { + + // if previous was javadoc, and the current one is not, then add block comment start + if (partType == IDocument.DEFAULT_CONTENT_TYPE || + partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE || + isSpecialPartition(partType)) { + edits.add(factory.createEdit(partition.getOffset(), 0, getCommentStart())); + } + + } else { // !wasJavadoc + + if (partType == IPHPPartitions.PHP_PHPDOC_COMMENT) { + // if next is javadoc, end block comment before + edits.add(factory.createEdit(partition.getOffset(), 0, getCommentEnd())); + } else if (partType == IPHPPartitions.PHP_MULTILINE_COMMENT) { + // already in a comment - remove startToken + edits.add(factory.createEdit(partition.getOffset(), getCommentStart().length(), "")); //$NON-NLS-1$ + } + } + + return partition; + } + + /** + * Handles the end of the last partition. + * + * @param partition + * @param edits + * @param factory + * @param endOffset + */ + private void handleLastPartition(ITypedRegion partition, List edits, Edit.EditFactory factory, int endOffset) + throws BadLocationException { + + String partType = partition.getType(); + + if (partType == IDocument.DEFAULT_CONTENT_TYPE || + partType == PHPDocumentPartitioner.PHP_SCRIPT_CODE) { + // normal java: end comment where selection ends + edits.add(factory.createEdit(endOffset, 0, getCommentEnd())); + } else if (isSpecialPartition(partType)) { + // special types: consume entire partition + edits.add(factory.createEdit(partition.getOffset() + partition.getLength(), 0, getCommentEnd())); + } + + } + + /** + * Returns whether partType is special, i.e. a Java String,Character, or + * Line End Comment partition. + * + * @param partType + * the partition type to check + * @return true if partType is special, false otherwise + */ + private boolean isSpecialPartition(String partType) { + // return partType == IJavaPartitions.JAVA_CHARACTER + return partType == IPHPPartitions.PHP_STRING_DQ || partType == IPHPPartitions.PHP_STRING_SQ + || partType == IPHPPartitions.PHP_SINGLELINE_COMMENT; + } + + /* + * @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#validSelection(org.eclipse.jface.text.ITextSelection) + */ + protected boolean isValidSelection(ITextSelection selection) { + return selection != null && !selection.isEmpty() && selection.getLength() > 0; + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java index 285a373..647800f 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/BlockCommentAction.java @@ -1,10 +1,10 @@ /******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation *******************************************************************************/ @@ -14,21 +14,10 @@ import java.util.Iterator; import java.util.List; import java.util.ResourceBundle; -import net.sourceforge.phpdt.internal.corext.Assert; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.BadPartitioningException; -import org.eclipse.jface.text.BadPositionCategoryException; -import org.eclipse.jface.text.DefaultPositionUpdater; -import org.eclipse.jface.text.DocumentEvent; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IDocumentExtension3; -import org.eclipse.jface.text.IPositionUpdater; -import org.eclipse.jface.text.IRewriteTarget; -import org.eclipse.jface.text.ITextSelection; -import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.*; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; + import org.eclipse.ui.IEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java new file mode 100644 index 0000000..7700f37 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/IndentAction.java @@ -0,0 +1,499 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.actions; + +import java.util.ResourceBundle; + +import net.sourceforge.phpdt.core.JavaCore; +import net.sourceforge.phpdt.core.formatter.DefaultCodeFormatterConstants; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; +import net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner; +import net.sourceforge.phpdt.internal.ui.text.JavaIndenter; +import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager; +import net.sourceforge.phpdt.internal.ui.text.SmartBackspaceManager.UndoSpec; +import net.sourceforge.phpdt.internal.ui.text.phpdoc.JavaDocAutoIndentStrategy; +import net.sourceforge.phpdt.ui.PreferenceConstants; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.IRewriteTarget; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.text.TextUtilities; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Display; +import org.eclipse.text.edits.MalformedTreeException; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.text.edits.TextEdit; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; +import org.eclipse.ui.texteditor.IDocumentProvider; +import org.eclipse.ui.texteditor.ITextEditor; +import org.eclipse.ui.texteditor.ITextEditorExtension3; +import org.eclipse.ui.texteditor.TextEditorAction; + + +/** + * Indents a line or range of lines in a Java document to its correct position. No complete + * AST must be present, the indentation is computed using heuristics. The algorith used is fast for + * single lines, but does not store any information and therefore not so efficient for large line + * ranges. + * + * @see net.sourceforge.phpdt.internal.ui.text.JavaHeuristicScanner + * @see net.sourceforge.phpdt.internal.ui.text.JavaIndenter + * @since 3.0 + */ +public class IndentAction extends TextEditorAction { + + /** The caret offset after an indent operation. */ + private int fCaretOffset; + + /** + * Whether this is the action invoked by TAB. When true, indentation behaves + * differently to accomodate normal TAB operation. + */ + private final boolean fIsTabAction; + + /** + * Creates a new instance. + * + * @param bundle the resource bundle + * @param prefix the prefix to use for keys in bundle + * @param editor the text editor + * @param isTabAction whether the action should insert tabs if over the indentation + */ + public IndentAction(ResourceBundle bundle, String prefix, ITextEditor editor, boolean isTabAction) { + super(bundle, prefix, editor); + fIsTabAction= isTabAction; + } + + /* + * @see org.eclipse.jface.action.Action#run() + */ + public void run() { + // update has been called by the framework + if (!isEnabled() || !validateEditorInputState()) + return; + + ITextSelection selection= getSelection(); + final IDocument document= getDocument(); + + if (document != null) { + + final int offset= selection.getOffset(); + final int length= selection.getLength(); + final Position end= new Position(offset + length); + final int firstLine, nLines; + fCaretOffset= -1; + + try { + document.addPosition(end); + firstLine= document.getLineOfOffset(offset); + // check for marginal (zero-length) lines + int minusOne= length == 0 ? 0 : 1; + nLines= document.getLineOfOffset(offset + length - minusOne) - firstLine + 1; + } catch (BadLocationException e) { + // will only happen on concurrent modification + PHPeclipsePlugin.log(new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), IStatus.OK, "", e)); //$NON-NLS-1$ + return; + } + + Runnable runnable= new Runnable() { + public void run() { + IRewriteTarget target= (IRewriteTarget)getTextEditor().getAdapter(IRewriteTarget.class); + if (target != null) { + target.beginCompoundChange(); + target.setRedraw(false); + } + + try { + JavaHeuristicScanner scanner= new JavaHeuristicScanner(document); + JavaIndenter indenter= new JavaIndenter(document, scanner); + boolean hasChanged= false; + for (int i= 0; i < nLines; i++) { + hasChanged |= indentLine(document, firstLine + i, offset, indenter, scanner); + } + + // update caret position: move to new position when indenting just one line + // keep selection when indenting multiple + int newOffset, newLength; + if (fIsTabAction) { + newOffset= fCaretOffset; + newLength= 0; + } else if (nLines > 1) { + newOffset= offset; + newLength= end.getOffset() - offset; + } else { + newOffset= fCaretOffset; + newLength= 0; + } + + // always reset the selection if anything was replaced + // but not when we had a singleline nontab invocation + if (newOffset != -1 && (hasChanged || newOffset != offset || newLength != length)) + selectAndReveal(newOffset, newLength); + + document.removePosition(end); + } catch (BadLocationException e) { + // will only happen on concurrent modification + PHPeclipsePlugin.log(new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), IStatus.OK, "ConcurrentModification in IndentAction", e)); //$NON-NLS-1$ + + } finally { + + if (target != null) { + target.endCompoundChange(); + target.setRedraw(true); + } + } + } + }; + + if (nLines > 50) { + Display display= getTextEditor().getEditorSite().getWorkbenchWindow().getShell().getDisplay(); + BusyIndicator.showWhile(display, runnable); + } else + runnable.run(); + + } + } + + /** + * Selects the given range on the editor. + * + * @param newOffset the selection offset + * @param newLength the selection range + */ + private void selectAndReveal(int newOffset, int newLength) { + Assert.isTrue(newOffset >= 0); + Assert.isTrue(newLength >= 0); + ITextEditor editor= getTextEditor(); + if (editor instanceof PHPEditor) { + ISourceViewer viewer= ((PHPEditor)editor).getViewer(); + if (viewer != null) + viewer.setSelectedRange(newOffset, newLength); + } else + // this is too intrusive, but will never get called anyway + getTextEditor().selectAndReveal(newOffset, newLength); + + } + + /** + * Indents a single line using the java heuristic scanner. Javadoc and multiline comments are + * indented as specified by the JavaDocAutoIndentStrategy. + * + * @param document the document + * @param line the line to be indented + * @param caret the caret position + * @param indenter the java indenter + * @param scanner the heuristic scanner + * @return true if document was modified, false otherwise + * @throws BadLocationException if the document got changed concurrently + */ + private boolean indentLine(IDocument document, int line, int caret, JavaIndenter indenter, JavaHeuristicScanner scanner) throws BadLocationException { + IRegion currentLine= document.getLineInformation(line); + int offset= currentLine.getOffset(); + int wsStart= offset; // where we start searching for non-WS; after the "//" in single line comments + + String indent= null; + if (offset < document.getLength()) { + ITypedRegion partition= TextUtilities.getPartition(document, IPHPPartitions.PHP_PARTITIONING, offset, true); + String type= partition.getType(); + if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT) || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) { + + // TODO this is a hack + // what I want to do +// new JavaDocAutoIndentStrategy().indentLineAtOffset(document, offset); +// return; + + int start= 0; + if (line > 0) { + + IRegion previousLine= document.getLineInformation(line - 1); + start= previousLine.getOffset() + previousLine.getLength(); + } + + DocumentCommand command= new DocumentCommand() {}; + command.text= "\n"; //$NON-NLS-1$ + command.offset= start; + new JavaDocAutoIndentStrategy(IPHPPartitions.PHP_PARTITIONING).customizeDocumentCommand(document, command); + int to= 1; + while (to < command.text.length() && Character.isWhitespace(command.text.charAt(to))) + to++; + indent= command.text.substring(1, to); + + } else if (!fIsTabAction && partition.getOffset() == offset && type.equals(IPHPPartitions.PHP_SINGLELINE_COMMENT)) { + + // line comment starting at position 0 -> indent inside + int slashes= 2; + while (slashes < document.getLength() - 1 && document.get(offset + slashes, 2).equals("//")) //$NON-NLS-1$ + slashes+= 2; + + wsStart= offset + slashes; + + StringBuffer computed= indenter.computeIndentation(offset); + int tabSize= PHPeclipsePlugin.getDefault().getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); + while (slashes > 0 && computed.length() > 0) { + char c= computed.charAt(0); + if (c == '\t') + if (slashes > tabSize) + slashes-= tabSize; + else + break; + else if (c == ' ') + slashes--; + else break; + + computed.deleteCharAt(0); + } + + indent= document.get(offset, wsStart - offset) + computed; + + } + } + + // standard java indentation + if (indent == null) { + StringBuffer computed= indenter.computeIndentation(offset); + if (computed != null) + indent= computed.toString(); + else + indent= new String(); + } + + // change document: + // get current white space + int lineLength= currentLine.getLength(); + int end= scanner.findNonWhitespaceForwardInAnyPartition(wsStart, offset + lineLength); + if (end == JavaHeuristicScanner.NOT_FOUND) + end= offset + lineLength; + int length= end - offset; + String currentIndent= document.get(offset, length); + + // if we are right before the text start / line end, and already after the insertion point + // then just insert a tab. + if (fIsTabAction && caret == end && whiteSpaceLength(currentIndent) >= whiteSpaceLength(indent)) { + String tab= getTabEquivalent(); + document.replace(caret, 0, tab); + fCaretOffset= caret + tab.length(); + return true; + } + + // set the caret offset so it can be used when setting the selection + if (caret >= offset && caret <= end) + fCaretOffset= offset + indent.length(); + else + fCaretOffset= -1; + + // only change the document if it is a real change + if (!indent.equals(currentIndent)) { + String deletedText= document.get(offset, length); + document.replace(offset, length, indent); + + if (fIsTabAction && indent.length() > currentIndent.length() && PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_BACKSPACE)) { + ITextEditor editor= getTextEditor(); + if (editor != null) { + final SmartBackspaceManager manager= (SmartBackspaceManager) editor.getAdapter(SmartBackspaceManager.class); + if (manager != null) { + try { + // restore smart portion + ReplaceEdit smart= new ReplaceEdit(offset, indent.length(), deletedText); + + final UndoSpec spec= new UndoSpec( + offset + indent.length(), + new Region(caret, 0), + new TextEdit[] { smart }, + 2, + null); + manager.register(spec); + } catch (MalformedTreeException e) { + // log & ignore + PHPeclipsePlugin.log(new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), IStatus.OK, "Illegal smart backspace action", e)); //$NON-NLS-1$ + } + } + } + } + + + return true; + } else + return false; + } + + /** + * Returns the size in characters of a string. All characters count one, tabs count the editor's + * preference for the tab display + * + * @param indent the string to be measured. + * @return + */ + private int whiteSpaceLength(String indent) { + if (indent == null) + return 0; + else { + int size= 0; + int l= indent.length(); + int tabSize= PHPeclipsePlugin.getDefault().getPreferenceStore().getInt(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH); + + for (int i= 0; i < l; i++) + size += indent.charAt(i) == '\t' ? tabSize : 1; + return size; + } + } + + /** + * Returns a tab equivalent, either as a tab character or as spaces, depending on the editor and + * formatter preferences. + * + * @return a string representing one tab in the editor, never null + */ + private String getTabEquivalent() { + String tab; + if (PHPeclipsePlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SPACES_FOR_TABS)) { + int size= JavaCore.getPlugin().getPluginPreferences().getInt(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE); + StringBuffer buf= new StringBuffer(); + for (int i= 0; i< size; i++) + buf.append(' '); + tab= buf.toString(); + } else + tab= "\t"; //$NON-NLS-1$ + + return tab; + } + + /** + * Returns the editor's selection provider. + * + * @return the editor's selection provider or null + */ + private ISelectionProvider getSelectionProvider() { + ITextEditor editor= getTextEditor(); + if (editor != null) { + return editor.getSelectionProvider(); + } + return null; + } + + /* + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + super.update(); + + if (isEnabled()) + if (fIsTabAction) + setEnabled(canModifyEditor() && isSmartMode() && isValidSelection()); + else + setEnabled(canModifyEditor() && !getSelection().isEmpty()); + } + + /** + * Returns if the current selection is valid, i.e. whether it is empty and the caret in the + * whitespace at the start of a line, or covers multiple lines. + * + * @return true if the selection is valid for an indent operation + */ + private boolean isValidSelection() { + ITextSelection selection= getSelection(); + if (selection.isEmpty()) + return false; + + int offset= selection.getOffset(); + int length= selection.getLength(); + + IDocument document= getDocument(); + if (document == null) + return false; + + try { + IRegion firstLine= document.getLineInformationOfOffset(offset); + int lineOffset= firstLine.getOffset(); + + // either the selection has to be empty and the caret in the WS at the line start + // or the selection has to extend over multiple lines + if (length == 0) + return document.get(lineOffset, offset - lineOffset).trim().length() == 0; + else +// return lineOffset + firstLine.getLength() < offset + length; + return false; // only enable for empty selections for now + + } catch (BadLocationException e) { + } + + return false; + } + + /** + * Returns the smart preference state. + * + * @return true if smart mode is on, false otherwise + */ + private boolean isSmartMode() { + ITextEditor editor= getTextEditor(); + + if (editor instanceof ITextEditorExtension3) + return ((ITextEditorExtension3) editor).getInsertMode() == ITextEditorExtension3.SMART_INSERT; + + return false; + } + + /** + * Returns the document currently displayed in the editor, or null if none can be + * obtained. + * + * @return the current document or null + */ + private IDocument getDocument() { + + ITextEditor editor= getTextEditor(); + if (editor != null) { + + IDocumentProvider provider= editor.getDocumentProvider(); + IEditorInput input= editor.getEditorInput(); + if (provider != null && input != null) + return provider.getDocument(input); + + } + return null; + } + + /** + * Returns the selection on the editor or an invalid selection if none can be obtained. Returns + * never null. + * + * @return the current selection, never null + */ + private ITextSelection getSelection() { + ISelectionProvider provider= getSelectionProvider(); + if (provider != null) { + + ISelection selection= provider.getSelection(); + if (selection instanceof ITextSelection) + return (ITextSelection) selection; + } + + // null object + return TextSelection.emptySelection(); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java index 38c0291..ea5e0b2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/actions/RemoveBlockCommentAction.java @@ -1,10 +1,10 @@ /******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation *******************************************************************************/ @@ -14,15 +14,15 @@ import java.util.LinkedList; import java.util.List; import java.util.ResourceBundle; -import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; - import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.BadPartitioningException; import org.eclipse.jface.text.IDocumentExtension3; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITypedRegion; + import org.eclipse.ui.texteditor.ITextEditor; +import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; /** * Action that removes the enclosing comment marks from a Java block comment. @@ -30,8 +30,7 @@ import org.eclipse.ui.texteditor.ITextEditor; * @since 3.0 */ public class RemoveBlockCommentAction extends BlockCommentAction { - final static String DEFAULT_PARTITIONING_CONTENT_TYPE = "__dftl_partition_content_type"; //$NON-NLS-1$ - + /** * Creates a new instance. * @@ -55,28 +54,23 @@ public class RemoveBlockCommentAction extends BlockCommentAction { int offset= selection.getOffset(); int endOffset= offset + selection.getLength(); -// ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, offset, false); - ITypedRegion partition= docExtension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false); - + ITypedRegion partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, offset, false); int partOffset= partition.getOffset(); int partEndOffset= partOffset + partition.getLength(); while (partEndOffset < endOffset) { - if (partition.getType() == IPHPPartitions.PHP_PHPDOC_COMMENT) { + if (partition.getType() == IPHPPartitions.PHP_MULTILINE_COMMENT) { edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$ edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$ } -// partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false); - partition= docExtension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, partEndOffset, false); - + partition= docExtension.getPartition(IPHPPartitions.PHP_PARTITIONING, partEndOffset, false); partOffset= partition.getOffset(); partEndOffset= partOffset + partition.getLength(); } -// if (partition.getType() == IPHPPartitions.PHP_PHPDOC_COMMENT) { - if (partition.getType() == DEFAULT_PARTITIONING_CONTENT_TYPE) { + if (partition.getType() == IPHPPartitions.PHP_MULTILINE_COMMENT) { edits.add(factory.createEdit(partOffset, tokenLength, "")); //$NON-NLS-1$ edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$ } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java index 73543a2..61abec9 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/JavaEditorPreferencePage.java @@ -40,6 +40,7 @@ import net.sourceforge.phpeclipse.preferences.ColorEditor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; +import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -49,12 +50,15 @@ import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -271,9 +275,9 @@ public class JavaEditorPreferencePage extends PreferencePage implements IWorkben private Button fShowInVerticalRulerCheckBox; - // private Text fBrowserLikeLinksKeyModifierText; - // private Button fBrowserLikeLinksCheckBox; - // private StatusInfo fBrowserLikeLinksKeyModifierStatus; + private Text fBrowserLikeLinksKeyModifierText; + private Button fBrowserLikeLinksCheckBox; + private StatusInfo fBrowserLikeLinksKeyModifierStatus; // private Button fCompletionInsertsRadioButton; // private Button fCompletionOverwritesRadioButton; // private Button fStickyOccurrencesButton; @@ -1195,124 +1199,124 @@ public class JavaEditorPreferencePage extends PreferencePage implements IWorkben GridLayout layout = new GridLayout(); layout.numColumns = 2; composite.setLayout(layout); - // String text= - // PreferencesMessages.getString("JavaEditorPreferencePage.navigation.browserLikeLinks"); - // //$NON-NLS-1$ - // fBrowserLikeLinksCheckBox= addCheckBox(composite, text, - // PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS, 0); - // fBrowserLikeLinksCheckBox.addSelectionListener(new SelectionListener() { - // public void widgetSelected(SelectionEvent e) { - // boolean state= fBrowserLikeLinksCheckBox.getSelection(); - // fBrowserLikeLinksKeyModifierText.setEnabled(state); - // handleBrowserLikeLinksKeyModifierModified(); - // } - // public void widgetDefaultSelected(SelectionEvent e) { - // } - // }); - // Text field for modifier string - // text= - // PreferencesMessages.getString("JavaEditorPreferencePage.navigation.browserLikeLinksKeyModifier"); - // //$NON-NLS-1$ - // fBrowserLikeLinksKeyModifierText= addTextField(composite, text, - // PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER, 20, 0, - // false); - // fBrowserLikeLinksKeyModifierText.setTextLimit(Text.LIMIT); - // - // if - // (computeStateMask(fOverlayStore.getString(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER)) - // == -1) { - // // Fix possible illegal modifier string - // int stateMask= - // fOverlayStore.getInt(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); - // if (stateMask == -1) - // fBrowserLikeLinksKeyModifierText.setText(""); //$NON-NLS-1$ - // else - // fBrowserLikeLinksKeyModifierText.setText(EditorUtility.getModifierString(stateMask)); - // } - // fBrowserLikeLinksKeyModifierText.addKeyListener(new KeyListener() { - // private boolean isModifierCandidate; - // public void keyPressed(KeyEvent e) { - // isModifierCandidate= e.keyCode > 0 && e.character == 0 && e.stateMask == - // 0; - // } - // - // public void keyReleased(KeyEvent e) { - // if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask - // && e.character == 0) {// && e.time -time < 1000) { - // String modifierString= fBrowserLikeLinksKeyModifierText.getText(); - // Point selection= fBrowserLikeLinksKeyModifierText.getSelection(); - // int i= selection.x - 1; - // while (i > -1 && Character.isWhitespace(modifierString.charAt(i))) { - // i--; - // } - // boolean needsPrefixDelimiter= i > -1 && - // !String.valueOf(modifierString.charAt(i)).equals(DELIMITER); - // - // i= selection.y; - // while (i < modifierString.length() && - // Character.isWhitespace(modifierString.charAt(i))) { - // i++; - // } - // boolean needsPostfixDelimiter= i < modifierString.length() && - // !String.valueOf(modifierString.charAt(i)).equals(DELIMITER); - // - // String insertString; - // - // if (needsPrefixDelimiter && needsPostfixDelimiter) - // insertString= - // PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertDelimiterAndModifierAndDelimiter", - // new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ - // else if (needsPrefixDelimiter) - // insertString= - // PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertDelimiterAndModifier", - // new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ - // else if (needsPostfixDelimiter) - // insertString= - // PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertModifierAndDelimiter", - // new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ - // else - // insertString= Action.findModifierString(e.stateMask); - // - // fBrowserLikeLinksKeyModifierText.insert(insertString); - // } - // } - // }); - // - // fBrowserLikeLinksKeyModifierText.addModifyListener(new ModifyListener() - // { - // public void modifyText(ModifyEvent e) { - // handleBrowserLikeLinksKeyModifierModified(); - // } - // }); + String text= + PreferencesMessages.getString("JavaEditorPreferencePage.navigation.browserLikeLinks"); + //$NON-NLS-1$ + fBrowserLikeLinksCheckBox= addCheckBox(composite, text, + PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS, 0); + fBrowserLikeLinksCheckBox.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + boolean state= fBrowserLikeLinksCheckBox.getSelection(); + fBrowserLikeLinksKeyModifierText.setEnabled(state); + handleBrowserLikeLinksKeyModifierModified(); + } + public void widgetDefaultSelected(SelectionEvent e) { + } + }); +// Text field for modifier string + text= + PreferencesMessages.getString("JavaEditorPreferencePage.navigation.browserLikeLinksKeyModifier"); + //$NON-NLS-1$ + fBrowserLikeLinksKeyModifierText= addTextField(composite, text, + PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER, 20, 0, + false); + fBrowserLikeLinksKeyModifierText.setTextLimit(Text.LIMIT); + + if + (computeStateMask(fOverlayStore.getString(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER)) + == -1) { + // Fix possible illegal modifier string + int stateMask= + fOverlayStore.getInt(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); + if (stateMask == -1) + fBrowserLikeLinksKeyModifierText.setText(""); //$NON-NLS-1$ + else + fBrowserLikeLinksKeyModifierText.setText(EditorUtility.getModifierString(stateMask)); + } + fBrowserLikeLinksKeyModifierText.addKeyListener(new KeyListener() { + private boolean isModifierCandidate; + public void keyPressed(KeyEvent e) { + isModifierCandidate= e.keyCode > 0 && e.character == 0 && e.stateMask == + 0; + } + + public void keyReleased(KeyEvent e) { + if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask + && e.character == 0) {// && e.time -time < 1000) { + String modifierString= fBrowserLikeLinksKeyModifierText.getText(); + Point selection= fBrowserLikeLinksKeyModifierText.getSelection(); + int i= selection.x - 1; + while (i > -1 && Character.isWhitespace(modifierString.charAt(i))) { + i--; + } + boolean needsPrefixDelimiter= i > -1 && + !String.valueOf(modifierString.charAt(i)).equals(DELIMITER); + + i= selection.y; + while (i < modifierString.length() && + Character.isWhitespace(modifierString.charAt(i))) { + i++; + } + boolean needsPostfixDelimiter= i < modifierString.length() && + !String.valueOf(modifierString.charAt(i)).equals(DELIMITER); + + String insertString; + + if (needsPrefixDelimiter && needsPostfixDelimiter) + insertString= + PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertDelimiterAndModifierAndDelimiter", + new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ + else if (needsPrefixDelimiter) + insertString= + PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertDelimiterAndModifier", + new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ + else if (needsPostfixDelimiter) + insertString= + PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.insertModifierAndDelimiter", + new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$ + else + insertString= Action.findModifierString(e.stateMask); + + fBrowserLikeLinksKeyModifierText.insert(insertString); + } + } + }); + + fBrowserLikeLinksKeyModifierText.addModifyListener(new ModifyListener() + { + public void modifyText(ModifyEvent e) { + handleBrowserLikeLinksKeyModifierModified(); + } + }); return composite; } private void handleBrowserLikeLinksKeyModifierModified() { - // String modifiers= fBrowserLikeLinksKeyModifierText.getText(); - // int stateMask= computeStateMask(modifiers); - // if (fBrowserLikeLinksCheckBox.getSelection() && (stateMask == -1 || - // (stateMask & SWT.SHIFT) != 0)) { - // if (stateMask == -1) - // fBrowserLikeLinksKeyModifierStatus= new StatusInfo(IStatus.ERROR, - // PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.modifierIsNotValid", - // modifiers)); //$NON-NLS-1$ - // else - // fBrowserLikeLinksKeyModifierStatus= new StatusInfo(IStatus.ERROR, - // PreferencesMessages.getString("JavaEditorPreferencePage.navigation.shiftIsDisabled")); - // //$NON-NLS-1$ - // setValid(false); - // StatusUtil.applyToStatusLine(this, fBrowserLikeLinksKeyModifierStatus); - // } else { - // fBrowserLikeLinksKeyModifierStatus= new StatusInfo(); - // updateStatus(fBrowserLikeLinksKeyModifierStatus); - // } + String modifiers= fBrowserLikeLinksKeyModifierText.getText(); + int stateMask= computeStateMask(modifiers); + if (fBrowserLikeLinksCheckBox.getSelection() && (stateMask == -1 || + (stateMask & SWT.SHIFT) != 0)) { + if (stateMask == -1) + fBrowserLikeLinksKeyModifierStatus= new StatusInfo(IStatus.ERROR, + PreferencesMessages.getFormattedString("JavaEditorPreferencePage.navigation.modifierIsNotValid", + modifiers)); //$NON-NLS-1$ + else + fBrowserLikeLinksKeyModifierStatus= new StatusInfo(IStatus.ERROR, + PreferencesMessages.getString("JavaEditorPreferencePage.navigation.shiftIsDisabled")); + //$NON-NLS-1$ + setValid(false); + StatusUtil.applyToStatusLine(this, fBrowserLikeLinksKeyModifierStatus); + } else { + fBrowserLikeLinksKeyModifierStatus= new StatusInfo(); + updateStatus(fBrowserLikeLinksKeyModifierStatus); + } } - // private IStatus getBrowserLikeLinksKeyModifierStatus() { - // if (fBrowserLikeLinksKeyModifierStatus == null) - // fBrowserLikeLinksKeyModifierStatus= new StatusInfo(); - // return fBrowserLikeLinksKeyModifierStatus; - // } + private IStatus getBrowserLikeLinksKeyModifierStatus() { + if (fBrowserLikeLinksKeyModifierStatus == null) + fBrowserLikeLinksKeyModifierStatus= new StatusInfo(); + return fBrowserLikeLinksKeyModifierStatus; + } /** * Computes the state mask for the given modifier string. * @@ -1369,10 +1373,10 @@ public class JavaEditorPreferencePage extends PreferencePage implements IWorkben //$NON-NLS-1$ fJavaEditorHoverConfigurationBlock = new JavaEditorHoverConfigurationBlock(this, fOverlayStore); item.setControl(fJavaEditorHoverConfigurationBlock.createControl(folder)); - // item= new TabItem(folder, SWT.NONE); - // item.setText(PreferencesMessages.getString("JavaEditorPreferencePage.navigationTab.title")); + item = new TabItem(folder, SWT.NONE); + item.setText(PreferencesMessages.getString("JavaEditorPreferencePage.navigationTab.title")); // //$NON-NLS-1$ - // item.setControl(createNavigationPage(folder)); + item.setControl(createNavigationPage(folder)); item = new TabItem(folder, SWT.NONE); item.setText(PreferencesMessages.getString("JavaEditorPreferencePage.folding.title")); //$NON-NLS-1$ item.setControl(fFoldingConfigurationBlock.createControl(folder)); @@ -1467,7 +1471,7 @@ public class JavaEditorPreferencePage extends PreferencePage implements IWorkben // fCompletionInsertsRadioButton.setSelection(completionInserts); // fCompletionOverwritesRadioButton.setSelection(! completionInserts); // - // fBrowserLikeLinksKeyModifierText.setEnabled(fBrowserLikeLinksCheckBox.getSelection()); + fBrowserLikeLinksKeyModifierText.setEnabled(fBrowserLikeLinksCheckBox.getSelection()); // boolean markOccurrences= // fOverlayStore.getBoolean(PreferenceConstants.EDITOR_MARK_OCCURRENCES); // fStickyOccurrencesButton.setEnabled(markOccurrences); @@ -1505,8 +1509,8 @@ public class JavaEditorPreferencePage extends PreferencePage implements IWorkben public boolean performOk() { // fJavaEditorHoverConfigurationBlock.performOk(); fFoldingConfigurationBlock.performOk(); - // fOverlayStore.setValue(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK, - // computeStateMask(fBrowserLikeLinksKeyModifierText.getText())); + fOverlayStore.setValue(PreferenceConstants.EDITOR_BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK, + computeStateMask(fBrowserLikeLinksKeyModifierText.getText())); fOverlayStore.propagate(); PHPeclipsePlugin.getDefault().savePluginPreferences(); return true; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java new file mode 100644 index 0000000..1aabb54 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/DocumentCharacterIterator.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import java.text.CharacterIterator; + +import org.eclipse.jface.text.Assert; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; + + +/** + * An IDocument based implementation of CharacterIterator. + * + * @since 3.0 + */ +public class DocumentCharacterIterator implements CharacterIterator, CharSequence { + + private int fIndex= -1; + private final IDocument fDocument; + private final int fFirst; + private final int fLast; + + private void invariant() { + Assert.isTrue(fIndex >= fFirst); + Assert.isTrue(fIndex <= fLast); + } + + /** + * Creates an iterator for the entire sequence. + * + * @param sequence the sequence backing this iterator + */ + public DocumentCharacterIterator(IDocument sequence) { + this(sequence, 0); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public DocumentCharacterIterator(IDocument sequence, int first) throws IllegalArgumentException { + this(sequence, first, sequence.getLength()); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @param last the last character index to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public DocumentCharacterIterator(IDocument sequence, int first, int last) throws IllegalArgumentException { + if (sequence == null) + throw new NullPointerException(); + if (first < 0 || first > last) + throw new IllegalArgumentException(); + if (last > sequence.getLength()) + throw new IllegalArgumentException(); + fDocument= sequence; + fFirst= first; + fLast= last; + fIndex= first; + invariant(); + } + + /* + * @see java.text.CharacterIterator#first() + */ + public char first() { + return setIndex(getBeginIndex()); + } + + /* + * @see java.text.CharacterIterator#last() + */ + public char last() { + if (fFirst == fLast) + return setIndex(getEndIndex()); + else + return setIndex(getEndIndex() - 1); + } + + /* + * @see java.text.CharacterIterator#current() + */ + public char current() { + if (fIndex >= fFirst && fIndex < fLast) + try { + return fDocument.getChar(fIndex); + } catch (BadLocationException e) { + // ignore + } + return DONE; + } + + /* + * @see java.text.CharacterIterator#next() + */ + public char next() { + return setIndex(Math.min(fIndex + 1, getEndIndex())); + } + + /* + * @see java.text.CharacterIterator#previous() + */ + public char previous() { + if (fIndex > getBeginIndex()) { + return setIndex(fIndex - 1); + } else { + return DONE; + } + } + + /* + * @see java.text.CharacterIterator#setIndex(int) + */ + public char setIndex(int position) { + if (position >= getBeginIndex() && position <= getEndIndex()) + fIndex= position; + else + throw new IllegalArgumentException(); + + invariant(); + return current(); + } + + /* + * @see java.text.CharacterIterator#getBeginIndex() + */ + public int getBeginIndex() { + return fFirst; + } + + /* + * @see java.text.CharacterIterator#getEndIndex() + */ + public int getEndIndex() { + return fLast; + } + + /* + * @see java.text.CharacterIterator#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* + * @see java.text.CharacterIterator#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + } + + /* + * @see java.lang.CharSequence#length() + */ + public int length() { + return getEndIndex() - getBeginIndex(); + } + + /* + * @see java.lang.CharSequence#charAt(int) + */ + public char charAt(int index) { + if (index >= getBeginIndex() && index <= getEndIndex()) + try { + return fDocument.getChar(index); + } catch (BadLocationException e) { + // ignore and return DONE + return DONE; + } + else + throw new IllegalArgumentException(); + } + + /* + * @see java.lang.CharSequence#subSequence(int, int) + */ + public CharSequence subSequence(int start, int end) { + return new DocumentCharacterIterator(fDocument, getBeginIndex() + start, getBeginIndex() + start + end); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java new file mode 100644 index 0000000..14a9b0b --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaBreakIterator.java @@ -0,0 +1,418 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import java.text.BreakIterator; +import java.text.CharacterIterator; + +import org.eclipse.jface.text.Assert; + + +/** + * A java break iterator. It returns all breaks, including before and after + * whitespace, and it returns all camelcase breaks. + *

    + * A line break may be any of "\n", "\r", "\r\n", "\n\r". + *

    + * + * @since 3.0 + */ +public class JavaBreakIterator extends BreakIterator { + + /** + * A run of common characters. + */ + protected static abstract class Run { + /** The length of this run. */ + protected int length; + + public Run() { + init(); + } + + /** + * Returns true if this run consumes ch, + * false otherwise. If true is returned, + * the length of the receiver is adjusted accordingly. + * + * @param ch the character to test + * @return true if ch was consumed + */ + protected boolean consume(char ch) { + if (isValid(ch)) { + length++; + return true; + } + return false; + } + + /** + * Whether this run accepts that character; does not update state. Called + * from the default implementation of consume. + * + * @param ch the character to test + * @return true if ch is accepted + */ + protected abstract boolean isValid(char ch); + + /** + * Resets this run to the initial state. + */ + protected void init() { + length= 0; + } + } + + static final class Whitespace extends Run { + protected boolean isValid(char ch) { + return Character.isWhitespace(ch) && ch != '\n' && ch != '\r'; + } + } + + static final class LineDelimiter extends Run { + /** State: INIT -> delimiter -> EXIT. */ + private char fState; + private static final char INIT= '\0'; + private static final char EXIT= '\1'; + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#init() + */ + protected void init() { + super.init(); + fState= INIT; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#consume(char) + */ + protected boolean consume(char ch) { + if (!isValid(ch) || fState == EXIT) + return false; + + if (fState == INIT) { + fState= ch; + length++; + return true; + } else if (fState != ch) { + fState= EXIT; + length++; + return true; + } else { + return false; + } + } + + protected boolean isValid(char ch) { + return ch == '\n' || ch == '\r'; + } + } + + static final class Identifier extends Run { + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + protected boolean isValid(char ch) { + return Character.isJavaIdentifierPart(ch); + } + } + + static final class CamelCaseIdentifier extends Run { + /* states */ + private static final int S_INIT= 0; + private static final int S_LOWER= 1; + private static final int S_ONE_CAP= 2; + private static final int S_ALL_CAPS= 3; + private static final int S_EXIT= 4; + private static final int S_EXIT_MINUS_ONE= 5; + + /* character types */ + private static final int K_INVALID= 0; + private static final int K_LOWER= 1; + private static final int K_UPPER= 2; + private static final int K_OTHER= 3; + + private int fState; + + private final static int[][] MATRIX= new int[][] { + // K_INVALID, K_LOWER, K_UPPER, K_OTHER + { S_EXIT, S_LOWER, S_ONE_CAP, S_LOWER }, // S_INIT + { S_EXIT, S_LOWER, S_EXIT, S_LOWER }, // S_LOWER + { S_EXIT, S_LOWER, S_ALL_CAPS, S_LOWER }, // S_ONE_CAP + { S_EXIT, S_EXIT_MINUS_ONE, S_ALL_CAPS, S_LOWER }, // S_ALL_CAPS + }; + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#init() + */ + protected void init() { + super.init(); + fState= S_INIT; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#consumes(char) + */ + protected boolean consume(char ch) { + int kind= getKind(ch); + fState= MATRIX[fState][kind]; + switch (fState) { + case S_LOWER: + case S_ONE_CAP: + case S_ALL_CAPS: + length++; + return true; + case S_EXIT: + return false; + case S_EXIT_MINUS_ONE: + length--; + return false; + default: + Assert.isTrue(false); + return false; + } + } + + /** + * Determines the kind of a character. + * + * @param ch the character to test + */ + private int getKind(char ch) { + if (Character.isUpperCase(ch)) + return K_UPPER; + if (Character.isLowerCase(ch)) + return K_LOWER; + if (Character.isJavaIdentifierPart(ch)) // _, digits... + return K_OTHER; + return K_INVALID; + } + + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + protected boolean isValid(char ch) { + return Character.isJavaIdentifierPart(ch); + } + } + + static final class Other extends Run { + /* + * @see org.eclipse.jdt.internal.ui.text.JavaBreakIterator.Run#isValid(char) + */ + protected boolean isValid(char ch) { + return !Character.isWhitespace(ch) && !Character.isJavaIdentifierPart(ch); + } + } + + private static final Run WHITESPACE= new Whitespace(); + private static final Run DELIMITER= new LineDelimiter(); + private static final Run CAMELCASE= new CamelCaseIdentifier(); // new Identifier(); + private static final Run OTHER= new Other(); + + /** The platform break iterator (word instance) used as a base. */ + protected final BreakIterator fIterator; + /** The text we operate on. */ + protected CharSequence fText; + /** our current position for the stateful methods. */ + private int fIndex; + + + /** + * Creates a new break iterator. + */ + public JavaBreakIterator() { + fIterator= BreakIterator.getWordInstance(); + fIndex= fIterator.current(); + } + + /* + * @see java.text.BreakIterator#current() + */ + public int current() { + return fIndex; + } + + /* + * @see java.text.BreakIterator#first() + */ + public int first() { + fIndex= fIterator.first(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#following(int) + */ + public int following(int offset) { + // work around too eager IAEs in standard impl + if (offset == getText().getEndIndex()) + return DONE; + + int next= fIterator.following(offset); + if (next == DONE) + return DONE; + + // TODO deal with complex script word boundaries + // Math.min(offset + run.length, next) does not work + // since wordinstance considers _ as boundaries + // seems to work fine, however + Run run= consumeRun(offset); + return offset + run.length; + + } + + /** + * Consumes a run of characters at the limits of which we introduce a break. + * @param offset the offset to start at + * @return the run that was consumed + */ + private Run consumeRun(int offset) { + // assert offset < length + + char ch= fText.charAt(offset); + int length= fText.length(); + Run run= getRun(ch); + while (run.consume(ch) && offset < length - 1) { + offset++; + ch= fText.charAt(offset); + } + + return run; + } + + /** + * Retunrs a run based on a character. + * + * @param ch the character to test + * @return the correct character given ch + */ + private Run getRun(char ch) { + Run run; + if (WHITESPACE.isValid(ch)) + run= WHITESPACE; + else if (DELIMITER.isValid(ch)) + run= DELIMITER; + else if (CAMELCASE.isValid(ch)) + run= CAMELCASE; + else if (OTHER.isValid(ch)) + run= OTHER; + else { + Assert.isTrue(false); + return null; + } + + run.init(); + return run; + } + + /* + * @see java.text.BreakIterator#getText() + */ + public CharacterIterator getText() { + return fIterator.getText(); + } + + /* + * @see java.text.BreakIterator#isBoundary(int) + */ + public boolean isBoundary(int offset) { + if (offset == getText().getBeginIndex()) + return true; + else + return following(offset - 1) == offset; + } + + /* + * @see java.text.BreakIterator#last() + */ + public int last() { + fIndex= fIterator.last(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next() + */ + public int next() { + fIndex= following(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next(int) + */ + public int next(int n) { + return fIterator.next(n); + } + + /* + * @see java.text.BreakIterator#preceding(int) + */ + public int preceding(int offset) { + if (offset == getText().getBeginIndex()) + return DONE; + + if (isBoundary(offset - 1)) + return offset - 1; + + int previous= offset - 1; + do { + previous= fIterator.preceding(previous); + } while (!isBoundary(previous)); + + int last= DONE; + while (previous < offset) { + last= previous; + previous= following(previous); + } + + return last; + } + + /* + * @see java.text.BreakIterator#previous() + */ + public int previous() { + fIndex= preceding(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#setText(java.lang.String) + */ + public void setText(String newText) { + setText((CharSequence) newText); + } + + /** + * Creates a break iterator given a char sequence. + * @param newText the new text + */ + public void setText(CharSequence newText) { + fText= newText; + fIterator.setText(new SequenceCharacterIterator(newText)); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.text.CharacterIterator) + */ + public void setText(CharacterIterator newText) { + if (newText instanceof CharSequence) { + fText= (CharSequence) newText; + fIterator.setText(newText); + first(); + } else { + throw new UnsupportedOperationException("CharacterIterator not supported"); //$NON-NLS-1$ + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java new file mode 100644 index 0000000..cca37ca --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/JavaWordIterator.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import java.text.BreakIterator; +import java.text.CharacterIterator; + +import org.eclipse.jface.text.Assert; + + +/** + * Breaks java text into word starts, also stops at line start and end. No + * direction dependency. + * + * @since 3.0 + */ +public class JavaWordIterator extends BreakIterator { + + /** + * The underlying java break iterator. It returns all breaks, including + * before and after every whitespace. + */ + private JavaBreakIterator fIterator; + /** The current index for the stateful operations. */ + private int fIndex; + + /** + * Creates a new word iterator. + */ + public JavaWordIterator() { + fIterator= new JavaBreakIterator(); + first(); + } + + /* + * @see java.text.BreakIterator#first() + */ + public int first() { + fIndex= fIterator.first(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#last() + */ + public int last() { + fIndex= fIterator.last(); + return fIndex; + } + + /* + * @see java.text.BreakIterator#next(int) + */ + public int next(int n) { + int next= 0; + while (--n > 0 && next != DONE) { + next= next(); + } + return next; + } + + /* + * @see java.text.BreakIterator#next() + */ + public int next() { + fIndex= following(fIndex); + return fIndex; + } + + /* + * @see java.text.BreakIterator#previous() + */ + public int previous() { + fIndex= preceding(fIndex); + return fIndex; + } + + + /* + * @see java.text.BreakIterator#preceding(int) + */ + public int preceding(int offset) { + int first= fIterator.preceding(offset); + if (isWhitespace(first, offset)) { + int second= fIterator.preceding(first); + if (second != DONE && !isDelimiter(second, first)) + return second; + } + return first; + } + + /* + * @see java.text.BreakIterator#following(int) + */ + public int following(int offset) { + int first= fIterator.following(offset); + if (eatFollowingWhitespace(offset, first)) { + int second= fIterator.following(first); + if (isWhitespace(first, second)) + return second; + } + return first; + } + + private boolean eatFollowingWhitespace(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + if (isWhitespace(offset, exclusiveEnd)) + return false; + if (isDelimiter(offset, exclusiveEnd)) + return false; + + return true; + } + + /** + * Returns true if the given sequence into the underlying text + * represents a delimiter, false otherwise. + * + * @param offset the offset + * @param exclusiveEnd the end offset + * @return true if the given range is a delimiter + */ + private boolean isDelimiter(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + Assert.isTrue(offset >= 0); + Assert.isTrue(exclusiveEnd <= getText().getEndIndex()); + Assert.isTrue(exclusiveEnd > offset); + + CharSequence seq= fIterator.fText; + + while (offset < exclusiveEnd) { + char ch= seq.charAt(offset); + if (ch != '\n' && ch != '\r') + return false; + offset++; + } + + return true; + } + + /** + * Returns true if the given sequence into the underlying text + * represents whitespace, but not a delimiter, false otherwise. + * + * @param offset the offset + * @param exclusiveEnd the end offset + * @return true if the given range is whitespace + */ + private boolean isWhitespace(int offset, int exclusiveEnd) { + if (exclusiveEnd == DONE || offset == DONE) + return false; + + Assert.isTrue(offset >= 0); + Assert.isTrue(exclusiveEnd <= getText().getEndIndex()); + Assert.isTrue(exclusiveEnd > offset); + + CharSequence seq= fIterator.fText; + + while (offset < exclusiveEnd) { + char ch= seq.charAt(offset); + if (!Character.isWhitespace(ch)) + return false; + if (ch == '\n' || ch == '\r') + return false; + offset++; + } + + return true; + } + + /* + * @see java.text.BreakIterator#current() + */ + public int current() { + return fIndex; + } + + /* + * @see java.text.BreakIterator#getText() + */ + public CharacterIterator getText() { + return fIterator.getText(); + } + + /** + * Sets the text as CharSequence. + * @param newText the new text + */ + public void setText(CharSequence newText) { + fIterator.setText(newText); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.text.CharacterIterator) + */ + public void setText(CharacterIterator newText) { + fIterator.setText(newText); + first(); + } + + /* + * @see java.text.BreakIterator#setText(java.lang.String) + */ + public void setText(String newText) { + setText((CharSequence) newText); + } + +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java new file mode 100644 index 0000000..7613b77 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/SequenceCharacterIterator.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text; + +import java.text.CharacterIterator; + +import org.eclipse.jface.text.Assert; + + +/** + * A CharSequence based implementation of CharacterIterator. + * + * @since 3.0 + */ +public class SequenceCharacterIterator implements CharacterIterator { + + private int fIndex= -1; + private final CharSequence fSequence; + private final int fFirst; + private final int fLast; + + private void invariant() { + Assert.isTrue(fIndex >= fFirst); + Assert.isTrue(fIndex <= fLast); + } + + /** + * Creates an iterator for the entire sequence. + * + * @param sequence the sequence backing this iterator + */ + public SequenceCharacterIterator(CharSequence sequence) { + this(sequence, 0); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public SequenceCharacterIterator(CharSequence sequence, int first) throws IllegalArgumentException { + this(sequence, first, sequence.length()); + } + + /** + * Creates an iterator. + * + * @param sequence the sequence backing this iterator + * @param first the first character to consider + * @param last the last character index to consider + * @throws IllegalArgumentException if the indices are out of bounds + */ + public SequenceCharacterIterator(CharSequence sequence, int first, int last) throws IllegalArgumentException { + if (sequence == null) + throw new NullPointerException(); + if (first < 0 || first > last) + throw new IllegalArgumentException(); + if (last > sequence.length()) + throw new IllegalArgumentException(); + fSequence= sequence; + fFirst= first; + fLast= last; + fIndex= first; + invariant(); + } + + /* + * @see java.text.CharacterIterator#first() + */ + public char first() { + return setIndex(getBeginIndex()); + } + + /* + * @see java.text.CharacterIterator#last() + */ + public char last() { + if (fFirst == fLast) + return setIndex(getEndIndex()); + else + return setIndex(getEndIndex() - 1); + } + + /* + * @see java.text.CharacterIterator#current() + */ + public char current() { + if (fIndex >= fFirst && fIndex < fLast) + return fSequence.charAt(fIndex); + else + return DONE; + } + + /* + * @see java.text.CharacterIterator#next() + */ + public char next() { + return setIndex(Math.min(fIndex + 1, getEndIndex())); + } + + /* + * @see java.text.CharacterIterator#previous() + */ + public char previous() { + if (fIndex > getBeginIndex()) { + return setIndex(fIndex - 1); + } else { + return DONE; + } + } + + /* + * @see java.text.CharacterIterator#setIndex(int) + */ + public char setIndex(int position) { + if (position >= getBeginIndex() && position <= getEndIndex()) + fIndex= position; + else + throw new IllegalArgumentException(); + + invariant(); + return current(); + } + + /* + * @see java.text.CharacterIterator#getBeginIndex() + */ + public int getBeginIndex() { + return fFirst; + } + + /* + * @see java.text.CharacterIterator#getEndIndex() + */ + public int getEndIndex() { + return fLast; + } + + /* + * @see java.text.CharacterIterator#getIndex() + */ + public int getIndex() { + return fIndex; + } + + /* + * @see java.text.CharacterIterator#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new InternalError(); + } + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java new file mode 100644 index 0000000..fc4e006 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaExpandHover.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import net.sourceforge.phpdt.internal.ui.PHPUiImages; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.phpeditor.JavaMarkerAnnotation; + +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.CompositeRuler; +import org.eclipse.jface.text.source.IAnnotationAccess; +import org.eclipse.jface.text.source.IAnnotationAccessExtension; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.text.source.IAnnotationPresentation; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.ImageUtilities; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.ui.internal.texteditor.AnnotationExpandHover; +import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl; +import org.eclipse.ui.internal.texteditor.AnnotationExpansionControl.AnnotationHoverInput; +import org.eclipse.ui.texteditor.AnnotationPreference; +import org.eclipse.ui.texteditor.AnnotationPreferenceLookup; + +/** + * + * + * @since 3.0 + */ +public class JavaExpandHover extends AnnotationExpandHover { + + /** Id of the no breakpoint fake annotation */ + public static final String NO_BREAKPOINT_ANNOTATION= "org.eclipse.jdt.internal.ui.NoBreakpointAnnotation"; //$NON-NLS-1$ + + private static class NoBreakpointAnnotation extends Annotation implements IAnnotationPresentation { + + public NoBreakpointAnnotation() { + super(NO_BREAKPOINT_ANNOTATION, false, JavaHoverMessages.getString("NoBreakpointAnnotation.addBreakpoint")); //$NON-NLS-1$ + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle) + */ + public void paint(GC gc, Canvas canvas, Rectangle bounds) { + // draw affordance so the user know she can click here to get a breakpoint + Image fImage= PHPUiImages.get(PHPUiImages.IMG_FIELD_PUBLIC); + ImageUtilities.drawImage(fImage, gc, canvas, bounds, SWT.CENTER); + } + + /* + * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer() + */ + public int getLayer() { + return IAnnotationPresentation.DEFAULT_LAYER; + } + } + + private AnnotationPreferenceLookup fLookup= new AnnotationPreferenceLookup(); + private IPreferenceStore fStore= PHPeclipsePlugin.getDefault().getCombinedPreferenceStore(); + + public JavaExpandHover(CompositeRuler ruler, IAnnotationAccess access, IDoubleClickListener doubleClickListener) { + super(ruler, access, doubleClickListener); + } + + /* + * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getHoverInfoForLine(org.eclipse.jface.text.source.ISourceViewer, int) + */ + protected Object getHoverInfoForLine(final ISourceViewer viewer, final int line) { + IAnnotationModel model= viewer.getAnnotationModel(); + IDocument document= viewer.getDocument(); + + if (model == null) + return null; + + List exact= new ArrayList(); + HashMap messagesAtPosition= new HashMap(); + + Iterator e= model.getAnnotationIterator(); + while (e.hasNext()) { + Annotation annotation= (Annotation) e.next(); + + // don't prune deleted ones as we don't get many errors this way +// if (annotation.isMarkedDeleted()) +// continue; + + if (fAnnotationAccess instanceof IAnnotationAccessExtension) + if (!((IAnnotationAccessExtension)fAnnotationAccess).isPaintable(annotation)) + continue; + +// TODO need a new check the this one is not OK +// +// if (annotation instanceof IJavaAnnotation && annotation instanceof IAnnotationPresentation) +// if (((IJavaAnnotation) annotation).getImage(display) == null) +// continue; + + AnnotationPreference pref= fLookup.getAnnotationPreference(annotation); + if (pref != null) { + String key= pref.getVerticalRulerPreferenceKey(); + if (key != null && !fStore.getBoolean(key)) + continue; + } + + Position position= model.getPosition(annotation); + if (position == null) + continue; + + if (compareRulerLine(position, document, line) == 1) { + + if (isDuplicateMessage(messagesAtPosition, position, annotation.getText())) + continue; + + exact.add(annotation); + } + } + + sort(exact, model); + + if (exact.size() > 0) + setLastRulerMouseLocation(viewer, line); + + if (exact.size() > 0) { + Annotation first= (Annotation) exact.get(0); + if (!isBreakpointAnnotation(first)) + exact.add(0, new NoBreakpointAnnotation()); + } + + if (exact.size() <= 1) +// if (exact.size() < 1) + return null; + + AnnotationHoverInput input= new AnnotationHoverInput(); + input.fAnnotations= (Annotation[]) exact.toArray(new Annotation[0]); + input.fViewer= viewer; + input.fRulerInfo= fCompositeRuler; + input.fAnnotationListener= fgListener; + input.fDoubleClickListener= fDblClickListener; + input.redoAction= new AnnotationExpansionControl.ICallback() { + + public void run(IInformationControlExtension2 control) { + control.setInput(getHoverInfoForLine(viewer, line)); + } + + }; + input.model= model; + + return input; + } + + /* + * @see org.eclipse.ui.internal.texteditor.AnnotationExpandHover#getOrder(org.eclipse.jface.text.source.Annotation) + */ + protected int getOrder(Annotation annotation) { + if (isBreakpointAnnotation(annotation)) //$NON-NLS-1$ + return 1000; + else + return super.getOrder(annotation); + } + + private boolean isBreakpointAnnotation(Annotation a) { + if (a instanceof JavaMarkerAnnotation) { + JavaMarkerAnnotation jma= (JavaMarkerAnnotation) a; + // HACK to get breakpoints to show up first + return jma.getType().equals("org.eclipse.debug.core.breakpoint"); //$NON-NLS-1$ + } + return false; + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java new file mode 100644 index 0000000..c4f9335 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.ui.text.java; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +class JavaHoverMessages { + + private static final String RESOURCE_BUNDLE= JavaHoverMessages.class.getName(); + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private JavaHoverMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + * @since 3.0 + */ + public static String getFormattedString(String key, Object arg) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + if (arg == null) + arg= ""; //$NON-NLS-1$ + return MessageFormat.format(format, new Object[] { arg }); + } + /** + * Gets a string from the resource bundle and formats it with the arguments + * + * @param key the string used to get the bundle value, must not be null + * @since 3.0 + */ + public static String getFormattedString(String key, Object arg1, Object arg2) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + if (arg1 == null) + arg1= ""; //$NON-NLS-1$ + if (arg2 == null) + arg2= ""; //$NON-NLS-1$ + return MessageFormat.format(format, new Object[] { arg1, arg2 }); + } + + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + * @since 3.0 + */ + public static String getFormattedString(String key, boolean arg) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + return MessageFormat.format(format, new Object[] { new Boolean(arg) }); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties new file mode 100644 index 0000000..01f64aa --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaHoverMessages.properties @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation +############################################################################### + +TypeHover.more_to_come=\ ... + +JavaTextHover.createTextHover= Could not create PHP text hover + +JavaTextHover.makeStickyHint= Press ''{0}'' for focus. + +NoBreakpointAnnotation.addBreakpoint= Add a breakpoint 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 01b7157..c2b5815 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/PreferenceConstants.java @@ -514,7 +514,8 @@ public class PreferenceConstants { * Value is of type Int: positive int value specifying the number of spaces per tab. *

    */ - public final static String EDITOR_TAB_WIDTH = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH; //"net.sourceforge.phpdt.ui.editor.tab.width"; //$NON-NLS-1$ + public final static String EDITOR_TAB_WIDTH = AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH; //"net.sourceforge.phpdt.ui.editor.tab.width"; + // //$NON-NLS-1$ /** * A named preference that controls whether the outline view selection should stay in sync with with the element at the current @@ -2107,6 +2108,17 @@ public class PreferenceConstants { public static final String TEMPLATES_USE_CODEFORMATTER = "net.sourceforge.phpdt.ui.template.format"; //$NON-NLS-1$ /** + * A named preference that controls whether annotation roll over is used or not. + *

    + * Value is of type Boolean. If true the annotation ruler column + * uses a roll over to display multiple annotations + *

    + * + * @since 3.0 + */ + public static final String EDITOR_ANNOTATION_ROLL_OVER = "editor_annotation_roll_over"; //$NON-NLS-1$ + + /** * A named preference that controls the key modifier mask for browser like links. The value is only used if the value of * EDITOR_BROWSER_LIKE_LINKS cannot be resolved to valid SWT modifier bits. *

    @@ -2240,25 +2252,8 @@ public class PreferenceConstants { // must add here to guarantee that it is the first in the listener list store.addPropertyChangeListener(PHPeclipsePlugin.getDefault().getMemberOrderPreferenceCache()); - // PHPEditorPreferencePage - /* - * Ensure that the display is accessed only in the UI thread. Ensure that there are no side effects of switching the thread. - */ - final RGB[] rgbs = new RGB[3]; - final Display display = Display.getDefault(); - display.syncExec(new Runnable() { - public void run() { - Color c = display.getSystemColor(SWT.COLOR_GRAY); - rgbs[0] = c.getRGB(); - c = display.getSystemColor(SWT.COLOR_LIST_FOREGROUND); - rgbs[1] = c.getRGB(); - c = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); - rgbs[2] = c.getRGB(); - } - }); - store.setDefault(PreferenceConstants.EDITOR_MATCHING_BRACKETS, true); - PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR, rgbs[0]); + PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_MATCHING_BRACKETS_COLOR, new RGB(192, 192,192)); store.setDefault(PreferenceConstants.EDITOR_CURRENT_LINE, true); PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_CURRENT_LINE_COLOR, new RGB(225, 235, 224)); @@ -2308,10 +2303,8 @@ public class PreferenceConstants { PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_LINKED_POSITION_COLOR, new RGB(0, 200, 100)); PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_LINK_COLOR, new RGB(0, 0, 255)); - PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_FOREGROUND_COLOR, rgbs[1]); store.setDefault(PreferenceConstants.EDITOR_FOREGROUND_DEFAULT_COLOR, true); - PreferenceConverter.setDefault(store, PreferenceConstants.EDITOR_BACKGROUND_COLOR, rgbs[2]); store.setDefault(PreferenceConstants.EDITOR_BACKGROUND_DEFAULT_COLOR, true); store.setDefault(PreferenceConstants.EDITOR_TAB_WIDTH, 4); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java new file mode 100644 index 0000000..067a9f1 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/OpenEditorActionGroup.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation 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 API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.ui.actions; + +import net.sourceforge.phpdt.internal.ui.actions.ActionMessages; +import net.sourceforge.phpdt.ui.IContextMenuConstants; +import net.sourceforge.phpeclipse.actions.PHPOpenDeclarationAction; +import net.sourceforge.phpeclipse.actions.PHPOpenDeclarationEditorAction; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.actions.OpenWithMenu; + +/** + * Action group that adds the actions opening a new editor to the + * context menu and the action bar's navigate menu. + * + *

    + * This class may be instantiated; it is not intended to be subclassed. + *

    + * + * @since 2.0 + */ +public class OpenEditorActionGroup extends ActionGroup { + + private IWorkbenchSite fSite; + private boolean fIsEditorOwner; + private PHPOpenDeclarationAction fOpen; + + /** + * Creates a new OpenActionGroup. The group requires + * that the selection provided by the part's selection provider is of type + * org.eclipse.jface.viewers.IStructuredSelection. + * + * @param part the view part that owns this action group + */ + public OpenEditorActionGroup(IViewPart part) { + fSite= part.getSite(); + fOpen= new PHPOpenDeclarationAction(fSite); + fOpen.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_EDITOR); + initialize(fSite.getSelectionProvider()); + } + + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public OpenEditorActionGroup(PHPEditor part) { + fIsEditorOwner= true; + fOpen= new PHPOpenDeclarationAction(part); + fOpen.setActionDefinitionId(PHPEditorActionDefinitionIds.OPEN_EDITOR); + part.setAction("OpenEditor", fOpen); //$NON-NLS-1$ + fSite= part.getEditorSite(); + initialize(fSite.getSelectionProvider()); + } + + /** + * Returns the open action managed by this action group. + * + * @return the open action. Returns null if the group + * doesn't provide any open action + */ + public IAction getOpenAction() { + return fOpen; + } + + private void initialize(ISelectionProvider provider) { + ISelection selection= provider.getSelection(); + fOpen.update(selection); + if (!fIsEditorOwner) { + provider.addSelectionChangedListener(fOpen); + } + } + + /* (non-Javadoc) + * Method declared in ActionGroup + */ + public void fillActionBars(IActionBars actionBar) { + super.fillActionBars(actionBar); + setGlobalActionHandlers(actionBar); + } + + /* (non-Javadoc) + * Method declared in ActionGroup + */ + public void fillContextMenu(IMenuManager menu) { + super.fillContextMenu(menu); + appendToGroup(menu, fOpen); + if (!fIsEditorOwner) { + addOpenWithMenu(menu); + } + } + + /* + * @see ActionGroup#dispose() + */ + public void dispose() { + ISelectionProvider provider= fSite.getSelectionProvider(); + provider.removeSelectionChangedListener(fOpen); + super.dispose(); + } + + private void setGlobalActionHandlers(IActionBars actionBars) { + actionBars.setGlobalActionHandler(PHPdtActionConstants.OPEN, fOpen); + } + + private void appendToGroup(IMenuManager menu, IAction action) { + if (action.isEnabled()) + menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, action); + } + + private void addOpenWithMenu(IMenuManager menu) { + ISelection selection= getContext().getSelection(); + if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) + return; + IStructuredSelection ss= (IStructuredSelection)selection; + if (ss.size() != 1) + return; + + Object o= ss.getFirstElement(); + if (!(o instanceof IAdaptable)) + return; + + IAdaptable element= (IAdaptable)o; + Object resource= element.getAdapter(IResource.class); + if (!(resource instanceof IFile)) + return; + + // Create a menu flyout. + IMenuManager submenu= new MenuManager(ActionMessages.getString("OpenWithMenu.label")); //$NON-NLS-1$ + submenu.add(new OpenWithMenu(fSite.getPage(), (IFile) resource)); + + // Add the submenu. + menu.appendToGroup(IContextMenuConstants.GROUP_OPEN, submenu); + } +} diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java index 1e70b6f..324b300 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/ui/actions/PHPEditorActionDefinitionIds.java @@ -17,7 +17,7 @@ public interface PHPEditorActionDefinitionIds { * Action definition ID of the navigate -> open action * (value "org.phpeclipse.phpdt.ui.edit.text.php.open.editor"). */ - public static final String OPEN_EDITOR = "net.sourceforge.phpeclipse.ui.edit.text.php.open.editor"; //$NON-NLS-1$ + public static final String OPEN_EDITOR = "net.sourceforge.phpeclipse.ui.edit.text.java.open.editor"; //$NON-NLS-1$ /** * Action definition ID of the toggle presentation toolbar button action * (value "org.eclipse.jdt.ui.edit.text.java.toggle.presentation"). diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java index 3f48e2b..a556aef 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/IncludesScanner.java @@ -90,7 +90,7 @@ public class IncludesScanner implements ITerminalSymbols { String identifier; int counter = 0; - Scanner scanner = new Scanner(false, false, false, false, true, null, null); + Scanner scanner = new Scanner(false, false, false, false, true, null, null, true /*taskCaseSensitive*/); scanner.setSource(charArray); scanner.setPHPMode(false); int token = getNextToken(scanner); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java new file mode 100644 index 0000000..aa7e725 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/OpenDeclarationEditorAction.java @@ -0,0 +1,263 @@ +/*********************************************************************************************************************************** + * 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: www.phpeclipse.de + **********************************************************************************************************************************/ +package net.sourceforge.phpeclipse.actions; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; +import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; +import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.dialogs.ListSelectionDialog; +import org.eclipse.ui.internal.dialogs.ListContentProvider; + +public class OpenDeclarationEditorAction { + + private PHPEditor fEditor; + + private IProject fProject; + + private boolean isIncludeString; + + public OpenDeclarationEditorAction(PHPEditor editor) { + fEditor = editor; + fProject = null; + isIncludeString = false; + } + + /** + * @param selection + */ + protected void openSelectedElement(ITextSelection selection) { + IDocument doc = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()); + int pos = selection.getOffset(); + openSelectedPosition(doc, pos); + } + + protected void openSelectedPosition(IDocument doc, int position) { + IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile(); + fProject = f.getProject(); + // System.out.println(selection.getText()); + String identifierOrInclude = getIdentifierOrInclude(doc, position); + // System.out.println(word); + if (identifierOrInclude != null && !identifierOrInclude.equals("")) { + if (isIncludeString) { + openIncludeFile(identifierOrInclude); + } else { + openIdentifierDeclaration(f, identifierOrInclude); + } + } + } + + /** + * @param filename + */ + private void openIncludeFile(String filename) { + if (filename != null && !filename.equals("")) { + try { + IFile currentFile = ((IFileEditorInput) fEditor.getEditorInput()).getFile(); + IPath path = PHPFileUtil.determineFilePath(filename, currentFile, fProject); + if (path != null) { + IFile file = PHPFileUtil.createFile(path, fProject); + if (file != null && file.exists()) { + PHPeclipsePlugin.getDefault().openFileInTextEditor(file.getLocation().toString()); + return; + } + } + } catch (Exception e) { + // ignore + } + + try { + + IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject); + // filename = StringUtil.replaceRegExChars(filename); + List list = indexManager.getFileList(filename); + if (list != null && list.size() > 0) { + //String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); + String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar; + + ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getShell(), list, new ListContentProvider(), new LabelProvider(), + "Select the includes to open."); + listSelectionDialog.setTitle("Multiple includes found"); + if (listSelectionDialog.open() == Window.OK) { + Object[] locations = listSelectionDialog.getResult(); + if (locations != null) { + try { + for (int i = 0; i < locations.length; i++) { + // PHPIdentifierLocation location = (PHPIdentifierLocation) + // locations[i]; + String openFilename = workspaceLocation + ((String) locations[i]); + PHPeclipsePlugin.getDefault().openFileInTextEditor(openFilename); + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + } + } catch (Exception e) { + } + + } + return; + } + + /** + * @param f + * @param identiifer + */ + private void openIdentifierDeclaration(IFile f, String identiifer) { + if (identiifer != null && !identiifer.equals("")) { + IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject); + List locationsList = indexManager.getLocations(identiifer); + if (locationsList != null && locationsList.size() > 0) { + + // String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot() + // .getLocation().toString(); + + String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar; + // TODO show all entries of the list in a dialog box + // at the moment always the first entry will be opened + if (locationsList.size() > 1) { + // determine all includes: + IncludesScanner includesScanner = new IncludesScanner(fProject, (IFileEditorInput) fEditor.getEditorInput()); + includesScanner.addFile(f); + Set exactIncludeSet = includesScanner.getSet(); + + PHPIdentifierLocation includeName; + for (int i = 0; i < locationsList.size(); i++) { + includeName = (PHPIdentifierLocation) locationsList.get(i); + if (exactIncludeSet.contains(includeName.getFilename())) { + includeName.setMatch(PHPIdentifierLocation.EXACT_MATCH); + } else { + includeName.setMatch(PHPIdentifierLocation.UNDEFINED_MATCH); + } + } + Collections.sort(locationsList); + + ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench() + .getActiveWorkbenchWindow().getShell(), locationsList, new ListContentProvider(), new LabelProvider(), + "Select the resources to open."); + listSelectionDialog.setTitle("Multiple declarations found"); + if (listSelectionDialog.open() == Window.OK) { + Object[] locations = listSelectionDialog.getResult(); + if (locations != null) { + try { + for (int i = 0; i < locations.length; i++) { + PHPIdentifierLocation location = (PHPIdentifierLocation) locations[i]; + String filename = workspaceLocation + location.getFilename(); + // System.out.println(filename); + if (location.getOffset() >= 0) { + PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length()); + } else { + PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer); + } + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } else { + try { + PHPIdentifierLocation location = (PHPIdentifierLocation) locationsList.get(0); + String filename = workspaceLocation + location.getFilename(); + // System.out.println(filename); + if (location.getOffset() >= 0) { + PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length()); + } else { + PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer); + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + } + + private String getIdentifierOrInclude(IDocument doc, int pos) { + // private String getPHPIncludeText(IDocument doc, int pos) { + Point word = null; + int start = -1; + int end = -1; + isIncludeString = false; + try { + // try to find an include string + int position = pos; + char character = ' '; + + while (position >= 0) { + character = doc.getChar(position); + if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n')) + break; + --position; + } + if ((character == '\"') || (character == '\'')) { + start = position; + + position = pos; + int length = doc.getLength(); + character = ' '; + while (position < length) { + character = doc.getChar(position); + if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n')) + break; + ++position; + } + if ((character == '\"') || (character == '\'')) { + start++; + end = position; + + if (end > start) { + word = new Point(start, end - start); // include name found + isIncludeString = true; + } + } + } + + // try to find an identifier + if (word == null) { + word = PHPWordExtractor.findWord(doc, pos); // identifier found + isIncludeString = false; + } + } catch (BadLocationException x) { + } + + if (word != null) { + try { + return doc.get(word.x, word.y); + } catch (BadLocationException e) { + } + } + return ""; + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java new file mode 100644 index 0000000..7fc1dae --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationAction.java @@ -0,0 +1,103 @@ +/*********************************************************************************************************************************** + * 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: www.phpeclipse.de + **********************************************************************************************************************************/ +package net.sourceforge.phpeclipse.actions; + +import net.sourceforge.phpdt.internal.ui.actions.ActionUtil; +import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter; +import net.sourceforge.phpdt.ui.actions.SelectionDispatchAction; +import net.sourceforge.phpeclipse.phpeditor.PHPEditor; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.TextSelection; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.IWorkbenchWindow; + +public class PHPOpenDeclarationAction extends SelectionDispatchAction { + private IWorkbenchWindow fWindow; + + private PHPEditor fEditor; + + public void dispose() { + } + + public PHPOpenDeclarationAction(IWorkbenchSite site) { + super(site); + // setText(ActionMessages.getString("OpenAction.label")); //$NON-NLS-1$ + // setToolTipText(ActionMessages.getString("OpenAction.tooltip")); //$NON-NLS-1$ + // setDescription(ActionMessages.getString("OpenAction.description")); //$NON-NLS-1$ + // WorkbenchHelp.setHelp(this, IJavaHelpContextIds.OPEN_ACTION); + } + + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public PHPOpenDeclarationAction(PHPEditor editor) { + this(editor.getEditorSite()); + fEditor = editor; + // setText(ActionMessages.getString("OpenAction.declaration.label")); //$NON-NLS-1$ + setEnabled(SelectionConverter.canOperateOn(fEditor)); + } + + public void init(IWorkbenchWindow window) { + this.fWindow = window; + } + + public void selectionChanged(IAction action, ISelection selection) { + if (!selection.isEmpty()) { + if (selection instanceof TextSelection) { + action.setEnabled(true); + } else if (fWindow.getActivePage() != null && fWindow.getActivePage().getActivePart() != null) { + // + } + } + } + + private boolean checkEnabled(IStructuredSelection selection) { + if (selection.isEmpty()) + return false; + return true; + } + + /* + * (non-Javadoc) Method declared on SelectionDispatchAction. + */ + public void run(ITextSelection selection) { + if (!ActionUtil.isProcessable(getShell(), fEditor)) + return; + OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(fEditor); + openAction.openSelectedElement(selection); + } + + /* + * (non-Javadoc) Method declared on SelectionDispatchAction. + */ + public void run(IStructuredSelection selection) { + if (!checkEnabled(selection)) + return; + run(selection.toArray()); + } + + /** + * Note: this method is for internal use only. Clients should not call this method. + */ + public void run(Object[] elements) { + if (elements != null && elements.length > 0) { + ITextSelection selection = (ITextSelection) fEditor.getSelectionProvider().getSelection(); + IDocument doc = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()); + int pos = selection.getOffset(); + + OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(fEditor); + openAction.openSelectedPosition(doc, pos); + } + } + +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java index 486f7cf..e689c33 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/actions/PHPOpenDeclarationEditorAction.java @@ -7,53 +7,23 @@ **********************************************************************************************************************************/ package net.sourceforge.phpeclipse.actions; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; -import net.sourceforge.phpeclipse.PHPeclipsePlugin; -import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; -import net.sourceforge.phpeclipse.builder.PHPIdentifierLocation; import net.sourceforge.phpeclipse.phpeditor.PHPEditor; -import net.sourceforge.phpeclipse.phpeditor.php.PHPWordExtractor; -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.internal.resources.File; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.graphics.Point; +import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorActionDelegate; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.actions.ActionDelegate; -import org.eclipse.ui.dialogs.ListSelectionDialog; -import org.eclipse.ui.internal.dialogs.ListContentProvider; public class PHPOpenDeclarationEditorAction extends ActionDelegate implements IEditorActionDelegate { - private IWorkbenchWindow fWindow; private PHPEditor fEditor; - private IProject fProject; - - private boolean isIncludeString; - - public void dispose() { - } - public void init(IWorkbenchWindow window) { this.fWindow = window; } @@ -68,6 +38,12 @@ public class PHPOpenDeclarationEditorAction extends ActionDelegate implements IE } } + private boolean checkEnabled(IStructuredSelection selection) { + if (selection.isEmpty()) + return false; + return true; + } + public void run(IAction action) { if (fEditor == null) { IEditorPart targetEditor = fWindow.getActivePage().getActiveEditor(); @@ -76,161 +52,9 @@ public class PHPOpenDeclarationEditorAction extends ActionDelegate implements IE } } if (fEditor != null) { - // determine the current Project from a (file-based) Editor - IFile f = ((IFileEditorInput) fEditor.getEditorInput()).getFile(); - fProject = f.getProject(); - // System.out.println(fProject.toString()); - ITextSelection selection = (ITextSelection) fEditor.getSelectionProvider().getSelection(); - IDocument doc = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()); - int pos = selection.getOffset(); - // System.out.println(selection.getText()); - String identifierOrInclude = getIdentifierOrInclude(doc, pos); - // System.out.println(word); - if (identifierOrInclude != null && !identifierOrInclude.equals("")) { - if (isIncludeString) { - openIncludeFile(identifierOrInclude); - } else { - openIdentifierDeclaration(f, identifierOrInclude); - } - } - } - } - - /** - * @param filename - */ - private void openIncludeFile(String filename) { - if (filename != null && !filename.equals("")) { - try { - IFile currentFile = ((IFileEditorInput) fEditor.getEditorInput()).getFile(); - IPath path = PHPFileUtil.determineFilePath(filename, currentFile, fProject); - if (path != null) { -// String projectPath = fProject.getLocation().toString(); -// String filePath = path.toString().substring(projectPath.length()+1); -// IFile file = fProject.getFile(filePath); - IFile file = PHPFileUtil.createFile(path, fProject); - // IFile file = getIncludeFile(fProject, (IFileEditorInput) fEditor.getEditorInput(), filename); - if (file != null && file.exists()) { - PHPeclipsePlugin.getDefault().openFileInTextEditor(file.getLocation().toString()); - return; - } - } - } catch (Exception e) { - // ignore - } - - try { - - IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject); - // filename = StringUtil.replaceRegExChars(filename); - List list = indexManager.getFileList(filename); - if (list != null && list.size() > 0) { - //String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot().getLocation().toString(); - String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar; - - ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getShell(), list, new ListContentProvider(), new LabelProvider(), - "Select the includes to open."); - listSelectionDialog.setTitle("Multiple includes found"); - if (listSelectionDialog.open() == Window.OK) { - Object[] locations = listSelectionDialog.getResult(); - if (locations != null) { - try { - for (int i = 0; i < locations.length; i++) { - // PHPIdentifierLocation location = (PHPIdentifierLocation) - // locations[i]; - String openFilename = workspaceLocation + ((String) locations[i]); - PHPeclipsePlugin.getDefault().openFileInTextEditor(openFilename); - } - } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - } - } catch (Exception e) { - } - - } - return; - } - - /** - * @param f - * @param identiifer - */ - private void openIdentifierDeclaration(IFile f, String identiifer) { - if (identiifer != null && !identiifer.equals("")) { - IdentifierIndexManager indexManager = PHPeclipsePlugin.getDefault().getIndexManager(fProject); - List locationsList = indexManager.getLocations(identiifer); - if (locationsList != null && locationsList.size() > 0) { - - // String workspaceLocation = PHPeclipsePlugin.getWorkspace().getRoot() - // .getLocation().toString(); - - String workspaceLocation = fProject.getLocation().toString() + java.io.File.separatorChar; - // TODO show all entries of the list in a dialog box - // at the moment always the first entry will be opened - if (locationsList.size() > 1) { - // determine all includes: - IncludesScanner includesScanner = new IncludesScanner(fProject, (IFileEditorInput) fEditor.getEditorInput()); - includesScanner.addFile(f); - Set exactIncludeSet = includesScanner.getSet(); - - PHPIdentifierLocation includeName; - for (int i = 0; i < locationsList.size(); i++) { - includeName = (PHPIdentifierLocation) locationsList.get(i); - if (exactIncludeSet.contains(includeName.getFilename())) { - includeName.setMatch(PHPIdentifierLocation.EXACT_MATCH); - } else { - includeName.setMatch(PHPIdentifierLocation.UNDEFINED_MATCH); - } - } - Collections.sort(locationsList); - - ListSelectionDialog listSelectionDialog = new ListSelectionDialog(PHPeclipsePlugin.getDefault().getWorkbench() - .getActiveWorkbenchWindow().getShell(), locationsList, new ListContentProvider(), new LabelProvider(), - "Select the resources to open."); - listSelectionDialog.setTitle("Multiple declarations found"); - if (listSelectionDialog.open() == Window.OK) { - Object[] locations = listSelectionDialog.getResult(); - if (locations != null) { - try { - for (int i = 0; i < locations.length; i++) { - PHPIdentifierLocation location = (PHPIdentifierLocation) locations[i]; - String filename = workspaceLocation + location.getFilename(); - // System.out.println(filename); - if (location.getOffset() >= 0) { - PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length()); - } else { - PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer); - } - } - } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - } else { - try { - PHPIdentifierLocation location = (PHPIdentifierLocation) locationsList.get(0); - String filename = workspaceLocation + location.getFilename(); - // System.out.println(filename); - if (location.getOffset() >= 0) { - PHPeclipsePlugin.getDefault().openFileAndGotoOffset(filename, location.getOffset(), identiifer.length()); - } else { - PHPeclipsePlugin.getDefault().openFileAndFindString(filename, identiifer); - } - } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } + OpenDeclarationEditorAction openAction = new OpenDeclarationEditorAction(fEditor); + openAction.openSelectedElement(selection); } } @@ -240,103 +64,4 @@ public class PHPOpenDeclarationEditorAction extends ActionDelegate implements IE } } - private String getIdentifierOrInclude(IDocument doc, int pos) { - // private String getPHPIncludeText(IDocument doc, int pos) { - Point word = null; - int start = -1; - int end = -1; - isIncludeString = false; - try { - // try to find an include string - int position = pos; - char character = ' '; - - while (position >= 0) { - character = doc.getChar(position); - if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n')) - break; - --position; - } - if ((character == '\"') || (character == '\'')) { - start = position; - - position = pos; - int length = doc.getLength(); - character = ' '; - while (position < length) { - character = doc.getChar(position); - if ((character == '\"') || (character == '\'') || (character == '\r') || (character == '\n')) - break; - ++position; - } - if ((character == '\"') || (character == '\'')) { - start++; - end = position; - - if (end > start) { - word = new Point(start, end - start); // include name found - isIncludeString = true; - } - } - } - - // try to find an identifier - if (word == null) { - word = PHPWordExtractor.findWord(doc, pos); // identifier found - isIncludeString = false; - } - } catch (BadLocationException x) { - } - - if (word != null) { - try { - return doc.get(word.x, word.y); - } catch (BadLocationException e) { - } - } - return ""; - } - - // - // - // Point word = PHPWordExtractor.findWord(doc, pos); - // if (word != null) { - // try { - // return doc.get(word.x, word.y); - // } catch (BadLocationException e) { - // } - // } - // return ""; - // } - private IContainer getWorkingLocation(IFileEditorInput editorInput) { - if (editorInput == null || editorInput.getFile() == null) { - return null; - } - return editorInput.getFile().getParent(); - } - - // private IFile getIncludeFile(IProject project, IFileEditorInput editorInput, String relativeFilename) { - // IContainer container = getWorkingLocation(editorInput); - // String fullPath = project.getLocation().toString(); - // IFile file = null; - // if (relativeFilename.startsWith("../")) { - // Path path = new Path(relativeFilename); - // file = container.getFile(path); - // return file; - // } - // int index = relativeFilename.lastIndexOf('/'); - // - // if (index >= 0) { - // Path path = new Path(relativeFilename); - // file = project.getFile(path); - // if (file.exists()) { - // return file; - // } - // } - // - // Path path = new Path(relativeFilename); - // file = container.getFile(path); - // - // return file; - // } } \ No newline at end of file diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java index 2769154..cd647e3 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/builder/IdentifierIndexManager.java @@ -41,7 +41,7 @@ public class IdentifierIndexManager { private int fToken; public LineCreator() { - fScanner = new Scanner(true, false, false, false, true, null, null); + fScanner = new Scanner(true, false, false, false, true, null, null, true /*taskCaseSensitive*/); } /** diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java index 87c7ee5..f6852b8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/internal/compiler/ast/CompilationUnitDeclaration.java @@ -9,7 +9,6 @@ * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpeclipse.internal.compiler.ast; - import java.util.ArrayList; import net.sourceforge.phpdt.core.compiler.CharOperation; @@ -30,6 +29,7 @@ public class CompilationUnitDeclaration extends ASTNode implements ProblemSeveri public ImportReference[] imports; // public TypeDeclaration[] types; public ArrayList types; + //public char[][] name; public int[][] comments; diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java index d79c30d..c179005 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/BasicJavaEditorActionContributor.java @@ -57,8 +57,8 @@ public class BasicJavaEditorActionContributor extends BasicTextEditorActionContr // private RetargetTextEditorAction fStructureSelectPreviousAction; // private RetargetTextEditorAction fStructureSelectHistoryAction; -// private RetargetTextEditorAction fGotoNextMemberAction; -// private RetargetTextEditorAction fGotoPreviousMemberAction; + private RetargetTextEditorAction fGotoNextMemberAction; + private RetargetTextEditorAction fGotoPreviousMemberAction; // // private RetargetTextEditorAction fRemoveOccurrenceAnnotationsAction; @@ -102,10 +102,10 @@ public class BasicJavaEditorActionContributor extends BasicTextEditorActionContr // fStructureSelectHistoryAction= new RetargetTextEditorAction(b, "StructureSelectHistory."); //$NON-NLS-1$ // fStructureSelectHistoryAction.setActionDefinitionId(PHPEditorActionDefinitionIds.SELECT_LAST); // -// fGotoNextMemberAction= new RetargetTextEditorAction(b, "GotoNextMember."); //$NON-NLS-1$ -// fGotoNextMemberAction.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER); -// fGotoPreviousMemberAction= new RetargetTextEditorAction(b, "GotoPreviousMember."); //$NON-NLS-1$ -// fGotoPreviousMemberAction.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER); + fGotoNextMemberAction= new RetargetTextEditorAction(b, "GotoNextMember."); //$NON-NLS-1$ + fGotoNextMemberAction.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_NEXT_MEMBER); + fGotoPreviousMemberAction= new RetargetTextEditorAction(b, "GotoPreviousMember."); //$NON-NLS-1$ + fGotoPreviousMemberAction.setActionDefinitionId(PHPEditorActionDefinitionIds.GOTO_PREVIOUS_MEMBER); // // fRemoveOccurrenceAnnotationsAction= new RetargetTextEditorAction(b, "RemoveOccurrenceAnnotations."); //$NON-NLS-1$ // fRemoveOccurrenceAnnotationsAction.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_OCCURRENCE_ANNOTATIONS); @@ -168,8 +168,8 @@ public class BasicJavaEditorActionContributor extends BasicTextEditorActionContr IMenuManager gotoMenu= menu.findMenuUsingPath("navigate/goTo"); //$NON-NLS-1$ if (gotoMenu != null) { gotoMenu.add(new Separator("additions2")); //$NON-NLS-1$ -// gotoMenu.appendToGroup("additions2", fGotoPreviousMemberAction); //$NON-NLS-1$ -// gotoMenu.appendToGroup("additions2", fGotoNextMemberAction); //$NON-NLS-1$ + gotoMenu.appendToGroup("additions2", fGotoPreviousMemberAction); //$NON-NLS-1$ + gotoMenu.appendToGroup("additions2", fGotoNextMemberAction); //$NON-NLS-1$ gotoMenu.appendToGroup("additions2", fGotoMatchingBracket); //$NON-NLS-1$ } } @@ -209,7 +209,6 @@ public class BasicJavaEditorActionContributor extends BasicTextEditorActionContr // fGotoPreviousMemberAction.setAction(getAction(textEditor, GoToNextPreviousMemberAction.PREVIOUS_MEMBER)); // fRemoveOccurrenceAnnotationsAction.setAction(getAction(textEditor, "RemoveOccurrenceAnnotations")); //$NON-NLS-1$ - if (part instanceof PHPEditor) { PHPEditor javaEditor= (PHPEditor) part; javaEditor.getActionGroup().fillActionBars(getActionBars()); diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java index e6708e6..f5af618 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/CompilationUnitEditorActionContributor.java @@ -12,8 +12,6 @@ import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.ui.editor.ShowExternalPreviewAction; import org.eclipse.core.resources.IFile; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; @@ -41,10 +39,8 @@ public class CompilationUnitEditorActionContributor extends BasicEditorActionCon bars.setGlobalActionHandler(PHPdtActionConstants.UNCOMMENT, getAction(textEditor, "Uncomment")); //$NON-NLS-1$ bars.setGlobalActionHandler(PHPdtActionConstants.TOGGLE_COMMENT, getAction(textEditor, "ToggleComment")); //$NON-NLS-1$ bars.setGlobalActionHandler(PHPdtActionConstants.FORMAT, getAction(textEditor, "Format")); //$NON-NLS-1$ - // bars.setGlobalActionHandler(PHPdtActionConstants.ADD_BLOCK_COMMENT, - // getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$ - // bars.setGlobalActionHandler(PHPdtActionConstants.REMOVE_BLOCK_COMMENT, - // getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$ + bars.setGlobalActionHandler(PHPdtActionConstants.ADD_BLOCK_COMMENT, getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$ + bars.setGlobalActionHandler(PHPdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$ // bars.setGlobalActionHandler(PHPdtActionConstants.INDENT, getAction( // textEditor, "Indent")); //$NON-NLS-1$ //$NON-NLS-2$ 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 d5eeb74..ade4363 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditor.java @@ -13,6 +13,8 @@ package net.sourceforge.phpeclipse.phpeditor; **********************************************************************/ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.text.BreakIterator; +import java.text.CharacterIterator; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -31,18 +33,24 @@ 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.internal.compiler.parser.Scanner; import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; import net.sourceforge.phpdt.internal.ui.actions.FoldingActionGroup; +import net.sourceforge.phpdt.internal.ui.actions.SelectionConverter; 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.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.IViewPartInputProvider; import net.sourceforge.phpdt.ui.IContextMenuConstants; import net.sourceforge.phpdt.ui.JavaUI; import net.sourceforge.phpdt.ui.PreferenceConstants; import net.sourceforge.phpdt.ui.actions.GotoMatchingBracketAction; +import net.sourceforge.phpdt.ui.actions.OpenEditorActionGroup; import net.sourceforge.phpdt.ui.text.JavaTextTools; import net.sourceforge.phpdt.ui.text.PHPSourceViewerConfiguration; import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingStructureProvider; @@ -74,23 +82,30 @@ import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ISynchronizable; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.ITextInputListener; +import org.eclipse.jface.text.ITextPresentationListener; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.ITextViewerExtension2; import org.eclipse.jface.text.ITextViewerExtension3; +import org.eclipse.jface.text.ITextViewerExtension4; import org.eclipse.jface.text.ITextViewerExtension5; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.Region; +import org.eclipse.jface.text.TextPresentation; 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.reconciler.IReconciler; import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.AnnotationRulerColumn; +import org.eclipse.jface.text.source.CompositeRuler; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModelExtension; import org.eclipse.jface.text.source.IOverviewRuler; import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.jface.text.source.ISourceViewerExtension2; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.OverviewRuler; import org.eclipse.jface.text.source.SourceViewerConfiguration; @@ -99,6 +114,8 @@ import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.ListenerList; import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -109,6 +126,7 @@ import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BidiSegmentEvent; import org.eclipse.swt.custom.BidiSegmentListener; +import org.eclipse.swt.custom.ST; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.FocusEvent; @@ -133,6 +151,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPartService; +import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; @@ -149,16 +168,18 @@ import org.eclipse.ui.texteditor.ChainedPreferenceStore; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.IEditorStatusLine; import org.eclipse.ui.texteditor.ITextEditorActionConstants; +import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; +import org.eclipse.ui.texteditor.IUpdate; import org.eclipse.ui.texteditor.MarkerAnnotation; import org.eclipse.ui.texteditor.ResourceAction; import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; import org.eclipse.ui.texteditor.TextEditorAction; +import org.eclipse.ui.texteditor.TextNavigationAction; import org.eclipse.ui.texteditor.TextOperationAction; import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import org.eclipse.ui.views.tasklist.TaskList; - /** * PHP specific text editor. */ @@ -229,37 +250,36 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I /** * "Smart" runnable for updating the outline page's selection. */ - class OutlinePageSelectionUpdater implements Runnable { - - /** Has the runnable already been posted? */ - private boolean fPosted = false; - - public OutlinePageSelectionUpdater() { - } - - /* - * @see Runnable#run() - */ - public void run() { - synchronizeOutlinePageSelection(); - fPosted = false; - } - - /** - * Posts this runnable into the event queue. - */ - public void post() { - if (fPosted) - return; - - Shell shell = getSite().getShell(); - if (shell != null & !shell.isDisposed()) { - fPosted = true; - shell.getDisplay().asyncExec(this); - } - } - }; - + // class OutlinePageSelectionUpdater implements Runnable { + // + // /** Has the runnable already been posted? */ + // private boolean fPosted = false; + // + // public OutlinePageSelectionUpdater() { + // } + // + // /* + // * @see Runnable#run() + // */ + // public void run() { + // synchronizeOutlinePageSelection(); + // fPosted = false; + // } + // + // /** + // * Posts this runnable into the event queue. + // */ + // public void post() { + // if (fPosted) + // return; + // + // Shell shell = getSite().getShell(); + // if (shell != null & !shell.isDisposed()) { + // fPosted = true; + // shell.getDisplay().asyncExec(this); + // } + // } + // }; class SelectionChangedListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { doSelectionChanged(event); @@ -656,8 +676,672 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I /* * Link mode. */ + // class MouseClickListener implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, + // IPropertyChangeListener, IDocumentListener, ITextInputListener { + // + // /** The session is active. */ + // private boolean fActive; + // + // /** The currently active style range. */ + // private IRegion fActiveRegion; + // + // /** The currently active style range as position. */ + // private Position fRememberedPosition; + // + // /** The hand cursor. */ + // private Cursor fCursor; + // + // /** The link color. */ + // private Color fColor; + // + // /** The key modifier mask. */ + // private int fKeyModifierMask; + // + // public void deactivate() { + // deactivate(false); + // } + // + // public void deactivate(boolean redrawAll) { + // if (!fActive) + // return; + // + // repairRepresentation(redrawAll); + // fActive = false; + // } + // + // public void install() { + // + // ISourceViewer sourceViewer = getSourceViewer(); + // if (sourceViewer == null) + // return; + // + // StyledText text = sourceViewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // + // updateColor(sourceViewer); + // + // sourceViewer.addTextInputListener(this); + // + // IDocument document = sourceViewer.getDocument(); + // if (document != null) + // document.addDocumentListener(this); + // + // text.addKeyListener(this); + // text.addMouseListener(this); + // text.addMouseMoveListener(this); + // text.addFocusListener(this); + // text.addPaintListener(this); + // + // updateKeyModifierMask(); + // + // IPreferenceStore preferenceStore = getPreferenceStore(); + // preferenceStore.addPropertyChangeListener(this); + // } + // + // private void updateKeyModifierMask() { + // String modifiers = getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER); + // fKeyModifierMask = computeStateMask(modifiers); + // if (fKeyModifierMask == -1) { + // // Fallback to stored state mask + // fKeyModifierMask = getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); + // } + // ; + // } + // + // private int computeStateMask(String modifiers) { + // if (modifiers == null) + // return -1; + // + // if (modifiers.length() == 0) + // return SWT.NONE; + // + // int stateMask = 0; + // StringTokenizer modifierTokenizer = new StringTokenizer(modifiers, ",;.:+-* "); //$NON-NLS-1$ + // while (modifierTokenizer.hasMoreTokens()) { + // int modifier = EditorUtility.findLocalizedModifier(modifierTokenizer.nextToken()); + // if (modifier == 0 || (stateMask & modifier) == modifier) + // return -1; + // stateMask = stateMask | modifier; + // } + // return stateMask; + // } + // + // public void uninstall() { + // + // if (fColor != null) { + // fColor.dispose(); + // fColor = null; + // } + // + // if (fCursor != null) { + // fCursor.dispose(); + // fCursor = null; + // } + // + // ISourceViewer sourceViewer = getSourceViewer(); + // if (sourceViewer == null) + // return; + // + // sourceViewer.removeTextInputListener(this); + // + // IDocument document = sourceViewer.getDocument(); + // if (document != null) + // document.removeDocumentListener(this); + // + // IPreferenceStore preferenceStore = getPreferenceStore(); + // if (preferenceStore != null) + // preferenceStore.removePropertyChangeListener(this); + // + // StyledText text = sourceViewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // + // text.removeKeyListener(this); + // text.removeMouseListener(this); + // text.removeMouseMoveListener(this); + // text.removeFocusListener(this); + // text.removePaintListener(this); + // } + // + // /* + // * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) + // */ + // public void propertyChange(PropertyChangeEvent event) { + // if (event.getProperty().equals(PHPEditor.LINK_COLOR)) { + // ISourceViewer viewer = getSourceViewer(); + // if (viewer != null) + // updateColor(viewer); + // } else if (event.getProperty().equals(BROWSER_LIKE_LINKS_KEY_MODIFIER)) { + // updateKeyModifierMask(); + // } + // } + // + // private void updateColor(ISourceViewer viewer) { + // if (fColor != null) + // fColor.dispose(); + // + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // + // Display display = text.getDisplay(); + // fColor = createColor(getPreferenceStore(), PHPEditor.LINK_COLOR, display); + // } + // + // /** + // * Creates a color from the information stored in the given preference store. Returns null if there is no such + // * information available. + // */ + // private Color createColor(IPreferenceStore store, String key, Display display) { + // + // RGB rgb = null; + // + // if (store.contains(key)) { + // + // if (store.isDefault(key)) + // rgb = PreferenceConverter.getDefaultColor(store, key); + // else + // rgb = PreferenceConverter.getColor(store, key); + // + // if (rgb != null) + // return new Color(display, rgb); + // } + // + // return null; + // } + // + // private void repairRepresentation() { + // repairRepresentation(false); + // } + // + // private void repairRepresentation(boolean redrawAll) { + // + // if (fActiveRegion == null) + // return; + // + // ISourceViewer viewer = getSourceViewer(); + // if (viewer != null) { + // resetCursor(viewer); + // + // int offset = fActiveRegion.getOffset(); + // int length = fActiveRegion.getLength(); + // + // // remove style + // if (!redrawAll && viewer instanceof ITextViewerExtension2) + // ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length); + // else + // viewer.invalidateTextPresentation(); + // + // // remove underline + // if (viewer instanceof ITextViewerExtension3) { + // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + // offset = extension.modelOffset2WidgetOffset(offset); + // } else { + // offset -= viewer.getVisibleRegion().getOffset(); + // } + // + // StyledText text = viewer.getTextWidget(); + // try { + // text.redrawRange(offset, length, true); + // } catch (IllegalArgumentException x) { + // PHPeclipsePlugin.log(x); + // } + // } + // + // fActiveRegion = null; + // } + // + // // will eventually be replaced by a method provided by jdt.core + // private IRegion selectWord(IDocument document, int anchor) { + // + // try { + // int offset = anchor; + // char c; + // + // while (offset >= 0) { + // c = document.getChar(offset); + // if (!Character.isJavaIdentifierPart(c)) + // break; + // --offset; + // } + // + // int start = offset; + // + // offset = anchor; + // int length = document.getLength(); + // + // while (offset < length) { + // c = document.getChar(offset); + // if (!Character.isJavaIdentifierPart(c)) + // break; + // ++offset; + // } + // + // int end = offset; + // + // if (start == end) + // return new Region(start, 0); + // else + // return new Region(start + 1, end - start - 1); + // + // } catch (BadLocationException x) { + // return null; + // } + // } + // + // IRegion getCurrentTextRegion(ISourceViewer viewer) { + // + // int offset = getCurrentTextOffset(viewer); + // if (offset == -1) + // return null; + // + // return null; + // // IJavaElement input= SelectionConverter.getInput(PHPEditor.this); + // // if (input == null) + // // return null; + // // + // // try { + // // + // // IJavaElement[] elements= null; + // // synchronized (input) { + // // elements= ((ICodeAssist) input).codeSelect(offset, 0); + // // } + // // + // // if (elements == null || elements.length == 0) + // // return null; + // // + // // return selectWord(viewer.getDocument(), offset); + // // + // // } catch (JavaModelException e) { + // // return null; + // // } + // } + // + // private int getCurrentTextOffset(ISourceViewer viewer) { + // + // try { + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return -1; + // + // Display display = text.getDisplay(); + // Point absolutePosition = display.getCursorLocation(); + // Point relativePosition = text.toControl(absolutePosition); + // + // int widgetOffset = text.getOffsetAtLocation(relativePosition); + // if (viewer instanceof ITextViewerExtension3) { + // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + // return extension.widgetOffset2ModelOffset(widgetOffset); + // } else { + // return widgetOffset + viewer.getVisibleRegion().getOffset(); + // } + // + // } catch (IllegalArgumentException e) { + // return -1; + // } + // } + // + // private void highlightRegion(ISourceViewer viewer, IRegion region) { + // + // if (region.equals(fActiveRegion)) + // return; + // + // repairRepresentation(); + // + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // + // // highlight region + // int offset = 0; + // int length = 0; + // + // if (viewer instanceof ITextViewerExtension3) { + // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + // IRegion widgetRange = extension.modelRange2WidgetRange(region); + // if (widgetRange == null) + // return; + // + // offset = widgetRange.getOffset(); + // length = widgetRange.getLength(); + // + // } else { + // offset = region.getOffset() - viewer.getVisibleRegion().getOffset(); + // length = region.getLength(); + // } + // + // StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset); + // Color foregroundColor = fColor; + // Color backgroundColor = oldStyleRange == null ? text.getBackground() : oldStyleRange.background; + // StyleRange styleRange = new StyleRange(offset, length, foregroundColor, backgroundColor); + // text.setStyleRange(styleRange); + // + // // underline + // text.redrawRange(offset, length, true); + // + // fActiveRegion = region; + // } + // + // private void activateCursor(ISourceViewer viewer) { + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // Display display = text.getDisplay(); + // if (fCursor == null) + // fCursor = new Cursor(display, SWT.CURSOR_HAND); + // text.setCursor(fCursor); + // } + // + // private void resetCursor(ISourceViewer viewer) { + // StyledText text = viewer.getTextWidget(); + // if (text != null && !text.isDisposed()) + // text.setCursor(null); + // + // if (fCursor != null) { + // fCursor.dispose(); + // fCursor = null; + // } + // } + // + // /* + // * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) + // */ + // public void keyPressed(KeyEvent event) { + // + // if (fActive) { + // deactivate(); + // return; + // } + // + // if (event.keyCode != fKeyModifierMask) { + // deactivate(); + // return; + // } + // + // fActive = true; + // + // // removed for #25871 + // // + // // ISourceViewer viewer= getSourceViewer(); + // // if (viewer == null) + // // return; + // // + // // IRegion region= getCurrentTextRegion(viewer); + // // if (region == null) + // // return; + // // + // // highlightRegion(viewer, region); + // // activateCursor(viewer); + // } + // + // /* + // * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + // */ + // public void keyReleased(KeyEvent event) { + // + // if (!fActive) + // return; + // + // deactivate(); + // } + // + // /* + // * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + // */ + // public void mouseDoubleClick(MouseEvent e) { + // } + // + // /* + // * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + // */ + // public void mouseDown(MouseEvent event) { + // + // if (!fActive) + // return; + // + // if (event.stateMask != fKeyModifierMask) { + // deactivate(); + // return; + // } + // + // if (event.button != 1) { + // deactivate(); + // return; + // } + // } + // + // /* + // * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + // */ + // public void mouseUp(MouseEvent e) { + // + // if (!fActive) + // return; + // + // if (e.button != 1) { + // deactivate(); + // return; + // } + // + // boolean wasActive = fCursor != null; + // + // deactivate(); + // + // if (wasActive) { + // IAction action = getAction("OpenEditor"); //$NON-NLS-1$ + // if (action != null) + // action.run(); + // } + // } + // + // /* + // * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent) + // */ + // public void mouseMove(MouseEvent event) { + // + // if (event.widget instanceof Control && !((Control) event.widget).isFocusControl()) { + // deactivate(); + // return; + // } + // + // if (!fActive) { + // if (event.stateMask != fKeyModifierMask) + // return; + // // modifier was already pressed + // fActive = true; + // } + // + // ISourceViewer viewer = getSourceViewer(); + // if (viewer == null) { + // deactivate(); + // return; + // } + // + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) { + // deactivate(); + // return; + // } + // + // if ((event.stateMask & SWT.BUTTON1) != 0 && text.getSelectionCount() != 0) { + // deactivate(); + // return; + // } + // + // IRegion region = getCurrentTextRegion(viewer); + // if (region == null || region.getLength() == 0) { + // repairRepresentation(); + // return; + // } + // + // highlightRegion(viewer, region); + // activateCursor(viewer); + // } + // + // /* + // * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent) + // */ + // public void focusGained(FocusEvent e) { + // } + // + // /* + // * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) + // */ + // public void focusLost(FocusEvent event) { + // deactivate(); + // } + // + // /* + // * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent) + // */ + // public void documentAboutToBeChanged(DocumentEvent event) { + // if (fActive && fActiveRegion != null) { + // fRememberedPosition = new Position(fActiveRegion.getOffset(), fActiveRegion.getLength()); + // try { + // event.getDocument().addPosition(fRememberedPosition); + // } catch (BadLocationException x) { + // fRememberedPosition = null; + // } + // } + // } + // + // /* + // * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) + // */ + // public void documentChanged(DocumentEvent event) { + // if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) { + // event.getDocument().removePosition(fRememberedPosition); + // fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); + // } + // fRememberedPosition = null; + // + // ISourceViewer viewer = getSourceViewer(); + // if (viewer != null) { + // StyledText widget = viewer.getTextWidget(); + // if (widget != null && !widget.isDisposed()) { + // widget.getDisplay().asyncExec(new Runnable() { + // public void run() { + // deactivate(); + // } + // }); + // } + // } + // } + // + // /* + // * @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; + // deactivate(); + // 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); + // } + // + // /* + // * @see PaintListener#paintControl(PaintEvent) + // */ + // public void paintControl(PaintEvent event) { + // if (fActiveRegion == null) + // return; + // + // ISourceViewer viewer = getSourceViewer(); + // if (viewer == null) + // return; + // + // StyledText text = viewer.getTextWidget(); + // if (text == null || text.isDisposed()) + // return; + // + // int offset = 0; + // int length = 0; + // + // if (viewer instanceof ITextViewerExtension3) { + // + // ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + // IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset, length)); + // if (widgetRange == null) + // return; + // + // offset = widgetRange.getOffset(); + // length = widgetRange.getLength(); + // + // } else { + // + // IRegion region = viewer.getVisibleRegion(); + // if (!includes(region, fActiveRegion)) + // return; + // + // offset = fActiveRegion.getOffset() - region.getOffset(); + // length = fActiveRegion.getLength(); + // } + // + // // support for bidi + // Point minLocation = getMinimumLocation(text, offset, length); + // Point maxLocation = getMaximumLocation(text, offset, length); + // + // int x1 = minLocation.x; + // int x2 = minLocation.x + maxLocation.x - minLocation.x - 1; + // int y = minLocation.y + text.getLineHeight() - 1; + // + // GC gc = event.gc; + // if (fColor != null && !fColor.isDisposed()) + // gc.setForeground(fColor); + // gc.drawLine(x1, y, x2, y); + // } + // + // private boolean includes(IRegion region, IRegion position) { + // return position.getOffset() >= region.getOffset() + // && position.getOffset() + position.getLength() <= region.getOffset() + region.getLength(); + // } + // + // private Point getMinimumLocation(StyledText text, int offset, int length) { + // Point minLocation = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); + // + // for (int i = 0; i <= length; i++) { + // Point location = text.getLocationAtOffset(offset + i); + // + // if (location.x < minLocation.x) + // minLocation.x = location.x; + // if (location.y < minLocation.y) + // minLocation.y = location.y; + // } + // + // return minLocation; + // } + // + // private Point getMaximumLocation(StyledText text, int offset, int length) { + // Point maxLocation = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE); + // + // for (int i = 0; i <= length; i++) { + // Point location = text.getLocationAtOffset(offset + i); + // + // if (location.x > maxLocation.x) + // maxLocation.x = location.x; + // if (location.y > maxLocation.y) + // maxLocation.y = location.y; + // } + // + // return maxLocation; + // } + // }; + /* + * Link mode. + */ class MouseClickListener implements KeyListener, MouseListener, MouseMoveListener, FocusListener, PaintListener, - IPropertyChangeListener, IDocumentListener, ITextInputListener { + IPropertyChangeListener, IDocumentListener, ITextInputListener, ITextPresentationListener { /** The session is active. */ private boolean fActive; @@ -690,7 +1374,6 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } public void install() { - ISourceViewer sourceViewer = getSourceViewer(); if (sourceViewer == null) return; @@ -713,6 +1396,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I text.addFocusListener(this); text.addPaintListener(this); + ((ITextViewerExtension4) sourceViewer).addTextPresentationListener(this); + updateKeyModifierMask(); IPreferenceStore preferenceStore = getPreferenceStore(); @@ -723,10 +1408,9 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I String modifiers = getPreferenceStore().getString(BROWSER_LIKE_LINKS_KEY_MODIFIER); fKeyModifierMask = computeStateMask(modifiers); if (fKeyModifierMask == -1) { - // Fallback to stored state mask + // Fall back to stored state mask fKeyModifierMask = getPreferenceStore().getInt(BROWSER_LIKE_LINKS_KEY_MODIFIER_MASK); } - ; } private int computeStateMask(String modifiers) { @@ -760,19 +1444,23 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } ISourceViewer sourceViewer = getSourceViewer(); - if (sourceViewer == null) - return; - - sourceViewer.removeTextInputListener(this); + if (sourceViewer != null) + sourceViewer.removeTextInputListener(this); - IDocument document = sourceViewer.getDocument(); - if (document != null) - document.removeDocumentListener(this); + IDocumentProvider documentProvider = getDocumentProvider(); + if (documentProvider != null) { + IDocument document = documentProvider.getDocument(getEditorInput()); + if (document != null) + document.removeDocumentListener(this); + } IPreferenceStore preferenceStore = getPreferenceStore(); if (preferenceStore != null) preferenceStore.removePropertyChangeListener(this); + if (sourceViewer == null) + return; + StyledText text = sourceViewer.getTextWidget(); if (text == null || text.isDisposed()) return; @@ -782,6 +1470,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I text.removeMouseMoveListener(this); text.removeFocusListener(this); text.removePaintListener(this); + + ((ITextViewerExtension4) sourceViewer).removeTextPresentationListener(this); } /* @@ -810,8 +1500,15 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } /** - * Creates a color from the information stored in the given preference store. Returns null if there is no such - * information available. + * Creates a color from the information stored in the given preference store. + * + * @param store + * the preference store + * @param key + * the key + * @param display + * the display + * @return the color or null if there is no such information available */ private Color createColor(IPreferenceStore store, String key, Display display) { @@ -840,36 +1537,36 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I if (fActiveRegion == null) return; + int offset = fActiveRegion.getOffset(); + int length = fActiveRegion.getLength(); + fActiveRegion = null; + ISourceViewer viewer = getSourceViewer(); if (viewer != null) { - resetCursor(viewer); - int offset = fActiveRegion.getOffset(); - int length = fActiveRegion.getLength(); + resetCursor(viewer); - // remove style + // Invalidate ==> remove applied text presentation if (!redrawAll && viewer instanceof ITextViewerExtension2) ((ITextViewerExtension2) viewer).invalidateTextPresentation(offset, length); else viewer.invalidateTextPresentation(); - // remove underline - if (viewer instanceof ITextViewerExtension3) { - ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + // Remove underline + if (viewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; offset = extension.modelOffset2WidgetOffset(offset); } else { offset -= viewer.getVisibleRegion().getOffset(); } - - StyledText text = viewer.getTextWidget(); try { - text.redrawRange(offset, length, true); + StyledText text = viewer.getTextWidget(); + + text.redrawRange(offset, length, false); } catch (IllegalArgumentException x) { - PHPeclipsePlugin.log(x); + // JavaPlugin.log(x); } } - - fActiveRegion = null; } // will eventually be replaced by a method provided by jdt.core @@ -881,7 +1578,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I while (offset >= 0) { c = document.getChar(offset); - if (!Character.isJavaIdentifierPart(c)) + // if (!Character.isJavaIdentifierPart(c)&&c!='$') + if (!Scanner.isPHPIdentifierPart(c) && c != '$') break; --offset; } @@ -893,7 +1591,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I while (offset < length) { c = document.getChar(offset); - if (!Character.isJavaIdentifierPart(c)) + // if (!Character.isJavaIdentifierPart(c)&&c!='$') + if (!Scanner.isPHPIdentifierPart(c) && c != '$') break; ++offset; } @@ -916,26 +1615,25 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I if (offset == -1) return null; - return null; - // IJavaElement input= SelectionConverter.getInput(PHPEditor.this); - // if (input == null) - // return null; - // - // try { - // - // IJavaElement[] elements= null; - // synchronized (input) { - // elements= ((ICodeAssist) input).codeSelect(offset, 0); - // } - // - // if (elements == null || elements.length == 0) - // return null; - // - // return selectWord(viewer.getDocument(), offset); - // - // } catch (JavaModelException e) { - // return null; - // } + IJavaElement input = SelectionConverter.getInput(PHPEditor.this); + if (input == null) + return null; + + // try { + + // IJavaElement[] elements= null; + // synchronized (input) { + // elements= ((ICodeAssist) input).codeSelect(offset, 0); + // } + // + // if (elements == null || elements.length == 0) + // return null; + + return selectWord(viewer.getDocument(), offset); + + // } catch (JavaModelException e) { + // return null; + // } } private int getCurrentTextOffset(ISourceViewer viewer) { @@ -950,8 +1648,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I Point relativePosition = text.toControl(absolutePosition); int widgetOffset = text.getOffsetAtLocation(relativePosition); - if (viewer instanceof ITextViewerExtension3) { - ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + if (viewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; return extension.widgetOffset2ModelOffset(widgetOffset); } else { return widgetOffset + viewer.getVisibleRegion().getOffset(); @@ -962,6 +1660,15 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } } + public void applyTextPresentation(TextPresentation textPresentation) { + if (fActiveRegion == null) + return; + IRegion region = textPresentation.getExtent(); + if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region.getOffset() + && region.getOffset() + region.getLength() > fActiveRegion.getOffset()) + textPresentation.mergeStyleRange(new StyleRange(fActiveRegion.getOffset(), fActiveRegion.getLength(), fColor, null)); + } + private void highlightRegion(ISourceViewer viewer, IRegion region) { if (region.equals(fActiveRegion)) @@ -973,12 +1680,11 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I if (text == null || text.isDisposed()) return; - // highlight region + // Underline int offset = 0; int length = 0; - - if (viewer instanceof ITextViewerExtension3) { - ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; + if (viewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; IRegion widgetRange = extension.modelRange2WidgetRange(region); if (widgetRange == null) return; @@ -990,17 +1696,14 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I offset = region.getOffset() - viewer.getVisibleRegion().getOffset(); length = region.getLength(); } + text.redrawRange(offset, length, false); - StyleRange oldStyleRange = text.getStyleRangeAtOffset(offset); - Color foregroundColor = fColor; - Color backgroundColor = oldStyleRange == null ? text.getBackground() : oldStyleRange.background; - StyleRange styleRange = new StyleRange(offset, length, foregroundColor, backgroundColor); - text.setStyleRange(styleRange); - - // underline - text.redrawRange(offset, length, true); - + // Invalidate region ==> apply text presentation fActiveRegion = region; + if (viewer instanceof ITextViewerExtension2) + ((ITextViewerExtension2) viewer).invalidateTextPresentation(region.getOffset(), region.getLength()); + else + viewer.invalidateTextPresentation(); } private void activateCursor(ISourceViewer viewer) { @@ -1041,18 +1744,18 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I fActive = true; - // removed for #25871 + // removed for #25871 // - // ISourceViewer viewer= getSourceViewer(); - // if (viewer == null) - // return; + // ISourceViewer viewer= getSourceViewer(); + // if (viewer == null) + // return; // - // IRegion region= getCurrentTextRegion(viewer); - // if (region == null) - // return; + // IRegion region= getCurrentTextRegion(viewer); + // if (region == null) + // return; // - // highlightRegion(viewer, region); - // activateCursor(viewer); + // highlightRegion(viewer, region); + // activateCursor(viewer); } /* @@ -1190,21 +1893,29 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentChanged(DocumentEvent event) { - if (fRememberedPosition != null && !fRememberedPosition.isDeleted()) { - event.getDocument().removePosition(fRememberedPosition); - fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); - } - fRememberedPosition = null; + if (fRememberedPosition != null) { + if (!fRememberedPosition.isDeleted()) { - ISourceViewer viewer = getSourceViewer(); - if (viewer != null) { - StyledText widget = viewer.getTextWidget(); - if (widget != null && !widget.isDisposed()) { - widget.getDisplay().asyncExec(new Runnable() { - public void run() { - deactivate(); + event.getDocument().removePosition(fRememberedPosition); + fActiveRegion = new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength()); + fRememberedPosition = null; + + ISourceViewer viewer = getSourceViewer(); + if (viewer != null) { + StyledText widget = viewer.getTextWidget(); + if (widget != null && !widget.isDisposed()) { + widget.getDisplay().asyncExec(new Runnable() { + public void run() { + deactivate(); + } + }); } - }); + } + + } else { + fActiveRegion = null; + fRememberedPosition = null; + deactivate(); } } } @@ -1248,10 +1959,10 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I int offset = 0; int length = 0; - if (viewer instanceof ITextViewerExtension3) { + if (viewer instanceof ITextViewerExtension5) { - ITextViewerExtension3 extension = (ITextViewerExtension3) viewer; - IRegion widgetRange = extension.modelRange2WidgetRange(new Region(offset, length)); + ITextViewerExtension5 extension = (ITextViewerExtension5) viewer; + IRegion widgetRange = extension.modelRange2WidgetRange(fActiveRegion); if (widgetRange == null) return; @@ -1316,7 +2027,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I return maxLocation; } - }; + } /** * This action dispatches into two behaviours: If there is no current text hover, the javadoc is displayed using information @@ -1431,6 +2142,416 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } }; + /** + * This action implements smart home. + * + * Instead of going to the start of a line it does the following: + * - if smart home/end is enabled and the caret is after the line's first non-whitespace then the caret is moved directly before + * it, taking JavaDoc and multi-line comments into account. - if the caret is before the line's first non-whitespace the caret is + * moved to the beginning of the line - if the caret is at the beginning of the line see first case. + * + * @since 3.0 + */ + protected class SmartLineStartAction extends LineStartAction { + + /** + * Creates a new smart line start action + * + * @param textWidget + * the styled text widget + * @param doSelect + * a boolean flag which tells if the text up to the beginning of the line should be selected + */ + public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) { + super(textWidget, doSelect); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#getLineStartPosition(java.lang.String, int, + * java.lang.String) + */ + protected int getLineStartPosition(final IDocument document, final String line, final int length, final int offset) { + + String type = IDocument.DEFAULT_CONTENT_TYPE; + try { + type = TextUtilities.getContentType(document, IPHPPartitions.PHP_PARTITIONING, offset, true); + } catch (BadLocationException exception) { + // Should not happen + } + + int index = super.getLineStartPosition(document, line, length, offset); + if (type.equals(IPHPPartitions.PHP_PHPDOC_COMMENT) || type.equals(IPHPPartitions.PHP_MULTILINE_COMMENT)) { + if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') { + do { + ++index; + } while (index < length && Character.isWhitespace(line.charAt(index))); + } + } else { + if (index < length - 1 && line.charAt(index) == '/' && line.charAt(index + 1) == '/') { + index++; + do { + ++index; + } while (index < length && Character.isWhitespace(line.charAt(index))); + } + } + return index; + } + } + + /** + * Text navigation action to navigate to the next sub-word. + * + * @since 3.0 + */ + protected abstract class NextSubWordAction extends TextNavigationAction { + + protected JavaWordIterator fIterator = new JavaWordIterator(); + + /** + * Creates a new next sub-word action. + * + * @param code + * Action code for the default operation. Must be an action code from + * @see org.eclipse.swt.custom.ST. + */ + protected NextSubWordAction(int code) { + super(getSourceViewer().getTextWidget(), code); + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + // Check whether we are in a java code partition and the preference is enabled + final IPreferenceStore store = getPreferenceStore(); + if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) { + super.run(); + return; + } + + final ISourceViewer viewer = getSourceViewer(); + final IDocument document = viewer.getDocument(); + fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document)); + int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + if (position == -1) + return; + + int next = findNextPosition(position); + if (next != BreakIterator.DONE) { + setCaretPosition(next); + getTextWidget().showSelection(); + fireSelectionChanged(); + } + + } + + /** + * Finds the next position after the given position. + * + * @param position + * the current position + * @return the next position + */ + protected int findNextPosition(int position) { + ISourceViewer viewer = getSourceViewer(); + int widget = -1; + while (position != BreakIterator.DONE && widget == -1) { // TODO: optimize + position = fIterator.following(position); + if (position != BreakIterator.DONE) + widget = modelOffset2WidgetOffset(viewer, position); + } + return position; + } + + /** + * Sets the caret position to the sub-word boundary given with position. + * + * @param position + * Position where the action should move the caret + */ + protected abstract void setCaretPosition(int position); + } + + /** + * Text navigation action to navigate to the next sub-word. + * + * @since 3.0 + */ + protected class NavigateNextSubWordAction extends NextSubWordAction { + + /** + * Creates a new navigate next sub-word action. + */ + public NavigateNextSubWordAction() { + super(ST.WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position)); + } + } + + /** + * Text operation action to delete the next sub-word. + * + * @since 3.0 + */ + protected class DeleteNextSubWordAction extends NextSubWordAction implements IUpdate { + + /** + * Creates a new delete next sub-word action. + */ + public DeleteNextSubWordAction() { + super(ST.DELETE_WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + if (!validateEditorInputState()) + return; + + final ISourceViewer viewer = getSourceViewer(); + final int caret = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + + try { + viewer.getDocument().replace(caret, position - caret, ""); //$NON-NLS-1$ + } catch (BadLocationException exception) { + // Should not happen + } + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#findNextPosition(int) + */ + protected int findNextPosition(int position) { + return fIterator.following(position); + } + + /* + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + setEnabled(isEditorInputModifiable()); + } + } + + /** + * Text operation action to select the next sub-word. + * + * @since 3.0 + */ + protected class SelectNextSubWordAction extends NextSubWordAction { + + /** + * Creates a new select next sub-word action. + */ + public SelectNextSubWordAction() { + super(ST.SELECT_WORD_NEXT); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.NextSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + final ISourceViewer viewer = getSourceViewer(); + + final StyledText text = viewer.getTextWidget(); + if (text != null && !text.isDisposed()) { + + final Point selection = text.getSelection(); + final int caret = text.getCaretOffset(); + final int offset = modelOffset2WidgetOffset(viewer, position); + + if (caret == selection.x) + text.setSelectionRange(selection.y, offset - selection.y); + else + text.setSelectionRange(selection.x, offset - selection.x); + } + } + } + + /** + * Text navigation action to navigate to the previous sub-word. + * + * @since 3.0 + */ + protected abstract class PreviousSubWordAction extends TextNavigationAction { + + protected JavaWordIterator fIterator = new JavaWordIterator(); + + /** + * Creates a new previous sub-word action. + * + * @param code + * Action code for the default operation. Must be an action code from + * @see org.eclipse.swt.custom.ST. + */ + protected PreviousSubWordAction(final int code) { + super(getSourceViewer().getTextWidget(), code); + } + + /* + * @see org.eclipse.jface.action.IAction#run() + */ + public void run() { + // Check whether we are in a java code partition and the preference is enabled + final IPreferenceStore store = getPreferenceStore(); + if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) { + super.run(); + return; + } + + final ISourceViewer viewer = getSourceViewer(); + final IDocument document = viewer.getDocument(); + fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document)); + int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + if (position == -1) + return; + + int previous = findPreviousPosition(position); + if (previous != BreakIterator.DONE) { + setCaretPosition(previous); + getTextWidget().showSelection(); + fireSelectionChanged(); + } + + } + + /** + * Finds the previous position before the given position. + * + * @param position + * the current position + * @return the previous position + */ + protected int findPreviousPosition(int position) { + ISourceViewer viewer = getSourceViewer(); + int widget = -1; + while (position != BreakIterator.DONE && widget == -1) { // TODO: optimize + position = fIterator.preceding(position); + if (position != BreakIterator.DONE) + widget = modelOffset2WidgetOffset(viewer, position); + } + return position; + } + + /** + * Sets the caret position to the sub-word boundary given with position. + * + * @param position + * Position where the action should move the caret + */ + protected abstract void setCaretPosition(int position); + } + + /** + * Text navigation action to navigate to the previous sub-word. + * + * @since 3.0 + */ + protected class NavigatePreviousSubWordAction extends PreviousSubWordAction { + + /** + * Creates a new navigate previous sub-word action. + */ + public NavigatePreviousSubWordAction() { + super(ST.WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position)); + } + } + + /** + * Text operation action to delete the previous sub-word. + * + * @since 3.0 + */ + protected class DeletePreviousSubWordAction extends PreviousSubWordAction implements IUpdate { + + /** + * Creates a new delete previous sub-word action. + */ + public DeletePreviousSubWordAction() { + super(ST.DELETE_WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + if (!validateEditorInputState()) + return; + + final ISourceViewer viewer = getSourceViewer(); + final int caret = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset()); + + try { + viewer.getDocument().replace(position, caret - position, ""); //$NON-NLS-1$ + } catch (BadLocationException exception) { + // Should not happen + } + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#findPreviousPosition(int) + */ + protected int findPreviousPosition(int position) { + return fIterator.preceding(position); + } + + /* + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + setEnabled(isEditorInputModifiable()); + } + } + + /** + * Text operation action to select the previous sub-word. + * + * @since 3.0 + */ + protected class SelectPreviousSubWordAction extends PreviousSubWordAction { + + /** + * Creates a new select previous sub-word action. + */ + public SelectPreviousSubWordAction() { + super(ST.SELECT_WORD_PREVIOUS); + } + + /* + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.PreviousSubWordAction#setCaretPosition(int) + */ + protected void setCaretPosition(final int position) { + final ISourceViewer viewer = getSourceViewer(); + + final StyledText text = viewer.getTextWidget(); + if (text != null && !text.isDisposed()) { + + final Point selection = text.getSelection(); + final int caret = text.getCaretOffset(); + final int offset = modelOffset2WidgetOffset(viewer, position); + + if (caret == selection.x) + text.setSelectionRange(selection.y, offset - selection.y); + else + text.setSelectionRange(selection.x, offset - selection.x); + } + } + } + // static protected class AnnotationAccess implements IAnnotationAccess { // /* // * @see @@ -1633,10 +2754,8 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I private int fIgnoreOutlinePageSelection; /** The outline page selection updater */ - private OutlinePageSelectionUpdater fUpdater; - + // private OutlinePageSelectionUpdater fUpdater; // protected PHPSyntaxParserThread fValidationThread = null; - // private IPreferenceStore fPHPPrefStore; /** The selection changed listener */ // protected ISelectionChangedListener fSelectionChangedListener = new @@ -1906,11 +3025,14 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I fEditorSelectionChangedListener = new EditorSelectionChangedListener(); fEditorSelectionChangedListener.install(getSelectionProvider()); + if (isBrowserLikeLinks()) + enableBrowserLikeLinks(); + if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_DISABLE_OVERWRITE_MODE)) enableOverwriteMode(false); - + setWordWrap(); - // getEditorSite().getShell().addShellListener(fActivationListener); + // getEditorSite().getShell().addShellListener(fActivationListener); } private void setWordWrap() { @@ -2054,6 +3176,15 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I protected void createActions() { super.createActions(); + ActionGroup oeg, ovg, jsg, sg; + fActionGroups = new CompositeActionGroup(new ActionGroup[] { oeg = new OpenEditorActionGroup(this), + // sg= new ShowActionGroup(this), + // ovg= new OpenViewActionGroup(this), + // jsg= new JavaSearchActionGroup(this) + }); + fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { oeg }); + //, ovg, sg, jsg}); + fFoldingGroup = new FoldingActionGroup(this, getViewer()); ResourceAction resAction = new TextOperationAction(PHPEditorMessages.getResourceBundle(), @@ -2316,18 +3447,36 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I */ // protected void doSetInput(IEditorInput input) throws CoreException { // super.doSetInput(input); - // // if (fEncodingSupport != null) // fEncodingSupport.reset(); - // if (fOutlinePage != null) - // fOutlinePage.setInput(input); - // // setOutlinePageInput(fOutlinePage, input); + // setOutlinePageInput(fOutlinePage, input); // } + /* + * @see AbstractTextEditor#doSetInput + */ protected void doSetInput(IEditorInput input) throws CoreException { - super.doSetInput(input); - if (fEncodingSupport != null) - fEncodingSupport.reset(); - setOutlinePageInput(fOutlinePage, input); + ISourceViewer sourceViewer = getSourceViewer(); + if (!(sourceViewer instanceof ISourceViewerExtension2)) { + setPreferenceStore(createCombinedPreferenceStore(input)); + internalDoSetInput(input); + return; + } + + // uninstall & unregister preference store listener + if (isBrowserLikeLinks()) + disableBrowserLikeLinks(); + getSourceViewerDecorationSupport(sourceViewer).uninstall(); + ((ISourceViewerExtension2) sourceViewer).unconfigure(); + + setPreferenceStore(createCombinedPreferenceStore(input)); + + // install & register preference store listener + sourceViewer.configure(getSourceViewerConfiguration()); + getSourceViewerDecorationSupport(sourceViewer).install(getPreferenceStore()); + if (isBrowserLikeLinks()) + enableBrowserLikeLinks(); + + internalDoSetInput(input); } /* @@ -2747,7 +3896,7 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I } else if (value instanceof String) { try { sourceViewer.getTextWidget().setTabs(Integer.parseInt((String) value)); - } catch (NumberFormatException e){ + } catch (NumberFormatException e) { // bug #1038071 - set default tab: sourceViewer.getTextWidget().setTabs(80); } @@ -3013,12 +4162,11 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I /* * @see AbstractTextEditor#handleCursorPositionChanged() */ - protected void handleCursorPositionChanged() { - super.handleCursorPositionChanged(); - if (!isEditingScriptRunning() && fUpdater != null) - fUpdater.post(); - } - + // protected void handleCursorPositionChanged() { + // super.handleCursorPositionChanged(); + // if (!isEditingScriptRunning() && fUpdater != null) + // fUpdater.post(); + // } /* * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleElementContentReplaced() */ @@ -3915,6 +5063,88 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I return key != null && store.getBoolean(key); } + protected boolean isPrefQuickDiffAlwaysOn() { + return false; // never show change ruler for the non-editable java editor. Overridden in subclasses like PHPUnitEditor + } + + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#createNavigationActions() + */ + protected void createNavigationActions() { + super.createNavigationActions(); + + final StyledText textWidget = getSourceViewer().getTextWidget(); + + IAction action = new SmartLineStartAction(textWidget, false); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.LINE_START); + setAction(ITextEditorActionDefinitionIds.LINE_START, action); + + action = new SmartLineStartAction(textWidget, true); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_LINE_START); + setAction(ITextEditorActionDefinitionIds.SELECT_LINE_START, action); + + action = new NavigatePreviousSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_PREVIOUS); + setAction(ITextEditorActionDefinitionIds.WORD_PREVIOUS, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_LEFT, SWT.NULL); + + action = new NavigateNextSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.WORD_NEXT); + setAction(ITextEditorActionDefinitionIds.WORD_NEXT, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.ARROW_RIGHT, SWT.NULL); + + action = new SelectPreviousSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS); + setAction(ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_LEFT, SWT.NULL); + + action = new SelectNextSubWordAction(); + action.setActionDefinitionId(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT); + setAction(ITextEditorActionDefinitionIds.SELECT_WORD_NEXT, action); + textWidget.setKeyBinding(SWT.CTRL | SWT.SHIFT | SWT.ARROW_RIGHT, SWT.NULL); + } + + /* + * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createCompositeRuler() + */ + protected CompositeRuler createCompositeRuler() { + if (!getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER)) + return super.createCompositeRuler(); + + CompositeRuler ruler = new CompositeRuler(); + AnnotationRulerColumn column = new AnnotationRulerColumn(VERTICAL_RULER_WIDTH, getAnnotationAccess()); + column.setHover(new JavaExpandHover(ruler, getAnnotationAccess(), new IDoubleClickListener() { + + public void doubleClick(DoubleClickEvent event) { + // for now: just invoke ruler double click action + triggerAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK); + } + + private void triggerAction(String actionID) { + IAction action = getAction(actionID); + if (action != null) { + if (action instanceof IUpdate) + ((IUpdate) action).update(); + // hack to propagate line change + if (action instanceof ISelectionListener) { + ((ISelectionListener) action).selectionChanged(null, null); + } + if (action.isEnabled()) + action.run(); + } + } + + })); + ruler.addDecorator(0, column); + + if (isLineNumberRulerVisible()) + ruler.addDecorator(1, createLineNumberRulerColumn()); + else if (isPrefQuickDiffAlwaysOn()) + ruler.addDecorator(1, createChangeRulerColumn()); + + return ruler; + } + /** * Returns the folding action group, or null if there is none. * @@ -3925,6 +5155,34 @@ public abstract class PHPEditor extends AbstractDecoratedTextEditor implements I return fFoldingGroup; } + /* + * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() + */ + protected void performRevert() { + ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); + projectionViewer.setRedraw(false); + try { + + boolean projectionMode = projectionViewer.isProjectionMode(); + if (projectionMode) { + projectionViewer.disableProjection(); + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.uninstall(); + } + + super.performRevert(); + + if (projectionMode) { + if (fProjectionModelUpdater != null) + fProjectionModelUpdater.install(this, projectionViewer); + projectionViewer.enableProjection(); + } + + } finally { + projectionViewer.setRedraw(true); + } + } + /** * React to changed selection. * diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java index 6605410..5ee914e 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPEditorActionDefinitionIds.java @@ -10,6 +10,21 @@ public interface PHPEditorActionDefinitionIds extends ITextEditorActionDefiniti * @since 2.1 */ public static final String GOTO_MATCHING_BRACKET = "net.sourceforge.phpeclipse.ui.edit.text.php.goto.matching.bracket"; //$NON-NLS-1$ + /** + * Action definition ID of the edit -> go to next member action + * (value "org.eclipse.jdt.ui.edit.text.java.goto.next.member"). + * + * @since 2.1 + */ + public static final String GOTO_NEXT_MEMBER= "net.sourceforge.phpeclipse.ui.edit.text.php.goto.next.member"; //$NON-NLS-1$ + + /** + * Action definition ID of the edit -> go to previous member action + * (value "org.eclipse.jdt.ui.edit.text.java.goto.previous.member"). + * + * @since 2.1 + */ + public static final String GOTO_PREVIOUS_MEMBER= "net.sourceforge.phpeclipse.ui.edit.text.php.goto.previous.member"; //$NON-NLS-1$ /** * Value: net.sourceforge.phpeclipse.phpeditor.comment @@ -60,5 +75,4 @@ public interface PHPEditorActionDefinitionIds extends ITextEditorActionDefiniti */ // public static final String CONTENT_ASSIST_PROPOSALS = "net.sourceforge.phpeclipse.ui.edit.text.php.content.assist.proposals"; //$NON-NLS-1$ - } diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java index ac33467..d1a3355 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/PHPUnitEditor.java @@ -17,7 +17,10 @@ import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.core.JavaModelException; import net.sourceforge.phpdt.core.dom.CompilationUnit; import net.sourceforge.phpdt.internal.compiler.parser.Scanner; +import net.sourceforge.phpdt.internal.ui.actions.AddBlockCommentAction; import net.sourceforge.phpdt.internal.ui.actions.CompositeActionGroup; +import net.sourceforge.phpdt.internal.ui.actions.IndentAction; +import net.sourceforge.phpdt.internal.ui.actions.RemoveBlockCommentAction; import net.sourceforge.phpdt.internal.ui.text.ContentAssistPreference; import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions; import net.sourceforge.phpdt.internal.ui.text.PHPPairMatcher; @@ -44,7 +47,6 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; -import net.sourceforge.phpeclipse.phpeditor.ICompilationUnitDocumentProvider; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; @@ -1516,21 +1518,51 @@ public class PHPUnitEditor extends PHPEditor { //implements // markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$ // markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$ // + + action= new AddBlockCommentAction(PHPEditorMessages.getResourceBundle(), "AddBlockComment.", this); //$NON-NLS-1$ + action.setActionDefinitionId(PHPEditorActionDefinitionIds.ADD_BLOCK_COMMENT); + setAction("AddBlockComment", action); //$NON-NLS-1$ + markAsStateDependentAction("AddBlockComment", true); //$NON-NLS-1$ + markAsSelectionDependentAction("AddBlockComment", true); //$NON-NLS-1$ +// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.ADD_BLOCK_COMMENT_ACTION); + + action= new RemoveBlockCommentAction(PHPEditorMessages.getResourceBundle(), "RemoveBlockComment.", this); //$NON-NLS-1$ + action.setActionDefinitionId(PHPEditorActionDefinitionIds.REMOVE_BLOCK_COMMENT); + setAction("RemoveBlockComment", action); //$NON-NLS-1$ + markAsStateDependentAction("RemoveBlockComment", true); //$NON-NLS-1$ + markAsSelectionDependentAction("RemoveBlockComment", true); //$NON-NLS-1$ +// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.REMOVE_BLOCK_COMMENT_ACTION); + +// action= new IndentAction(PHPEditorMessages.getResourceBundle(), "Indent.", this, false); //$NON-NLS-1$ +// action.setActionDefinitionId(PHPEditorActionDefinitionIds.INDENT); +// setAction("Indent", action); //$NON-NLS-1$ +// markAsStateDependentAction("Indent", true); //$NON-NLS-1$ +// markAsSelectionDependentAction("Indent", true); //$NON-NLS-1$ +//// WorkbenchHelp.setHelp(action, IJavaHelpContextIds.INDENT_ACTION); +// + action= new IndentAction(PHPEditorMessages.getResourceBundle(), "Indent.", this, true); //$NON-NLS-1$ + setAction("IndentOnTab", action); //$NON-NLS-1$ + markAsStateDependentAction("IndentOnTab", true); //$NON-NLS-1$ + markAsSelectionDependentAction("IndentOnTab", true); //$NON-NLS-1$ + if (getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_SMART_TAB)) { // don't replace Shift Right - have to make sure their enablement is // mutually exclusive // removeActionActivationCode(ITextEditorActionConstants.SHIFT_RIGHT); setActionActivationCode("IndentOnTab", '\t', -1, SWT.NONE); //$NON-NLS-1$ } - fGenerateActionGroup = new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); - fActionGroups = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup }); - // We have to keep the context menu group separate to have better - // control - // over positioning - fContextMenuGroup = new CompositeActionGroup(new ActionGroup[] { fGenerateActionGroup }); - // rg, - // new LocalHistoryActionGroup(this, - // ITextEditorActionConstants.GROUP_EDIT)}); + fGenerateActionGroup= new GenerateActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); +// ActionGroup rg= new RefactorActionGroup(this, ITextEditorActionConstants.GROUP_EDIT); + +// fActionGroups.addGroup(rg); + fActionGroups.addGroup(fGenerateActionGroup); + + // We have to keep the context menu group separate to have better control over positioning + fContextMenuGroup= new CompositeActionGroup(new ActionGroup[] { + fGenerateActionGroup +// rg, +// new LocalHistoryActionGroup(this, ITextEditorActionConstants.GROUP_EDIT) + }); } @@ -1715,78 +1747,6 @@ public class PHPUnitEditor extends PHPEditor { //implements // return store.getBoolean(PRINT_MARGIN); // } - // private void startAnnotationIndication(AnnotationType annotationType) { - // if (fProblemPainter == null) { - // fProblemPainter = new ProblemPainter(this, getSourceViewer()); - //// fPaintManager.addPainter(fProblemPainter); - // } - // fProblemPainter.setColor(annotationType, getColor(annotationType)); - // fProblemPainter.paintAnnotations(annotationType, true); - // fProblemPainter.paint(IPainter.CONFIGURATION); - // } - // - // private void shutdownAnnotationIndication() { - // if (fProblemPainter != null) { - // - // if (!fProblemPainter.isPaintingAnnotations()) { - //// fPaintManager.removePainter(fProblemPainter); - // fProblemPainter.deactivate(true); - // fProblemPainter.dispose(); - // fProblemPainter = null; - // } else { - // fProblemPainter.paint(IPainter.CONFIGURATION); - // } - // } - // } - // - // private void stopAnnotationIndication(AnnotationType annotationType) { - // if (fProblemPainter != null) { - // fProblemPainter.paintAnnotations(annotationType, false); - // shutdownAnnotationIndication(); - // } - // } - // - // private boolean isAnnotationIndicationEnabled(AnnotationType - // annotationType) { - // IPreferenceStore store = getPreferenceStore(); - // AnnotationInfo info = (AnnotationInfo) - // ANNOTATION_MAP.get(annotationType); - // if (info != null) - // return store.getBoolean(info.fEditorPreference); - // return false; - // } - // - // private boolean - // isAnnotationIndicationInOverviewRulerEnabled(AnnotationType - // annotationType) { - // IPreferenceStore store = getPreferenceStore(); - // AnnotationInfo info = (AnnotationInfo) - // ANNOTATION_MAP.get(annotationType); - // if (info != null) - // return store.getBoolean(info.fOverviewRulerPreference); - // return false; - // } - // - // private void showAnnotationIndicationInOverviewRuler(AnnotationType - // annotationType, boolean show) { - // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); - // OverviewRuler ruler = asv.getOverviewRuler(); - // if (ruler != null) { - // ruler.setColor(annotationType, getColor(annotationType)); - // ruler.showAnnotation(annotationType, show); - // ruler.update(); - // } - // } - // - // private void setColorInOverviewRuler(AnnotationType annotationType, Color - // color) { - // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); - // OverviewRuler ruler = asv.getOverviewRuler(); - // if (ruler != null) { - // ruler.setColor(annotationType, color); - // ruler.update(); - // } - // } private int getTabSize() { Preferences preferences = PHPeclipsePlugin.getDefault().getPluginPreferences(); @@ -1798,30 +1758,6 @@ public class PHPUnitEditor extends PHPEditor { //implements return store.getBoolean(SPACES_FOR_TABS); } - // private void showOverviewRuler() { - // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); - // asv.showOverviewRuler(); - // - // OverviewRuler overviewRuler = asv.getOverviewRuler(); - // if (overviewRuler != null) { - // for (int i = 0; i < ANNOTATION_LAYERS.length; i++) { - // AnnotationType type = ANNOTATION_LAYERS[i]; - // overviewRuler.setLayer(type, i); - // if (isAnnotationIndicationInOverviewRulerEnabled(type)) - // showAnnotationIndicationInOverviewRuler(type, true); - // } - // } - // } - // - // private void hideOverviewRuler() { - // AdaptedSourceViewer asv = (AdaptedSourceViewer) getSourceViewer(); - // asv.hideOverviewRuler(); - // } - // - // private boolean isOverviewRulerVisible() { - // IPreferenceStore store = getPreferenceStore(); - // return store.getBoolean(OVERVIEW_RULER); - // } private Color getColor(String key) { RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), key); return getColor(rgb); -- 1.7.1