Improve copy functionality in find results window
Just copy the actual results, without the additional formatting with line and file name. It respects the hierarchy in the results, i.e. you can copy all results from a search operation, or from a specific file, or just the lines you selected.
This commit is contained in:
parent
54c8fd7ac8
commit
d6081a5f37
@ -777,4 +777,37 @@ double stodLocale(const generic_string& str, _locale_t loc, size_t* idx)
|
|||||||
if (idx != NULL)
|
if (idx != NULL)
|
||||||
*idx = (size_t)(eptr - ptr);
|
*idx = (size_t)(eptr - ptr);
|
||||||
return ans;
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool str2Clipboard(const TCHAR *str2cpy, HWND hwnd)
|
||||||
|
{
|
||||||
|
if (!str2cpy)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int len2Allocate = lstrlen(str2cpy) + 1;
|
||||||
|
len2Allocate *= sizeof(TCHAR);
|
||||||
|
unsigned int cilpboardFormat = CF_TEXT;
|
||||||
|
|
||||||
|
cilpboardFormat = CF_UNICODETEXT;
|
||||||
|
|
||||||
|
HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, len2Allocate);
|
||||||
|
if (hglbCopy == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!::OpenClipboard(hwnd)) //_pPublicInterface->getHSelf()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::EmptyClipboard();
|
||||||
|
|
||||||
|
// Lock the handle and copy the text to the buffer.
|
||||||
|
TCHAR *pStr = (TCHAR *)::GlobalLock(hglbCopy);
|
||||||
|
lstrcpy(pStr, str2cpy);
|
||||||
|
::GlobalUnlock(hglbCopy);
|
||||||
|
|
||||||
|
// Place the handle on the clipboard.
|
||||||
|
::SetClipboardData(cilpboardFormat, hglbCopy);
|
||||||
|
::CloseClipboard();
|
||||||
|
return true;
|
||||||
}
|
}
|
@ -198,4 +198,6 @@ generic_string stringJoin(const std::vector<generic_string>& strings, const gene
|
|||||||
generic_string stringTakeWhileAdmissable(const generic_string& input, const generic_string& admissable);
|
generic_string stringTakeWhileAdmissable(const generic_string& input, const generic_string& admissable);
|
||||||
double stodLocale(const generic_string& str, _locale_t loc, size_t* idx = NULL);
|
double stodLocale(const generic_string& str, _locale_t loc, size_t* idx = NULL);
|
||||||
|
|
||||||
|
bool str2Clipboard(const TCHAR *str2cpy, HWND hwnd);
|
||||||
|
|
||||||
#endif //M30_IDE_COMMUN_H
|
#endif //M30_IDE_COMMUN_H
|
||||||
|
@ -4557,35 +4557,7 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD
|
|||||||
|
|
||||||
bool Notepad_plus::str2Cliboard(const TCHAR *str2cpy)
|
bool Notepad_plus::str2Cliboard(const TCHAR *str2cpy)
|
||||||
{
|
{
|
||||||
if (!str2cpy)
|
return str2Clipboard(str2cpy, _pPublicInterface->getHSelf());
|
||||||
return false;
|
|
||||||
|
|
||||||
int len2Allocate = lstrlen(str2cpy) + 1;
|
|
||||||
len2Allocate *= sizeof(TCHAR);
|
|
||||||
unsigned int cilpboardFormat = CF_TEXT;
|
|
||||||
|
|
||||||
cilpboardFormat = CF_UNICODETEXT;
|
|
||||||
|
|
||||||
HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, len2Allocate);
|
|
||||||
if (hglbCopy == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!::OpenClipboard(_pPublicInterface->getHSelf()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
::EmptyClipboard();
|
|
||||||
|
|
||||||
// Lock the handle and copy the text to the buffer.
|
|
||||||
TCHAR *pStr = (TCHAR *)::GlobalLock(hglbCopy);
|
|
||||||
lstrcpy(pStr, str2cpy);
|
|
||||||
::GlobalUnlock(hglbCopy);
|
|
||||||
|
|
||||||
// Place the handle on the clipboard.
|
|
||||||
::SetClipboardData(cilpboardFormat, hglbCopy);
|
|
||||||
::CloseClipboard();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//ONLY CALL IN CASE OF EMERGENCY: EXCEPTION
|
//ONLY CALL IN CASE OF EMERGENCY: EXCEPTION
|
||||||
|
@ -2505,6 +2505,75 @@ void Finder::openAll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Finder::isLineActualSearchResult(int line)
|
||||||
|
{
|
||||||
|
const int foldLevel = _scintView.execute(SCI_GETFOLDLEVEL, line) & SC_FOLDLEVELNUMBERMASK;
|
||||||
|
return foldLevel == SC_FOLDLEVELBASE + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
generic_string Finder::prepareStringForClipboard(generic_string s)
|
||||||
|
{
|
||||||
|
// Input: a string like "\tLine 3: search result".
|
||||||
|
// Output: "search result"
|
||||||
|
s = stringReplace(s, TEXT("\r"), TEXT(""));
|
||||||
|
s = stringReplace(s, TEXT("\n"), TEXT(""));
|
||||||
|
const unsigned int firstColon = s.find(TEXT(':'));
|
||||||
|
if (firstColon == std::string::npos)
|
||||||
|
{
|
||||||
|
// Should never happen.
|
||||||
|
assert(false);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Plus 2 in order to deal with ": ".
|
||||||
|
return s.substr(2 + firstColon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finder::copy()
|
||||||
|
{
|
||||||
|
size_t fromLine, toLine;
|
||||||
|
{
|
||||||
|
const int selStart = _scintView.execute(SCI_GETSELECTIONSTART);
|
||||||
|
const int selEnd = _scintView.execute(SCI_GETSELECTIONEND);
|
||||||
|
const bool hasSelection = selStart != selEnd;
|
||||||
|
const pair<int, int> lineRange = _scintView.getSelectionLinesRange();
|
||||||
|
if (hasSelection && lineRange.first != lineRange.second)
|
||||||
|
{
|
||||||
|
fromLine = lineRange.first;
|
||||||
|
toLine = lineRange.second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Abuse fold levels to find out which lines to copy to clipboard.
|
||||||
|
// We get the current line and then the next line which has a smaller fold level (SCI_GETLASTCHILD).
|
||||||
|
// Then we loop all lines between them and determine which actually contain search results.
|
||||||
|
fromLine = _scintView.getCurrentLineNumber();
|
||||||
|
const int selectedLineFoldLevel = _scintView.execute(SCI_GETFOLDLEVEL, fromLine) & SC_FOLDLEVELNUMBERMASK;
|
||||||
|
toLine = _scintView.execute(SCI_GETLASTCHILD, fromLine, selectedLineFoldLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<generic_string> lines;
|
||||||
|
for (size_t line = fromLine; line <= toLine; ++line)
|
||||||
|
{
|
||||||
|
if (isLineActualSearchResult(line))
|
||||||
|
{
|
||||||
|
lines.push_back(prepareStringForClipboard(_scintView.getLine(line)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const generic_string toClipboard = stringJoin(lines, TEXT("\r\n"));
|
||||||
|
if (!toClipboard.empty())
|
||||||
|
{
|
||||||
|
if (!str2Clipboard(toClipboard.c_str(), _hSelf))
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
::MessageBox(NULL, TEXT("Error placing text in clipboard."), TEXT("Notepad++"), MB_ICONINFORMATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Finder::beginNewFilesSearch()
|
void Finder::beginNewFilesSearch()
|
||||||
{
|
{
|
||||||
//_scintView.execute(SCI_SETLEXER, SCLEX_NULL);
|
//_scintView.execute(SCI_SETLEXER, SCLEX_NULL);
|
||||||
@ -2617,7 +2686,7 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
case NPPM_INTERNAL_SCINTILLAFINFERCOPY :
|
case NPPM_INTERNAL_SCINTILLAFINFERCOPY :
|
||||||
{
|
{
|
||||||
_scintView.execute(SCI_COPY);
|
copy();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ public:
|
|||||||
void setFinderStyle();
|
void setFinderStyle();
|
||||||
void removeAll();
|
void removeAll();
|
||||||
void openAll();
|
void openAll();
|
||||||
|
void copy();
|
||||||
void beginNewFilesSearch();
|
void beginNewFilesSearch();
|
||||||
void finishFilesSearch(int count);
|
void finishFilesSearch(int count);
|
||||||
void gotoNextFoundResult(int direction);
|
void gotoNextFoundResult(int direction);
|
||||||
@ -177,6 +178,9 @@ private:
|
|||||||
_scintView.execute(SCI_SETREADONLY, isReadOnly);
|
_scintView.execute(SCI_SETREADONLY, isReadOnly);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool isLineActualSearchResult(int line);
|
||||||
|
generic_string prepareStringForClipboard(generic_string s);
|
||||||
|
|
||||||
static FoundInfo EmptyFoundInfo;
|
static FoundInfo EmptyFoundInfo;
|
||||||
static SearchResultMarking EmptySearchResultMarking;
|
static SearchResultMarking EmptySearchResultMarking;
|
||||||
};
|
};
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "Parameters.h"
|
#include "Parameters.h"
|
||||||
#include "Sorters.h"
|
#include "Sorters.h"
|
||||||
#include "TCHAR.h"
|
#include "TCHAR.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -1913,6 +1914,15 @@ void ScintillaEditView::showCallTip(int startPos, const TCHAR * def)
|
|||||||
execute(SCI_CALLTIPSHOW, startPos, LPARAM(defA));
|
execute(SCI_CALLTIPSHOW, startPos, LPARAM(defA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic_string ScintillaEditView::getLine(int lineNumber)
|
||||||
|
{
|
||||||
|
int lineLen = execute(SCI_LINELENGTH, lineNumber);
|
||||||
|
const int bufSize = lineLen;
|
||||||
|
std::unique_ptr<TCHAR[]> buf = std::make_unique<TCHAR[]>(bufSize);
|
||||||
|
getLine(lineNumber, buf.get(), bufSize);
|
||||||
|
return buf.get();
|
||||||
|
}
|
||||||
|
|
||||||
void ScintillaEditView::getLine(int lineNumber, TCHAR * line, int lineBufferLen)
|
void ScintillaEditView::getLine(int lineNumber, TCHAR * line, int lineBufferLen)
|
||||||
{
|
{
|
||||||
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
|
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
|
||||||
|
@ -272,6 +272,7 @@ public:
|
|||||||
int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const;
|
int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const;
|
||||||
void showAutoComletion(int lenEntered, const TCHAR * list);
|
void showAutoComletion(int lenEntered, const TCHAR * list);
|
||||||
void showCallTip(int startPos, const TCHAR * def);
|
void showCallTip(int startPos, const TCHAR * def);
|
||||||
|
generic_string getLine(int lineNumber);
|
||||||
void getLine(int lineNumber, TCHAR * line, int lineBufferLen);
|
void getLine(int lineNumber, TCHAR * line, int lineBufferLen);
|
||||||
void addText(int length, const char *buf);
|
void addText(int length, const char *buf);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user