diff --git a/Build/Notepad3.ini b/Build/Notepad3.ini index 51d5ac21f..ec1e76f8a 100644 Binary files a/Build/Notepad3.ini and b/Build/Notepad3.ini differ diff --git a/scintilla/lexers/LexRegistry.cxx b/scintilla/lexers/LexRegistry.cxx index d2a37740a..55578be20 100644 --- a/scintilla/lexers/LexRegistry.cxx +++ b/scintilla/lexers/LexRegistry.cxx @@ -88,11 +88,16 @@ class LexerRegistry : public DefaultLexer { return (!curr || (curr == '\n') || (curr == '\r' && next != '\n')); } + static bool AtBeginOfLine(LexAccessor& styler, Sci_Position pos) { + const char prev = styler.SafeGetCharAt(pos-1, '\0'); + const char curr = styler.SafeGetCharAt(pos, '\0'); + return (!curr || (prev == '\n') || (prev == '\r' && curr != '\n')); + } + static bool IsNextNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) { while (!AtEndOfLine(styler, start + 1)) { ++start; char curr = styler.SafeGetCharAt(start, '\0'); - char next = styler.SafeGetCharAt(start+1, '\0'); if (curr == ch) { return true; } else if (!isspacechar(curr)) { @@ -102,6 +107,20 @@ class LexerRegistry : public DefaultLexer { return false; } + static bool IsPrevNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) { + while (!AtBeginOfLine(styler, start - 1)) { + --start; + char curr = styler.SafeGetCharAt(start, '\0'); + if (curr == ch) { + return true; + } + else if (!isspacechar(curr)) { + return false; + } + } + return false; + } + // Looks for the equal sign at the end of the string static bool AtValueName(LexAccessor &styler, Sci_Position start) { bool escaped = false; @@ -160,6 +179,17 @@ class LexerRegistry : public DefaultLexer { } } + static void ContextForwardSetState(StyleContext& context, const int newState, int& lastNonDefaultState) + { + if (context.state != SCE_REG_DEFAULT) { + lastNonDefaultState = context.state; + } + if (newState >= SCE_REG_DEFAULT) + context.ForwardSetState(newState); + else + context.Forward(); + } + public: LexerRegistry() {} virtual ~LexerRegistry() {} @@ -218,15 +248,17 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, StyleContext context(startPos, length, initStyle, styler); bool highlight = true; bool afterEqualSign = false; - int stateBefore = SCE_REG_DEFAULT; + //int statePrevious = SCE_REG_DEFAULT; + int stateLastNonDefault = SCE_REG_DEFAULT; while (context.More() && context.ch) { if (context.atLineStart) { Sci_Position currPos = static_cast(context.currentPos); - bool continued = styler[currPos-3] == '\\'; + bool continued = IsPrevNonWhitespace(styler, currPos, '\\'); //styler[currPos - 3] == '\\'; highlight = continued ? true : false; - if (IsKeyPathState(context.state) && !highlight) { + if (!continued) { context.SetState(SCE_REG_DEFAULT); + stateLastNonDefault = SCE_REG_DEFAULT; } } switch (context.state) { @@ -239,7 +271,7 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, case SCE_REG_STRING: { Sci_Position currPos = static_cast(context.currentPos); if (context.ch == '"') { - context.ForwardSetState(SCE_REG_DEFAULT); + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); } else if (context.ch == '\\') { beforeEscape = context.state; context.SetState(SCE_REG_ESCAPED); @@ -258,9 +290,9 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, } break; case SCE_REG_PARAMETER: - context.ForwardSetState(SCE_REG_STRING); + ContextForwardSetState(context, SCE_REG_STRING, stateLastNonDefault); if (context.ch == '"') { - context.ForwardSetState(SCE_REG_DEFAULT); + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); } break; case SCE_REG_VALUETYPE: @@ -277,7 +309,7 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, case SCE_REG_ADDEDKEY: { Sci_Position currPos = static_cast(context.currentPos); if (context.ch == ']' && AtKeyPathEnd(styler, currPos)) { - context.ForwardSetState(SCE_REG_DEFAULT); + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); } else if (context.ch == '{') { if (AtGUID(styler, currPos)) { beforeGUID = context.state; @@ -289,7 +321,7 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, case SCE_REG_ESCAPED: if (context.ch == '"') { context.SetState(beforeEscape); - context.ForwardSetState(SCE_REG_DEFAULT); + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); } else if (context.ch == '\\') { context.Forward(); } else { @@ -300,14 +332,19 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, case SCE_REG_STRING_GUID: case SCE_REG_KEYPATH_GUID: { if (context.ch == '}') { - context.ForwardSetState(beforeGUID); + ContextForwardSetState(context, beforeGUID, stateLastNonDefault); beforeGUID = SCE_REG_DEFAULT; } Sci_Position currPos = static_cast(context.currentPos); if (context.ch == '"' && IsStringState(context.state)) { - context.ForwardSetState(SCE_REG_DEFAULT); - } else if (context.ch == ']' && AtKeyPathEnd(styler, currPos) && IsKeyPathState(context.state)) { - context.ForwardSetState(SCE_REG_DEFAULT); + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); + } else if (context.ch == ']' && IsKeyPathState(context.state)) { + if (AtKeyPathEnd(styler, currPos)) { + ContextForwardSetState(context, SCE_REG_DEFAULT, stateLastNonDefault); + } + else { + ContextForwardSetState(context, beforeGUID, stateLastNonDefault); + } } else if (context.ch == '\\' && IsStringState(context.state)) { beforeEscape = context.state; context.SetState(SCE_REG_ESCAPED); @@ -348,12 +385,13 @@ void SCI_METHOD LexerRegistry::Lex(Sci_PositionU startPos, if (setOperators.Contains(context.ch) && highlight) { context.SetState(SCE_REG_OPERATOR); } - if (context.chPrev == ']' && !IsNextNonWhitespace(styler, currPos - 1, ';')) { - context.SetState(stateBefore); // continue Reg-Key style for eolfilled + // continue style for eolfilled + if (context.ch == '\r' || context.ch == '\n') { + context.SetState(stateLastNonDefault); } } - stateBefore = context.state; - context.Forward(); + //statePrevious = context.state; + ContextForwardSetState(context, -1, stateLastNonDefault); } context.Complete(); } diff --git a/src/Edit.c b/src/Edit.c index e27bf1feb..3ccd30c17 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -86,6 +86,7 @@ extern BOOL bLoadNFOasOEM; extern BOOL bAccelWordNavigation; +extern int iReplacedOccurrences; extern int iMarkOccurrences; extern int iMarkOccurrencesCount; extern int iMarkOccurrencesMaxCount; @@ -634,6 +635,62 @@ char* EditGetClipboardText(HWND hwnd,BOOL bCheckEncoding,int* pLineCount,int* pL } +//============================================================================= +// +// EditSetClipboardText() +// +BOOL EditSetClipboardText(HWND hwnd, const char* pszText) +{ + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) { + SciCall_CopyText((DocPos)strlen(pszText), pszText); + return TRUE; + } + + WCHAR* pszTextW = L""; + UINT uCodePage = Encoding_SciGetCodePage(hwnd); + int cchTextW = MultiByteToWideChar(uCodePage, 0, pszText, -1, NULL, 0) + 1; + if (cchTextW > 1) { + pszTextW = LocalAlloc(LPTR, sizeof(WCHAR)*cchTextW); + MultiByteToWideChar(uCodePage, 0, pszText, -1, pszTextW, cchTextW); + } + + if (!OpenClipboard(GetParent(hwnd))) { + LocalFree(pszTextW); + return FALSE; + } + + HANDLE hNew = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(WCHAR) * cchTextW); + WCHAR* pszNew = GlobalLock(hNew); + + StringCchCopy(pszNew, cchTextW, pszTextW); + GlobalUnlock(hNew); + + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, hNew); + CloseClipboard(); + return TRUE; +} + + +//============================================================================= +// +// EditClearClipboard() +// +BOOL EditClearClipboard(HWND hwnd) +{ + if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) { + SciCall_CopyText(0, ""); + return TRUE; + } + if (!OpenClipboard(GetParent(hwnd))) { + return FALSE; + } + EmptyClipboard(); + CloseClipboard(); + return TRUE; +} + + //============================================================================= // // EditPaste2RectSel() @@ -742,34 +799,63 @@ BOOL EditPasteClipboard(HWND hwnd, BOOL bSwapClipBoard) } const DocPos clipLen = lstrlenA(pClip); - if (bSwapClipBoard) { SciCall_Copy(); } + const DocPos iCurPos = SciCall_GetCurrentPos(); + const DocPos iAnchorPos = SciCall_GetAnchor(); - if ((lineCount <= 1) || SciCall_IsSelectionEmpty()) + if (SciCall_IsSelectionEmpty() || (lineCount <= 1)) { SciCall_SetMultiPaste(SC_MULTIPASTE_EACH); - SciCall_Paste(); + + if (SciCall_IsSelectionEmpty()) + { + SciCall_Paste(); + if (bSwapClipBoard) { + EditClearClipboard(hwnd); + EditSelectEx(hwnd, iAnchorPos, SciCall_GetCurrentPos()); + } + } + else { + int iSelLength = SciCall_GetSelText(NULL); + char* pszText = LocalAlloc(LPTR, iSelLength); + SciCall_GetSelText(pszText); + if (clipLen == 0) { SciCall_Clear(); } else { SciCall_Paste(); } + EditSetClipboardText(hwnd, pszText); + LocalFree(pszText); + if (bSwapClipBoard) { + if (iCurPos < iAnchorPos) + EditSelectEx(hwnd, SciCall_GetCurrentPos(), iCurPos); + else + EditSelectEx(hwnd, iAnchorPos, SciCall_GetCurrentPos()); + } + else { + if (iCurPos < iAnchorPos) + EditSelectEx(hwnd, iCurPos, iCurPos); + } + } + SciCall_SetMultiPaste(SC_MULTIPASTE_ONCE); } else { if (SciCall_IsSelectionRectangle()) { + if (bSwapClipBoard) { SciCall_Copy(); } EditPaste2RectSel(hwnd, pClip); + // TODO: restore selection } else // Selection: SC_SEL_STREAM, SC_SEL_LINES, SC_SEL_THIN { - const DocPos iCurPos = SciCall_GetCurrentPos(); - const DocPos iAnchorPos = SciCall_GetAnchor(); - - SciCall_ReplaceSel(pClip); - if (bSwapClipBoard) { + SciCall_Copy(); + SciCall_ReplaceSel(pClip); if (iCurPos < iAnchorPos) EditSelectEx(hwnd, iCurPos + clipLen, iCurPos); else EditSelectEx(hwnd, iAnchorPos, iAnchorPos + clipLen); } - else if (iCurPos < iAnchorPos) { - EditSelectEx(hwnd, iCurPos, iCurPos); + else { + SciCall_ReplaceSel(pClip); + if (iCurPos < iAnchorPos) + EditSelectEx(hwnd, iCurPos, iCurPos); } } } @@ -782,15 +868,15 @@ BOOL EditPasteClipboard(HWND hwnd, BOOL bSwapClipBoard) // // EditCopyAppend() // -BOOL EditCopyAppend(HWND hwnd) +BOOL EditCopyAppend(HWND hwnd, BOOL bAppend) { if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) { - SendMessage(hwnd,SCI_COPY,0,0); + SciCall_Copy(); return TRUE; } - int iCurPos = (int)SendMessage(hwnd,SCI_GETCURRENTPOS,0,0); - int iAnchorPos = (int)SendMessage(hwnd,SCI_GETANCHOR,0,0); + int iCurPos = SciCall_GetCurrentPos(); + int iAnchorPos = SciCall_GetAnchor(); char* pszText = NULL; if (iCurPos != iAnchorPos) { @@ -799,28 +885,23 @@ BOOL EditCopyAppend(HWND hwnd) return FALSE; } else { - int iSelLength = (int)SendMessage(hwnd, SCI_GETSELTEXT, 0, 0); + int iSelLength = SciCall_GetSelText(NULL); pszText = LocalAlloc(LPTR, iSelLength); - (int)SendMessage(hwnd, SCI_GETSELTEXT, 0, (LPARAM)pszText); + SciCall_GetSelText(pszText); } } else { - int cchText = (int)SendMessage(hwnd, SCI_GETTEXTLENGTH, 0, 0); + int cchText = SciCall_GetTextLength(); pszText = LocalAlloc(LPTR,cchText + 1); - SendMessage(hwnd,SCI_GETTEXT,(int)LocalSize(pszText),(LPARAM)pszText); + SciCall_GetTextFromBegin((DocPos)LocalSize(pszText), pszText); } - WCHAR* pszTextW = NULL; + WCHAR* pszTextW = L""; UINT uCodePage = Encoding_SciGetCodePage(hwnd); int cchTextW = MultiByteToWideChar(uCodePage,0,pszText,-1,NULL,0); if (cchTextW > 0) { - WCHAR *pszSep = L"\r\n\r\n"; - int lenTxt = (lstrlen(pszSep) + cchTextW + 1); + int lenTxt = (cchTextW + 1); pszTextW = LocalAlloc(LPTR,sizeof(WCHAR)*lenTxt); - StringCchCopy(pszTextW,lenTxt,pszSep); - MultiByteToWideChar(uCodePage,0,pszText,-1,StrEnd(pszTextW),lenTxt); - } - else { - pszTextW = L""; + MultiByteToWideChar(uCodePage,0,pszText,-1,pszTextW,lenTxt); } if (pszText) @@ -834,13 +915,21 @@ BOOL EditCopyAppend(HWND hwnd) HANDLE hOld = GetClipboardData(CF_UNICODETEXT); WCHAR* pszOld = GlobalLock(hOld); - int sizeNew = (lstrlen(pszOld) + lstrlen(pszTextW) + 1); + int sizeNew = bAppend ? (lstrlen(pszOld) + lstrlen(pszTextW) + 1) : (lstrlen(pszTextW) + 1); + const WCHAR *pszSep = L"\r\n\r\n"; + sizeNew += bAppend ? (int)lstrlen(pszSep) : 0; + HANDLE hNew = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof(WCHAR) * sizeNew); WCHAR* pszNew = GlobalLock(hNew); - StringCchCopy(pszNew,sizeNew,pszOld); - StringCchCat(pszNew,sizeNew,pszTextW); - + if (bAppend) { + StringCchCopy(pszNew, sizeNew, pszOld); + StringCchCat(pszNew, sizeNew, pszSep); + StringCchCat(pszNew, sizeNew, pszTextW); + } + else { + StringCchCopy(pszNew, sizeNew, pszTextW); + } GlobalUnlock(hNew); GlobalUnlock(hOld); @@ -4594,6 +4683,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA case WM_INITDIALOG: { static BOOL bFirstTime = TRUE; + iReplacedOccurrences = 0; SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)lParam); lpefr = (LPEDITFINDREPLACE)lParam; @@ -4808,6 +4898,8 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA bMarkOccurrencesMatchVisible = bSaveOccVisible; EnableCmd(GetMenu(g_hwndMain), IDM_VIEW_MARKOCCUR_VISIBLE, bMarkOccurrencesMatchVisible); + iReplacedOccurrences = 0; + KillTimer(hwnd, IDT_TIMER_MRKALL); } return FALSE; @@ -4910,6 +5002,7 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA // called on timer trigger case IDC_MARKALL_OCC: { + iMarkOccurrencesCount = 0; EditSetSearchFlags(hwnd, lpefr); if (lpefr->bMarkOccurences) { if (bFlagsChanged || (StringCchCompareXA(g_lastFind, lpefr->szFind) != 0)) { @@ -5035,10 +5128,11 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA case IDOK: - case IDC_FINDPREV: case IDC_REPLACE: case IDC_REPLACEALL: case IDC_REPLACEINSEL: + iReplacedOccurrences = 0; + case IDC_FINDPREV: case IDACC_SELTONEXT: case IDACC_SELTOPREV: case IDMSG_SWITCHTOFIND: @@ -5151,8 +5245,12 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA break; case IDC_REPLACE: - bReplaceInitialized = TRUE; - EditReplace(lpefr->hwnd, lpefr); + { + bReplaceInitialized = TRUE; + int token = BeginUndoAction(); + EditReplace(lpefr->hwnd, lpefr); + EndUndoAction(token); + } break; case IDC_REPLACEALL: @@ -5161,8 +5259,10 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA break; case IDC_REPLACEINSEL: - bReplaceInitialized = TRUE; - EditReplaceAllInSelection(lpefr->hwnd, lpefr, TRUE); + if (!SciCall_IsSelectionEmpty()) { + bReplaceInitialized = TRUE; + EditReplaceAllInSelection(lpefr->hwnd, lpefr, TRUE); + } break; } } @@ -5338,12 +5438,8 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA // HWND EditFindReplaceDlg(HWND hwnd,LPCEDITFINDREPLACE lpefr,BOOL bReplace) { - - HWND hDlg; - lpefr->hwnd = hwnd; - - hDlg = CreateThemedDialogParam(g_hInstance, + HWND hDlg = CreateThemedDialogParam(g_hInstance, (bReplace) ? MAKEINTRESOURCEW(IDD_REPLACE) : MAKEINTRESOURCEW(IDD_FIND), GetParent(hwnd), EditFindReplaceDlgProcW, @@ -5594,11 +5690,12 @@ BOOL EditReplace(HWND hwnd, LPCEDITFINDREPLACE lpefr) { DocPos start = (SciCall_IsSelectionEmpty() ? SciCall_GetCurrentPos() : SciCall_GetSelectionStart()); DocPos end = SciCall_GetTextLength(); DocPos _start = start; + iReplacedOccurrences = 0; - DocPos iPos = EditFindInTarget(hwnd, lpefr->szFind, StringCchLenA(lpefr->szFind, FNDRPL_BUFFER), (int)(lpefr->fuFlags), &start, &end, FALSE); + const DocPos iPos = EditFindInTarget(hwnd, lpefr->szFind, StringCchLenA(lpefr->szFind, FNDRPL_BUFFER), (int)(lpefr->fuFlags), &start, &end, FALSE); // w/o selection, replacement string is put into current position - // but this mayby not intended here + // but this maybe not intended here if (SciCall_IsSelectionEmpty()) { if ((iPos < 0) || (_start != start) || (_start != end)) { // empty-replace was not intended @@ -5611,6 +5708,7 @@ BOOL EditReplace(HWND hwnd, LPCEDITFINDREPLACE lpefr) { } } } + iReplacedOccurrences = 1; EditEnterTargetTransaction(); @@ -5618,8 +5716,9 @@ BOOL EditReplace(HWND hwnd, LPCEDITFINDREPLACE lpefr) { SendMessage(hwnd, iReplaceMsg, (WPARAM)-1, (LPARAM)pszReplace); // move caret behind replacement - DocPos after = (DocPos)SendMessage(hwnd, SCI_GETTARGETEND, 0, 0); - SendMessage(hwnd, SCI_SETSEL, after, after); + + const DocPos after = SciCall_GetTargetEnd(); + SciCall_SetSel(after, after); EditLeaveTargetTransaction(); @@ -5752,11 +5851,11 @@ BOOL EditReplaceAll(HWND hwnd, LPCEDITFINDREPLACE lpefr, BOOL bShowInfo) int token = BeginUndoAction(); - int iCount = EditReplaceAllInRange(hwnd, lpefr, bShowInfo, start, end); + iReplacedOccurrences = EditReplaceAllInRange(hwnd, lpefr, bShowInfo, start, end); EndUndoAction(token); - return (iCount > 0) ? TRUE : FALSE; + return (iReplacedOccurrences > 0) ? TRUE : FALSE; } @@ -5776,11 +5875,11 @@ BOOL EditReplaceAllInSelection(HWND hwnd, LPCEDITFINDREPLACE lpefr, BOOL bShowIn int token = BeginUndoAction(); - int iCount = EditReplaceAllInRange(hwnd, lpefr, bShowInfo, start, end); + iReplacedOccurrences = EditReplaceAllInRange(hwnd, lpefr, bShowInfo, start, end); EndUndoAction(token); - if (iCount <= 0) + if (iReplacedOccurrences <= 0) return FALSE; return TRUE; diff --git a/src/Edit.h b/src/Edit.h index 752077498..96431764a 100644 --- a/src/Edit.h +++ b/src/Edit.h @@ -63,9 +63,11 @@ BOOL EditConvertText(HWND,int,int,BOOL); BOOL EditSetNewEncoding(HWND,int,BOOL,BOOL); BOOL EditIsRecodingNeeded(WCHAR*,int); char* EditGetClipboardText(HWND,BOOL,int*,int*); +BOOL EditSetClipboardText(HWND, const char*); +BOOL EditClearClipboard(HWND); void EditPaste2RectSel(HWND,char*); BOOL EditPasteClipboard(HWND,BOOL); -BOOL EditCopyAppend(HWND); +BOOL EditCopyAppend(HWND,BOOL); int EditDetectEOLMode(HWND,char*,DWORD); BOOL EditLoadFile(HWND,LPCWSTR,BOOL,int*,int*,BOOL*,BOOL*,BOOL*); BOOL EditSaveFile(HWND,LPCWSTR,int,BOOL*,BOOL); diff --git a/src/Notepad3.c b/src/Notepad3.c index a5eacd513..b9999d1b3 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -57,10 +57,10 @@ HWND g_hwndMain = NULL; HWND g_hwndEdit = NULL; HWND g_hwndStatus = NULL; HWND g_hwndToolbar = NULL; +HWND g_hwndDlgFindReplace = NULL; HWND hwndReBar = NULL; HWND hwndEditFrame = NULL; HWND hwndNextCBChain = NULL; -HWND hDlgFindReplace = NULL; #define INISECTIONBUFCNT 32 #define NUMTOOLBITMAPS 25 @@ -156,6 +156,7 @@ int iLongLineMode; int iWrapCol = 0; BOOL g_bShowSelectionMargin; BOOL bShowLineNumbers; +int iReplacedOccurrences; int iMarkOccurrences; int iMarkOccurrencesCount; int iMarkOccurrencesMaxCount; @@ -541,10 +542,10 @@ int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpCmdLine,int n while (GetMessage(&msg,NULL,0,0)) { - if (IsWindow(hDlgFindReplace) && ((msg.hwnd == hDlgFindReplace) || IsChild(hDlgFindReplace, msg.hwnd))) + if (IsWindow(g_hwndDlgFindReplace) && ((msg.hwnd == g_hwndDlgFindReplace) || IsChild(g_hwndDlgFindReplace, msg.hwnd))) { - int iTr = TranslateAccelerator(hDlgFindReplace, hAccFindReplace, &msg); - if (iTr || IsDialogMessage(hDlgFindReplace, &msg)) + int iTr = TranslateAccelerator(g_hwndDlgFindReplace, hAccFindReplace, &msg); + if (iTr || IsDialogMessage(g_hwndDlgFindReplace, &msg)) continue; } if (!TranslateAccelerator(hwnd,hAccMain,&msg)) { @@ -900,6 +901,7 @@ HWND InitInstance(HINSTANCE hInstance,LPSTR pszCmdLine,int nCmdShow) if (flagStartAsTrayIcon) SetNotifyIconTitle(g_hwndMain); + iReplacedOccurrences = 0; iMarkOccurrencesCount = 0; UpdateToolbar(); UpdateStatusbar(); @@ -1526,8 +1528,8 @@ void MsgEndSession(HWND hwnd, UINT umsg) } // Destroy find / replace dialog - if (IsWindow(hDlgFindReplace)) - DestroyWindow(hDlgFindReplace); + if (IsWindow(g_hwndDlgFindReplace)) + DestroyWindow(g_hwndDlgFindReplace); // call SaveSettings() when g_hwndToolbar is still valid SaveSettings(FALSE); @@ -2767,11 +2769,11 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) int token = BeginUndoAction(); if (!SciCall_IsSelectionEmpty()) { - SendMessage(g_hwndEdit, SCI_CUT, 0, 0); + SciCall_Cut(); } else { // VisualStudio behavior - SendMessage(g_hwndEdit, SCI_COPYALLOWLINE, 0, 0); - SendMessage(g_hwndEdit, SCI_LINEDELETE, 0, 0); + SciCall_CopyAllowLine(); + SciCall_LineDelete(); } EndUndoAction(token); UpdateToolbar(); @@ -2784,7 +2786,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) if (flagPasteBoard) bLastCopyFromMe = TRUE; int token = BeginUndoAction(); - SendMessage(g_hwndEdit, SCI_COPYALLOWLINE, 0, 0); + SciCall_CopyAllowLine(); EndUndoAction(token); UpdateToolbar(); } @@ -2808,7 +2810,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) if (flagPasteBoard) bLastCopyFromMe = TRUE; int token = BeginUndoAction(); - EditCopyAppend(g_hwndEdit); + EditCopyAppend(g_hwndEdit,TRUE); EndUndoAction(token); UpdateToolbar(); } @@ -2839,7 +2841,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) break; case IDM_EDIT_CLEARCLIPBOARD: - SciClearClipboard(); + EditClearClipboard(g_hwndEdit); UpdateToolbar(); UpdateStatusbar(); break; @@ -3658,35 +3660,37 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) case IDM_EDIT_FIND: - if (!IsWindow(hDlgFindReplace)) - hDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,FALSE); + if (!IsWindow(g_hwndDlgFindReplace)) + g_hwndDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,FALSE); else { - if (GetDlgItem(hDlgFindReplace,IDC_REPLACE)) { - SendMessage(hDlgFindReplace,WM_COMMAND,MAKELONG(IDMSG_SWITCHTOFIND,1),0); - DestroyWindow(hDlgFindReplace); - hDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,FALSE); + if (GetDlgItem(g_hwndDlgFindReplace,IDC_REPLACE)) { + SendMessage(g_hwndDlgFindReplace,WM_COMMAND,MAKELONG(IDMSG_SWITCHTOFIND,1),0); + DestroyWindow(g_hwndDlgFindReplace); + g_hwndDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,FALSE); } else { - SetForegroundWindow(hDlgFindReplace); - PostMessage(hDlgFindReplace,WM_NEXTDLGCTL,(WPARAM)(GetDlgItem(hDlgFindReplace,IDC_FINDTEXT)),1); + SetForegroundWindow(g_hwndDlgFindReplace); + PostMessage(g_hwndDlgFindReplace,WM_NEXTDLGCTL,(WPARAM)(GetDlgItem(g_hwndDlgFindReplace,IDC_FINDTEXT)),1); } + UpdateStatusbar(); } break; case IDM_EDIT_REPLACE: - if (!IsWindow(hDlgFindReplace)) - hDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,TRUE); + if (!IsWindow(g_hwndDlgFindReplace)) + g_hwndDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,TRUE); else { - if (!GetDlgItem(hDlgFindReplace,IDC_REPLACE)) { - SendMessage(hDlgFindReplace,WM_COMMAND,MAKELONG(IDMSG_SWITCHTOREPLACE,1),0); - DestroyWindow(hDlgFindReplace); - hDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,TRUE); + if (!GetDlgItem(g_hwndDlgFindReplace,IDC_REPLACE)) { + SendMessage(g_hwndDlgFindReplace,WM_COMMAND,MAKELONG(IDMSG_SWITCHTOREPLACE,1),0); + DestroyWindow(g_hwndDlgFindReplace); + g_hwndDlgFindReplace = EditFindReplaceDlg(g_hwndEdit,&g_efrData,TRUE); } else { - SetForegroundWindow(hDlgFindReplace); - PostMessage(hDlgFindReplace,WM_NEXTDLGCTL,(WPARAM)(GetDlgItem(hDlgFindReplace,IDC_FINDTEXT)),1); + SetForegroundWindow(g_hwndDlgFindReplace); + PostMessage(g_hwndDlgFindReplace,WM_NEXTDLGCTL,(WPARAM)(GetDlgItem(g_hwndDlgFindReplace,IDC_FINDTEXT)),1); } + UpdateStatusbar(); } break; @@ -6957,7 +6961,9 @@ void UpdateStatusbar() static WCHAR tchSel[32] = { L'\0' }; static WCHAR tchSelB[32] = { L'\0' }; static WCHAR tchOcc[32] = { L'\0' }; - static WCHAR tchDocPos[256] = { L'\0' }; + static WCHAR tchReplOccs[32] = { L'\0' }; + static WCHAR tchDocPos[128] = { L'\0' }; + static WCHAR tchFRStatus[128] = { L'\0' }; static WCHAR tchBytes[64] = { L'\0' }; static WCHAR tchDocSize[64] = { L'\0' }; @@ -7050,6 +7056,17 @@ void UpdateStatusbar() else { FormatString(tchDocPos, COUNTOF(tchDocPos), IDS_DOCPOS2, tchLn, tchLines, tchCol, tchCols, tchSel, tchSelB, tchLinesSelected, tchOcc); } + + // update Find/Replace dialog (if any) + if (g_hwndDlgFindReplace) { + if (iReplacedOccurrences > 0) + StringCchPrintf(tchReplOccs, COUNTOF(tchReplOccs), L"%i", iReplacedOccurrences); + else + StringCchCopy(tchReplOccs, COUNTOF(tchReplOccs), L"--"); + + FormatString(tchFRStatus, COUNTOF(tchFRStatus), IDS_FR_STATUS_FMT, tchLn, tchLines, tchCol, tchSel, tchOcc, tchReplOccs); + SetWindowText(GetDlgItem(g_hwndDlgFindReplace, IDS_FR_STATUS_TEXT), tchFRStatus); + } // get number of bytes in current encoding StrFormatByteSize(iTextLength, tchBytes, COUNTOF(tchBytes)); diff --git a/src/Notepad3.rc b/src/Notepad3.rc index dc79060c5..465bbe359 100644 --- a/src/Notepad3.rc +++ b/src/Notepad3.rc @@ -181,8 +181,8 @@ BEGIN END POPUP "&Block" BEGIN - MENUITEM "&Indent", IDM_EDIT_INDENT - MENUITEM "&Unindent", IDM_EDIT_UNINDENT + MENUITEM "&Indent", IDM_EDIT_INDENT + MENUITEM "&Unindent", IDM_EDIT_UNINDENT MENUITEM SEPARATOR POPUP "&Enclose Selection" BEGIN @@ -275,10 +275,10 @@ BEGIN END MENUITEM SEPARATOR MENUITEM "&Find...\tCtrl+F", IDM_EDIT_FIND - MENUITEM "Save Find Text\tAlt+F3", IDM_EDIT_SAVEFIND + MENUITEM "Save Find Text\tAlt+F3", IDM_EDIT_SAVEFIND MENUITEM "Find Ne&xt\tF3", IDM_EDIT_FINDNEXT - MENUITEM "Find Pre&vious\tShift+F3", IDM_EDIT_FINDPREV - MENUITEM "&Replace...\tCtrl+H", IDM_EDIT_REPLACE + MENUITEM "Find Pre&vious\tShift+F3", IDM_EDIT_FINDPREV + MENUITEM "&Replace...\tCtrl+H", IDM_EDIT_REPLACE MENUITEM "Replace Ne&xt\tF4", IDM_EDIT_REPLACENEXT MENUITEM "&Goto...\tCtrl+G", IDM_EDIT_GOTOLINE END @@ -652,7 +652,7 @@ BEGIN LTEXT "Contributors: Derick Payne (Rizonesoft), Flo Balmer (Notepad2), N.Hodgson (Scintilla), XhmikosR (Notepad2-mod), Kai Liu, RL Vision, A.Lekov, B.Barbieri, M.Ellis (MinimizeToTray), D.Dyer (crypt), T.D.Hanson (uthash), RaiKoHoff",IDC_STATIC,45,150,200,44 END -IDD_FIND DIALOGEX 0, 0, 273, 120 +IDD_FIND DIALOGEX 0, 0, 273, 129 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_NOFAILCREATE | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Find Text" FONT 8, "MS Shell Dlg", 0, 0, 0x0 @@ -669,25 +669,26 @@ BEGIN CONTROL "C&lose after find",IDC_FINDCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,49,65,10 CONTROL "Mark &Occurrences",IDC_ALL_OCCURRENCES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,61,73,10 CONTROL "W&ildcard Search",IDC_WILDCARDSEARCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,85,63,10 - DEFPUSHBUTTON "&Find Next",IDOK,216,7,50,14 - PUSHBUTTON "Find &Previous",IDC_FINDPREV,216,24,50,14 - PUSHBUTTON "Close",IDCANCEL,216,41,50,14 + DEFPUSHBUTTON "&Find Next",IDOK,211,7,55,14 + PUSHBUTTON "Find &Previous",IDC_FINDPREV,211,24,55,14 + PUSHBUTTON "Close",IDCANCEL,212,99,54,14 CONTROL "Goto Replace (Ctrl+H)",IDC_TOGGLEFINDREPLACE, - "SysLink",0x0,125,104,74,10 + "SysLink",0x0,125,103,74,10 CONTROL "(?)",IDC_REGEXPHELP,"SysLink",0x0,106,85,14,10 CONTROL "(?)",IDC_BACKSLASHHELP,"SysLink",0x0,106,73,14,10 CONTROL "(?)",IDC_WILDCARDHELP,"SysLink",0x0,191,85,14,10 + CONTROL "",IDS_FR_STATUS_TEXT,"Static",SS_LEFTNOWORDWRAP,7,117,259,9,WS_EX_STATICEDGE END -IDD_REPLACE DIALOGEX 0, 0, 273, 147 +IDD_REPLACE DIALOGEX 0, 0, 273, 156 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_NOFAILCREATE | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Replace Text" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN LTEXT "Search Strin&g:",IDC_STATIC,7,7,46,8 COMBOBOX IDC_FINDTEXT,7,17,192,116,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - LTEXT "Replace wit&h:",IDC_STATIC,7,35,44,8 - COMBOBOX IDC_REPLACETEXT,7,46,192,116,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + LTEXT "Replace wit&h:",IDC_STATIC,7,36,44,8 + COMBOBOX IDC_REPLACETEXT,7,47,192,116,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP CONTROL "Match &case",IDC_FINDCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,66,53,10 CONTROL "Match &whole word only",IDC_FINDWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,78,89,10 CONTROL "Match &beginning of word only",IDC_FINDSTART,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,90,110,10 @@ -698,18 +699,19 @@ BEGIN CONTROL "C&lose after replace",IDC_FINDCLOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,78,77,10 CONTROL "Mark &Occurrences",IDC_ALL_OCCURRENCES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,90,73,10 CONTROL "W&ildcard Search",IDC_WILDCARDSEARCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,125,114,63,10 - DEFPUSHBUTTON "&Find Next",IDOK,216,7,50,14 - PUSHBUTTON "Find &Previous",IDC_FINDPREV,216,24,50,14 - PUSHBUTTON "&Replace",IDC_REPLACE,216,41,50,14 - PUSHBUTTON "Replace &All",IDC_REPLACEALL,216,58,50,14 - PUSHBUTTON "In &Selection",IDC_REPLACEINSEL,216,75,50,14 - PUSHBUTTON "Swap Strings",IDC_SWAPSTRG,216,92,50,14 - PUSHBUTTON "Close",IDCANCEL,216,127,50,14 + DEFPUSHBUTTON "&Find Next",IDOK,211,7,55,14 + PUSHBUTTON "Find &Previous",IDC_FINDPREV,211,24,55,14 + PUSHBUTTON "&Replace",IDC_REPLACE,211,53,55,14 + PUSHBUTTON "In &Selection",IDC_REPLACEINSEL,211,70,55,14 + PUSHBUTTON "Replace &All",IDC_REPLACEALL,211,88,55,14 + PUSHBUTTON "Swap Strings",IDC_SWAPSTRG,149,32,49,12 + PUSHBUTTON "Close",IDCANCEL,211,126,55,14 CONTROL "Goto Find (Ctrl+F)",IDC_TOGGLEFINDREPLACE, - "SysLink",0x0,125,131,74,10 - CONTROL "(?)",IDC_REGEXPHELP,"SysLink",0x0,107,114,14,10 + "SysLink",0x0,125,130,74,10 CONTROL "(?)",IDC_BACKSLASHHELP,"SysLink",0x0,107,102,14,10 + CONTROL "(?)",IDC_REGEXPHELP,"SysLink",0x0,107,114,14,10 CONTROL "(?)",IDC_WILDCARDHELP,"SysLink",0x0,191,114,14,10 + CONTROL "",IDS_FR_STATUS_TEXT,"Static",SS_LEFTNOWORDWRAP,7,144,259,9,WS_EX_STATICEDGE END IDD_RUN DIALOGEX 0, 0, 229, 96 @@ -1173,7 +1175,7 @@ BEGIN RIGHTMARGIN, 266 VERTGUIDE, 7 TOPMARGIN, 7 - BOTTOMMARGIN, 114 + BOTTOMMARGIN, 113 END IDD_REPLACE, DIALOG @@ -1182,7 +1184,7 @@ BEGIN RIGHTMARGIN, 266 VERTGUIDE, 7 TOPMARGIN, 7 - BOTTOMMARGIN, 141 + BOTTOMMARGIN, 140 END IDD_RUN, DIALOG @@ -1446,6 +1448,7 @@ BEGIN IDS_BACKSLASHHELP "Backslash Transformations\n\n\\a\tAlert (BEL, Ascii 7)\n\\b\tBackspace (BS, Ascii 8)\n\\f\tFormfeed (FF, Ascii 12)\n\\n\tNewline (LF, Ascii 10)\n\\r\tCarriage return (CR, Ascii 13)\n\\t\tHorizontal Tab (HT, Ascii 9)\n\\v\tVertical Tab (VT, Ascii 11)\n\\0oo\tOctal Value\n\\u####\tHexadecimal Value\n\\xhh\tHexadecimal Value\n\\\\\tBackslash" IDS_REGEXPHELP "RegExp Matching Syntax (Multi Lines)\n\n.\tMatches any character\n^\tEmpty string immediately after Newline\n$\tEmpty string immediately before End of Line\n\\<\tStart of a word\n\\>\tEnd of a word\n\\b\tWord boundary\n[...]\tA set of chars ([abc]) or a range ([a-z])\n[^...]\tChars NOT in the set or range\n\\d\tAny decimal digit\n\\D\tAny non-digit char\n\\s\tAny whitespace char\n\\S\tNot a whitespace char\n\\w\tAny ""word"" char\n\\W\tAny ""non-word"" char\n\\x\tEscape character with otherwise special meaning\n\\xHH\tChar with hex code HH\n?\tMatches preceding 0 or 1 times\n*\tMatches preceding 0 or more times\n+\tMatches preceding 1 or more times\n*? or +?\tNon greedy matching of quantifiers ""?"" and ""+""\n(\tStart of a region\n)\tEnd of a region\n\\n\tRefers to a region when replacing (n is 1-9)\n" IDS_WILDCARDHELP "Wildcard Search\n\n*\tMatches zero or more characters.\n?\tMatches exactly one character. " + IDS_FR_STATUS_FMT " Ln %s / %s Col %s Sel %s Occ %s Repl %s " END STRINGTABLE diff --git a/src/SciCall.h b/src/SciCall.h index 99848b3c7..5d9219f18 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -89,7 +89,7 @@ __forceinline LRESULT SciCall_##fn(type1 var1, type2 var2) { \ DeclareSciCallR0(IsDocModified, GETMODIFY, bool); DeclareSciCallR0(IsSelectionEmpty, GETSELECTIONEMPTY, bool); DeclareSciCallR0(IsSelectionRectangle, SELECTIONISRECTANGLE, bool); - +DeclareSciCallR0(CanPaste, CANPASTE, bool); DeclareSciCallR0(GetCurrentPos, GETCURRENTPOS, DocPos); DeclareSciCallR0(GetAnchor, GETANCHOR, DocPos); @@ -99,16 +99,25 @@ DeclareSciCallR0(GetSelectionEnd, GETSELECTIONEND, DocPos); DeclareSciCallR1(GetLineSelStartPosition, GETLINESELSTARTPOSITION, DocPos, DocLn, line); DeclareSciCallR1(GetLineSelEndPosition, GETLINESELENDPOSITION, DocPos, DocLn, line); -DeclareSciCallV0(Clear, CLEAR); + +DeclareSciCallV0(Cut, CUT); DeclareSciCallV0(Copy, COPY); DeclareSciCallV0(Paste, PASTE); +DeclareSciCallV0(Clear, CLEAR); +DeclareSciCallV0(CopyAllowLine, COPYALLOWLINE); +DeclareSciCallV0(LineDelete, LINEDELETE); DeclareSciCallV2(CopyText, COPYTEXT, DocPos, length, LPCCH, text); +DeclareSciCallV2(GetTextFromBegin, GETTEXT, DocPos, length, LPCCH, text); + DeclareSciCallV2(SetSel, SETSEL, DocPos, anchorPos, DocPos, currentPos); DeclareSciCallV0(SelectAll, SELECTALL); -DeclareSciCallV2(SetTargetRange, SETTARGETRANGE, DocPos, start, DocPos, end); -DeclareSciCallV0(TargetFromSelection, TARGETFROMSELECTION); DeclareSciCallR01(GetSelText, GETSELTEXT, DocPos, LPCCH, text); DeclareSciCallV01(ReplaceSel, REPLACESEL, LPCCH, text); + +DeclareSciCallR0(GetTargetStart, GETTARGETSTART, DocPos); +DeclareSciCallR0(GetTargetEnd, GETTARGETEND, DocPos); +DeclareSciCallV0(TargetFromSelection, TARGETFROMSELECTION); +DeclareSciCallV2(SetTargetRange, SETTARGETRANGE, DocPos, start, DocPos, end); DeclareSciCallV2(ReplaceTarget, REPLACETARGET, DocPos, length, LPCCH, text); DeclareSciCallV1(SetAnchor, SETANCHOR, DocPos, position); @@ -229,8 +238,6 @@ DeclareSciCallV1(SetTechnology, SETTECHNOLOGY, int, technology); // // Utilities // -#define SciClearClipboard() SciCall_CopyText(0, "") - #define IsSelThinRectangle() (SciCall_GetSelectionMode() == SC_SEL_THIN) #define IsFullLineSelected() (SciCall_GetSelectionMode() == SC_SEL_LINES) #define IsSingleLineSelection() \ diff --git a/src/resource.h b/src/resource.h index 2a53528fb..51fd87add 100644 --- a/src/resource.h +++ b/src/resource.h @@ -161,6 +161,7 @@ #define IDS_PASS_FAILURE 511 #define IDS_NOPASS 512 #define IDM_HELP_UPDATECHECK 513 +#define IDS_FR_STATUS_TEXT 514 #define IDS_APPTITLE 10000 #define IDS_APPTITLE_ELEVATED 10001 #define IDS_APPTITLE_PASTEBOARD 10002 @@ -183,6 +184,7 @@ #define IDS_BACKSLASHHELP 10019 #define IDS_REGEXPHELP 10020 #define IDS_WILDCARDHELP 10021 +#define IDS_FR_STATUS_FMT 10022 #define CMD_ESCAPE 20000 #define CMD_SHIFTESC 20001 #define CMD_SHIFTCTRLENTER 20002