1) Moved net.sourceforge.phpeclipse.ui\src\net\sourceforge\phpdt back to net.sourcefo...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / php / PHPDoubleClickSelector.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDoubleClickSelector.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPDoubleClickSelector.java
new file mode 100644 (file)
index 0000000..9a38d3b
--- /dev/null
@@ -0,0 +1,261 @@
+/**********************************************************************
+ Copyright (c) 2000, 2002 IBM Corp. and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Common Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/cpl-v10.html
+
+ Contributors:
+ IBM Corporation - Initial implementation
+ www.phpeclipse.de
+ **********************************************************************/
+package net.sourceforge.phpeclipse.phpeditor.php;
+
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.ITextViewer;
+
+/**
+ * Double click strategy aware of PHP identifier syntax rules.
+ */
+public class PHPDoubleClickSelector implements ITextDoubleClickStrategy {
+
+       protected ITextViewer fText;
+
+       protected int fPos;
+
+       protected int fStartPos;
+
+       protected int fEndPos;
+
+       protected static char[] fgBrackets = { '{', '}', '(', ')', '[', ']', '"',
+                       '"' };
+
+       /*
+        * Create a PHPDoubleClickSelector.
+        */
+       public PHPDoubleClickSelector() {
+               super();
+       }
+
+       /*
+        * (non-Javadoc) Method declared on ITextDoubleClickStrategy
+        */
+       public void doubleClicked(ITextViewer text) {
+
+               fPos = text.getSelectedRange().x;
+
+               if (fPos < 0)
+                       return;
+
+               fText = text;
+
+               if (!selectBracketBlock())
+                       selectWord();
+       }
+
+       /**
+        * Match the brackets at the current selection. Return true if successful,
+        * false otherwise.
+        */
+       protected boolean matchBracketsAt() {
+
+               char prevChar, nextChar;
+
+               int i;
+               int bracketIndex1 = fgBrackets.length;
+               int bracketIndex2 = fgBrackets.length;
+
+               fStartPos = -1;
+               fEndPos = -1;
+
+               // get the chars preceding and following the start position
+               try {
+
+                       IDocument doc = fText.getDocument();
+
+                       prevChar = doc.getChar(fPos - 1);
+                       nextChar = doc.getChar(fPos);
+
+                       // is the char either an open or close bracket?
+                       for (i = 0; i < fgBrackets.length; i = i + 2) {
+                               if (prevChar == fgBrackets[i]) {
+                                       fStartPos = fPos - 1;
+                                       bracketIndex1 = i;
+                               }
+                       }
+                       for (i = 1; i < fgBrackets.length; i = i + 2) {
+                               if (nextChar == fgBrackets[i]) {
+                                       fEndPos = fPos;
+                                       bracketIndex2 = i;
+                               }
+                       }
+
+                       if (fStartPos > -1 && bracketIndex1 < bracketIndex2) {
+                               fEndPos = searchForClosingBracket(fStartPos, prevChar,
+                                               fgBrackets[bracketIndex1 + 1], doc);
+                               if (fEndPos > -1)
+                                       return true;
+                               else
+                                       fStartPos = -1;
+                       } else if (fEndPos > -1) {
+                               fStartPos = searchForOpenBracket(fEndPos,
+                                               fgBrackets[bracketIndex2 - 1], nextChar, doc);
+                               if (fStartPos > -1)
+                                       return true;
+                               else
+                                       fEndPos = -1;
+                       }
+
+               } catch (BadLocationException x) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Select the word at the current selection. Return true if successful,
+        * false otherwise.
+        */
+       protected boolean matchWord() {
+
+               IDocument doc = fText.getDocument();
+
+               try {
+
+                       int pos = fPos;
+                       char c;
+
+                       while (pos >= 0) {
+                               c = doc.getChar(pos);
+                               if (!Scanner.isPHPIdentifierPart(c) && (c != '$')) {
+                                       break;
+                               }
+                               --pos;
+                       }
+
+                       fStartPos = pos;
+
+                       pos = fPos;
+                       int length = doc.getLength();
+
+                       while (pos < length) {
+                               c = doc.getChar(pos);
+                               if (!Scanner.isPHPIdentifierPart(c) && (c != '$'))
+                                       break;
+                               ++pos;
+                       }
+
+                       fEndPos = pos;
+
+                       return true;
+
+               } catch (BadLocationException x) {
+               }
+
+               return false;
+       }
+
+       /**
+        * Returns the position of the closing bracket after startPosition.
+        * 
+        * @returns the location of the closing bracket.
+        * @param startPosition -
+        *            the beginning position
+        * @param openBracket -
+        *            the character that represents the open bracket
+        * @param closeBracket -
+        *            the character that represents the close bracket
+        * @param document -
+        *            the document being searched
+        */
+       protected int searchForClosingBracket(int startPosition, char openBracket,
+                       char closeBracket, IDocument document) throws BadLocationException {
+               int stack = 1;
+               int closePosition = startPosition + 1;
+               int length = document.getLength();
+               char nextChar;
+
+               while (closePosition < length && stack > 0) {
+                       nextChar = document.getChar(closePosition);
+                       if (nextChar == openBracket && nextChar != closeBracket)
+                               stack++;
+                       else if (nextChar == closeBracket)
+                               stack--;
+                       closePosition++;
+               }
+
+               if (stack == 0)
+                       return closePosition - 1;
+               else
+                       return -1;
+
+       }
+
+       /**
+        * Returns the position of the open bracket before startPosition.
+        * 
+        * @returns the location of the starting bracket.
+        * @param startPosition -
+        *            the beginning position
+        * @param openBracket -
+        *            the character that represents the open bracket
+        * @param closeBracket -
+        *            the character that represents the close bracket
+        * @param document -
+        *            the document being searched
+        */
+       protected int searchForOpenBracket(int startPosition, char openBracket,
+                       char closeBracket, IDocument document) throws BadLocationException {
+               int stack = 1;
+               int openPos = startPosition - 1;
+               char nextChar;
+
+               while (openPos >= 0 && stack > 0) {
+                       nextChar = document.getChar(openPos);
+                       if (nextChar == closeBracket && nextChar != openBracket)
+                               stack++;
+                       else if (nextChar == openBracket)
+                               stack--;
+                       openPos--;
+               }
+
+               if (stack == 0)
+                       return openPos + 1;
+               else
+                       return -1;
+       }
+
+       /**
+        * Select the area between the selected bracket and the closing bracket.
+        * Return true if successful.
+        */
+       protected boolean selectBracketBlock() {
+               if (matchBracketsAt()) {
+
+                       if (fStartPos == fEndPos)
+                               fText.setSelectedRange(fStartPos, 0);
+                       else
+                               fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Select the word at the current selection.
+        */
+       protected void selectWord() {
+               if (matchWord()) {
+
+                       if (fStartPos == fEndPos)
+                               fText.setSelectedRange(fStartPos, 0);
+                       else
+                               fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
+               }
+       }
+}