[BUG_FIXED] Fix Incremental search bug.

Signed-off-by: Don HO <don.h@free.fr>

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@502 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2009-06-27 00:34:11 +00:00
parent 736137918e
commit 5d20ba21a8
5 changed files with 98 additions and 25 deletions

View File

@ -3333,7 +3333,8 @@ void Notepad_plus::command(int id)
const int strSize = FINDREPLACE_MAXLENGTH; const int strSize = FINDREPLACE_MAXLENGTH;
TCHAR str[strSize]; 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.setSearchText(str, _pEditView->getCurrentBuffer()->getUnicodeMode() != uni8Bit);
_incrementFindDlg.display(); _incrementFindDlg.display();

View File

@ -675,7 +675,6 @@ BOOL CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
_isInSelection = true; _isInSelection = true;
} }
} }
// Searching/replacing in column selection is not allowed // Searching/replacing in column selection is not allowed
if ((*_ppEditView)->execute(SCI_GETSELECTIONMODE) == SC_SEL_RECTANGLE) 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 : // return value :
// true : the text2find is found // true : the text2find is found
// false : the text2find is not 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]) if (!txt2find || !txt2find[0])
return false; return false;
@ -1126,10 +1128,23 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options)
endPosition = 0; 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; 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; bool isRegExp = pOptions->_searchType == FindRegex;
@ -1147,11 +1162,15 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options)
{ {
startPosition = 0; startPosition = 0;
endPosition = docLength; endPosition = docLength;
if (oFindStatus)
*oFindStatus = FSEndReached;
} }
else else
{ {
startPosition = docLength; startPosition = docLength;
endPosition = 0; endPosition = 0;
if (oFindStatus)
*oFindStatus = FSTopReached;
} }
//new target, search again //new target, search again
@ -1159,8 +1178,10 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, FindOption *options)
} }
if (posFind == -1) if (posFind == -1)
{ {
if (oFindStatus)
*oFindStatus = FSNotFound;
//failed, or failed twice with wrap //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\""); generic_string msg = TEXT("Can't find the text:\r\n\"");
msg += pText; msg += pText;
@ -1921,10 +1942,15 @@ void FindIncrementDlg::display(bool toShow) const
return; return;
} }
if (toShow) if (toShow)
{
::SetFocus(::GetDlgItem(_hSelf, IDC_INCFINDTEXT)); ::SetFocus(::GetDlgItem(_hSelf, IDC_INCFINDTEXT));
// select the whole find editor text
::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, EM_SETSEL, 0, -1);
}
_pRebar->setIDVisible(_rbBand.wID, toShow); _pRebar->setIDVisible(_rbBand.wID, toShow);
} }
#define SHIFTED 0x8000
BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) switch (message)
@ -1932,6 +1958,7 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
case WM_COMMAND : case WM_COMMAND :
{ {
bool isUnicode = (*(_pFRDlg->_ppEditView))->getCurrentBuffer()->getUnicodeMode() != uni8Bit; bool isUnicode = (*(_pFRDlg->_ppEditView))->getCurrentBuffer()->getUnicodeMode() != uni8Bit;
FindStatus findStatus = FSFound;
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDCANCEL : case IDCANCEL :
@ -1943,46 +1970,80 @@ BOOL CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
case IDC_INCFINDPREVOK : case IDC_INCFINDPREVOK :
case IDC_INCFINDNXTOK : case IDC_INCFINDNXTOK :
case IDOK :
{ {
FindOption fo; FindOption fo;
fo._isWholeWord = false; fo._isWholeWord = false;
fo._incrementalType = NextIncremental;
fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0));
if (LOWORD(wParam) == IDC_INCFINDPREVOK) if (LOWORD(wParam) == IDC_INCFINDPREVOK)
fo._whichDirection = DIR_UP; 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); 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; return TRUE;
case IDC_INCFINDMATCHCASE: case IDC_INCFINDMATCHCASE:
case IDC_INCFINDTEXT :
case IDC_INCFINDHILITEALL :
{
if (_doSearchFromBegin)
{ {
FindOption fo; FindOption fo;
fo._isWholeWord = false; fo._isWholeWord = false;
fo._isIncremental = true; fo._incrementalType = FirstIncremental;
fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0)); fo._isMatchCase = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDMATCHCASE, BM_GETCHECK, 0, 0));
generic_string str2Search = _pFRDlg->getTextFromCombo(::GetDlgItem(_hSelf, IDC_INCFINDTEXT), isUnicode); 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) if (!isFound)
{ {
CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection(); CharacterRange range = (*(_pFRDlg->_ppEditView))->getSelection();
(*(_pFRDlg->_ppEditView))->execute(SCI_SETSEL, -1, range.cpMin); (*(_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)); bool isHiLieAll = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_INCFINDHILITEALL, BM_GETCHECK, 0, 0));
if (str2Search == TEXT("")) if (str2Search == TEXT(""))
isHiLieAll = false; isHiLieAll = false;
markSelectedTextInc(isHiLieAll, &fo); markSelectedTextInc(isHiLieAll, &fo);
} }
else
_doSearchFromBegin = true;
}
return TRUE; return TRUE;
} }

View File

@ -53,6 +53,7 @@ struct TargetRange {
int targetEnd; int targetEnd;
}; };
enum SearchIncrementalType { NotIncremental, FirstIncremental, NextIncremental };
enum SearchType { FindNormal, FindExtended, FindRegex }; enum SearchType { FindNormal, FindExtended, FindRegex };
enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt }; enum ProcessOperation { ProcessFindAll, ProcessReplaceAll, ProcessCountAll, ProcessMarkAll, ProcessMarkAll_2, ProcessMarkAll_IncSearch, ProcessMarkAllExt };
@ -61,10 +62,10 @@ struct FindOption {
bool _isMatchCase; bool _isMatchCase;
bool _isWrapAround; bool _isWrapAround;
bool _whichDirection; bool _whichDirection;
bool _isIncremental; SearchIncrementalType _incrementalType;
SearchType _searchType; SearchType _searchType;
FindOption() :_isWholeWord(true), _isMatchCase(true), _searchType(FindNormal),\ 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 //This class contains generic search functions as static functions for easy access
@ -251,6 +252,7 @@ private:
static SearchResultMarking EmptySearchResultMarking; static SearchResultMarking EmptySearchResultMarking;
}; };
enum FindStatus { FSFound, FSNotFound, FSTopReached, FSEndReached};
//FindReplaceDialog: standard find/replace window //FindReplaceDialog: standard find/replace window
class FindReplaceDlg : public StaticDialog class FindReplaceDlg : public StaticDialog
{ {
@ -306,7 +308,7 @@ public :
::SetFocus(::GetDlgItem(_hSelf, IDFINDWHAT)); ::SetFocus(::GetDlgItem(_hSelf, IDFINDWHAT));
display(); 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); bool processReplace(const TCHAR *txt2find, const TCHAR *txt2replace, FindOption *options = NULL);
int markAll(const TCHAR *txt2find, int styleID); int markAll(const TCHAR *txt2find, int styleID);
@ -551,7 +553,6 @@ public :
virtual void display(bool toShow = true) const; virtual void display(bool toShow = true) const;
void setSearchText(const TCHAR * txt2find, bool isUTF8 = false) { void setSearchText(const TCHAR * txt2find, bool isUTF8 = false) {
_doSearchFromBegin = false;
#ifdef UNICODE #ifdef UNICODE
::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, WM_SETTEXT, 0, (LPARAM)txt2find); ::SendDlgItemMessage(_hSelf, IDC_INCFINDTEXT, WM_SETTEXT, 0, (LPARAM)txt2find);
#else #else
@ -574,6 +575,15 @@ public :
} }
#endif #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); void addToRebar(ReBar * rebar);
private : private :
@ -583,7 +593,6 @@ private :
ReBar * _pRebar; ReBar * _pRebar;
REBARBANDINFO _rbBand; REBARBANDINFO _rbBand;
bool _doSearchFromBegin;
virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
void markSelectedTextInc(bool enable, FindOption *opt = NULL); void markSelectedTextInc(bool enable, FindOption *opt = NULL);
}; };

View File

@ -83,11 +83,12 @@ FONT 8, TEXT("MS Shell Dlg")
BEGIN BEGIN
PUSHBUTTON "X",IDCANCEL,2,3,16,14 PUSHBUTTON "X",IDCANCEL,2,3,16,14
RTEXT "Find :",IDC_INCSTATIC,20,6,25,12 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 EDITTEXT IDC_INCFINDTEXT,45,4,175,12,ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | WS_TABSTOP ,WS_EX_STATICEDGE
PUSHBUTTON "<",IDC_INCFINDPREVOK,223,3,16,14 PUSHBUTTON "<",IDC_INCFINDPREVOK | WS_TABSTOP,223,3,16,14
DEFPUSHBUTTON ">",IDC_INCFINDNXTOK,243,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 "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 CONTROL "Match case", IDC_INCFINDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,335,5,60,12
LTEXT "Find Status",IDC_INCFINDSTATUS,400,6,180,12
END END
IDD_FINDRESULT DIALOGEX 26, 41, 223, 67 IDD_FINDRESULT DIALOGEX 26, 41, 223, 67

View File

@ -69,6 +69,7 @@
#define IDC_INCFINDNXTOK 1684 #define IDC_INCFINDNXTOK 1684
#define IDC_INCFINDMATCHCASE 1685 #define IDC_INCFINDMATCHCASE 1685
#define IDC_INCFINDHILITEALL 1686 #define IDC_INCFINDHILITEALL 1686
#define IDC_INCFINDSTATUS 1689
#define IDC_TRANSPARENT_CHECK 1686 #define IDC_TRANSPARENT_CHECK 1686
#define IDC_TRANSPARENT_LOSSFOCUS_RADIO 1687 #define IDC_TRANSPARENT_LOSSFOCUS_RADIO 1687