diff options
| author | nyamatongwe <unknown> | 2011-01-10 12:08:49 +1100 | 
|---|---|---|
| committer | nyamatongwe <unknown> | 2011-01-10 12:08:49 +1100 | 
| commit | 7a55b6d47b75b665100a04ca16e6a210d436d235 (patch) | |
| tree | 3501681428732495b06b4321cbb0c8d977e9e3ec /src | |
| parent | b5f28ae72e7d19b28bb190189ba78a54ad9976a0 (diff) | |
| download | scintilla-mirror-7a55b6d47b75b665100a04ca16e6a210d436d235.tar.gz | |
Fixing double-click inside word selecting non-word characters. Bug #3111174.
A double-click on a visible character always selects that character and the word it is in.
From Jordan Russell.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Document.h | 2 | ||||
| -rw-r--r-- | src/Editor.cxx | 70 | ||||
| -rw-r--r-- | src/Editor.h | 4 | 
3 files changed, 62 insertions, 14 deletions
| diff --git a/src/Document.h b/src/Document.h index 78f00a766..ecdf5ff65 100644 --- a/src/Document.h +++ b/src/Document.h @@ -357,6 +357,7 @@ public:  	const WatcherWithUserData *GetWatchers() const { return watchers; }  	int GetLenWatchers() const { return lenWatchers; } +	CharClassify::cc WordCharClass(unsigned char ch);  	bool IsWordPartSeparator(char ch);  	int WordPartLeft(int pos);  	int WordPartRight(int pos); @@ -368,7 +369,6 @@ public:  	int BraceMatch(int position, int maxReStyle);  private: -	CharClassify::cc WordCharClass(unsigned char ch);  	bool IsWordStartAt(int pos);  	bool IsWordEndAt(int pos);  	bool IsWordAt(int start, int end); diff --git a/src/Editor.cxx b/src/Editor.cxx index fb66c8a86..7f51ced64 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -133,6 +133,9 @@ Editor::Editor() {  	lastXChosen = 0;  	lineAnchor = 0;  	originalAnchorPos = 0; +	wordSelectAnchorStartPos = 0; +	wordSelectAnchorEndPos = 0; +	wordSelectInitialCaretPos = -1;  	primarySelection = true; @@ -5853,6 +5856,30 @@ void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {  	}  } +void Editor::WordSelection(int pos) { +	if (pos < wordSelectAnchorStartPos) { +		// Extend backward to the word containing pos. +		// Skip ExtendWordSelect if the line is empty or if pos is after the last character. +		// This ensures that a series of empty lines isn't counted as a single "word". +		if (!pdoc->IsLineEndPosition(pos)) +			pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1); +		SetSelection(pos, wordSelectAnchorEndPos); +	} else if (pos > wordSelectAnchorEndPos) { +		// Extend forward to the word containing the character to the left of pos. +		// Skip ExtendWordSelect if the line is empty or if pos is the first position on the line. +		// This ensures that a series of empty lines isn't counted as a single "word". +		if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos))) +			pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1); +		SetSelection(pos, wordSelectAnchorStartPos); +	} else { +		// Select only the anchored word +		if (pos >= originalAnchorPos) +			SetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos); +		else +			SetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos); +	} +} +  void Editor::DwellEnd(bool mouseMoved) {  	if (mouseMoved)  		ticksToDwell = dwellDelay; @@ -5914,13 +5941,33 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b  		}  		if (selectionType == selWord) { -			if (sel.MainCaret() >= originalAnchorPos) {	// Moved forward -				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1), -				        pdoc->ExtendWordSelect(originalAnchorPos, -1)); -			} else {	// Moved backward -				SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1), -				        pdoc->ExtendWordSelect(originalAnchorPos, 1)); +			int charPos = originalAnchorPos; +			if (sel.MainCaret() == originalAnchorPos) { +				charPos = PositionFromLocation(pt, false, true); +				charPos = MovePositionOutsideChar(charPos, -1); +			} + +			int startWord, endWord; +			if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) { +				startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1); +				endWord = pdoc->ExtendWordSelect(charPos, 1); +			} else { +				// Selecting backwards, or anchor beyond last character on line. In these cases, +				// we select the word containing the character to the *left* of the anchor. +				if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) { +					startWord = pdoc->ExtendWordSelect(charPos, -1); +					endWord = pdoc->ExtendWordSelect(startWord, 1); +				} else { +					// Anchor at start of line; select nothing to begin with. +					startWord = charPos; +					endWord = charPos; +				}  			} + +			wordSelectAnchorStartPos = startWord; +			wordSelectAnchorEndPos = endWord; +			wordSelectInitialCaretPos = sel.MainCaret(); +			WordSelection(wordSelectInitialCaretPos);  		} else if (selectionType == selLine) {  			lineAnchor = LineFromLocation(pt);  			SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor)); @@ -6103,7 +6150,7 @@ void Editor::ButtonMove(Point pt) {  				}  			} else if (selectionType == selWord) {  				// Continue selecting by word -				if (movePos.Position() == originalAnchorPos) {	// Didn't move +				if (movePos.Position() == wordSelectInitialCaretPos) {  // Didn't move  					// No need to do anything. Previously this case was lumped  					// in with "Moved forward", but that can be harmful in this  					// case: a handler for the NotifyDoubleClick re-adjusts @@ -6113,12 +6160,9 @@ void Editor::ButtonMove(Point pt) {  					// the ButtonMove() called via Tick() for auto-scrolling  					// could result in the fancier word selection adjustment  					// being unmade. -				} else if (movePos.Position() > originalAnchorPos) {	// Moved forward -					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1), -					        pdoc->ExtendWordSelect(originalAnchorPos, -1)); -				} else {	// Moved backward -					SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1), -					        pdoc->ExtendWordSelect(originalAnchorPos, 1)); +				} else { +					wordSelectInitialCaretPos = -1; +					WordSelection(movePos.Position());  				}  			} else {  				// Continue selecting by line diff --git a/src/Editor.h b/src/Editor.h index a618e1e40..97af7b089 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -201,6 +201,9 @@ protected:	// ScintillaBase subclass needs access to much of Editor  	int lastXChosen;  	int lineAnchor;  	int originalAnchorPos; +	int wordSelectAnchorStartPos; +	int wordSelectAnchorEndPos; +	int wordSelectInitialCaretPos;  	int targetStart;  	int targetEnd;  	int searchFlags; @@ -481,6 +484,7 @@ protected:	// ScintillaBase subclass needs access to much of Editor  	bool PointInSelection(Point pt);  	bool PointInSelMargin(Point pt);  	void LineSelection(int lineCurrent_, int lineAnchor_); +	void WordSelection(int pos);  	void DwellEnd(bool mouseMoved);  	void MouseLeave();  	virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); | 
