From 9ab554a1291f83668eb728cb499f2a009b98f81a Mon Sep 17 00:00:00 2001 From: Scott Sumner <30118311+sasumner@users.noreply.github.com> Date: Thu, 17 Sep 2020 14:34:18 -0400 Subject: [PATCH] Add ability to copy marked text to the clipboard Fix #6095, close #8867 --- PowerEditor/installer/nativeLang/english.xml | 4 +- PowerEditor/src/Notepad_plus.rc | 2 + PowerEditor/src/NppCommands.cpp | 10 +++ PowerEditor/src/Parameters.cpp | 1 + .../src/ScitillaComponent/FindReplaceDlg.cpp | 64 +++++++++++++++++-- .../src/ScitillaComponent/FindReplaceDlg.h | 3 +- .../src/ScitillaComponent/FindReplaceDlg.rc | 3 +- .../src/ScitillaComponent/FindReplaceDlg_rc.h | 2 + PowerEditor/src/menuCmdID.h | 1 + 9 files changed, 83 insertions(+), 7 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 8169b759..359f2d5e 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -166,6 +166,7 @@ + @@ -398,8 +399,9 @@ - + + diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 755bd885..d536233e 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -288,6 +288,8 @@ BEGIN MENUITEM "Current Full File path to Clipboard", IDM_EDIT_FULLPATHTOCLIP MENUITEM "Current Filename to Clipboard", IDM_EDIT_FILENAMETOCLIP MENUITEM "Current Dir. Path to Clipboard", IDM_EDIT_CURRENTDIRTOCLIP + MENUITEM SEPARATOR + MENUITEM "Marked Text to Clipboard", IDM_EDIT_MARKEDTOCLIP END POPUP "Indent" BEGIN diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 8ddff2cd..085bf634 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -1048,6 +1048,15 @@ void Notepad_plus::command(int id) } break; + case IDM_EDIT_MARKEDTOCLIP: + { + if (_findReplaceDlg.isCreated()) + { + _findReplaceDlg.markedTextToClipboard(SCE_UNIVERSAL_FOUND_STYLE); + } + } + break; + case IDM_SEARCH_FIND : case IDM_SEARCH_REPLACE : case IDM_SEARCH_MARK : @@ -3533,6 +3542,7 @@ void Notepad_plus::command(int id) case IDM_EDIT_FULLPATHTOCLIP : case IDM_EDIT_FILENAMETOCLIP : case IDM_EDIT_CURRENTDIRTOCLIP : + case IDM_EDIT_MARKEDTOCLIP: case IDM_EDIT_CLEARREADONLY : case IDM_EDIT_RTL : case IDM_EDIT_LTR : diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 9fbdf6ad..9b7b98fe 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -117,6 +117,7 @@ static const WinMenuKeyDefinition winKeyDefs[] = { VK_NULL, IDM_EDIT_FULLPATHTOCLIP, false, false, false, nullptr }, { VK_NULL, IDM_EDIT_FILENAMETOCLIP, false, false, false, nullptr }, { VK_NULL, IDM_EDIT_CURRENTDIRTOCLIP, false, false, false, nullptr }, + { VK_NULL, IDM_EDIT_MARKEDTOCLIP, false, false, false, nullptr }, { VK_NULL, IDM_EDIT_INS_TAB, false, false, false, nullptr }, { VK_NULL, IDM_EDIT_RMV_TAB, false, false, false, nullptr }, { VK_U, IDM_EDIT_UPPERCASE, true, false, true, nullptr }, diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index 9262b9de..c1b905f6 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -794,7 +794,7 @@ void FindReplaceDlg::resizeDialogElements(LONG newWidth) IDD_FINDINFILES_BROWSE_BUTTON, IDCMARKALL, IDC_CLEAR_ALL, IDCCOUNTALL, IDC_FINDALL_OPENEDFILES, IDC_FINDALL_CURRENTFILE, IDREPLACE, IDREPLACEALL,IDC_REPLACE_OPENEDFILES, IDD_FINDINFILES_FIND_BUTTON, IDD_FINDINFILES_REPLACEINFILES, IDOK, IDCANCEL, - IDC_FINDPREV, IDC_FINDNEXT, IDC_2_BUTTONS_MODE + IDC_FINDPREV, IDC_FINDNEXT, IDC_2_BUTTONS_MODE, IDC_COPY_MARKED_TEXT }; const UINT flags = SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS; @@ -900,8 +900,8 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM RECT arc; ::GetWindowRect(::GetDlgItem(_hSelf, IDCANCEL), &arc); - _findInFilesClosePos.bottom = _replaceClosePos.bottom = _findClosePos.bottom = arc.bottom - arc.top; - _findInFilesClosePos.right = _replaceClosePos.right = _findClosePos.right = arc.right - arc.left; + _markClosePos.bottom = _findInFilesClosePos.bottom = _replaceClosePos.bottom = _findClosePos.bottom = arc.bottom - arc.top; + _markClosePos.right = _findInFilesClosePos.right = _replaceClosePos.right = _findClosePos.right = arc.right - arc.left; POINT p; p.x = arc.left; @@ -916,6 +916,10 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM _findInFilesClosePos.left = p.x; _findInFilesClosePos.top = p.y; + p = getTopPoint(::GetDlgItem(_hSelf, IDC_REPLACE_OPENEDFILES), !_isRTL); + _markClosePos.left = p.x; + _markClosePos.top = p.y; + p = getTopPoint(::GetDlgItem(_hSelf, IDCANCEL), !_isRTL); _findClosePos.left = p.x; _findClosePos.top = p.y + 10; @@ -1453,6 +1457,13 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM } } return TRUE; + + case IDC_COPY_MARKED_TEXT: + { + markedTextToClipboard(SCE_UNIVERSAL_FOUND_STYLE); + } + return TRUE; + //Option actions case IDREDOTMATCHNL: findHistory._dotMatchesNewline = _options._dotMatchesNewline = isCheckedOrNot(IDREDOTMATCHNL); @@ -2669,6 +2680,7 @@ void FindReplaceDlg::enableMarkAllControls(bool isEnable) showFindDlgItem(IDC_PURGE_CHECK, isEnable); showFindDlgItem(IDC_CLEAR_ALL, isEnable); showFindDlgItem(IDC_IN_SELECTION_CHECK, isEnable); + showFindDlgItem(IDC_COPY_MARKED_TEXT, isEnable); } void FindReplaceDlg::enableFindInFilesControls(bool isEnable) @@ -2701,7 +2713,8 @@ void FindReplaceDlg::enableFindInFilesControls(bool isEnable) showFindDlgItem(IDC_IN_SELECTION_CHECK, !isEnable); showFindDlgItem(IDC_CLEAR_ALL, !isEnable); showFindDlgItem(IDCMARKALL, !isEnable); - + showFindDlgItem(IDC_COPY_MARKED_TEXT, !isEnable); + showFindDlgItem(IDREPLACE, !isEnable); showFindDlgItem(IDC_REPLACEINSELECTION, !isEnable); showFindDlgItem(IDREPLACEALL, !isEnable); @@ -3258,6 +3271,7 @@ void FindReplaceDlg::enableMarkFunc() ::MoveWindow(::GetDlgItem(_hSelf, IDCANCEL), _findInFilesClosePos.left + _deltaWidth, _findInFilesClosePos.top, _findInFilesClosePos.right, _findInFilesClosePos.bottom, TRUE); ::MoveWindow(::GetDlgItem(_hSelf, IDC_IN_SELECTION_CHECK), _replaceInSelCheckPos.left + _deltaWidth, _replaceInSelCheckPos.top, _replaceInSelCheckPos.right, _replaceInSelCheckPos.bottom, TRUE); ::MoveWindow(::GetDlgItem(_hSelf, IDC_REPLACEINSELECTION), _replaceInSelFramePos.left + _deltaWidth, _replaceInSelFramePos.top, _replaceInSelFramePos.right, _replaceInSelFramePos.bottom, TRUE); + ::MoveWindow(::GetDlgItem(_hSelf, IDCANCEL), _markClosePos.left + _deltaWidth, _markClosePos.top, _markClosePos.right, _markClosePos.bottom, TRUE); TCHAR label[MAX_PATH]; _tab.getCurrentTitle(label, MAX_PATH); @@ -3392,6 +3406,48 @@ bool FindReplaceDlg::replaceInOpenDocsConfirmCheck(void) return confirmed; } +void FindReplaceDlg::markedTextToClipboard(int indiStyle) +{ + auto pos = (*_ppEditView)->execute(SCI_INDICATOREND, indiStyle, 0); + if (pos > 0) + { + std::vector markedTextStr; + bool atEndOfIndic = (*_ppEditView)->execute(SCI_INDICATORVALUEAT, indiStyle, 0) != 0; + auto prevPos = pos; + if (atEndOfIndic) prevPos = 0; + + const generic_string cr = TEXT("\r"); + const generic_string lf = TEXT("\n"); + bool dataHasLineEndingChar = false; + + do + { + if (atEndOfIndic) + { + generic_string s = (*_ppEditView)->getGenericTextAsString(prevPos, pos); + if (!dataHasLineEndingChar) + { + if (s.find(cr) != std::string::npos || s.find(lf) != std::string::npos) + { + dataHasLineEndingChar = true; + } + } + markedTextStr.push_back(s); + } + atEndOfIndic = !atEndOfIndic; + prevPos = pos; + pos = (*_ppEditView)->execute(SCI_INDICATOREND, indiStyle, pos); + } while (pos != prevPos); + + if (markedTextStr.size() > 0) + { + const generic_string delim = dataHasLineEndingChar ? TEXT("\r\n----\r\n") : TEXT("\r\n"); + generic_string joined = stringJoin(markedTextStr, delim) + delim; + str2Clipboard(joined, NULL); + } + } +} + generic_string Finder::getHitsString(int count) const { NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h index 2d6ea6aa..2b3595a3 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.h @@ -340,6 +340,7 @@ public : generic_string getScopeInfoForStatusBar(FindOption const *pFindOpt) const; Finder * createFinder(); bool removeFinder(Finder *finder2remove); + void markedTextToClipboard(int indiStyle); protected : void resizeDialogElements(LONG newWidth); @@ -360,7 +361,7 @@ private : LONG _initialClientWidth; DIALOG_TYPE _currentStatus; - RECT _findClosePos, _replaceClosePos, _findInFilesClosePos; + RECT _findClosePos, _replaceClosePos, _findInFilesClosePos, _markClosePos; RECT _countInSelFramePos, _replaceInSelFramePos; RECT _countInSelCheckPos, _replaceInSelCheckPos; diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc index 0f0dd15a..b432b597 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.rc @@ -71,7 +71,7 @@ BEGIN PUSHBUTTON "", IDC_FINDPREV, 268, 20, 18, 14, WS_GROUP | BS_MULTILINE PUSHBUTTON "", IDC_FINDNEXT, 289, 20, 70, 14, WS_GROUP | BS_MULTILINE PUSHBUTTON "Find Next",IDOK,268,20,91,14,WS_GROUP - CONTROL "", IDC_2_BUTTONS_MODE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 363, 20, 15, 15 + CONTROL "", IDC_2_BUTTONS_MODE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 363, 20, 15, 15 PUSHBUTTON "Coun&t",IDCCOUNTALL,268,38,91,14 PUSHBUTTON "Find All in Current &Document",IDC_FINDALL_CURRENTFILE,268,56,91,21,BS_MULTILINE PUSHBUTTON "Find All in All &Opened Documents",IDC_FINDALL_OPENEDFILES,268,80,91,21,BS_MULTILINE @@ -80,6 +80,7 @@ BEGIN PUSHBUTTON "Replace All in All Opened Doc&uments",IDC_REPLACE_OPENEDFILES,268,74,91,21,BS_MULTILINE PUSHBUTTON "Find All",IDD_FINDINFILES_FIND_BUTTON,268,20,91,14,WS_GROUP PUSHBUTTON "Replace in Files",IDD_FINDINFILES_REPLACEINFILES,268,38,91,14 + PUSHBUTTON "Copy Marked Text",IDC_COPY_MARKED_TEXT,268,56,91,14 PUSHBUTTON "Close",IDCANCEL,268,98,91,14 GROUPBOX "",IDC_TRANSPARENT_GRPBOX,258,131,99,48 CONTROL "Transparenc&y",IDC_TRANSPARENT_CHECK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,254,131,80,10 diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h index 39c62902..d1509ca2 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg_rc.h @@ -138,4 +138,6 @@ #define IDC_FINDNEXT 1723 #define IDC_2_BUTTONS_MODE 1724 +#define IDC_COPY_MARKED_TEXT 1725 + #endif //FINDREPLACE_DLG_H diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 2efc2245..6af9a447 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -168,6 +168,7 @@ #define IDM_EDIT_FULLPATHTOCLIP (IDM_EDIT + 29) #define IDM_EDIT_FILENAMETOCLIP (IDM_EDIT + 30) #define IDM_EDIT_CURRENTDIRTOCLIP (IDM_EDIT + 31) + #define IDM_EDIT_MARKEDTOCLIP (IDM_EDIT + 79) // Menu macro #define IDM_MACRO_RUNMULTIMACRODLG (IDM_EDIT + 32)