mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-11 21:03:05 +08:00
+upd: grepWinNP3 update to ver 2.1.13.
This commit is contained in:
parent
1795dee126
commit
820fb66b3a
@ -521,16 +521,16 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Import Project="..\packages\boost.1.80.0\build\boost.targets" Condition="Exists('..\packages\boost.1.80.0\build\boost.targets')" />
|
||||
<Import Project="..\packages\boost_iostreams-vc143.1.80.0\build\boost_iostreams-vc143.targets" Condition="Exists('..\packages\boost_iostreams-vc143.1.80.0\build\boost_iostreams-vc143.targets')" />
|
||||
<Import Project="..\packages\boost_regex-vc143.1.80.0\build\boost_regex-vc143.targets" Condition="Exists('..\packages\boost_regex-vc143.1.80.0\build\boost_regex-vc143.targets')" />
|
||||
<Import Project="..\packages\boost.1.81.0\build\boost.targets" Condition="Exists('..\packages\boost.1.81.0\build\boost.targets')" />
|
||||
<Import Project="..\packages\boost_iostreams-vc143.1.81.0\build\boost_iostreams-vc143.targets" Condition="Exists('..\packages\boost_iostreams-vc143.1.81.0\build\boost_iostreams-vc143.targets')" />
|
||||
<Import Project="..\packages\boost_regex-vc143.1.81.0\build\boost_regex-vc143.targets" Condition="Exists('..\packages\boost_regex-vc143.1.81.0\build\boost_regex-vc143.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\boost.1.80.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.80.0\build\boost.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\boost_iostreams-vc143.1.80.0\build\boost_iostreams-vc143.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_iostreams-vc143.1.80.0\build\boost_iostreams-vc143.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\boost_regex-vc143.1.80.0\build\boost_regex-vc143.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_regex-vc143.1.80.0\build\boost_regex-vc143.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\boost.1.81.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost.1.81.0\build\boost.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\boost_iostreams-vc143.1.81.0\build\boost_iostreams-vc143.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_iostreams-vc143.1.81.0\build\boost_iostreams-vc143.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\boost_regex-vc143.1.81.0\build\boost_regex-vc143.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\boost_regex-vc143.1.81.0\build\boost_regex-vc143.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="boost" version="1.80.0" targetFramework="native" />
|
||||
<package id="boost_iostreams-vc143" version="1.80.0" targetFramework="native" />
|
||||
<package id="boost_regex-vc143" version="1.80.0" targetFramework="native" />
|
||||
<package id="boost" version="1.81.0" targetFramework="native" />
|
||||
<package id="boost_iostreams-vc143" version="1.81.0" targetFramework="native" />
|
||||
<package id="boost_regex-vc143" version="1.81.0" targetFramework="native" />
|
||||
</packages>
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2011-2012, 2014-2015, 2021 - Stefan Kueng
|
||||
// Copyright (C) 2011-2012, 2014-2015, 2021, 2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -21,11 +21,12 @@
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "StringUtils.h"
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996) // warning STL4010: Various members of std::allocator are deprecated in C++17
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/spirit/include/classic_file_iterator.hpp>
|
||||
#include <boost/iostreams/device/mapped_file.hpp>
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
class NumberReplacer
|
||||
@ -160,7 +161,7 @@ public:
|
||||
if ((itBegin == sReplace.begin()) || ((*(itBegin - 1)) != '\\'))
|
||||
{
|
||||
auto itEnd = itBegin + it->expression.size();
|
||||
wchar_t format[10] = {0};
|
||||
wchar_t format[20] = {0};
|
||||
if (it->padding)
|
||||
{
|
||||
if (it->leadZero)
|
||||
@ -170,9 +171,18 @@ public:
|
||||
}
|
||||
else
|
||||
wcscpy_s(format, L"%d");
|
||||
wchar_t buf[50] = {0};
|
||||
if (it->padding < 50)
|
||||
{
|
||||
// for small strings, reserve space on the stack
|
||||
wchar_t buf[128] = {0};
|
||||
swprintf_s(buf, _countof(buf), format, it->start);
|
||||
sReplace.replace(itBegin, itEnd, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = CStringUtils::Format(format, it->start);
|
||||
sReplace.replace(itBegin, itEnd, s);
|
||||
}
|
||||
it->start += it->increment;
|
||||
}
|
||||
else if ((*(itBegin - 1)) == '\\')
|
||||
@ -287,7 +297,7 @@ public:
|
||||
if ((itBegin == sReplace.begin()) || ((*(itBegin - 1)) != '\\'))
|
||||
{
|
||||
auto itEnd = itBegin + it->expression.size();
|
||||
char format[10] = {0};
|
||||
char format[20] = {0};
|
||||
if (it->padding)
|
||||
{
|
||||
if (it->leadZero)
|
||||
@ -297,9 +307,18 @@ public:
|
||||
}
|
||||
else
|
||||
strcpy_s(format, "%d");
|
||||
char buf[50] = {0};
|
||||
if (it->padding < 50)
|
||||
{
|
||||
// for small strings, reserve space on the stack
|
||||
char buf[128] = {0};
|
||||
sprintf_s(buf, _countof(buf), format, it->start);
|
||||
sReplace.replace(itBegin, itEnd, buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto s = CStringUtils::Format(format, it->start);
|
||||
sReplace.replace(itBegin, itEnd, s);
|
||||
}
|
||||
it->start += it->increment;
|
||||
}
|
||||
else if ((*(itBegin - 1)) == '\\')
|
||||
|
||||
Binary file not shown.
BIN
grepWinNP3/src/Resources/grepWin_orig.rc
Normal file
BIN
grepWinNP3/src/Resources/grepWin_orig.rc
Normal file
Binary file not shown.
@ -143,6 +143,7 @@ CSearchDlg::CSearchDlg(HWND hParent)
|
||||
: m_hParent(hParent)
|
||||
//, m_dwThreadRunning(FALSE)
|
||||
//, m_cancelled(FALSE)
|
||||
, m_bBlockUpdate(false)
|
||||
, m_bookmarksDlg(nullptr)
|
||||
, m_patternRegexC(false)
|
||||
, m_excludeDirsPatternRegexC(false)
|
||||
@ -743,11 +744,8 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
return DoCommand(LOWORD(wParam), HIWORD(wParam));
|
||||
case WM_CONTEXTMENU:
|
||||
{
|
||||
if (reinterpret_cast<HWND>(wParam) == GetDlgItem(*this, IDC_RESULTLIST))
|
||||
{
|
||||
ShowContextMenu(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
ShowContextMenu(reinterpret_cast<HWND>(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
@ -2101,62 +2099,206 @@ void CSearchDlg::FillResultList()
|
||||
RedrawWindow(hListControl, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
|
||||
void CSearchDlg::ShowContextMenu(int x, int y)
|
||||
void CSearchDlg::ShowContextMenu(HWND hWnd, int x, int y)
|
||||
{
|
||||
HWND hListControl = GetDlgItem(*this, IDC_RESULTLIST);
|
||||
if (hWnd != GetDlgItem(*this, IDC_RESULTLIST))
|
||||
return;
|
||||
bool fileList = (IsDlgButtonChecked(*this, IDC_RESULTFILES) == BST_CHECKED);
|
||||
// check if clicked on a header
|
||||
POINT pt = {x, y};
|
||||
auto hHeader = ListView_GetHeader(hListControl);
|
||||
RECT headerRc{};
|
||||
GetWindowRect(hHeader, &headerRc);
|
||||
if (PtInRect(&headerRc, pt))
|
||||
{
|
||||
int colCount = Header_GetItemCount(hHeader);
|
||||
int clickedCol = -1;
|
||||
for (int i = 0; i < colCount; ++i)
|
||||
{
|
||||
RECT iRc{};
|
||||
Header_GetItemRect(hHeader, i, &iRc);
|
||||
MapWindowPoints(hHeader, nullptr, reinterpret_cast<LPPOINT>(&iRc), 2);
|
||||
if (PtInRect(&iRc, pt))
|
||||
{
|
||||
clickedCol = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (clickedCol >= 0)
|
||||
{
|
||||
HMENU hMenu = CreatePopupMenu();
|
||||
if (hMenu)
|
||||
{
|
||||
OnOutOfScope(DestroyMenu(hMenu));
|
||||
auto sCopyColumn = TranslatedString(hResource, IDS_COPY_COLUMN);
|
||||
AppendMenu(hMenu, MF_STRING, 1, sCopyColumn.c_str());
|
||||
// Display the menu.
|
||||
auto cmdId = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, *this, nullptr);
|
||||
if (cmdId == 1)
|
||||
{
|
||||
int iItem = -1;
|
||||
std::wstring copyText;
|
||||
auto sReadError = TranslatedString(hResource, IDS_READERROR);
|
||||
while ((iItem = ListView_GetNextItem(hListControl, iItem, LVNI_ALL)) != (-1))
|
||||
{
|
||||
int selIndex = GetSelectedListIndex(fileList, iItem);
|
||||
if ((selIndex < 0) || (selIndex >= static_cast<int>(m_items.size())))
|
||||
continue;
|
||||
if (!copyText.empty())
|
||||
copyText += L"\r\n";
|
||||
if (fileList)
|
||||
{
|
||||
const auto* pInfo = &m_items[selIndex];
|
||||
switch (clickedCol)
|
||||
{
|
||||
case 0: // name of the file
|
||||
copyText += pInfo->filePath.substr(pInfo->filePath.find_last_of('\\') + 1);
|
||||
break;
|
||||
case 1: // file size
|
||||
if (!pInfo->folder)
|
||||
{
|
||||
wchar_t buf[1024]{};
|
||||
StrFormatByteSizeW(pInfo->fileSize, buf, _countof(buf));
|
||||
copyText += buf;
|
||||
}
|
||||
break;
|
||||
case 2: // match count or read error
|
||||
if (pInfo->readError)
|
||||
copyText += sReadError.c_str();
|
||||
else
|
||||
copyText += std::to_wstring(pInfo->matchCount);
|
||||
break;
|
||||
case 3: // path
|
||||
if (m_searchPath.find('|') != std::wstring::npos)
|
||||
copyText += pInfo->filePath.substr(0, pInfo->filePath.size() - pInfo->filePath.substr(pInfo->filePath.find_last_of('\\')).size());
|
||||
else
|
||||
{
|
||||
auto filePart = pInfo->filePath.substr(pInfo->filePath.find_last_of('\\'));
|
||||
auto len = pInfo->filePath.size() - m_searchPath.size() - filePart.size();
|
||||
if (len > 0)
|
||||
--len;
|
||||
if (m_searchPath.size() < pInfo->filePath.size())
|
||||
{
|
||||
auto text = pInfo->filePath.substr(m_searchPath.size() + 1, len);
|
||||
if (text.empty())
|
||||
text = L"\\.";
|
||||
copyText += text;
|
||||
}
|
||||
else
|
||||
copyText += pInfo->filePath.c_str();
|
||||
}
|
||||
break;
|
||||
case 4: // extension of the file
|
||||
{
|
||||
if (!pInfo->folder)
|
||||
{
|
||||
auto dotPos = pInfo->filePath.find_last_of('.');
|
||||
if (dotPos != std::wstring::npos)
|
||||
{
|
||||
if (pInfo->filePath.find('\\', dotPos) == std::wstring::npos)
|
||||
copyText += pInfo->filePath.substr(dotPos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5: // encoding
|
||||
copyText += CTextFile::GetEncodingString(pInfo->encoding);
|
||||
break;
|
||||
case 6: // modification date
|
||||
{
|
||||
wchar_t buf[1024]{};
|
||||
FormatDate(buf, pInfo->modifiedTime, true);
|
||||
copyText += buf;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tup = m_listItems[iItem];
|
||||
auto index = std::get<0>(tup);
|
||||
auto subIndex = std::get<1>(tup);
|
||||
const auto& item = m_items[index];
|
||||
const auto& pInfo = &item;
|
||||
switch (clickedCol)
|
||||
{
|
||||
case 0: // name of the file
|
||||
copyText += pInfo->filePath.substr(pInfo->filePath.find_last_of('\\') + 1);
|
||||
break;
|
||||
case 1: // line number
|
||||
copyText += std::to_wstring(pInfo->matchLinesNumbers[subIndex]);
|
||||
break;
|
||||
case 2: // line
|
||||
{
|
||||
std::wstring line;
|
||||
if (pInfo->matchLines.size() > static_cast<size_t>(subIndex))
|
||||
{
|
||||
line = pInfo->matchLines[subIndex];
|
||||
std::ranges::replace(line, '\n', ' ');
|
||||
std::ranges::replace(line, '\r', ' ');
|
||||
}
|
||||
copyText += line;
|
||||
}
|
||||
break;
|
||||
case 3: // path
|
||||
copyText += pInfo->filePath.substr(0, pInfo->filePath.size() - pInfo->filePath.substr(pInfo->filePath.find_last_of('\\') + 1).size() - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
WriteAsciiStringToClipboard(copyText.c_str(), *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nCount = ListView_GetItemCount(hListControl);
|
||||
if (nCount == 0)
|
||||
return;
|
||||
CShellContextMenu shellMenu;
|
||||
int iItem = -1;
|
||||
std::vector<CSearchInfo> paths;
|
||||
std::unordered_map<size_t, std::wstring> pathMap;
|
||||
|
||||
while ((iItem = ListView_GetNextItem(hListControl, iItem, LVNI_SELECTED)) != (-1))
|
||||
{
|
||||
int selIndex = GetSelectedListIndex(iItem);
|
||||
int selIndex = GetSelectedListIndex(fileList, iItem);
|
||||
if ((selIndex < 0) || (selIndex >= static_cast<int>(m_items.size())))
|
||||
continue;
|
||||
paths.push_back(m_items[selIndex]);
|
||||
pathMap[selIndex] = m_items[selIndex].filePath;
|
||||
}
|
||||
|
||||
if (paths.empty())
|
||||
if (pathMap.empty())
|
||||
return;
|
||||
|
||||
std::vector<LineData> lines;
|
||||
bool fileList = (IsDlgButtonChecked(*this, IDC_RESULTFILES) == BST_CHECKED);
|
||||
if (!fileList)
|
||||
{
|
||||
WCHAR numBuf[40] = {0};
|
||||
while ((iItem = ListView_GetNextItem(hListControl, iItem, LVNI_SELECTED)) != (-1))
|
||||
{
|
||||
ListView_GetItemText(hListControl, iItem, 1, numBuf, 40);
|
||||
DWORD line = _wtoi(numBuf);
|
||||
if (line)
|
||||
for (const auto& idx : pathMap | std::views::keys)
|
||||
{
|
||||
LineData data;
|
||||
const CSearchInfo info = m_items[GetSelectedListIndex(iItem)];
|
||||
data.path = info.filePath;
|
||||
const auto matchLinesNumbers = info.matchLinesNumbers;
|
||||
size_t lineIndex = 0;
|
||||
for (unsigned long matchlinesnumber : matchLinesNumbers)
|
||||
{
|
||||
if (matchlinesnumber == line)
|
||||
const auto& info = m_items[idx];
|
||||
data.lines.reserve(info.matchLinesNumbers.size());
|
||||
for (size_t i = 0; i < info.matchLinesNumbers.size(); ++i)
|
||||
{
|
||||
LineDataLine dataLine;
|
||||
dataLine.number = info.matchLinesNumbers[lineIndex];
|
||||
if (info.matchLines.size() > lineIndex)
|
||||
dataLine.text = info.matchLines[lineIndex];
|
||||
if (info.matchLinesNumbers.size() > i)
|
||||
dataLine.number = info.matchLinesNumbers[i];
|
||||
if (info.matchLines.size() > i)
|
||||
dataLine.text = info.matchLines[i];
|
||||
data.lines.push_back(dataLine);
|
||||
}
|
||||
++lineIndex;
|
||||
}
|
||||
lines.push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CSearchInfo> vPaths;
|
||||
for (const auto& idx : pathMap | std::views::keys)
|
||||
{
|
||||
vPaths.push_back(m_items[idx]);
|
||||
}
|
||||
shellMenu.SetObjects(vPaths, lines);
|
||||
|
||||
shellMenu.SetObjects(paths, lines);
|
||||
|
||||
POINT pt = {x, y};
|
||||
if ((x == -1) && (y == -1))
|
||||
{
|
||||
RECT rc;
|
||||
@ -2199,11 +2341,17 @@ bool CSearchDlg::PreTranslateMessage(MSG* pMsg)
|
||||
if ((GetFocus() == hListControl) && bCtrl && !bShift && !bAlt)
|
||||
{
|
||||
// select all entries
|
||||
m_bBlockUpdate = true;
|
||||
SendMessage(hListControl, WM_SETREDRAW, FALSE, 0);
|
||||
int nCount = ListView_GetItemCount(hListControl);
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
ListView_SetItemState(hListControl, i, LVIS_SELECTED, LVIS_SELECTED);
|
||||
}
|
||||
SendMessage(hListControl, WM_SETREDRAW, TRUE, 0);
|
||||
m_bBlockUpdate = false;
|
||||
m_selectedItems = ListView_GetSelectedCount(hListControl);
|
||||
UpdateInfoLabel();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2278,9 +2426,10 @@ bool CSearchDlg::PreTranslateMessage(MSG* pMsg)
|
||||
if (bCtrl && !bShift && !bAlt)
|
||||
{
|
||||
int iItem = -1;
|
||||
bool fileList = (IsDlgButtonChecked(*this, IDC_RESULTFILES) == BST_CHECKED);
|
||||
while ((iItem = ListView_GetNextItem(hListControl, iItem, LVNI_SELECTED)) != (-1))
|
||||
{
|
||||
int selIndex = GetSelectedListIndex(iItem);
|
||||
int selIndex = GetSelectedListIndex(fileList, iItem);
|
||||
if ((selIndex < 0) || (selIndex >= static_cast<int>(m_items.size())))
|
||||
continue;
|
||||
OpenFileAtListIndex(selIndex);
|
||||
@ -2308,11 +2457,14 @@ void CSearchDlg::DoListNotify(LPNMITEMACTIVATE lpNMItemActivate)
|
||||
{
|
||||
if ((lpNMItemActivate->uOldState & LVIS_SELECTED) || (lpNMItemActivate->uNewState & LVIS_SELECTED))
|
||||
{
|
||||
if (!m_bBlockUpdate)
|
||||
{
|
||||
HWND hListControl = GetDlgItem(*this, IDC_RESULTLIST);
|
||||
m_selectedItems = ListView_GetSelectedCount(hListControl);
|
||||
UpdateInfoLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lpNMItemActivate->hdr.code == LVN_BEGINDRAG)
|
||||
{
|
||||
CDropFiles dropFiles; // class for creating DROPFILES struct
|
||||
@ -2323,9 +2475,10 @@ void CSearchDlg::DoListNotify(LPNMITEMACTIVATE lpNMItemActivate)
|
||||
return;
|
||||
|
||||
int iItem = -1;
|
||||
bool fileList = (IsDlgButtonChecked(*this, IDC_RESULTFILES) == BST_CHECKED);
|
||||
while ((iItem = ListView_GetNextItem(hListControl, iItem, LVNI_SELECTED)) != (-1))
|
||||
{
|
||||
dropFiles.AddFile(m_items[GetSelectedListIndex(iItem)].filePath);
|
||||
dropFiles.AddFile(m_items[GetSelectedListIndex(fileList, iItem)].filePath);
|
||||
}
|
||||
|
||||
if (dropFiles.GetCount() > 0)
|
||||
@ -2535,28 +2688,8 @@ void CSearchDlg::DoListNotify(LPNMITEMACTIVATE lpNMItemActivate)
|
||||
}
|
||||
break;
|
||||
case 5: // encoding
|
||||
switch (pInfo->encoding)
|
||||
{
|
||||
case CTextFile::Ansi:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"ANSI", pItem->cchTextMax - 1LL);
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, CTextFile::GetEncodingString(pInfo->encoding).c_str(), pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
case CTextFile::Unicode_Le:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"UTF-16-LE", pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
case CTextFile::Unicode_Be:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"UTF-16-BE", pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
case CTextFile::UTF8:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"UTF8", pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
case CTextFile::Binary:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"BINARY", pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
default:
|
||||
wcsncpy_s(pItem->pszText, pItem->cchTextMax, L"", pItem->cchTextMax - 1LL);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 6: // modification date
|
||||
FormatDate(pItem->pszText, pInfo->modifiedTime, true);
|
||||
break;
|
||||
@ -3216,10 +3349,17 @@ DWORD CSearchDlg::SearchThread()
|
||||
SendMessage(*this, SEARCH_START, 0, 0);
|
||||
|
||||
std::wstring searchStringutf16;
|
||||
|
||||
for (auto c : m_searchString)
|
||||
{
|
||||
searchStringutf16 += c;
|
||||
if (std::iswalpha(c) && ((c & 0xFF00) == 0))
|
||||
searchStringutf16 += L"\\x00";
|
||||
else
|
||||
{
|
||||
searchStringutf16 = m_searchString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::wstring searchPath : pathVector)
|
||||
@ -3243,7 +3383,7 @@ DWORD CSearchDlg::SearchThread()
|
||||
bool bIsDirectory = false;
|
||||
CDirFileEnum fileEnumerator(searchPath.c_str());
|
||||
if (!m_bIncludeSymLinks)
|
||||
fileEnumerator.SetAttributesToIgnore(FILE_ATTRIBUTE_REPARSE_POINT | IO_REPARSE_TAG_MOUNT_POINT);
|
||||
fileEnumerator.SetAttributesToIgnore(FILE_ATTRIBUTE_REPARSE_POINT);
|
||||
bool bRecurse = m_bIncludeSubfolders;
|
||||
std::wstring sPath;
|
||||
|
||||
@ -4439,6 +4579,11 @@ void CSearchDlg::AutoSizeAllColumns()
|
||||
int CSearchDlg::GetSelectedListIndex(int index)
|
||||
{
|
||||
bool fileList = (IsDlgButtonChecked(*this, IDC_RESULTFILES) == BST_CHECKED);
|
||||
return GetSelectedListIndex(fileList, index);
|
||||
}
|
||||
|
||||
int CSearchDlg::GetSelectedListIndex(bool fileList, int index) const
|
||||
{
|
||||
if (fileList)
|
||||
return index;
|
||||
auto tup = m_listItems[index];
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2007-2022 - Stefan Kueng
|
||||
// Copyright (C) 2007-2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -126,12 +126,12 @@ public:
|
||||
inline void SetKeepFileDate(bool bSet) { m_bWholeWordsC = true; m_bWholeWords = bSet; }
|
||||
inline void SetWholeWords(bool bSet) { m_bWholeWordsC = true; m_bWholeWords = bSet; }
|
||||
inline void SetUTF8(bool bSet) { m_bUTF8C = true; m_bUTF8 = bSet; m_bForceBinary = false; }
|
||||
inline void SetIncludeSymLinks(bool bSet) { m_bIncludeSymLinksC = true; m_bIncludeSymLinks = bSet; }
|
||||
inline void SetBinary(bool bSet) { m_bUTF8C = true; m_bForceBinary = bSet; m_bUTF8 = false; }
|
||||
inline void SetSize(uint64_t size, int cmp) { m_bSizeC = true; m_lSize = size << 10; m_sizeCmp = cmp; m_bAllSize = (m_lSize == MaxFileSize()) ? true : m_bAllSize; }
|
||||
inline void SetIncludeSystem(bool bSet) { m_bIncludeSystemC = true; m_bIncludeSystem = bSet; }
|
||||
inline void SetIncludeHidden(bool bSet) { m_bIncludeHiddenC = true; m_bIncludeHidden = bSet; }
|
||||
inline void SetIncludeSubfolders(bool bSet) { m_bIncludeSubfoldersC = true; m_bIncludeSubfolders = bSet; }
|
||||
inline void SetIncludeSymLinks(bool bSet) { m_bIncludeSymLinksC = true; m_bIncludeSymLinks = bSet; }
|
||||
inline void SetIncludeBinary(bool bSet) { m_bIncludeBinaryC = true; m_bIncludeBinary = bSet; }
|
||||
inline void SetDateLimit(int datelimit, FILETIME t1, FILETIME t2) { m_bDateLimitC = true; m_dateLimit = datelimit; m_date1 = t1; m_date2 = t2; }
|
||||
inline void SetNoSaveSettings(bool nosave) { m_bNoSaveSettings = nosave; }
|
||||
@ -152,7 +152,7 @@ protected:
|
||||
bool InitResultList();
|
||||
void FillResultList();
|
||||
bool AddFoundEntry(const CSearchInfo* pInfo, bool bOnlyListControl = false);
|
||||
void ShowContextMenu(int x, int y);
|
||||
void ShowContextMenu(HWND hWnd, int x, int y);
|
||||
void DoListNotify(LPNMITEMACTIVATE lpNMItemActivate);
|
||||
void OpenFileAtListIndex(int listIndex);
|
||||
void UpdateInfoLabel();
|
||||
@ -163,6 +163,7 @@ protected:
|
||||
bool MatchPath(LPCTSTR pathBuf) const;
|
||||
void AutoSizeAllColumns();
|
||||
int GetSelectedListIndex(int index);
|
||||
int GetSelectedListIndex(bool fileList, int index) const;
|
||||
static bool FailedShowMessage(HRESULT hr);
|
||||
#ifdef NP3_ALLOW_UPDATE
|
||||
void CheckForUpdates(bool force = false);
|
||||
@ -177,6 +178,7 @@ private:
|
||||
HWND m_hParent;
|
||||
//std::atomic_bool LONG m_dwThreadRunning;
|
||||
//std::atomic_bool LONG m_cancelled;
|
||||
bool m_bBlockUpdate;
|
||||
|
||||
std::unique_ptr<CBookmarksDlg> m_bookmarksDlg;
|
||||
ComPtr<ITaskbarList3> m_pTaskbarList;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2007-2008, 2012-2014, 2021-2022 - Stefan Kueng
|
||||
// Copyright (C) 2007-2008, 2012-2014, 2021-2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -141,3 +141,25 @@ bool CSearchInfo::ExtCompareDesc(const CSearchInfo& entry1, const CSearchInfo& e
|
||||
std::wstring ext2 = dotPos2 != std::wstring::npos ? entry2.filePath.substr(dotPos2 + 1) : L"";
|
||||
return StrCmpLogicalW(ext1.c_str(), ext2.c_str()) > 0;
|
||||
}
|
||||
|
||||
bool CSearchInfo::operator<(const CSearchInfo& other) const
|
||||
{
|
||||
auto res = _wcsicmp(filePath.c_str(), other.filePath.c_str());
|
||||
if (res != 0)
|
||||
return res < 0;
|
||||
if (fileSize != other.fileSize)
|
||||
return fileSize < other.fileSize;
|
||||
if (matchCount != other.matchCount)
|
||||
return matchCount < matchCount;
|
||||
if (readError != other.readError)
|
||||
return readError != other.readError;
|
||||
if (folder != other.folder)
|
||||
return folder != other.folder;
|
||||
if (CompareFileTime(&modifiedTime, &other.modifiedTime) != 0)
|
||||
return CompareFileTime(&modifiedTime, &other.modifiedTime) < 0;
|
||||
if (matchLinesNumbers != other.matchLinesNumbers)
|
||||
return matchLinesNumbers < other.matchLinesNumbers;
|
||||
if (matchLines != other.matchLines)
|
||||
return matchLines < other.matchLines;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2007-2008, 2010, 2012-2013, 2021-2022 - Stefan Kueng
|
||||
// Copyright (C) 2007-2008, 2010, 2012-2013, 2021-2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -44,6 +44,8 @@ public:
|
||||
static bool ModifiedTimeCompareDesc(const CSearchInfo& entry1, const CSearchInfo& entry2);
|
||||
static bool ExtCompareDesc(const CSearchInfo& entry1, const CSearchInfo& entry2);
|
||||
|
||||
bool operator<(const CSearchInfo& other) const;
|
||||
|
||||
std::wstring filePath;
|
||||
__int64 fileSize;
|
||||
std::vector<DWORD> matchLinesNumbers;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2012-2013, 2016-2021 - Stefan Kueng
|
||||
// Copyright (C) 2012-2013, 2016-2021, 2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -254,7 +254,7 @@ LRESULT CSettingsDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
|
||||
SendDlgItemMessage(hwndDlg, IDC_LANGUAGE, CB_SETCURSEL, langIndex, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_ESCKEY, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"escclose", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\escclose", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_BACKUPINFOLDER, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"backupinfolder", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\backupinfolder", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_NOWARNINGIFNOBACKUP, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"nowarnifnobackup", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWin\\nowarnifnobackup", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_NOWARNINGIFNOBACKUP, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"settings", L"nowarnifnobackup", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\nowarnifnobackup", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_ONLYONE, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"global", L"onlyone", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\onlyone", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
#ifdef NP3_ALLOW_UPDATE
|
||||
SendDlgItemMessage(hwndDlg, IDC_DOUPDATECHECKS, BM_SETCHECK, bPortable ? g_iniFile.GetBoolValue(L"global", L"CheckForUpdates", false) : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\CheckForUpdates", FALSE)) ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2007-2015, 2017, 2020-2021 - Stefan Kueng
|
||||
// Copyright (C) 2007-2015, 2017, 2020-2021, 2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -44,8 +44,7 @@ struct ICompare
|
||||
};
|
||||
|
||||
CShellContextMenu::CShellContextMenu()
|
||||
: m_nItems(0)
|
||||
, bDelete(FALSE)
|
||||
: bDelete(FALSE)
|
||||
, m_menu(nullptr)
|
||||
, m_psfFolder(nullptr)
|
||||
, m_pidlArray(nullptr)
|
||||
@ -315,8 +314,6 @@ UINT CShellContextMenu::ShowContextMenu(HWND hWnd, POINT pt)
|
||||
std::wstring lines;
|
||||
for (auto it = m_lineVector.begin(); it != m_lineVector.end(); ++it)
|
||||
{
|
||||
if (!lines.empty())
|
||||
lines += L"\r\n";
|
||||
for (auto it2 = it->lines.cbegin(); it2 != it->lines.cend(); ++it2)
|
||||
{
|
||||
std::wstring l = it2->text;
|
||||
@ -324,6 +321,8 @@ UINT CShellContextMenu::ShowContextMenu(HWND hWnd, POINT pt)
|
||||
std::replace(l.begin(), l.end(), '\n', ' ');
|
||||
std::replace(l.begin(), l.end(), '\r', ' ');
|
||||
|
||||
if (!lines.empty())
|
||||
lines += L"\r\n";
|
||||
lines += l;
|
||||
}
|
||||
}
|
||||
@ -419,35 +418,35 @@ void CShellContextMenu::SetObjects(const std::vector<CSearchInfo>& strVector, co
|
||||
// but since we use the Desktop as our interface and the Desktop is the namespace root
|
||||
// that means that it's a fully qualified PIDL, which is what we need
|
||||
|
||||
m_nItems = strVector.size();
|
||||
m_pidlArray = static_cast<LPITEMIDLIST*>(CoTaskMemAlloc((m_nItems + 10) * sizeof(LPITEMIDLIST)));
|
||||
SecureZeroMemory(m_pidlArray, (m_nItems + 10) * sizeof(LPITEMIDLIST));
|
||||
auto nItems = strVector.size();
|
||||
m_pidlArray = static_cast<LPITEMIDLIST*>(CoTaskMemAlloc((nItems + 10) * sizeof(LPITEMIDLIST)));
|
||||
SecureZeroMemory(m_pidlArray, (nItems + 10) * sizeof(LPITEMIDLIST));
|
||||
m_pidlArrayItems = 0;
|
||||
int succeededItems = 0;
|
||||
LPITEMIDLIST pidl = nullptr;
|
||||
m_strVector.clear();
|
||||
m_lineVector.clear();
|
||||
m_strVector.reserve(m_nItems);
|
||||
m_lineVector.reserve(m_nItems);
|
||||
m_strVector.reserve(nItems);
|
||||
m_lineVector.reserve(nItems);
|
||||
|
||||
size_t bufSize = 1024;
|
||||
auto filePath = std::make_unique<WCHAR[]>(bufSize);
|
||||
for (size_t i = 0; i < m_nItems; i++)
|
||||
for (const auto& sInfo : strVector)
|
||||
{
|
||||
if (bufSize < strVector[i].filePath.size())
|
||||
if (bufSize < sInfo.filePath.size())
|
||||
{
|
||||
bufSize = strVector[i].filePath.size() + 3;
|
||||
bufSize = sInfo.filePath.size() + 3;
|
||||
filePath = std::make_unique<WCHAR[]>(bufSize);
|
||||
}
|
||||
wcscpy_s(filePath.get(), bufSize, strVector[i].filePath.c_str());
|
||||
wcscpy_s(filePath.get(), bufSize, sInfo.filePath.c_str());
|
||||
if (SUCCEEDED(m_psfFolder->ParseDisplayName(NULL, nullptr, filePath.get(), NULL, &pidl, NULL)))
|
||||
{
|
||||
m_pidlArray[succeededItems++] = pidl; // copy pidl to pidlArray
|
||||
m_strVector.push_back(strVector[i]);
|
||||
if (lineVector.size() > static_cast<size_t>(i))
|
||||
m_lineVector.push_back(lineVector[i]);
|
||||
m_strVector.push_back(sInfo);
|
||||
}
|
||||
}
|
||||
m_lineVector = lineVector;
|
||||
|
||||
m_pidlArrayItems = succeededItems;
|
||||
|
||||
bDelete = TRUE; // indicates that m_psfFolder should be deleted by CShellContextMenu
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// grepWin - regex search and replace for Windows
|
||||
|
||||
// Copyright (C) 2007-2008, 2011-2015, 2021 - Stefan Kueng
|
||||
// Copyright (C) 2007-2008, 2011-2015, 2021, 2023 - Stefan Kueng
|
||||
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
@ -35,7 +35,6 @@ public:
|
||||
virtual ~CShellContextMenu();
|
||||
|
||||
private:
|
||||
size_t m_nItems;
|
||||
BOOL bDelete;
|
||||
HMENU m_menu;
|
||||
IShellFolder * m_psfFolder;
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
|
||||
//#pragma message(__LOC__"Run the NAnt script to get proper version info")
|
||||
|
||||
#define FILEVER 2, 1, 12, 43
|
||||
#define PRODUCTVER 2, 1, 12, 43
|
||||
#define STRFILEVER "2.1.12.43\0"
|
||||
#define STRPRODUCTVER "2.1.12.43\0"
|
||||
#define FILEVER 2, 1, 13, 44
|
||||
#define PRODUCTVER 2, 1, 13, 44
|
||||
#define STRFILEVER "2.1.13.44\0"
|
||||
#define STRPRODUCTVER "2.1.13.44\0"
|
||||
|
||||
#define GREPWIN_VERMAJOR 2
|
||||
#define GREPWIN_VERMINOR 1
|
||||
#define GREPWIN_VERMICRO 12
|
||||
#define GREPWIN_VERBUILD 43
|
||||
#define GREPWIN_VERDATE "2023-02-22"
|
||||
#define GREPWIN_VERMICRO 13
|
||||
#define GREPWIN_VERBUILD 44
|
||||
#define GREPWIN_VERDATE "2023-02-24"
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<setenv>
|
||||
<variable name="MajorVersion" value="2" />
|
||||
<variable name="MinorVersion" value="0" />
|
||||
<variable name="MicroVersion" value="12" />
|
||||
<variable name="MicroVersion" value="13" />
|
||||
<variable name="WCREV" value="$WCLOGCOUNT$" />
|
||||
<variable name="WCDATE" value="$WCDATE$" />
|
||||
</setenv>
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
2.0.12.1183
|
||||
2.0.13.1197
|
||||
https://tools.stefankueng.com/grepWin.html
|
||||
|
||||
Loading…
Reference in New Issue
Block a user