+ fix: broken swap clipboard w/ selection

This commit is contained in:
Rainer Kottenhoff 2018-02-20 14:37:32 +01:00
parent f06fe63e4e
commit 6dd3c6b658
4 changed files with 135 additions and 41 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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() \