Commit 72f735b2 authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

wordpad: Fix behaviour of find/replace dialog.

Pressing replace should only replace a selected match, and afterwards it should find the next match. Searches should always start from the start of the selection, even if the selection is moved in between searches. Searches wrap at the end of text, and should keep track of whether it has wrapped from previous searches to determine if it reached the end position.
parent 117a436b
...@@ -89,6 +89,12 @@ typedef enum ...@@ -89,6 +89,12 @@ typedef enum
UNIT_PT UNIT_PT
} UNIT; } UNIT;
typedef struct
{
int endPos;
BOOL wrapped;
} FINDREPLACE_custom;
/* Load string resources */ /* Load string resources */
static void DoLoadStrings(void) static void DoLoadStrings(void)
{ {
...@@ -1215,13 +1221,11 @@ static LRESULT handle_findmsg(LPFINDREPLACEW pFr) ...@@ -1215,13 +1221,11 @@ static LRESULT handle_findmsg(LPFINDREPLACEW pFr)
if(pFr->Flags & FR_FINDNEXT || pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL) if(pFr->Flags & FR_FINDNEXT || pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL)
{ {
DWORD flags = FR_DOWN; FINDREPLACE_custom *custom_data = (FINDREPLACE_custom*)pFr->lCustData;
FINDTEXTW ft; DWORD flags;
static CHARRANGE cr; FINDTEXTEXW ft;
LRESULT end, ret; CHARRANGE sel;
GETTEXTLENGTHEX gt; LRESULT ret = -1;
LRESULT length;
int startPos;
HMENU hMenu = GetMenu(hMainWnd); HMENU hMenu = GetMenu(hMainWnd);
MENUITEMINFOW mi; MENUITEMINFOW mi;
...@@ -1230,69 +1234,59 @@ static LRESULT handle_findmsg(LPFINDREPLACEW pFr) ...@@ -1230,69 +1234,59 @@ static LRESULT handle_findmsg(LPFINDREPLACEW pFr)
mi.dwItemData = 1; mi.dwItemData = 1;
SetMenuItemInfoW(hMenu, ID_FIND_NEXT, FALSE, &mi); SetMenuItemInfoW(hMenu, ID_FIND_NEXT, FALSE, &mi);
gt.flags = GTL_NUMCHARS; SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&sel.cpMin, (LPARAM)&sel.cpMax);
gt.codepage = 1200; if(custom_data->endPos == -1) {
custom_data->endPos = sel.cpMin;
custom_data->wrapped = FALSE;
}
length = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0); flags = FR_DOWN | (pFr->Flags & (FR_MATCHCASE | FR_WHOLEWORD));
ft.lpstrText = pFr->lpstrFindWhat;
if(pFr->lCustData == -1) /* Only replace existing selectino if it is an exact match. */
if (sel.cpMin != sel.cpMax &&
(pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL))
{ {
SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&startPos, (LPARAM)&end); ft.chrg = sel;
cr.cpMin = startPos; SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
pFr->lCustData = startPos; if (ft.chrgText.cpMin == sel.cpMin && ft.chrgText.cpMax == sel.cpMax) {
cr.cpMax = length; SendMessageW(hEditorWnd, EM_REPLACESEL, TRUE, (LPARAM)pFr->lpstrReplaceWith);
if(cr.cpMin == length) SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&sel.cpMin, (LPARAM)&sel.cpMax);
cr.cpMin = 0;
} else
{
startPos = pFr->lCustData;
} }
if(cr.cpMax > length)
{
startPos = 0;
cr.cpMin = 0;
cr.cpMax = length;
} }
ft.chrg = cr; /* Search from the start of the selection, but exclude the first character
ft.lpstrText = pFr->lpstrFindWhat; * from search if there is a selection. */
ft.chrg.cpMin = sel.cpMin;
if(pFr->Flags & FR_MATCHCASE) if (sel.cpMin != sel.cpMax)
flags |= FR_MATCHCASE; ft.chrg.cpMin++;
if(pFr->Flags & FR_WHOLEWORD)
flags |= FR_WHOLEWORD;
ret = SendMessageW(hEditorWnd, EM_FINDTEXTW, flags, (LPARAM)&ft); /* Search to the end, then wrap around and search from the start. */
if (!custom_data->wrapped) {
if(ret == -1) ft.chrg.cpMax = -1;
{ ret = SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
if(cr.cpMax == length && cr.cpMax != startPos) if (ret == -1) {
{ custom_data->wrapped = TRUE;
ft.chrg.cpMin = cr.cpMin = 0; ft.chrg.cpMin = 0;
ft.chrg.cpMax = cr.cpMax = startPos;
ret = SendMessageW(hEditorWnd, EM_FINDTEXTW, flags, (LPARAM)&ft);
} }
} }
if(ret == -1) if (ret == -1) {
{ ft.chrg.cpMax = custom_data->endPos + lstrlenW(pFr->lpstrFindWhat) - 1;
pFr->lCustData = -1; if (ft.chrg.cpMax > ft.chrg.cpMin)
MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED), wszAppTitle, ret = SendMessageW(hEditorWnd, EM_FINDTEXTEXW, flags, (LPARAM)&ft);
MB_OK | MB_ICONASTERISK); }
} else
{
end = ret + lstrlenW(pFr->lpstrFindWhat);
cr.cpMin = end;
SendMessageW(hEditorWnd, EM_SETSEL, ret, end);
SendMessageW(hEditorWnd, EM_SCROLLCARET, 0, 0);
if(pFr->Flags & FR_REPLACE || pFr->Flags & FR_REPLACEALL) if (ret == -1) {
SendMessageW(hEditorWnd, EM_REPLACESEL, TRUE, (LPARAM)pFr->lpstrReplaceWith); custom_data->endPos = -1;
MessageBoxWithResStringW(hMainWnd, MAKEINTRESOURCEW(STRING_SEARCH_FINISHED),
wszAppTitle, MB_OK | MB_ICONASTERISK);
} else {
SendMessageW(hEditorWnd, EM_SETSEL, ft.chrgText.cpMin, ft.chrgText.cpMax);
SendMessageW(hEditorWnd, EM_SCROLLCARET, 0, 0);
if(pFr->Flags & FR_REPLACEALL) if (pFr->Flags & FR_REPLACEALL)
handle_findmsg(pFr); return handle_findmsg(pFr);
} }
} }
...@@ -1303,6 +1297,7 @@ static void dialog_find(LPFINDREPLACEW fr, BOOL replace) ...@@ -1303,6 +1297,7 @@ static void dialog_find(LPFINDREPLACEW fr, BOOL replace)
{ {
static WCHAR findBuffer[MAX_STRING_LEN]; static WCHAR findBuffer[MAX_STRING_LEN];
static WCHAR replaceBuffer[MAX_STRING_LEN]; static WCHAR replaceBuffer[MAX_STRING_LEN];
static FINDREPLACE_custom custom_data;
/* Allow only one search/replace dialog to open */ /* Allow only one search/replace dialog to open */
if(hFindWnd != NULL) if(hFindWnd != NULL)
...@@ -1317,7 +1312,9 @@ static void dialog_find(LPFINDREPLACEW fr, BOOL replace) ...@@ -1317,7 +1312,9 @@ static void dialog_find(LPFINDREPLACEW fr, BOOL replace)
fr->Flags = FR_HIDEUPDOWN; fr->Flags = FR_HIDEUPDOWN;
fr->lpstrFindWhat = findBuffer; fr->lpstrFindWhat = findBuffer;
fr->lpstrReplaceWith = replaceBuffer; fr->lpstrReplaceWith = replaceBuffer;
fr->lCustData = -1; custom_data.endPos = -1;
custom_data.wrapped = FALSE;
fr->lCustData = (LPARAM)&custom_data;
fr->wFindWhatLen = sizeof(findBuffer); fr->wFindWhatLen = sizeof(findBuffer);
fr->wReplaceWithLen = sizeof(replaceBuffer); fr->wReplaceWithLen = sizeof(replaceBuffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment