From 03a597a500968e3ee102ef1cc337fd93b7060c36 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Sun, 14 Jun 2020 12:08:08 +0200 Subject: [PATCH] + upd: current grepWin dev: add feature: export search results --- grepWinNP3/grepWinNP3.vcxproj | 4 + grepWinNP3/grepWinNP3.vcxproj.filters | 12 + grepWinNP3/src/COMPtrs.h | 38 +++ grepWinNP3/src/Resources/grepWin.rc | 14 +- grepWinNP3/src/SearchDlg.cpp | 226 +++++++++++++++++- grepWinNP3/src/SearchDlg.h | 2 +- grepWinNP3/src/last/version.h | 12 +- grepWinNP3/src/resource.h | 14 +- .../Deutsch (Deutschland) [de-DE].lang | 32 +++ .../English (United States) [en-US].lang | 32 +++ 10 files changed, 367 insertions(+), 19 deletions(-) create mode 100644 grepWinNP3/src/COMPtrs.h diff --git a/grepWinNP3/grepWinNP3.vcxproj b/grepWinNP3/grepWinNP3.vcxproj index edec49f33..77f1a514f 100644 --- a/grepWinNP3/grepWinNP3.vcxproj +++ b/grepWinNP3/grepWinNP3.vcxproj @@ -217,6 +217,7 @@ + @@ -261,7 +262,9 @@ + + @@ -275,6 +278,7 @@ + diff --git a/grepWinNP3/grepWinNP3.vcxproj.filters b/grepWinNP3/grepWinNP3.vcxproj.filters index 2158e1482..f13ace88f 100644 --- a/grepWinNP3/grepWinNP3.vcxproj.filters +++ b/grepWinNP3/grepWinNP3.vcxproj.filters @@ -144,6 +144,9 @@ sktoolslib_mod + + sktoolslib_mod + @@ -287,6 +290,15 @@ Header Files + + sktoolslib_mod + + + Header Files + + + sktoolslib_mod + diff --git a/grepWinNP3/src/COMPtrs.h b/grepWinNP3/src/COMPtrs.h new file mode 100644 index 000000000..b839f04a3 --- /dev/null +++ b/grepWinNP3/src/COMPtrs.h @@ -0,0 +1,38 @@ +// grepWin - regex search and replace for Windows + +// Copyright (C) 2007-2009, 2012-2013, 2016, 2019-2020 - Stefan Kueng + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +_COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog)); +_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); +_COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray)); +_COM_SMARTPTR_TYPEDEF(IFileOperation, __uuidof(IFileOperation)); +_COM_SMARTPTR_TYPEDEF(IStream, __uuidof(IStream)); +_COM_SMARTPTR_TYPEDEF(IFileSaveDialog, __uuidof(IFileSaveDialog)); +_COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); +_COM_SMARTPTR_TYPEDEF(IFileDialogCustomize, __uuidof(IFileDialogCustomize)); diff --git a/grepWinNP3/src/Resources/grepWin.rc b/grepWinNP3/src/Resources/grepWin.rc index cf1ee315a..bb9e3ced6 100644 --- a/grepWinNP3/src/Resources/grepWin.rc +++ b/grepWinNP3/src/Resources/grepWin.rc @@ -90,14 +90,15 @@ BEGIN CONTROL "Text match",IDC_FILEPATTERNTEXT,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,524,174,61,10 PUSHBUTTON "Settings",IDC_SETTINGSBUTTON,14,197,103,14 PUSHBUTTON "&Replace",IDC_REPLACE,457,198,62,14 - DEFPUSHBUTTON "Search",IDOK,523,198,62,14 + CONTROL "Search",IDOK,"Button",BS_DEFSPLITBUTTON | WS_TABSTOP,523,198,62,14 GROUPBOX "Limit search",IDC_GROUPLIMITSEARCH,7,128,587,65 CONTROL "",IDC_RESULTLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,14,234,571,81 LTEXT "",IDC_SEARCHINFOLABEL,14,321,580,8 - GROUPBOX "Search results",IDC_GROUPSEARCHRESULTS,7,214,587,118 RTEXT "About grepWinNP3",IDC_ABOUTLINK,449,2,136,8 + GROUPBOX "Search results",IDC_GROUPSEARCHRESULTS,7,214,587,118 CONTROL "Files",IDC_RESULTFILES,"Button",BS_AUTORADIOBUTTON | WS_GROUP,84,222,89,10 - CONTROL "Content",IDC_RESULTCONTENT,"Button",BS_AUTORADIOBUTTON,228,222,104,10 + CONTROL "Content",IDC_RESULTCONTENT,"Button",BS_AUTORADIOBUTTON,200,222,104,10 + PUSHBUTTON ">>>",IDC_EXPORT,316,222,28,10,NOT WS_VISIBLE CONTROL "",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | PBS_SMOOTHREVERSE | PBS_MARQUEE | NOT WS_VISIBLE,130,198,310,14 END @@ -421,6 +422,13 @@ END STRINGTABLE BEGIN IDS_ERR_PATHNOTEXIST "Path does not exist or is not accessible!" + IDS_INVERSESEARCH "Inverse search (NOT searchstring)" + IDS_SEARCHINFOUNDFILES "Search in found files" + IDS_EXPORT_TT "Export results..." + IDS_EXPORTTITLE "Export resultlist" + IDS_EXPORTPATHS "include file paths" + IDS_EXPORTMATCHLINENUMBER "include match line numbers" + IDS_EXPORTMATCHLINECONTENT "include match line text" END #endif // Neutral resources diff --git a/grepWinNP3/src/SearchDlg.cpp b/grepWinNP3/src/SearchDlg.cpp index 57745236c..096b80130 100644 --- a/grepWinNP3/src/SearchDlg.cpp +++ b/grepWinNP3/src/SearchDlg.cpp @@ -46,8 +46,10 @@ #include "DebugOutput.h" #include "Theme.h" #include "DarkModeHelper.h" - #include "SearchMT.h" // multi-threading helper +#include "OnOutOfScope.h" +#include "COMPtrs.h" +#include "PreserveChdir.h" #include #include @@ -236,6 +238,7 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara AddToolTip(IDC_SEARCHTEXT, TranslatedString(hResource, IDS_SEARCHTEXT_TT).c_str()); AddToolTip(IDC_EDITMULTILINE1, TranslatedString(hResource, IDS_EDITMULTILINE_TT).c_str()); AddToolTip(IDC_EDITMULTILINE2, TranslatedString(hResource, IDS_EDITMULTILINE_TT).c_str()); + AddToolTip(IDC_EXPORT, TranslatedString(hResource, IDS_EXPORT_TT).c_str()); AddToolTip(IDOK, TranslatedString(hResource, IDS_SHIFT_NOTSEARCH).c_str()); if (m_searchpath.empty()) @@ -483,9 +486,10 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara m_resizer.AddControl(hwndDlg, IDOK, RESIZER_TOPRIGHT); m_resizer.AddControl(hwndDlg, IDC_GROUPSEARCHRESULTS, RESIZER_TOPLEFTBOTTOMRIGHT); m_resizer.AddControl(hwndDlg, IDC_RESULTLIST, RESIZER_TOPLEFTBOTTOMRIGHT); + m_resizer.AddControl(hwndDlg, IDC_SEARCHINFOLABEL, RESIZER_BOTTOMLEFTRIGHT); m_resizer.AddControl(hwndDlg, IDC_RESULTFILES, RESIZER_TOPLEFT); m_resizer.AddControl(hwndDlg, IDC_RESULTCONTENT, RESIZER_TOPLEFT); - m_resizer.AddControl(hwndDlg, IDC_SEARCHINFOLABEL, RESIZER_BOTTOMLEFTRIGHT); + m_resizer.AddControl(hwndDlg, IDC_EXPORT, RESIZER_TOPLEFT); InitDialog(hwndDlg, IDI_GREPWIN); @@ -572,9 +576,42 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara break; case WM_NOTIFY: { - if (wParam == IDC_RESULTLIST) + switch (wParam) { - DoListNotify((LPNMITEMACTIVATE)lParam); + case IDC_RESULTLIST: + DoListNotify((LPNMITEMACTIVATE)lParam); + break; + case IDOK: + switch (((LPNMHDR)lParam)->code) + { + case BCN_DROPDOWN: + { + const NMBCDROPDOWN* pDropDown = (NMBCDROPDOWN*)lParam; + // Get screen coordinates of the button. + POINT pt; + pt.x = pDropDown->rcButton.left; + pt.y = pDropDown->rcButton.bottom; + ClientToScreen(pDropDown->hdr.hwndFrom, &pt); + // Create a menu and add items. + HMENU hSplitMenu = CreatePopupMenu(); + if (!hSplitMenu) + break; + OnOutOfScope(DestroyMenu(hSplitMenu)); + if (pDropDown->hdr.hwndFrom == GetDlgItem(*this, IDOK)) + { + auto sInverseSearch = TranslatedString(hResource, IDS_INVERSESEARCH); + auto sSearchInFoundFiles = TranslatedString(hResource, IDS_SEARCHINFOUNDFILES); + AppendMenu(hSplitMenu, MF_STRING, IDC_INVERSESEARCH, sInverseSearch.c_str()); + AppendMenu(hSplitMenu, MF_STRING, IDC_SEARCHINFOUNDFILES, sSearchInFoundFiles.c_str()); + } + // Display the menu. + TrackPopupMenu(hSplitMenu, TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, *this, nullptr); + + return TRUE; + } + break; + } + break; } } break; @@ -619,12 +656,13 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara SendDlgItemMessage(*this, IDC_PROGRESS, PBM_SETMARQUEE, 1, 0); } break; + //case SEARCH_FOUND: case SEARCH_PROGRESS: { const CSearchInfo* const sInfo = (const CSearchInfo* const)(wParam); int const nFound = static_cast(lParam); m_totalmatches += (int)sInfo->matchcount; - if ((nFound > 0) || (m_searchString.empty()) || (sInfo->readerror)) + if ((nFound > 0) || (m_searchString.empty()) || (sInfo->readerror) || IsNOTSearch()) { AddFoundEntry(sInfo); UpdateInfoLabel(); @@ -645,6 +683,7 @@ LRESULT CSearchDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara SendDlgItemMessage(*this, IDC_PROGRESS, PBM_SETMARQUEE, 0, 0); ShowWindow(GetDlgItem(*this, IDC_PROGRESS), SW_HIDE); EnableWindow(GetDlgItem(*this, IDC_SETTINGSBUTTON), TRUE); + ShowWindow(GetDlgItem(*this, IDC_EXPORT), m_items.empty() ? SW_HIDE : SW_SHOW); KillTimer(*this, LABELUPDATETIMER); } break; @@ -807,6 +846,8 @@ LRESULT CSearchDlg::DoCommand(int id, int msg) { case IDC_REPLACE: case IDOK: + case IDC_INVERSESEARCH: + case IDC_SEARCHINFOUNDFILES: { if (IsSearchThreadRunning()) { @@ -836,10 +877,21 @@ LRESULT CSearchDlg::DoCommand(int id, int msg) break; } } + if ((id == IDC_SEARCHINFOUNDFILES) && (!m_items.empty())) + { + m_searchpath.clear(); + for (const auto& item : m_items) + { + if (!m_searchpath.empty()) + m_searchpath += L"|"; + m_searchpath += item.filepath; + } + } m_searchedItems = 0; m_totalitems = 0; + ShowWindow(GetDlgItem(*this, IDC_EXPORT), SW_HIDE); m_items.clear(); m_listItems.clear(); m_listItems.reserve(500000); @@ -883,9 +935,15 @@ LRESULT CSearchDlg::DoCommand(int id, int msg) } } } - m_bConfirmationOnReplace = true; + InterlockedExchange(&s_Cancelled, FALSE); - InterlockedExchange(&s_NOTSearch, ((GetKeyState(VK_SHIFT) & 0x8000) != 0) ? TRUE : FALSE); + if (id == IDC_INVERSESEARCH) + InterlockedExchange(&s_NOTSearch, TRUE); + else + InterlockedExchange(&s_NOTSearch, ((GetKeyState(VK_SHIFT) & 0x8000) != 0) ? TRUE : FALSE); + + SetDlgItemText(*this, IDOK, TranslatedString(hResource, IDS_STOP).c_str()); + ShowWindow(GetDlgItem(*this, IDC_PROGRESS), SW_SHOW); EnableWindow(GetDlgItem(*this, IDC_SETTINGSBUTTON), FALSE); @@ -1286,6 +1344,149 @@ LRESULT CSearchDlg::DoCommand(int id, int msg) } } break; + case IDC_EXPORT: + { + PreserveChdir keepCWD; + IFileSaveDialogPtr pfd; + + HRESULT hr = pfd.CreateInstance(CLSID_FileSaveDialog, nullptr, CLSCTX_INPROC_SERVER); + if (FailedShowMessage(hr)) + break; + + // Set the dialog options + DWORD dwOptions; + hr = pfd->GetOptions(&dwOptions); + if (FailedShowMessage(hr)) + break; + hr = pfd->SetOptions(dwOptions | FOS_FORCEFILESYSTEM | FOS_OVERWRITEPROMPT); + if (FailedShowMessage(hr)) + break; + + hr = pfd->SetTitle(TranslatedString(hResource, IDS_EXPORTTITLE).c_str()); + if (FailedShowMessage(hr)) + break; + + IFileDialogCustomizePtr pfdCustomize; + hr = pfd.QueryInterface(IID_PPV_ARGS(&pfdCustomize)); + if (SUCCEEDED(hr)) + { + bool exportpaths = bPortable ? g_iniFile.GetBoolValue(L"export", L"paths", false) : + DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\export_paths")) != 0; + bool const exportlinenumbers = bPortable ? g_iniFile.GetBoolValue(L"export", L"linenumbers", false) : + DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\export_linenumbers")) != 0; + bool const exportlinecontent = bPortable ? g_iniFile.GetBoolValue(L"export", L"linecontent", false) : + DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\export_linecontent")) != 0; + + if (!exportpaths && !exportlinenumbers && !exportlinecontent) + exportpaths = true; + + pfdCustomize->AddCheckButton(101, TranslatedString(hResource, IDS_EXPORTPATHS).c_str(), exportpaths); + pfdCustomize->AddCheckButton(102, TranslatedString(hResource, IDS_EXPORTMATCHLINENUMBER).c_str(), exportlinenumbers); + pfdCustomize->AddCheckButton(103, TranslatedString(hResource, IDS_EXPORTMATCHLINECONTENT).c_str(), exportlinecontent); + } + + // Show the save file dialog + hr = pfd->Show(*this); + if (FailedShowMessage(hr)) + break; + IShellItemPtr psiResult = nullptr; + hr = pfd->GetResult(&psiResult); + if (FailedShowMessage(hr)) + break; + PWSTR pszPath = nullptr; + hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, &pszPath); + if (FailedShowMessage(hr)) + break; + std::wstring path = pszPath; + CoTaskMemFree(pszPath); + + bool includePaths = true; + bool includeMatchLineNumbers = false; + bool includeMatchLineTexts = false; + IFileDialogCustomizePtr pfdCustomizeRet; + hr = pfd.QueryInterface(IID_PPV_ARGS(&pfdCustomizeRet)); + if (SUCCEEDED(hr)) + { + BOOL bChecked = FALSE; + pfdCustomizeRet->GetCheckButtonState(101, &bChecked); + includePaths = (bChecked != 0); + pfdCustomizeRet->GetCheckButtonState(102, &bChecked); + includeMatchLineNumbers = (bChecked != 0); + pfdCustomizeRet->GetCheckButtonState(103, &bChecked); + includeMatchLineTexts = (bChecked != 0); + } + if (!includePaths && !includeMatchLineNumbers && !includeMatchLineTexts) + includePaths = true; + + bool onlypaths = !includeMatchLineNumbers && !includeMatchLineTexts; + if (!path.empty()) + { + std::ofstream file; + file.open(path); + + if (file.is_open()) + { + if (onlypaths) + { + for (const auto& item : m_items) + { + file << CUnicodeUtils::StdGetUTF8(item.filepath) << std::endl; + } + } + else + { + constexpr char separator = '*'; + for (const auto& item : m_items) + { + for (size_t i = 0; i < item.matchlinesnumbers.size(); ++i) + { + bool needSeparator = false; + if (includePaths) + { + file << CUnicodeUtils::StdGetUTF8(item.filepath); + needSeparator = true; + } + if (includeMatchLineNumbers) + { + if (needSeparator) + file << separator; + file << CStringUtils::Format("%lld", item.matchlinesnumbers[i]); + needSeparator = true; + } + if (includeMatchLineTexts) + { + if (needSeparator) + file << separator; + auto line = item.matchlines[i]; + CStringUtils::rtrim(line, L"\r\n"); + file << CUnicodeUtils::StdGetUTF8(line); + } + file << std::endl; + } + } + } + + file.close(); + + if (bPortable) + { + g_iniFile.SetBoolValue(L"export", L"paths", includePaths); + g_iniFile.SetBoolValue(L"export", L"linenumbers", includeMatchLineNumbers); + g_iniFile.SetBoolValue(L"export", L"linecontent", includeMatchLineTexts); + } + else + { + auto exportpaths = CRegStdDWORD(L"Software\\grepWin\\export_paths"); + auto exportlinenumbers = CRegStdDWORD(L"Software\\grepWin\\export_linenumbers"); + auto exportlinecontent = CRegStdDWORD(L"Software\\grepWin\\export_linecontent"); + exportpaths = includePaths ? 1 : 0; + exportlinenumbers = includeMatchLineNumbers ? 1 : 0; + exportlinecontent = includeMatchLineTexts ? 1 : 0; + } + } + } + } + break; } return 1; } @@ -3520,3 +3721,14 @@ int CSearchDlg::GetSelectedListIndex(int index) auto tup = m_listItems[index]; return std::get<0>(tup); } + +bool CSearchDlg::FailedShowMessage(HRESULT hr) +{ + if (FAILED(hr)) + { + _com_error err(hr); + MessageBox(nullptr, L"grepWinNP3", err.ErrorMessage(), MB_ICONERROR); + return true; + } + return false; +} diff --git a/grepWinNP3/src/SearchDlg.h b/grepWinNP3/src/SearchDlg.h index 7aff7a0f1..aac0d6b91 100644 --- a/grepWinNP3/src/SearchDlg.h +++ b/grepWinNP3/src/SearchDlg.h @@ -118,7 +118,7 @@ protected: bool MatchPath(LPCTSTR pathbuf); void AutoSizeAllColumns(); int GetSelectedListIndex(int index); - + bool FailedShowMessage(HRESULT hr); private: static bool NameCompareAsc(const CSearchInfo& Entry1, const CSearchInfo& Entry2); static bool SizeCompareAsc(const CSearchInfo& Entry1, const CSearchInfo& Entry2); diff --git a/grepWinNP3/src/last/version.h b/grepWinNP3/src/last/version.h index b46398bed..49835a863 100644 --- a/grepWinNP3/src/last/version.h +++ b/grepWinNP3/src/last/version.h @@ -6,13 +6,13 @@ //#pragma message(__LOC__"Run the NAnt script to get proper version info") -#define FILEVER 2, 1, 1, 13 -#define PRODUCTVER 2, 1, 1, 13 -#define STRFILEVER "2.1.1.13\0" -#define STRPRODUCTVER "2.1.1.13\0" +#define FILEVER 2, 1, 1, 14 +#define PRODUCTVER 2, 1, 1, 14 +#define STRFILEVER "2.1.1.14\0" +#define STRPRODUCTVER "2.1.1.14\0" #define GREPWIN_VERMAJOR 2 #define GREPWIN_VERMINOR 1 #define GREPWIN_VERMICRO 1 -#define GREPWIN_VERBUILD 13 -#define GREPWIN_VERDATE "2020-06-07" +#define GREPWIN_VERBUILD 14 +#define GREPWIN_VERDATE "2020-06-14" diff --git a/grepWinNP3/src/resource.h b/grepWinNP3/src/resource.h index bb0d53547..c01426299 100644 --- a/grepWinNP3/src/resource.h +++ b/grepWinNP3/src/resource.h @@ -71,6 +71,13 @@ #define IDS_FILEEXT 158 #define IDS_DARKMODE_TT 159 #define IDS_ERR_PATHNOTEXIST 160 +#define IDS_INVERSESEARCH 161 +#define IDS_SEARCHINFOUNDFILES 162 +#define IDS_EXPORT_TT 163 +#define IDS_EXPORTTITLE 164 +#define IDS_EXPORTPATHS 165 +#define IDS_EXPORTMATCHLINENUMBER 166 +#define IDS_EXPORTMATCHLINECONTENT 167 #define IDC_SEARCHTEXT 1000 #define IDC_REGEXRADIO 1001 #define IDC_TEXTRADIO 1002 @@ -158,6 +165,9 @@ #define IDC_TEXT_NUMOFWORKER 1088 #define IDC_BACKUPINFOLDER2 1089 #define IDC_NOWARNINGIFNOBACKUP 1090 +#define IDC_INVERSESEARCH 1091 +#define IDC_SEARCHINFOUNDFILES 1092 +#define IDC_EXPORT 1093 #define ID_REMOVEBOOKMARK 32771 #define ID_DUMMY_RENAMEPRESET 32774 #define ID_RENAMEBOOKMARK 32775 @@ -168,9 +178,9 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 161 +#define _APS_NEXT_RESOURCE_VALUE 168 #define _APS_NEXT_COMMAND_VALUE 32776 -#define _APS_NEXT_CONTROL_VALUE 1091 +#define _APS_NEXT_CONTROL_VALUE 1094 #define _APS_NEXT_SYMED_VALUE 110 #endif #endif diff --git a/grepWinNP3/translationsNP3/Deutsch (Deutschland) [de-DE].lang b/grepWinNP3/translationsNP3/Deutsch (Deutschland) [de-DE].lang index 0c3428e3e..dd2b73a1b 100644 --- a/grepWinNP3/translationsNP3/Deutsch (Deutschland) [de-DE].lang +++ b/grepWinNP3/translationsNP3/Deutsch (Deutschland) [de-DE].lang @@ -65,6 +65,10 @@ msgstr "..." msgid "/" msgstr "/" +#. Resource IDs: (1093) +msgid ">>>" +msgstr "" + #. Resource IDs: (1052, 135) msgid "About grepWinNP3" msgstr "Über grepWinNP3" @@ -190,6 +194,14 @@ msgstr "Verzeichnisse ausschließen (Regex):" msgid "Ext" msgstr "Ext" +#. Resource IDs: (164) +msgid "Export resultlist" +msgstr "Resultate exportieren" + +#. Resource IDs: (163) +msgid "Export results..." +msgstr "Resultate exportieren..." + #. Resource IDs: (1039) msgid "File Names match:\nuse '|' to separate multiple text match patterns, prepen&d '-' to exclude" msgstr "Dateinamen-Übereinstimmung:\n'|' zum Trennen multipler Text- Übereinstimmungsmuster, zum Ausschließen '-' vorans&tellen" @@ -226,6 +238,10 @@ msgstr "System-Items einbeziehen" msgid "Invalid path!" msgstr "Pfad ungültig!" +#. Resource IDs: (161) +msgid "Inverse search (NOT searchstring)" +msgstr "Umgekehrt suchen (NOT suchtext)" + #. Resource IDs: (1019) msgid "KB" msgstr "KB" @@ -371,6 +387,10 @@ msgstr "Case-sensitive suchen" msgid "Search in" msgstr "Suche in" +#. Resource IDs: (162) +msgid "Search in found files" +msgstr "Suche in gefundenen Dateien" + #. Resource IDs: (1018) msgid "Search results" msgstr "Suchresultate" @@ -476,6 +496,18 @@ msgstr "grepWinNP3 Einstellungen" msgid "hold down the shift key to find files that DO NOT contain the search string" msgstr "Halten Sie die Shifttaste gedrückt, um Dateien zu finden, die den Suchstring NICHT enthalten." +#. Resource IDs: (165) +msgid "include file paths" +msgstr "mit Pfaden" + +#. Resource IDs: (166) +msgid "include match line numbers" +msgstr "mit Zeilennummern" + +#. Resource IDs: (167) +msgid "include match line text" +msgstr "mit Zeilentext" + #. Resource IDs: (132) msgid "invalid regex!" msgstr "Regex ungültig!" diff --git a/grepWinNP3/translationsNP3/English (United States) [en-US].lang b/grepWinNP3/translationsNP3/English (United States) [en-US].lang index 51463e4c4..613326824 100644 --- a/grepWinNP3/translationsNP3/English (United States) [en-US].lang +++ b/grepWinNP3/translationsNP3/English (United States) [en-US].lang @@ -65,6 +65,10 @@ msgstr "" msgid "/" msgstr "" +#. Resource IDs: (1093) +msgid ">>>" +msgstr "" + #. Resource IDs: (1052, 135) msgid "About grepWinNP3" msgstr "" @@ -190,6 +194,14 @@ msgstr "" msgid "Ext" msgstr "" +#. Resource IDs: (164) +msgid "Export resultlist" +msgstr "Resultate exportieren" + +#. Resource IDs: (163) +msgid "Export results..." +msgstr "Resultate exportieren..." + #. Resource IDs: (1039) msgid "File Names match:\nuse '|' to separate multiple text match patterns, prepen&d '-' to exclude" msgstr "" @@ -226,6 +238,10 @@ msgstr "" msgid "Invalid path!" msgstr "" +#. Resource IDs: (161) +msgid "Inverse search (NOT searchstring)" +msgstr "" + #. Resource IDs: (1019) msgid "KB" msgstr "" @@ -371,6 +387,10 @@ msgstr "" msgid "Search in" msgstr "" +#. Resource IDs: (162) +msgid "Search in found files" +msgstr "" + #. Resource IDs: (1018) msgid "Search results" msgstr "" @@ -476,6 +496,18 @@ msgstr "" msgid "hold down the shift key to find files that DO NOT contain the search string" msgstr "" +#. Resource IDs: (165) +msgid "include file paths" +msgstr "" + +#. Resource IDs: (166) +msgid "include match line numbers" +msgstr "" + +#. Resource IDs: (167) +msgid "include match line text" +msgstr "" + #. Resource IDs: (132) msgid "invalid regex!" msgstr ""