From 3c6bb283611040e87a64785635882cfa2fbabf34 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Wed, 4 Oct 2017 14:45:48 +0200 Subject: [PATCH 1/2] + enhanced clipboard recoding detection + fix: bug in code-page related text conversion --- src/Edit.c | 34 ++++++++++++++++++++++------------ src/Notepad3.c | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index d1d34bfdd..a4a4b95c4 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -464,10 +464,8 @@ BOOL EditConvertText(HWND hwnd,int encSource,int encDest,BOOL bSetSavePoint) else { - //~UINT cpSrc = mEncoding[encSource].uCodePage; - //~UINT cpDst = mEncoding[encDest].uCodePage; - UINT cpSrc = Encoding_SciMappedCodePage(encSource); - UINT cpDst = Encoding_SciMappedCodePage(encDest); + UINT cpSrc = Encoding_SciGetCodePage(hwnd); // fixed internal + UINT cpDst = mEncoding[encDest].uCodePage; if (cpSrc == cpDst) return(TRUE); @@ -569,16 +567,26 @@ BOOL EditIsRecodingNeeded(WCHAR* pszText, int cchLen) 65001 // (UTF-8) }; + BOOL useNullParams = FALSE; DWORD dwFlags = WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | WC_DEFAULTCHAR; for (int i = 0; i < COUNTOF(uCodePageExcept); i++) { if (codepage == uCodePageExcept[i]) { - dwFlags = 0L; + useNullParams = TRUE; break; } } BOOL bDefaultCharsUsed = FALSE; - int cch = WideCharToMultiByte(codepage, dwFlags, pszText, cchLen, NULL, 0, NULL, &bDefaultCharsUsed); + int cch = 0; + if (useNullParams) + cch = WideCharToMultiByte(codepage, 0, pszText, cchLen, NULL, 0, NULL, NULL); + else + cch = WideCharToMultiByte(codepage, dwFlags, pszText, cchLen, NULL, 0, NULL, &bDefaultCharsUsed); + + if (useNullParams && (cch == 0)) { + if (GetLastError() != ERROR_NO_UNICODE_TRANSLATION) + cch = cchLen; // don't care + } BOOL bSuccess = ((cch >= cchLen) && (cch != (int)0xFFFD)) ? TRUE : FALSE; @@ -627,11 +635,13 @@ char* EditGetClipboardText(HWND hwnd,BOOL bCheckEncoding) { EditFixPositions(hwnd); } - UINT codepage = mEncoding[Encoding_Current(CPI_GET)].uCodePage; - mlen = WideCharToMultiByte(codepage,0,pwch,wlen + 2,NULL,0,NULL,NULL); - pmch = LocalAlloc(LPTR,mlen + 2); + // translate to SCI editor component codepage (default: UTF-8) + UINT codepage = Encoding_SciGetCodePage(hwnd); + + mlen = WideCharToMultiByte(codepage,0,pwch,wlen,NULL,0,NULL,NULL); + pmch = LocalAlloc(LPTR,mlen + 1); if (pmch && mlen != 0) { - int cnt = WideCharToMultiByte(codepage,0,pwch,wlen + 2,pmch,mlen + 2,NULL,NULL); + int cnt = WideCharToMultiByte(codepage,0,pwch,wlen,pmch,mlen + 1,NULL,NULL); if (cnt == 0) return (pmch); } @@ -670,8 +680,8 @@ char* EditGetClipboardText(HWND hwnd,BOOL bCheckEncoding) { mlen2 = (int)(d - ptmp); LocalFree(pmch); - pmch = LocalAlloc(LPTR,mlen2 + 2); - StringCchCopyA(pmch,mlen2 + 2,ptmp); + pmch = LocalAlloc(LPTR,mlen2 + 1); + StringCchCopyA(pmch,mlen2 + 1,ptmp); LocalFree(ptmp); } } diff --git a/src/Notepad3.c b/src/Notepad3.c index 0a2510753..3dbf1e832 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -3072,7 +3072,7 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) bSwapClipBoard = TRUE; case IDM_EDIT_PASTE: { - char *pClip = EditGetClipboardText(hwndEdit,TRUE); + char *pClip = EditGetClipboardText(hwndEdit,!bSkipUnicodeDetection); if (!pClip) break; // recoding canceled From 5eaf851da1d69675afbff7d1eafaa67becfdbba4 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Wed, 4 Oct 2017 18:44:30 +0200 Subject: [PATCH 2/2] + fix: copy/cut & paste of current line (in case of no selection - Visual Studio behavior - using SCI's MSDEVLineSelect) --- src/Edit.c | 2 -- src/Notepad3.c | 80 ++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index a4a4b95c4..baf617299 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -2062,7 +2062,6 @@ void EditInvertCase(HWND hwnd) SendMessage(hwnd,SCI_ADDTEXT,(WPARAM)(iSelEnd - iSelStart),(LPARAM)pszText); SendMessage(hwnd,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos); SendMessage(hwnd,SCI_ENDUNDOACTION,0,0); - } GlobalFree(pszText); @@ -2132,7 +2131,6 @@ void EditTitleCase(HWND hwnd) SendMessage(hwnd,SCI_ADDTEXT,(WPARAM)(iSelEnd - iSelStart),(LPARAM)pszText); SendMessage(hwnd,SCI_SETSEL,(WPARAM)iAnchorPos,(LPARAM)iCurPos); SendMessage(hwnd,SCI_ENDUNDOACTION,0,0); - } GlobalFree(pszText); diff --git a/src/Notepad3.c b/src/Notepad3.c index 3dbf1e832..01f08d985 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -1271,6 +1271,7 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) dwLastCopyTime = GetTickCount(); else bLastCopyFromMe = FALSE; + if (hwndNextCBChain) SendMessage(hwndNextCBChain,WM_DRAWCLIPBOARD,wParam,lParam); break; @@ -3022,24 +3023,31 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) if (flagPasteBoard) bLastCopyFromMe = TRUE; + int token = BeginSelUndoAction(); if (!SendMessage(hwndEdit, SCI_GETSELECTIONEMPTY, 0, 0)) { - int token = BeginSelUndoAction(); SendMessage(hwndEdit, SCI_CUT, 0, 0); - EndSelUndoAction(token); } - else { - SendMessage(hwndEdit, SCI_LINECUT, 0, 0); // VisualStudio behavior + else { // VisualStudio behavior + SendMessage(hwndEdit, SCI_COPYALLOWLINE, 0, 0); + SendMessage(hwndEdit, SCI_LINEDELETE, 0, 0); } + EndSelUndoAction(token); + UpdateToolbar(); } break; case IDM_EDIT_COPY: - if (flagPasteBoard) - bLastCopyFromMe = TRUE; - SendMessage(hwndEdit,SCI_COPYALLOWLINE, 0, 0); - UpdateToolbar(); + { + if (flagPasteBoard) + bLastCopyFromMe = TRUE; + + int token = BeginSelUndoAction(); + SendMessage(hwndEdit, SCI_COPYALLOWLINE, 0, 0); + EndSelUndoAction(token); + UpdateToolbar(); + } break; @@ -3050,8 +3058,8 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) int token = BeginSelUndoAction(); SendMessage(hwndEdit,SCI_COPYRANGE,0,SendMessage(hwndEdit,SCI_GETLENGTH,0,0)); - UpdateToolbar(); EndSelUndoAction(token); + UpdateToolbar(); } break; @@ -3060,14 +3068,15 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) { if (flagPasteBoard) bLastCopyFromMe = TRUE; - + int token = BeginSelUndoAction(); EditCopyAppend(hwndEdit); - UpdateToolbar(); EndSelUndoAction(token); + UpdateToolbar(); } break; + case IDM_EDIT_SWAP: bSwapClipBoard = TRUE; case IDM_EDIT_PASTE: @@ -3076,39 +3085,37 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) if (!pClip) break; // recoding canceled - int iPos = (int)SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0); - int iAnchor = (int)SendMessage(hwndEdit,SCI_GETANCHOR,0,0); - int token = BeginSelUndoAction(); - if (SendMessage(hwndEdit,SCI_GETSELECTIONEMPTY,0,0)) { - - SendMessage(hwndEdit,SCI_REPLACESEL,(WPARAM)0,(LPARAM)pClip); - - if (bSwapClipBoard) { - int iNewPos = (int)SendMessage(hwndEdit,SCI_GETCURRENTPOS,0,0); - SendMessage(hwndEdit,SCI_SETSEL,iPos,iNewPos); - SendMessage(hwnd,WM_COMMAND,MAKELONG(IDM_EDIT_CLEARCLIPBOARD,1),0); - } + if (SendMessage(hwndEdit,SCI_GETSELECTIONEMPTY,0,0)) + { + SendMessage(hwndEdit, SCI_PASTE, 0, 0); + if (bSwapClipBoard) + SendMessage(hwndEdit, SCI_COPYTEXT, 0, (LPARAM)NULL); } else { + + int iCurrPos = (int)SendMessage(hwndEdit, SCI_GETCURRENTPOS, 0, 0); + int iAnchor = (int)SendMessage(hwndEdit, SCI_GETANCHOR, 0, 0); + if (flagPasteBoard) bLastCopyFromMe = TRUE; if (bSwapClipBoard) - SendMessage(hwndEdit,SCI_CUT,0,0); - else - SendMessage(hwndEdit,SCI_CLEAR,0,0); + SendMessage(hwndEdit,SCI_COPY,0,0); - SendMessage(hwndEdit,SCI_REPLACESEL,(WPARAM)0,(LPARAM)pClip); + SendMessage(hwndEdit,SCI_REPLACESEL,0,(LPARAM)pClip); - if (iPos > iAnchor) - SendMessage(hwndEdit,SCI_SETSEL,iAnchor,iAnchor + lstrlenA(pClip)); + if (iCurrPos > iAnchor) + SendMessage(hwndEdit,SCI_SETSEL, iAnchor, iAnchor + lstrlenA(pClip)); else - SendMessage(hwndEdit,SCI_SETSEL,iPos + lstrlenA(pClip),iPos); + SendMessage(hwndEdit,SCI_SETSEL, iCurrPos + lstrlenA(pClip), iCurrPos); + } EndSelUndoAction(token); LocalFree(pClip); + UpdateToolbar(); + UpdateStatusbar(); } break; @@ -3123,14 +3130,9 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) case IDM_EDIT_CLEARCLIPBOARD: - if (OpenClipboard(hwnd)) { - if (CountClipboardFormats() > 0) { - EmptyClipboard(); - UpdateToolbar(); - UpdateStatusbar(); - } - CloseClipboard(); - } + SendMessage(hwndEdit, SCI_COPYTEXT, 0, (LPARAM)NULL); + UpdateToolbar(); + UpdateStatusbar(); break; @@ -3227,6 +3229,7 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) { if (flagPasteBoard) bLastCopyFromMe = TRUE; + int token = BeginSelUndoAction(); SendMessage(hwndEdit,SCI_LINECUT,0,0); UpdateToolbar(); @@ -3238,6 +3241,7 @@ LRESULT MsgCommand(HWND hwnd,WPARAM wParam,LPARAM lParam) case IDM_EDIT_COPYLINE: if (flagPasteBoard) bLastCopyFromMe = TRUE; + SendMessage(hwndEdit,SCI_LINECOPY,0,0); UpdateToolbar(); break;