diff --git a/src/Dialogs.c b/src/Dialogs.c index 085283e12..c351893f4 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -1143,7 +1143,7 @@ INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam // -------------------------------------------------------------------- - SetClipboardTextW(Globals.hwndMain, wchVerInfo, StringCchLen(wchVerInfo,0)); + SetClipboardText(Globals.hwndMain, wchVerInfo, StringCchLen(wchVerInfo,0)); } break; @@ -4207,7 +4207,7 @@ void WinInfoToScreen(WININFO* pWinInfo) // WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO* hMonitorInfo) { - WINDOWPLACEMENT wndpl; + WINDOWPLACEMENT wndpl = { 0 }; wndpl.length = sizeof(WINDOWPLACEMENT); GetWindowPlacement(hwnd, &wndpl); @@ -4626,7 +4626,7 @@ void DialogGrepWin(HWND hwnd, LPCWSTR searchPattern) StringCchPrintf(tchParams, COUNTOF(tchParams), L"/portable /content %s", tchOptions); } //if (StrIsNotEmpty(searchPattern)) { - // SetClipboardTextW(hwnd, searchPattern, StringCchLen(searchPattern, 0)); + // SetClipboardText(Globals.hwndMain, searchPattern, StringCchLen(searchPattern, 0)); //} SHELLEXECUTEINFO sei; diff --git a/src/Edit.c b/src/Edit.c index f563789ef..4f5a93815 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -686,7 +686,7 @@ bool EditSetClipboardText(HWND hwnd, const char* pszText, size_t cchText) } if (pszTextW) { - SetClipboardTextW(GetParent(hwnd), pszTextW, cchTextW); + SetClipboardText(GetParent(hwnd), pszTextW, cchTextW); FreeMem(pszTextW); return true; } @@ -700,10 +700,12 @@ bool EditSetClipboardText(HWND hwnd, const char* pszText, size_t cchText) // bool EditClearClipboard(HWND hwnd) { - if (!OpenClipboard(GetParent(hwnd))) { return false; } - EmptyClipboard(); - CloseClipboard(); - return true; + bool ok = false; + if (OpenClipboard(GetParent(hwnd))) { + ok = EmptyClipboard(); + CloseClipboard(); + } + return ok; } @@ -793,7 +795,7 @@ bool EditCopyRangeAppend(HWND hwnd, DocPos posBegin, DocPos posEnd, bool bAppend HWND const hwndParent = GetParent(hwnd); if (!bAppend) { - res = SetClipboardTextW(hwndParent, pszTextW, cchTextW); + res = SetClipboardText(hwndParent, pszTextW, cchTextW); FreeMem(pszTextW); return res; } @@ -828,7 +830,7 @@ bool EditCopyRangeAppend(HWND hwnd, DocPos posBegin, DocPos posEnd, bool bAppend // Add New if (pszTextW && *pszTextW && pszNewTextW) { StringCchCat(pszNewTextW, cchNewText + 1, pszTextW); - res = SetClipboardTextW(hwndParent, pszNewTextW, cchNewText); + res = SetClipboardText(hwndParent, pszNewTextW, cchNewText); } FreeMem(pszTextW); @@ -4289,38 +4291,92 @@ void EditFocusMarkedLinesCmd(HWND hwnd, bool bCopy, bool bDelete) return; } - if (bCopy) { - EditClearClipboard(hwnd); - } - - _IGNORE_NOTIFY_CHANGE_; - SciCall_BeginUndoAction(); - DocLn line = 0; - do { + + if (bCopy) { // --- copy to clipboard --- + + DocPosU copyBufSize = 0; + while (line >= 0) { line = SciCall_MarkerNext(line, bitmask); if (line >= 0) { - int const lnmask = SciCall_MarkerGet(line) & OCCURRENCE_MARKER_BITMASK(); - if (lnmask == bitmask) { // fit all markers - if (bCopy) { - DocPos const lnBeg = SciCall_PositionFromLine(line); - //DocPos const lnEnd = lnBeg + SciCall_LineLength(line); // incl line-breaks - DocPos const lnEnd = SciCall_GetLineEndPosition(line); // w/o line-breaks - EditCopyRangeAppend(hwnd, lnBeg, lnEnd, true); - } - if (bDelete) { - SciCall_GotoLine(line); - SciCall_MarkerDelete(line, -1); - SciCall_LineDelete(); - } else { - ++line; - } - } + int const lnmask = SciCall_MarkerGet(line) & OCCURRENCE_MARKER_BITMASK(); + if (lnmask == bitmask) { // must fit all markers + copyBufSize += SciCall_LineLength(line); // incl line-breaks + } + ++line; // next } - } while (line >= 0); + } - SciCall_EndUndoAction(); - _OBSERVE_NOTIFY_CHANGE_; + if (copyBufSize > 0) { + char *const pchBuffer = (char *const)AllocMem(copyBufSize + 1, HEAP_ZERO_MEMORY); + if (pchBuffer) { + // --- collect marked lines --- + line = 0; + char *p = pchBuffer; + while (line >= 0) { + line = SciCall_MarkerNext(line, bitmask); + if (line >= 0) { + int const lnmask = SciCall_MarkerGet(line) & OCCURRENCE_MARKER_BITMASK(); + if (lnmask == bitmask) { // must fit all markers + DocPos const lnBeg = SciCall_PositionFromLine(line); + DocPos const lnLen = SciCall_LineLength(line); // incl line-breaks + const char *const pszLine = SciCall_GetRangePointer(lnBeg, lnLen); + memcpy(p, pszLine, lnLen); + p += lnLen; + } + ++line; // next + } + } + // --- copy collection to clipboard --- + int const cchTextW = MultiByteToWideChar(Encoding_SciCP, 0, pchBuffer, -1, NULL, 0); + if (cchTextW > 0) { + bool ok = false; + HANDLE const hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (cchTextW + 1) * sizeof(WCHAR)); + if (hData) { + WCHAR* const pszClipBoard = GlobalLock(hData); + if (pszClipBoard) { + MultiByteToWideChar(Encoding_SciCP, 0, pchBuffer, -1, pszClipBoard, (int)(cchTextW + 1)); + GlobalUnlock(hData); + if (OpenClipboard(hwnd)) { + EmptyClipboard(); + ok = (SetClipboardData(CF_UNICODETEXT, hData) != NULL); // move ownership + CloseClipboard(); + } + } + if (!ok) { + GlobalFree(hData); + } + } + } + FreeMem(pchBuffer); + } + } + } // bCopy + + if (bDelete) { + + _IGNORE_NOTIFY_CHANGE_; + SciCall_BeginUndoAction(); + + line = 0; + while (line >= 0) { + line = SciCall_MarkerNext(line, bitmask); + if (line >= 0) { + int const lnmask = SciCall_MarkerGet(line) & OCCURRENCE_MARKER_BITMASK(); + if (lnmask == bitmask) { // must fit all markers + SciCall_MarkerDelete(line, -1); + DocPos const lnBeg = SciCall_PositionFromLine(line); + DocPos const lnLen = SciCall_LineLength(line); // incl line-breaks + SciCall_DeleteRange(lnBeg, lnLen); // complete line + } else { + ++line; // next + } + } + } + + SciCall_EndUndoAction(); + _OBSERVE_NOTIFY_CHANGE_; + } SciCall_GotoLine(min_ln(curLn, Sci_GetLastDocLineNumber())); } diff --git a/src/Helpers.c b/src/Helpers.c index a91b8c8bd..98099fa10 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -277,25 +277,28 @@ void GetWinVersionString(LPWSTR szVersionStr, size_t cchVersionStr) //============================================================================= // -// SetClipboardWchTextW() +// SetClipboardTextW() // -bool SetClipboardTextW(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW) +bool SetClipboardText(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW) { - if (!OpenClipboard(hwnd)) { return false; } - HANDLE hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (cchTextW + 1) * sizeof(WCHAR)); + bool ok = false; + HANDLE const hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (cchTextW + 1) * sizeof(WCHAR)); if (hData) { - WCHAR* pszNew = GlobalLock(hData); + WCHAR* const pszNew = GlobalLock(hData); if (pszNew) { StringCchCopy(pszNew, cchTextW + 1, pszTextW); GlobalUnlock(hData); - EmptyClipboard(); - SetClipboardData(CF_UNICODETEXT, hData); + if (OpenClipboard(hwnd)) { + EmptyClipboard(); + ok = (SetClipboardData(CF_UNICODETEXT, hData) != NULL); // move ownership + CloseClipboard(); + } + } + if (!ok) { + GlobalFree(hData); } - CloseClipboard(); - return true; } - CloseClipboard(); - return false; + return ok; } diff --git a/src/Helpers.h b/src/Helpers.h index 0952a50ec..abe7b990d 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -279,7 +279,7 @@ void GetWinVersionString(LPWSTR szVersionStr, size_t cchVersionStr); // ---------------------------------------------------------------------------- -bool SetClipboardTextW(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW); +bool SetClipboardText(HWND hwnd, LPCWSTR pszTextW, size_t cchTextW); // ---------------------------------------------------------------------------- diff --git a/src/Notepad3.c b/src/Notepad3.c index 61868db1d..a92531b42 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -4437,32 +4437,26 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (SciCall_IsSelectionEmpty()) { if (!Settings2.NoCutLineOnEmptySelection) { - _BEGIN_UNDO_ACTION_; SciCall_MarkerDelete(Sci_GetCurrentLineNumber(), -1); SciCall_LineCut(); - _END_UNDO_ACTION_; } } else { - _BEGIN_UNDO_ACTION_; SciCall_Cut(); - _END_UNDO_ACTION_; } } break; case IDM_EDIT_CUTLINE: - { - if (s_flagPasteBoard) { - s_bLastCopyFromMe = true; - } - _BEGIN_UNDO_ACTION_; + { + if (s_flagPasteBoard) { + s_bLastCopyFromMe = true; + } SciCall_MarkerDelete(Sci_GetCurrentLineNumber(), -1); SciCall_LineCut(); - _END_UNDO_ACTION_; - } - break; + } + break; case IDM_EDIT_COPY: @@ -4490,17 +4484,12 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (s_flagPasteBoard) { s_bLastCopyFromMe = true; } - DocPos const iSelLnStart = SciCall_PositionFromLine(SciCall_LineFromPosition(SciCall_GetSelectionStart())); + DocPos const iSelLnStart = Sci_GetLineStartPosition(SciCall_GetSelectionStart()); DocPos const iLineSelLast = SciCall_LineFromPosition(SciCall_GetSelectionEnd()); // copy incl last line-breaks DocPos const iSelLnEnd = SciCall_PositionFromLine(iLineSelLast) + SciCall_LineLength(iLineSelLast); - if (s_flagPasteBoard) { - s_bLastCopyFromMe = true; - } - _BEGIN_UNDO_ACTION_; SciCall_CopyRange(iSelLnStart, iSelLnEnd); - _END_UNDO_ACTION_; - } + } break; @@ -4516,18 +4505,15 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_EDIT_COPYADD: { - if (SciCall_IsSelectionEmpty()) { - break; - } if (Sci_IsMultiOrRectangleSelection()) { InfoBoxLng(MB_ICONWARNING, NULL, IDS_MUI_SELRECTORMULTI); break; } - DocPos const posSelStart = SciCall_GetSelectionStart(); - DocPos const posSelEnd = SciCall_GetSelectionEnd(); if (s_flagPasteBoard) { s_bLastCopyFromMe = true; } + DocPos const posSelStart = SciCall_IsSelectionEmpty() ? Sci_GetLineStartPosition(SciCall_GetSelectionStart()) : SciCall_GetSelectionStart(); + DocPos const posSelEnd = SciCall_IsSelectionEmpty() ? Sci_GetLineEndPosition(SciCall_GetSelectionEnd()) : SciCall_GetSelectionEnd(); EditCopyRangeAppend(Globals.hwndEdit, posSelStart, posSelEnd, true); } break; @@ -4538,9 +4524,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (s_flagPasteBoard) { s_bLastCopyFromMe = true; } - _BEGIN_UNDO_ACTION_; SciCall_Paste(); - _END_UNDO_ACTION_; } break; @@ -4550,9 +4534,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) if (s_flagPasteBoard) { s_bLastCopyFromMe = true; } - _BEGIN_UNDO_ACTION_; EditSwapClipboard(Globals.hwndEdit, Settings.SkipUnicodeDetection); - _END_UNDO_ACTION_; } break; @@ -4616,48 +4598,38 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_EDIT_DUPLINEORSELECTION: - _BEGIN_UNDO_ACTION_; if (SciCall_IsSelectionEmpty()) { SciCall_LineDuplicate(); } else { SciCall_SelectionDuplicate(); } - _END_UNDO_ACTION_; break; case IDM_EDIT_LINETRANSPOSE: - _BEGIN_UNDO_ACTION_; SciCall_LineTranspose(); - _END_UNDO_ACTION_; break; case IDM_EDIT_DELETELINE: { - _BEGIN_UNDO_ACTION_; SciCall_MarkerDelete(Sci_GetCurrentLineNumber(), -1); SciCall_LineDelete(); - _END_UNDO_ACTION_; } break; case IDM_EDIT_DELETELINELEFT: { - _BEGIN_UNDO_ACTION_; SciCall_DelLineLeft(); - _END_UNDO_ACTION_; } break; case IDM_EDIT_DELETELINERIGHT: { - _BEGIN_UNDO_ACTION_; SciCall_DelLineRight(); - _END_UNDO_ACTION_; } break; @@ -4698,10 +4670,8 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case CMD_DELETEBACK: { - ///~_BEGIN_UNDO_ACTION_; EditDeleteMarkerInSelection(); SciCall_DeleteBack(); - ///~_END_UNDO_ACTION_; } break; @@ -4837,20 +4807,12 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case IDM_EDIT_CONVERTUPPERCASE: - { - _BEGIN_UNDO_ACTION_; - SciCall_UpperCase(); - _END_UNDO_ACTION_; - } + SciCall_UpperCase(); break; case IDM_EDIT_CONVERTLOWERCASE: - { - _BEGIN_UNDO_ACTION_; - SciCall_LowerCase(); - _END_UNDO_ACTION_; - } + SciCall_LowerCase(); break; @@ -4948,7 +4910,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) GetLngString(IDS_MUI_UNTITLED, tchUntitled, COUNTOF(tchUntitled)); pszInsert = tchUntitled; } - SetClipboardTextW(hwnd, pszInsert, StringCchLen(pszInsert, 0)); + SetClipboardText(hwnd, pszInsert, StringCchLen(pszInsert, 0)); } break; @@ -4963,7 +4925,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) //if (WideCharToMultiByteEx(Encoding_SciCP, 0, tchMaxPathBuffer, -1, chMaxPathBuffer, COUNTOF(chMaxPathBuffer), NULL, NULL)) { // EditReplaceSelection(chMaxPathBuffer, false); //} - SetClipboardTextW(hwnd, tchMaxPathBuffer, StringCchLen(tchMaxPathBuffer, 0)); + SetClipboardText(hwnd, tchMaxPathBuffer, StringCchLen(tchMaxPathBuffer, 0)); } } } @@ -6112,9 +6074,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) } if ((!SciCall_IsSelectionEmpty() || Sci_IsMultiOrRectangleSelection()) && (skipLevel == Settings2.ExitOnESCSkipLevel)) { - //~_BEGIN_UNDO_ACTION_; Sci_GotoPosChooseCaret(iCurPos); - //~_END_UNDO_ACTION_; skipLevel -= Defaults2.ExitOnESCSkipLevel; } @@ -6584,7 +6544,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) GetLngString(IDS_MUI_UNTITLED, tchUntitled, COUNTOF(tchUntitled)); pszCopy = tchUntitled; } - SetClipboardTextW(hwnd, pszCopy, StringCchLen(pszCopy,0)); + SetClipboardText(hwnd, pszCopy, StringCchLen(pszCopy,0)); } break; @@ -6592,7 +6552,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case CMD_COPYWINPOS: { WININFO wi = GetMyWindowPlacement(Globals.hwndMain,NULL); StringCchPrintf(tchMaxPathBuffer,COUNTOF(tchMaxPathBuffer),L"/pos %i,%i,%i,%i,%i",wi.x,wi.y,wi.cx,wi.cy,wi.max); - SetClipboardTextW(hwnd, tchMaxPathBuffer, StringCchLen(tchMaxPathBuffer, 0)); + SetClipboardText(hwnd, tchMaxPathBuffer, StringCchLen(tchMaxPathBuffer, 0)); } break; @@ -7192,7 +7152,7 @@ bool HandleHotSpotURLClicked(const DocPos position, const HYPERLINK_OPS operatio if (pszEscapedW) { //~UrlEscape(szTextW, pszEscapedW, &cchEscapedW, (URL_BROWSER_MODE | URL_ESCAPE_AS_UTF8)); UrlEscapeEx(szTextW, pszEscapedW, &cchEscapedW, false); - SetClipboardTextW(Globals.hwndMain, pszEscapedW, cchEscapedW); + SetClipboardText(Globals.hwndMain, pszEscapedW, cchEscapedW); FreeMem(pszEscapedW); bHandled = true; } @@ -7385,9 +7345,7 @@ static void _HandleAutoIndent(int const charAdded) } } if (*pLineBuf) { - _BEGIN_UNDO_ACTION_; SciCall_AddText((DocPos)StringCchLenA(pLineBuf, SizeOfMem(pLineBuf)), pLineBuf); - _END_UNDO_ACTION_; } FreeMem(pLineBuf); } @@ -11217,7 +11175,7 @@ void SnapToWinInfoPos(HWND hwnd, const WININFO winInfo, SCREEN_MODE mode) static bool s_bPrevShowMenubar = true; static bool s_bPrevShowToolbar = true; static bool s_bPrevShowStatusbar = true; - static WINDOWPLACEMENT s_wndplPrev; + static WINDOWPLACEMENT s_wndplPrev = { 0 }; s_wndplPrev.length = sizeof(WINDOWPLACEMENT); UINT const fPrevFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED; diff --git a/src/SciCall.h b/src/SciCall.h index 214cf057d..5a5b1037c 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -628,6 +628,7 @@ DeclareSciCallR0(IsSelectionRectangle, SELECTIONISRECTANGLE, bool) #define Sci_GetLastDocLineNumber() (SciCall_GetLineCount() - 1) #define Sci_GetLineStartPosition(position) SciCall_PositionFromLine(SciCall_LineFromPosition(position)) +#define Sci_GetLineEndPosition(position) SciCall_GetLineEndPosition(SciCall_LineFromPosition(position)) // length of line w/o line-end chars (full use SciCall_LineLength() #define Sci_GetNetLineLength(line) (SciCall_GetLineEndPosition(line) - SciCall_PositionFromLine(line))