From 5d20ba21a8917adb501dc5088301665165714fb6 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Sat, 27 Jun 2009 00:34:11 +0000 Subject: [PATCH] [BUG_FIXED] Fix Incremental search bug. Signed-off-by: Don HO git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@502 f5eea248-9336-0410-98b8-ebc06183d4e3 --- PowerEditor/src/Notepad_plus.cpp | 3 +- .../src/ScitillaComponent/FindReplaceDlg.cpp | 93 +++++++++++++++---- .../src/ScitillaComponent/FindReplaceDlg.h | 19 +++- .../src/ScitillaComponent/FindReplaceDlg.rc | 7 +- .../src/ScitillaComponent/FindReplaceDlg_rc.h | 1 + 5 files changed, 98 insertions(+), 25 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index b64f47b35..9871203d7 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -3333,7 +3333,8 @@ void Notepad_plus::command(int id) const int strSize = FINDREPLACE_MAXLENGTH; TCHAR str[strSize]; - _pEditView->getGenericSelectedText(str, strSize); + _pEditView->getGenericSelectedText(str, strSize, false); + if (0!=str[0]) // the selected text is not empty, then use it _incrementFindDlg.setSearchText(str, _pEditView->getCurrentBuffer()->getUnicodeMode() != uni8Bit); _incrementFindDlg.display(); diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index d0bd6dce0..1eb72a0a8 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -675,7 +675,6 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP _isInSelection = true; } } - // Searching/replacing in column selection is not allowed if ((*_ppEditView)->execute(SCI_GETSELECTIONMODE) == SC_SEL_RECTANGLE) { @@ -1097,8 +1096,11 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP // return value : // true : the text2find is found // false : the text2find is not found -bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options) +bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options, FindStatus *oFindStatus) { + if (oFindStatus) + *oFindStatus = FSFound; + if (!txt2find || !txt2find[0]) return false; @@ -1126,10 +1128,23 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options) endPosition = 0; } - if (pOptions->_isIncremental) + if (FirstIncremental==pOptions->_incrementalType) { - startPosition = 0; + // the text to find is modified so use the current position + startPosition = cr.cpMin; + endPosition = docLength; + } + else if (NextIncremental==pOptions->_incrementalType) + { + // text to find is not modified, so use current position +1 + startPosition = cr.cpMin +1; endPosition = docLength; + if (pOptions->_whichDirection == DIR_UP) + { + //When searching upwards, start is the lower part, end the upper, for backwards search + startPosition = cr.cpMax - 1; + endPosition = 0; + } } bool isRegExp = pOptions->_searchType == FindRegex; @@ -1147,11 +1162,15 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options) { startPosition = 0; endPosition = docLength; + if (oFindStatus) + *oFindStatus = FSEndReached; } else { startPosition = docLength; endPosition = 0; + if (oFindStatus) + *oFindStatus = FSTopReached; } //new target, search again @@ -1159,8 +1178,10 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options) } if (posFind == -1) { + if (oFindStatus) + *oFindStatus = FSNotFound; //failed, or failed twice with wrap - if (!pOptions->_isIncremental) //incremental search doesnt trigger messages + if (NotIncremental==pOptions->_incrementalType) //incremental search doesnt trigger messages { generic_string msg = TEXT("Can't find the text:\r\n\""); msg += pText; @@ -1921,10 +1942,15 @@ void FindIncrementDlg::display(bool toShow) const return; } if (toShow) + { ::SetFocus(::GetDlgItem(_hSelf, IDC_INCFINDTEXT)); + // select the whole find editor text + ::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, EM_SETSEL, 0, -1); + } _pRebar->setIDVisible(_rbBand.wID, toShow); } +#define SHIFTED 0x8000 BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) @@ -1932,6 +1958,7 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM case WM_COMMAND : { bool isUnicode = (*(_pFRDlg->_ppEditView))->getCurrentBuffer()->getUnicodeMode() != uni8Bit; + FindStatus findStatus = FSFound; switch (LOWORD(wParam)) { case IDCANCEL : @@ -1943,46 +1970,80 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM case IDC_INCFINDPREVOK : case IDC_INCFINDNXTOK : + case IDOK : { FindOption fo; fo._isWholeWord = false; + fo._incrementalType = NextIncremental; fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); if (LOWORD(wParam) == IDC_INCFINDPREVOK) fo._whichDirection = DIR_UP; + else if (LOWORD(wParam) == IDOK) + { + SHORT nVirtKey = GetKeyState(VK_SHIFT); + if (nVirtKey & SHIFTED) + fo._whichDirection = DIR_UP; + } generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - _pFRDlg->processFindNext(str2Search.c_str(), &fo); + _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); + setFindStatus(findStatus); + } + return TRUE; + + case IDC_INCFINDTEXT : + { + switch(HIWORD(wParam)) + { + case EN_CHANGE : + { + FindOption fo; + fo._isWholeWord = false; + fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); + fo._incrementalType = FirstIncremental; + + generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); + _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); + setFindStatus(findStatus); + } + return TRUE; + case EN_KILLFOCUS : + case EN_SETFOCUS : + break; + } } return TRUE; case IDC_INCFINDMATCHCASE: - case IDC_INCFINDTEXT : - case IDC_INCFINDHILITEALL : - { - if (_doSearchFromBegin) { FindOption fo; fo._isWholeWord = false; - fo._isIncremental = true; + fo._incrementalType = FirstIncremental; fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); - bool isFound = _pFRDlg->processFindNext(str2Search.c_str(), &fo); + bool isFound = _pFRDlg->processFindNext(str2Search.c_str(), &fo, &findStatus); + setFindStatus(findStatus); if (!isFound) { CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); (*(_pFRDlg->_ppEditView))->execute(SCI_SETSEL, -1, range.cpMin); } + } + case IDC_INCFINDHILITEALL : + { + FindOption fo; + fo._isWholeWord = false; + fo._incrementalType = FirstIncremental; + fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); + + generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); bool isHiLieAll = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_GETCHECK, 0, 0)); if (str2Search == TEXT("")) isHiLieAll = false; - markSelectedTextInc(isHiLieAll, &fo); } - else - _doSearchFromBegin = true; - } return TRUE; } diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h index a9b2bed24..2f182b516 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h @@ -53,6 +53,7 @@ struct TargetRange { int targetEnd; }; +enum SearchIncrementalType { NotIncremental, FirstIncremental, NextIncremental }; enum SearchType { FindNormal, FindExtended, FindRegex }; enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt }; @@ -61,10 +62,10 @@ struct FindOption { bool _isMatchCase; bool _isWrapAround; bool _whichDirection; - bool _isIncremental; + SearchIncrementalType _incrementalType; SearchType _searchType; FindOption() :_isWholeWord(true), _isMatchCase(true), _searchType(FindNormal),\ - _isWrapAround(true), _whichDirection(DIR_DOWN), _isIncremental(false){}; + _isWrapAround(true), _whichDirection(DIR_DOWN), _incrementalType(NotIncremental){}; }; //This class contains generic search functions as static functions for easy access @@ -251,6 +252,7 @@ private: static SearchResultMarking EmptySearchResultMarking; }; +enum FindStatus { FSFound, FSNotFound, FSTopReached, FSEndReached}; //FindReplaceDialog: standard find/replace window class FindReplaceDlg : public StaticDialog { @@ -306,7 +308,7 @@ public : ::SetFocus(::GetDlgItem(_hSelf, IDFINDWHAT)); display(); }; - bool processFindNext(const TCHAR *txt2find, FindOption *options = NULL); + bool processFindNext(const TCHAR *txt2find, FindOption *options = NULL, FindStatus *oFindStatus = NULL); bool processReplace(const TCHAR *txt2find, const TCHAR *txt2replace, FindOption *options = NULL); int markAll(const TCHAR *txt2find, int styleID); @@ -551,7 +553,6 @@ public : virtual void display(bool toShow = true) const; void setSearchText(const TCHAR * txt2find, bool isUTF8 = false) { - _doSearchFromBegin = false; #ifdef UNICODE ::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, WM_SETTEXT, 0, (LPARAM)txt2find); #else @@ -574,6 +575,15 @@ public : } #endif } + void setFindStatus(FindStatus iStatus) { + static TCHAR *findStatus[] = { TEXT(""), // FSFound + TEXT("Phrase not found"), //FSNotFound + TEXT("Reached top of page, continued from bottom"), // FSTopReached + TEXT("Reached end of page, continued from top")}; // FSEndReached + if (iStatus<0 || iStatus >= sizeof(findStatus)/sizeof(findStatus[0])) + return; // out of range + ::SendDlgItemMessage(_hSelf, IDC_INCFINDSTATUS, WM_SETTEXT, 0, (LPARAM)findStatus[iStatus]); + } void addToRebar(ReBar * rebar); private : @@ -583,7 +593,6 @@ private : ReBar * _pRebar; REBARBANDINFO _rbBand; - bool _doSearchFromBegin; virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); void markSelectedTextInc(bool enable, FindOption *opt = NULL); }; diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc index 4372d463d..8efdcbc9a 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc @@ -83,11 +83,12 @@ FONT 8, TEXT("MS Shell Dlg") BEGIN PUSHBUTTON "X",IDCANCEL,2,3,16,14 RTEXT "Find :",IDC_INCSTATIC,20,6,25,12 - EDITTEXT IDC_INCFINDTEXT,45,4,175,12,ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER,WS_EX_STATICEDGE - PUSHBUTTON "<",IDC_INCFINDPREVOK,223,3,16,14 - DEFPUSHBUTTON ">",IDC_INCFINDNXTOK,243,3,16,14 + EDITTEXT IDC_INCFINDTEXT,45,4,175,12,ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | WS_TABSTOP ,WS_EX_STATICEDGE + PUSHBUTTON "<",IDC_INCFINDPREVOK | WS_TABSTOP,223,3,16,14 + DEFPUSHBUTTON ">",IDC_INCFINDNXTOK | WS_TABSTOP,243,3,16,14 CONTROL "Highlight all", IDC_INCFINDHILITEALL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,270,5,65,12 CONTROL "Match case", IDC_INCFINDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,5,60,12 + LTEXT "Find Status",IDC_INCFINDSTATUS,400,6,180,12 END IDD_FINDRESULT DIALOGEX 26, 41, 223, 67 diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h index 2a8fa27e5..30c7389aa 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h @@ -69,6 +69,7 @@ #define IDC_INCFINDNXTOK 1684 #define IDC_INCFINDMATCHCASE 1685 #define IDC_INCFINDHILITEALL 1686 +#define IDC_INCFINDSTATUS 1689 #define IDC_TRANSPARENT_CHECK 1686 #define IDC_TRANSPARENT_LOSSFOCUS_RADIO 1687