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:
Andreas Jönsson 2015-06-01 18:39:22 +02:00
parent 54c8fd7ac8
commit d6081a5f37
7 changed files with 121 additions and 30 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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