From 6dd3c6b6581f2f00b809f09e5d1532c0375ffe25 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Tue, 20 Feb 2018 14:37:32 +0100 Subject: [PATCH] + fix: broken swap clipboard w/ selection --- src/Edit.c | 148 +++++++++++++++++++++++++++++++++++++++---------- src/Edit.h | 4 +- src/Notepad3.c | 12 ++-- src/SciCall.h | 12 ++-- 4 files changed, 135 insertions(+), 41 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index da815a9d4..06298cd71 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -635,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() @@ -743,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); } } } @@ -783,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) { @@ -800,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) @@ -835,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); 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 cd4c4df2f..b9999d1b3 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -2769,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(); @@ -2786,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(); } @@ -2810,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(); } @@ -2841,7 +2841,7 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) break; case IDM_EDIT_CLEARCLIPBOARD: - SciClearClipboard(); + EditClearClipboard(g_hwndEdit); UpdateToolbar(); UpdateStatusbar(); break; diff --git a/src/SciCall.h b/src/SciCall.h index 99848b3c7..aa931f7be 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,10 +99,16 @@ 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); @@ -229,8 +235,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() \