Merge pull request #150 from andreas-jonsson/finder_copy2
[ENHANCEMENT] Improve copy found lines to clipboard.
This commit is contained in:
commit
ed8a51334d
@ -777,4 +777,51 @@ 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 generic_string &str2cpy, HWND hwnd)
|
||||||
|
{
|
||||||
|
int len2Allocate = (str2cpy.size() + 1) * sizeof(TCHAR);
|
||||||
|
HGLOBAL hglbCopy = ::GlobalAlloc(GMEM_MOVEABLE, len2Allocate);
|
||||||
|
if (hglbCopy == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!::OpenClipboard(hwnd))
|
||||||
|
{
|
||||||
|
::GlobalFree(hglbCopy);
|
||||||
|
::CloseClipboard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!::EmptyClipboard())
|
||||||
|
{
|
||||||
|
::GlobalFree(hglbCopy);
|
||||||
|
::CloseClipboard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Lock the handle and copy the text to the buffer.
|
||||||
|
TCHAR *pStr = (TCHAR *)::GlobalLock(hglbCopy);
|
||||||
|
if (pStr == NULL)
|
||||||
|
{
|
||||||
|
::GlobalUnlock(hglbCopy);
|
||||||
|
::GlobalFree(hglbCopy);
|
||||||
|
::CloseClipboard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_tcscpy_s(pStr, len2Allocate / sizeof(TCHAR), str2cpy.c_str());
|
||||||
|
::GlobalUnlock(hglbCopy);
|
||||||
|
// Place the handle on the clipboard.
|
||||||
|
unsigned int clipBoardFormat = CF_UNICODETEXT;
|
||||||
|
if (::SetClipboardData(clipBoardFormat, hglbCopy) == NULL)
|
||||||
|
{
|
||||||
|
::GlobalUnlock(hglbCopy);
|
||||||
|
::GlobalFree(hglbCopy);
|
||||||
|
::CloseClipboard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!::CloseClipboard())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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 generic_string &str2cpy, HWND hwnd);
|
||||||
|
|
||||||
#endif //M30_IDE_COMMUN_H
|
#endif //M30_IDE_COMMUN_H
|
||||||
|
@ -1933,7 +1933,7 @@ void Notepad_plus::copyMarkedLines()
|
|||||||
globalStr = currentStr;
|
globalStr = currentStr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str2Cliboard(globalStr.c_str());
|
str2Cliboard(globalStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notepad_plus::cutMarkedLines()
|
void Notepad_plus::cutMarkedLines()
|
||||||
@ -1953,7 +1953,7 @@ void Notepad_plus::cutMarkedLines()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_pEditView->execute(SCI_ENDUNDOACTION);
|
_pEditView->execute(SCI_ENDUNDOACTION);
|
||||||
str2Cliboard(globalStr.c_str());
|
str2Cliboard(globalStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notepad_plus::deleteMarkedLines(bool isMarked)
|
void Notepad_plus::deleteMarkedLines(bool isMarked)
|
||||||
@ -4555,37 +4555,9 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD
|
|||||||
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
|
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notepad_plus::str2Cliboard(const TCHAR *str2cpy)
|
bool Notepad_plus::str2Cliboard(const generic_string & 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
|
||||||
|
@ -599,7 +599,7 @@ private:
|
|||||||
|
|
||||||
void doSynScorll(HWND hW);
|
void doSynScorll(HWND hW);
|
||||||
void setWorkingDir(const TCHAR *dir);
|
void setWorkingDir(const TCHAR *dir);
|
||||||
bool str2Cliboard(const TCHAR *str2cpy);
|
bool str2Cliboard(const generic_string & str2cpy);
|
||||||
bool bin2Cliboard(const UCHAR *uchar2cpy, size_t length);
|
bool bin2Cliboard(const UCHAR *uchar2cpy, size_t length);
|
||||||
|
|
||||||
bool getIntegralDockingData(tTbData & dockData, int & iCont, bool & isVisible);
|
bool getIntegralDockingData(tTbData & dockData, int & iCont, bool & isVisible);
|
||||||
|
@ -676,7 +676,7 @@ void Notepad_plus::command(int id)
|
|||||||
{
|
{
|
||||||
generic_string dir(buf->getFullPathName());
|
generic_string dir(buf->getFullPathName());
|
||||||
PathRemoveFileSpec(dir);
|
PathRemoveFileSpec(dir);
|
||||||
str2Cliboard(dir.c_str());
|
str2Cliboard(dir);
|
||||||
}
|
}
|
||||||
else if (id == IDM_EDIT_FILENAMETOCLIP)
|
else if (id == IDM_EDIT_FILENAMETOCLIP)
|
||||||
{
|
{
|
||||||
|
@ -2505,6 +2505,75 @@ void Finder::openAll()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Finder::isLineActualSearchResult(int line) const
|
||||||
|
{
|
||||||
|
const int foldLevel = _scintView.execute(SCI_GETFOLDLEVEL, line) & SC_FOLDLEVELNUMBERMASK;
|
||||||
|
return foldLevel == SC_FOLDLEVELBASE + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
generic_string Finder::prepareStringForClipboard(generic_string s) const
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2658,10 +2727,10 @@ BOOL CALLBACK Finder::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE, TEXT("Uncollapse all")));
|
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERUNCOLLAPSE, TEXT("Uncollapse all")));
|
||||||
tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
|
tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
|
||||||
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy")));
|
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCOPY, TEXT("Copy")));
|
||||||
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select All")));
|
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERSELECTALL, TEXT("Select all")));
|
||||||
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCLEARALL, TEXT("Clear All")));
|
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFERCLEARALL, TEXT("Clear all")));
|
||||||
tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
|
tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
|
||||||
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFEROPENALL, TEXT("Open All")));
|
tmp.push_back(MenuItemUnit(NPPM_INTERNAL_SCINTILLAFINFEROPENALL, TEXT("Open all")));
|
||||||
|
|
||||||
scintillaContextmenu.create(_hSelf, tmp);
|
scintillaContextmenu.create(_hSelf, tmp);
|
||||||
|
|
||||||
|
@ -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) const;
|
||||||
|
generic_string prepareStringForClipboard(generic_string s) const;
|
||||||
|
|
||||||
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,11 +1914,22 @@ 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 + 1;
|
||||||
|
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();
|
||||||
unsigned int cp = execute(SCI_GETCODEPAGE);
|
unsigned int cp = execute(SCI_GETCODEPAGE);
|
||||||
char *lineA = new char[lineBufferLen];
|
char *lineA = new char[lineBufferLen];
|
||||||
|
// From Scintilla documentation for SCI_GETLINE: "The buffer is not terminated by a 0 character."
|
||||||
|
memset(lineA, '\0', sizeof(char) * lineBufferLen);
|
||||||
execute(SCI_GETLINE, lineNumber, (LPARAM)lineA);
|
execute(SCI_GETLINE, lineNumber, (LPARAM)lineA);
|
||||||
const TCHAR *lineW = wmc->char2wchar(lineA, cp);
|
const TCHAR *lineW = wmc->char2wchar(lineA, cp);
|
||||||
lstrcpyn(line, lineW, lineBufferLen);
|
lstrcpyn(line, lineW, lineBufferLen);
|
||||||
|
@ -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