Merge pull request #150 from andreas-jonsson/finder_copy2
[ENHANCEMENT] Improve copy found lines to clipboard.
This commit is contained in:
commit
ed8a51334d
@ -778,3 +778,50 @@ double stodLocale(const generic_string& str, _locale_t loc, size_t* idx)
|
||||
*idx = (size_t)(eptr - ptr);
|
||||
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);
|
||||
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
|
||||
|
@ -1933,7 +1933,7 @@ void Notepad_plus::copyMarkedLines()
|
||||
globalStr = currentStr;
|
||||
}
|
||||
}
|
||||
str2Cliboard(globalStr.c_str());
|
||||
str2Cliboard(globalStr);
|
||||
}
|
||||
|
||||
void Notepad_plus::cutMarkedLines()
|
||||
@ -1953,7 +1953,7 @@ void Notepad_plus::cutMarkedLines()
|
||||
}
|
||||
}
|
||||
_pEditView->execute(SCI_ENDUNDOACTION);
|
||||
str2Cliboard(globalStr.c_str());
|
||||
str2Cliboard(globalStr);
|
||||
}
|
||||
|
||||
void Notepad_plus::deleteMarkedLines(bool isMarked)
|
||||
@ -4555,37 +4555,9 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD
|
||||
_invisibleEditView.execute(SCI_SETDOCPOINTER, 0, oldDoc);
|
||||
}
|
||||
|
||||
bool Notepad_plus::str2Cliboard(const TCHAR *str2cpy)
|
||||
bool Notepad_plus::str2Cliboard(const generic_string & str2cpy)
|
||||
{
|
||||
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(_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;
|
||||
return str2Clipboard(str2cpy, _pPublicInterface->getHSelf());
|
||||
}
|
||||
|
||||
//ONLY CALL IN CASE OF EMERGENCY: EXCEPTION
|
||||
|
@ -599,7 +599,7 @@ private:
|
||||
|
||||
void doSynScorll(HWND hW);
|
||||
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 getIntegralDockingData(tTbData & dockData, int & iCont, bool & isVisible);
|
||||
|
@ -676,7 +676,7 @@ void Notepad_plus::command(int id)
|
||||
{
|
||||
generic_string dir(buf->getFullPathName());
|
||||
PathRemoveFileSpec(dir);
|
||||
str2Cliboard(dir.c_str());
|
||||
str2Cliboard(dir);
|
||||
}
|
||||
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()
|
||||
{
|
||||
//_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 :
|
||||
{
|
||||
_scintView.execute(SCI_COPY);
|
||||
copy();
|
||||
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(0, TEXT("Separator")));
|
||||
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_SCINTILLAFINFERCLEARALL, TEXT("Clear 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(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);
|
||||
|
||||
|
@ -144,6 +144,7 @@ public:
|
||||
void setFinderStyle();
|
||||
void removeAll();
|
||||
void openAll();
|
||||
void copy();
|
||||
void beginNewFilesSearch();
|
||||
void finishFilesSearch(int count);
|
||||
void gotoNextFoundResult(int direction);
|
||||
@ -177,6 +178,9 @@ private:
|
||||
_scintView.execute(SCI_SETREADONLY, isReadOnly);
|
||||
};
|
||||
|
||||
bool isLineActualSearchResult(int line) const;
|
||||
generic_string prepareStringForClipboard(generic_string s) const;
|
||||
|
||||
static FoundInfo EmptyFoundInfo;
|
||||
static SearchResultMarking EmptySearchResultMarking;
|
||||
};
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "Parameters.h"
|
||||
#include "Sorters.h"
|
||||
#include "TCHAR.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -1913,11 +1914,22 @@ void ScintillaEditView::showCallTip(int startPos, const TCHAR * def)
|
||||
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)
|
||||
{
|
||||
WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance();
|
||||
unsigned int cp = execute(SCI_GETCODEPAGE);
|
||||
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);
|
||||
const TCHAR *lineW = wmc->char2wchar(lineA, cp);
|
||||
lstrcpyn(line, lineW, lineBufferLen);
|
||||
|
@ -272,6 +272,7 @@ public:
|
||||
int replaceTargetRegExMode(const TCHAR * re, int fromTargetPos = -1, int toTargetPos = -1) const;
|
||||
void showAutoComletion(int lenEntered, const TCHAR * list);
|
||||
void showCallTip(int startPos, const TCHAR * def);
|
||||
generic_string getLine(int lineNumber);
|
||||
void getLine(int lineNumber, TCHAR * line, int lineBufferLen);
|
||||
void addText(int length, const char *buf);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user