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)