├── .clang-format ├── .gitattributes ├── .github └── workflows │ └── msbuild.yml ├── .gitignore ├── .gitmodules ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── .tgitconfig ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── build.txt ├── choco ├── chocolateyInstall.ps1 └── grepwin.nuspec ├── default.build ├── default.build.user.tmpl ├── grepWin.sln ├── grepWin.sln.DotSettings ├── src ├── AboutDlg.cpp ├── AboutDlg.h ├── Bookmarks.cpp ├── Bookmarks.h ├── BookmarksDlg.cpp ├── BookmarksDlg.h ├── COMPtrs.h ├── ExplorerCommandVerb │ ├── ExplorerCommandVerb.vcxproj │ ├── ExplorerCommandVerb.vcxproj.filters │ ├── compatibility.manifest │ ├── dllmain.cpp │ ├── framework.h │ ├── packages.config │ ├── pch.cpp │ ├── pch.h │ └── source.def ├── LineData.h ├── MultiLineEditDlg.cpp ├── MultiLineEditDlg.h ├── NameDlg.cpp ├── NameDlg.h ├── NewlinesDlg.cpp ├── NewlinesDlg.h ├── RegexReplaceFormatter.cpp ├── RegexReplaceFormatter.h ├── RegexTestDlg.cpp ├── RegexTestDlg.h ├── Resources │ ├── GitHub-socialpreview.png │ ├── grepWin.ico │ ├── grepWin.rc │ ├── grepWin.rc2 │ ├── grepWin_search-small.png │ ├── grepWin_search.png │ ├── grepwin.svg │ ├── grepwin_128.png │ ├── grepwin_16.png │ ├── grepwin_24.png │ ├── grepwin_256.png │ ├── grepwin_32.png │ ├── grepwin_48.png │ ├── grepwin_64.png │ ├── infodlg.rtf │ ├── logo.png │ ├── vs9-tools-grepwin-prj.png │ └── vs9-tools-grepwin-sln.png ├── SK.ruleset ├── SearchDlg.cpp ├── SearchDlg.h ├── SearchInfo.cpp ├── SearchInfo.h ├── Settings.cpp ├── Settings.h ├── Setup │ ├── AppXManifest.xml.in │ ├── Banner.jpg │ ├── CustomActions │ │ ├── CustomActions.cpp │ │ ├── CustomActions.def │ │ ├── CustomActions.vcxproj │ │ ├── CustomActions.vcxproj.filters │ │ └── CustomActions.vcxproj.user │ ├── Dialog.jpg │ ├── License.rtf │ ├── Setup.wxs │ ├── StefansTools_setupdialog.pdn │ ├── VersionNumberInclude.in.wxi │ ├── setup.build │ └── website.url ├── ShellContextMenu.cpp ├── ShellContextMenu.h ├── TextOffset.h ├── Theme.cpp ├── Theme.h ├── compatibility.manifest ├── grepWin.cpp ├── grepWin.vcxproj ├── grepWin.vcxproj.filters ├── last │ └── version.h ├── packages.config ├── resource.h ├── stdafx.cpp ├── stdafx.h └── version.in ├── tools ├── ResText.exe ├── checkyear.js └── coverity.bat ├── translations ├── Afrikaans.lang ├── Belarusian.lang ├── Chinese Simplified.lang ├── Chinese Traditional.lang ├── Dutch.lang ├── English.lang ├── French.lang ├── German.lang ├── Greek.lang ├── Hindi.lang ├── Hungarian.lang ├── Italian.lang ├── Japanese.lang ├── Korean.lang ├── Polish.lang ├── Portuguese Brazilian.lang ├── Portuguese.lang ├── Russian.lang ├── Slovak.lang ├── Spanish Mexican.lang ├── Spanish.lang ├── Swedish.lang ├── Tamil.lang └── Turkish.lang ├── version.build.in ├── version.txt └── versioninfo.build /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -4 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveAssignments: AcrossEmptyLinesAndComments 6 | AlignConsecutiveBitFields: AcrossEmptyLinesAndComments 7 | AlignConsecutiveDeclarations: AcrossEmptyLinesAndComments 8 | AlignConsecutiveMacros: AcrossEmptyLinesAndComments 9 | AlignEscapedNewlines: Right 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllParametersOfDeclarationOnNextLine: true 13 | AllowShortBlocksOnASingleLine: false 14 | AllowShortCaseLabelsOnASingleLine: false 15 | AllowShortFunctionsOnASingleLine: All 16 | AllowShortIfStatementsOnASingleLine: false 17 | AllowShortLoopsOnASingleLine: false 18 | AlwaysBreakAfterDefinitionReturnType: None 19 | AlwaysBreakAfterReturnType: None 20 | AlwaysBreakBeforeMultilineStrings: false 21 | AlwaysBreakTemplateDeclarations: false 22 | BinPackArguments: true 23 | BinPackParameters: true 24 | BraceWrapping: 25 | AfterCaseLabel: true 26 | AfterClass: true 27 | AfterControlStatement: true 28 | AfterEnum: true 29 | AfterFunction: true 30 | AfterNamespace: true 31 | AfterObjCDeclaration: true 32 | AfterStruct: true 33 | AfterUnion: true 34 | BeforeCatch: true 35 | BeforeElse: true 36 | IndentBraces: false 37 | SplitEmptyFunction: true 38 | SplitEmptyRecord: true 39 | SplitEmptyNamespace: true 40 | BreakBeforeBinaryOperators: None 41 | BreakBeforeBraces: Custom 42 | BreakBeforeInheritanceComma: true 43 | BreakBeforeTernaryOperators: true 44 | BreakConstructorInitializersBeforeComma: true 45 | BreakConstructorInitializers: BeforeColon 46 | BreakAfterJavaFieldAnnotations: false 47 | BreakStringLiterals: true 48 | ColumnLimit: 0 49 | CommentPragmas: '^ IWYU pragma:' 50 | CompactNamespaces: false 51 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 52 | ConstructorInitializerIndentWidth: 4 53 | ContinuationIndentWidth: 4 54 | Cpp11BracedListStyle: true 55 | DerivePointerAlignment: false 56 | DisableFormat: false 57 | ExperimentalAutoDetectBinPacking: false 58 | FixNamespaceComments: true 59 | ForEachMacros: 60 | - foreach 61 | - Q_FOREACH 62 | - BOOST_FOREACH 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: true 72 | IndentPPDirectives: AfterHash 73 | IndentWidth: 4 74 | IndentWrappedFunctionNames: true 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: false 78 | MacroBlockBegin: "^\ 79 | BEGIN_MSG_MAP|\ 80 | BEGIN_MESSAGE_MAP|\ 81 | BEGIN_MSG_MAP_EX|\ 82 | BEGIN_MESSAGE_MAP_EX|\ 83 | BEGIN_SAFE_MSG_MAP_EX|\ 84 | CR_BEGIN_MSG_MAP_EX|\ 85 | IPC_BEGIN_MESSAGE_MAP|\ 86 | IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\ 87 | IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\ 88 | IPC_STRUCT_BEGIN|\ 89 | IPC_STRUCT_BEGIN_WITH_PARENT|\ 90 | IPC_STRUCT_TRAITS_BEGIN|\ 91 | POLPARAMS_BEGIN|\ 92 | PPAPI_BEGIN_MESSAGE_MAP$" 93 | MacroBlockEnd: "^\ 94 | CR_END_MSG_MAP|\ 95 | END_MSG_MAP|\ 96 | END_MESSAGE_MAP|\ 97 | IPC_END_MESSAGE_MAP|\ 98 | IPC_PROTOBUF_MESSAGE_TRAITS_END|\ 99 | IPC_STRUCT_END|\ 100 | IPC_STRUCT_TRAITS_END|\ 101 | POLPARAMS_END|\ 102 | PPAPI_END_MESSAGE_MAP$" 103 | MaxEmptyLinesToKeep: 1 104 | NamespaceIndentation: None 105 | ObjCBlockIndentWidth: 2 106 | ObjCSpaceAfterProperty: false 107 | ObjCSpaceBeforeProtocolList: true 108 | PenaltyBreakAssignment: 2 109 | PenaltyBreakBeforeFirstCallParameter: 19 110 | PenaltyBreakComment: 300 111 | PenaltyBreakFirstLessLess: 120 112 | PenaltyBreakString: 1000 113 | PenaltyExcessCharacter: 1000000 114 | PenaltyReturnTypeOnItsOwnLine: 60 115 | PointerAlignment: Left 116 | ReflowComments: true 117 | SortIncludes: false 118 | SortUsingDeclarations: true 119 | SpaceAfterCStyleCast: false 120 | SpaceAfterTemplateKeyword: true 121 | SpaceBeforeAssignmentOperators: true 122 | SpaceBeforeParens: ControlStatements 123 | SpaceInEmptyParentheses: false 124 | SpacesBeforeTrailingComments: 1 125 | SpacesInAngles: false 126 | SpacesInContainerLiterals: false 127 | SpacesInCStyleCastParentheses: false 128 | SpacesInParentheses: false 129 | SpacesInSquareBrackets: false 130 | Standard: Cpp11 131 | TabWidth: 4 132 | UseTab: Never 133 | ... 134 | 135 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /src/Resources/grepWin.rc text working-tree-encoding=UTF-8 2 | /src/Resources/grepWin.rc2 text working-tree-encoding=UTF-8 3 | /src/resource.h text working-tree-encoding=UTF-8 4 | /translations/*.lang text working-tree-encoding=UTF-8 5 | -------------------------------------------------------------------------------- /.github/workflows/msbuild.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "*.md" 7 | pull_request: 8 | paths-ignore: 9 | - "*.md" 10 | 11 | env: 12 | # Path to the solution file relative to the root of the project. 13 | SOLUTION_FILE_PATH: . 14 | 15 | # Configuration type to build. 16 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 17 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 18 | BUILD_CONFIGURATION: Release 19 | 20 | jobs: 21 | build: 22 | runs-on: windows-latest 23 | strategy: 24 | matrix: 25 | include: 26 | - platform: Win32 27 | dir: Release 28 | - platform: x64 29 | dir: Release64 30 | 31 | steps: 32 | - uses: actions/checkout@v4 33 | with: 34 | fetch-depth: 0 35 | submodules: recursive 36 | 37 | - name: Add MSBuild to PATH 38 | uses: microsoft/setup-msbuild@v2 39 | 40 | - name: Restore NuGet packages 41 | working-directory: ${{env.GITHUB_WORKSPACE}} 42 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 43 | 44 | - name: Build ${{matrix.platform}} 45 | working-directory: ${{env.GITHUB_WORKSPACE}} 46 | run: | 47 | Select-Xml -Path ./version.build.in 'project/target/setenv/variable' | ForEach-Object { Set-Variable -Name $_.Node.name -Value $_.Node.value } 48 | $WCREV = git rev-list --count HEAD 49 | $WCDATE = "$($env:GITHUB_SHA.Substring(0,7))" # more specific 50 | $Version = "$MajorVersion.$MinorVersion.$MicroVersion.$WCREV" 51 | Copy-Item "./src/version.in" -Destination "./src/last/version.h" 52 | Copy-Item "./src/Setup/VersionNumberInclude.in.wxi" -Destination "./src/Setup/VersionNumberInclude.wxi" 53 | sed -i "s/\`$MajorVersion\`$/$MajorVersion/gm" ./src/last/version.h ./src/Setup/VersionNumberInclude.wxi 54 | sed -i "s/\`$MinorVersion\`$/$MinorVersion/gm" ./src/last/version.h ./src/Setup/VersionNumberInclude.wxi 55 | sed -i "s/\`$MicroVersion\`$/$MicroVersion/gm" ./src/last/version.h ./src/Setup/VersionNumberInclude.wxi 56 | sed -i "s/\`$WCREV\`$/$WCREV/gm" ./src/last/version.h ./src/Setup/VersionNumberInclude.wxi 57 | sed -i "s/\`$WCDATE\`$/$WCDATE/gm" ./src/last/version.h 58 | msbuild -m -p:Configuration=${{env.BUILD_CONFIGURATION}} -p:Platform=${{matrix.platform}} -warnAsError ${{env.SOLUTION_FILE_PATH}} 59 | Copy-Item "./bin/${{matrix.dir}}/grepWin.exe" -Destination "./bin/${{matrix.dir}}/grepWin-${{matrix.platform}}_portable.exe" 60 | Set-Location -Path "./src/Setup" 61 | if ("${{matrix.platform}}" -eq "x64") { 62 | New-Item -ItemType "directory" -Path . -Name "x64" 63 | sed "s/\`$Version\`$/$Version/gm" AppXManifest.xml.in > x64\AppxManifest.xml 64 | $MSVCRoot = vswhere -property installationPath 65 | & "${env:COMSPEC}" /s /c "`"$MSVCRoot\Common7\Tools\vsdevcmd.bat`" -no_logo -arch=amd64 && set" | ForEach-Object { 66 | $name, $value = $_ -split '=', 2 67 | set-content env:"$name" $value 68 | } 69 | MakeAppX pack /o /d x64 -p ..\..\bin\release64\package.msix /nv 70 | # unsigned 71 | } 72 | candle -nologo -dPlatform=${{matrix.platform}} -out ..\..\bin\Setup-${{matrix.platform}}.wixobj Setup.wxs 73 | light -nologo -sice:ICE57 -ext WixUIExtension -cultures:en-us -out ..\..\bin\grepWin-${{matrix.platform}}.msi ..\..\bin\Setup-${{matrix.platform}}.wixobj 74 | 75 | - name: Upload artifacts for ${{matrix.platform}} 76 | uses: actions/upload-artifact@v4 77 | with: 78 | name: grepWin-${{matrix.platform}}_portable 79 | path: bin/${{matrix.dir}}/grepWin-${{matrix.platform}}_portable.exe 80 | - name: Upload artifacts for ${{matrix.platform}} msi 81 | uses: actions/upload-artifact@v4 82 | with: 83 | name: grepWin-${{matrix.platform}}-msi 84 | path: bin/*.msi 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /default.build.user 2 | /obj 3 | /bin 4 | /.vs 5 | /packages 6 | /src/grepWin.vcxproj.user 7 | /src/version.h 8 | /version.build 9 | /signinfo.txt 10 | /src/Resources/grepWin.aps 11 | /src/Setup/VersionNumberInclude.wxi 12 | /test 13 | /choco/package 14 | /_ReSharper.Caches 15 | /src/ExplorerCommandVerb/ExplorerCommandVerb.vcxproj.user 16 | /src/Setup/x64 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sktoolslib"] 2 | path = sktoolslib 3 | url = https://github.com/stefankueng/sktoolslib.git 4 | branch = main 5 | -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/.nuget/NuGet.exe -------------------------------------------------------------------------------- /.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) 32 | 33 | 34 | 35 | 36 | $(SolutionDir).nuget 37 | packages.config 38 | 39 | 40 | 41 | 42 | $(NuGetToolsPath)\NuGet.exe 43 | @(PackageSource) 44 | 45 | "$(NuGetExePath)" 46 | mono --runtime=v4.0.30319 $(NuGetExePath) 47 | 48 | $(TargetDir.Trim('\\')) 49 | 50 | -RequireConsent 51 | -NonInteractive 52 | 53 | "$(SolutionDir) " 54 | "$(SolutionDir)" 55 | 56 | 57 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 58 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 59 | 60 | 61 | 62 | RestorePackages; 63 | $(BuildDependsOn); 64 | 65 | 66 | 67 | 68 | $(BuildDependsOn); 69 | BuildPackage; 70 | 71 | 72 | 73 | 74 | 75 | 76 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | 98 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /.tgitconfig: -------------------------------------------------------------------------------- 1 | [bugtraq] 2 | url = https://github.com/stefankueng/grepWin/issues/%BUGID% 3 | logregex = "([Cc]loses?)?:?(\\s*(,|and)?\\s*#\\d+)+\n(\\d+)" 4 | [hook "precommit"] 5 | cmdline = WScript %root%\\\\tools\\\\checkyear.js 6 | wait = true 7 | show = false 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Don't have one. Don't want one. 4 | 5 | That's the short version. 6 | 7 | Now the _long version_: 8 | 9 | 1. Having a code of conduct means forcing rules on our community. We don't want that. We want to be free of restrictions and just get the project going. 10 | 2. We don't care about your political views, your race, gender, hair color, tatoos or whatever. We just don't. And we don't ask. Because it has nothing to do with this project. 11 | 3. We do care about the project, and the code. And nothing else. 12 | 13 | If we can't be civil among each other, then having a code of conduct won't help either. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # grepWin 2 | Regular expression search and replace for Windows 3 | 4 | [![Build](https://github.com/stefankueng/grepWin/actions/workflows/msbuild.yml/badge.svg)](https://github.com/stefankueng/grepWin/actions/workflows/msbuild.yml) 5 | 6 | grepWin is a simple search and replace tool which can use [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) to do its job. This allows to do much more powerful searches and replaces. 7 | 8 | In case you're not familiar with regular expressions, we have a very short [regular expression tutorial](https://tools.stefankueng.com/regexhelp.html) for you. 9 | 10 | [![grepWin](https://github.com/stefankueng/grepWin/raw/main/src/Resources/grepWin_search-small.png)](https://github.com/stefankueng/grepWin/raw/main/src/Resources/grepWin_search.png) 11 | 12 | # Command line parameters 13 | The command line parameters are listed on a [separate page](https://tools.stefankueng.com/grepWin_cmd.html). 14 | 15 | Please visit the [homepage](https://tools.stefankueng.com/grepWin.html) of grepWin for more information. 16 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # .NET Desktop 2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/vsts/pipelines/apps/windows/dot-net 5 | 6 | pool: 7 | vmImage: 'windows-2019' 8 | 9 | variables: 10 | solution: '**/*.sln' 11 | buildPlatform: 'x64' 12 | buildConfiguration: 'Release' 13 | 14 | steps: 15 | - task: NuGetToolInstaller@1 16 | 17 | - task: NuGetCommand@2 18 | inputs: 19 | restoreSolution: '$(solution)' 20 | 21 | - task: VSBuild@1 22 | inputs: 23 | solution: '$(solution)' 24 | platform: '$(buildPlatform)' 25 | configuration: '$(buildConfiguration)' 26 | 27 | - task: VSTest@2 28 | inputs: 29 | platform: '$(buildPlatform)' 30 | configuration: '$(buildConfiguration)' 31 | -------------------------------------------------------------------------------- /build.txt: -------------------------------------------------------------------------------- 1 | First make sure you've cloned the repository recursively to get the submodule 2 | as well! 3 | 4 | Then you need to install the compiler package. 5 | 6 | - You need VS2022. 7 | If you want to build the msi make sure the "Tools for Redistributing 8 | Applications" are installed. 9 | 10 | If you just want to build the exe without the installer and if you're comfortable 11 | with the exe having version 1.0.0.0 in the resources, you can just open the 12 | grepWin.sln file in Visual Studio and build the project. 13 | 14 | If you want to use the build script you have to do a little bit more work first: 15 | 16 | you need to install some utilities/programs: 17 | - TortoiseGit : http://tortoisegit.org 18 | - WiX 3.10(*) : http://wixtoolset.org/ 19 | - NAnt 0.92(*) : http://nant.sourceforge.net 20 | 21 | (*) Add the paths of the binaries to the PATH environment variable. 22 | You may have to logoff/logon to make the new environment variables take effect! 23 | 24 | Now you're almost ready. Only a few more steps to do: 25 | - Clone the grepWin repository from GitHub and checkout the source 26 | Note: you have to clone recursively to also get the submodules 27 | - Make a copy of the file default.build.user.tmpl in the grepWin root folder and 28 | rename that copy to default.build.user. Then adjust the paths as mentioned 29 | in that file. 30 | 31 | 32 | Building packages 33 | 34 | Hint: before you can start building grepWin with the NAnt script, you need to 35 | call the vcvars32.bat or vcvars64.bat which are located in 36 | C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build 37 | 38 | > nant 39 | will compile grepWin 40 | 41 | > nant setup 42 | will compile grepWin and create the msi installer 43 | 44 | If you encounter any build errors, you can run nant again like this: 45 | 46 | > nant setup -l:buildlog.txt 47 | 48 | which will create a build log file which you can use to analyse where 49 | exactly the build failed. 50 | 51 | 52 | After the script finished, the packages can be found in .\bin. 53 | 54 | Once grepWin has been built with the NAnt script, you can build it again 55 | with VS2022 alone and get the correct version info in the resources. 56 | -------------------------------------------------------------------------------- /choco/chocolateyInstall.ps1: -------------------------------------------------------------------------------- 1 | Install-ChocolateyPackage 'grepWin' 'msi' '/quiet' 'https://github.com/stefankueng/grepWin/releases/download/$MajorVersion$.$MinorVersion$.$MicroVersion$/grepWin-$MajorVersion$.$MinorVersion$.$MicroVersion$.msi' 'https://github.com/stefankueng/grepWin/releases/download/$MajorVersion$.$MinorVersion$.$MicroVersion$/grepWin-$MajorVersion$.$MinorVersion$.$MicroVersion$-x64.msi' -checksum '$checksum$' -checksum64 '$checksum64$' -checksumType 'sha256' -------------------------------------------------------------------------------- /choco/grepwin.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | grepwin 5 | grepWin 6 | $MajorVersion$.$MinorVersion$.$MicroVersion$ 7 | Stefan Kueng 8 | Stefan Kueng 9 | grepWin is a powerful and fast search tool using regular expressions. 10 | grepWin is a simple search and replace tool which can use regular expressions to do its job. This allows to do much more powerful searches and replaces. 11 | https://tools.stefankueng.com/grepWin.html 12 | grepwin grep search regex admin 13 | http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 14 | false 15 | https://github.com/stefankueng/grepWin/raw/main/src/Resources/grepwin_256.png 16 | https://github.com/stefankueng/grepWin 17 | https://github.com/stefankueng/grepWin/issues 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /default.build.user.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | You must first call "%VS140COMNTOOLS%\vsvars32.bat" 24 | 25 | 26 | 27 | 28 | 34 | 35 | 36 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /grepWin.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.0.31912.275 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grepWin", "src\grepWin.vcxproj", "{0049F8CF-1BEC-4E6E-B457-0187A33AD522}" 6 | EndProject 7 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D32CB10B-1891-471D-B780-5445BC67C1E2}" 8 | ProjectSection(SolutionItems) = preProject 9 | .nuget\NuGet.Config = .nuget\NuGet.Config 10 | .nuget\NuGet.exe = .nuget\NuGet.exe 11 | .nuget\NuGet.targets = .nuget\NuGet.targets 12 | EndProjectSection 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerCommandVerb", "src\ExplorerCommandVerb\ExplorerCommandVerb.vcxproj", "{585A1606-DC66-49BA-BFFB-E6F0B63A66BF}" 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Setup", "Setup", "{89723F04-E4BB-4E0E-917F-75B12FBCD5F0}" 17 | ProjectSection(SolutionItems) = preProject 18 | src\Setup\AppXManifest.xml.in = src\Setup\AppXManifest.xml.in 19 | src\Setup\setup.build = src\Setup\setup.build 20 | src\Setup\Setup.wxs = src\Setup\Setup.wxs 21 | EndProjectSection 22 | EndProject 23 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CustomActions", "src\Setup\CustomActions\CustomActions.vcxproj", "{454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}" 24 | EndProject 25 | Global 26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 27 | Debug|Win32 = Debug|Win32 28 | Debug|x64 = Debug|x64 29 | Release|Win32 = Release|Win32 30 | Release|x64 = Release|x64 31 | EndGlobalSection 32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 33 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Debug|Win32.ActiveCfg = Debug|Win32 34 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Debug|Win32.Build.0 = Debug|Win32 35 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Debug|x64.ActiveCfg = Debug|x64 36 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Debug|x64.Build.0 = Debug|x64 37 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Release|Win32.ActiveCfg = Release|Win32 38 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Release|Win32.Build.0 = Release|Win32 39 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Release|x64.ActiveCfg = Release|x64 40 | {0049F8CF-1BEC-4E6E-B457-0187A33AD522}.Release|x64.Build.0 = Release|x64 41 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Debug|Win32.ActiveCfg = Debug|Win32 42 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Debug|Win32.Build.0 = Debug|Win32 43 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Debug|x64.ActiveCfg = Debug|x64 44 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Debug|x64.Build.0 = Debug|x64 45 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Release|Win32.ActiveCfg = Release|Win32 46 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Release|Win32.Build.0 = Release|Win32 47 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Release|x64.ActiveCfg = Release|x64 48 | {585A1606-DC66-49BA-BFFB-E6F0B63A66BF}.Release|x64.Build.0 = Release|x64 49 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Debug|Win32.ActiveCfg = Release|Win32 50 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Debug|Win32.Build.0 = Release|Win32 51 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Debug|x64.ActiveCfg = Release|x64 52 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Debug|x64.Build.0 = Release|x64 53 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Release|Win32.ActiveCfg = Release|Win32 54 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Release|Win32.Build.0 = Release|Win32 55 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Release|x64.ActiveCfg = Release|x64 56 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181}.Release|x64.Build.0 = Release|x64 57 | EndGlobalSection 58 | GlobalSection(SolutionProperties) = preSolution 59 | HideSolutionNode = FALSE 60 | EndGlobalSection 61 | GlobalSection(NestedProjects) = preSolution 62 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181} = {89723F04-E4BB-4E0E-917F-75B12FBCD5F0} 63 | EndGlobalSection 64 | GlobalSection(ExtensibilityGlobals) = postSolution 65 | SolutionGuid = {DD6F736F-53AC-4B02-8607-993275ABED73} 66 | EndGlobalSection 67 | EndGlobal 68 | -------------------------------------------------------------------------------- /grepWin.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | 4 | True 5 | MB 6 | <NamingElement Priority="24"><Descriptor Static="False" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="PUBLIC"><type Name="class field" /><type Name="union member" /></Descriptor><Policy Inspect="False" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="m_" Suffix="" Style="aaBb" /></Policy></NamingElement> -------------------------------------------------------------------------------- /src/AboutDlg.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2013, 2018, 2020-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "resource.h" 21 | #include "AboutDlg.h" 22 | #include "version.h" 23 | #include "Theme.h" 24 | #include 25 | #include 26 | 27 | CAboutDlg::CAboutDlg(HWND hParent) 28 | : m_hParent(hParent) 29 | , m_themeCallbackId(0) 30 | { 31 | } 32 | 33 | CAboutDlg::~CAboutDlg() 34 | { 35 | } 36 | 37 | LRESULT CAboutDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 38 | { 39 | UNREFERENCED_PARAMETER(lParam); 40 | switch (uMsg) 41 | { 42 | case WM_INITDIALOG: 43 | { 44 | m_themeCallbackId = CTheme::Instance().RegisterThemeChangeCallback( 45 | [this]() { 46 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 47 | }); 48 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 49 | InitDialog(hwndDlg, IDI_GREPWIN); 50 | CLanguage::Instance().TranslateWindow(*this); 51 | wchar_t buf[MAX_PATH] = {0}; 52 | swprintf_s(buf, _countof(buf), L"grepWin version %ld.%ld.%ld.%ld", GREPWIN_VERMAJOR, GREPWIN_VERMINOR, GREPWIN_VERMICRO, GREPWIN_VERBUILD); 53 | SetDlgItemText(*this, IDC_VERSIONINFO, buf); 54 | SetDlgItemText(*this, IDC_DATE, TEXT(GREPWIN_VERDATE)); 55 | } 56 | return TRUE; 57 | case WM_COMMAND: 58 | return DoCommand(LOWORD(wParam), HIWORD(wParam)); 59 | case WM_CLOSE: 60 | CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId); 61 | break; 62 | case WM_NOTIFY: 63 | { 64 | switch (wParam) 65 | { 66 | case IDC_WEBLINK: 67 | switch (reinterpret_cast(lParam)->code) 68 | { 69 | case NM_CLICK: 70 | case NM_RETURN: 71 | { 72 | PNMLINK pNMLink = reinterpret_cast(lParam); 73 | LITEM item = pNMLink->item; 74 | if (item.iLink == 0) 75 | { 76 | ShellExecute(*this, L"open", item.szUrl, nullptr, nullptr, SW_SHOW); 77 | } 78 | break; 79 | } 80 | } 81 | break; 82 | default: 83 | break; 84 | } 85 | } 86 | break; 87 | default: 88 | return FALSE; 89 | } 90 | return FALSE; 91 | } 92 | 93 | LRESULT CAboutDlg::DoCommand(int id, int /*msg*/) 94 | { 95 | switch (id) 96 | { 97 | case IDOK: 98 | // fall through 99 | case IDCANCEL: 100 | EndDialog(*this, id); 101 | break; 102 | default: 103 | break; 104 | } 105 | return 1; 106 | } 107 | -------------------------------------------------------------------------------- /src/AboutDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2013, 2020-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | 22 | /** 23 | * bookmarks dialog. 24 | */ 25 | class CAboutDlg : public CDialog 26 | { 27 | public: 28 | CAboutDlg(HWND hParent); 29 | ~CAboutDlg() override; 30 | 31 | protected: 32 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 33 | LRESULT DoCommand(int id, int msg); 34 | 35 | private: 36 | HWND m_hParent; 37 | int m_themeCallbackId; 38 | }; 39 | -------------------------------------------------------------------------------- /src/Bookmarks.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2009, 2012-2013, 2017, 2020-2023 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "Bookmarks.h" 21 | #include "maxpath.h" 22 | #include 23 | #include 24 | 25 | CBookmarks::CBookmarks() 26 | { 27 | SetUnicode(true); 28 | } 29 | 30 | CBookmarks::~CBookmarks() 31 | { 32 | } 33 | 34 | void CBookmarks::Load() 35 | { 36 | auto path = std::make_unique(MAX_PATH_NEW); 37 | GetModuleFileName(nullptr, path.get(), MAX_PATH_NEW); 38 | if (bPortable) 39 | { 40 | m_iniPath = path.get(); 41 | m_iniPath = m_iniPath.substr(0, m_iniPath.rfind('\\')); 42 | } 43 | else 44 | { 45 | SHGetFolderPath(nullptr, CSIDL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, path.get()); 46 | m_iniPath = path.get(); 47 | m_iniPath += L"\\grepWin"; 48 | } 49 | CreateDirectory(m_iniPath.c_str(), nullptr); 50 | m_iniPath += L"\\bookmarks"; 51 | SetUnicode(); 52 | SetMultiLine(true); // multiline search 53 | LoadFile(m_iniPath.c_str()); 54 | } 55 | 56 | void CBookmarks::Save() const 57 | { 58 | assert(!m_iniPath.empty()); 59 | FILE* pFile = nullptr; 60 | _wfopen_s(&pFile, m_iniPath.c_str(), L"wb"); 61 | SaveFile(pFile); 62 | fclose(pFile); 63 | } 64 | 65 | void CBookmarks::AddBookmark(const Bookmark& bm) 66 | { 67 | std::wstring val = L"\""; 68 | val += bm.Search; 69 | val += L"\""; 70 | SetValue(bm.Name.c_str(), L"searchString", val.c_str()); 71 | 72 | val = L"\""; 73 | val += bm.Replace; 74 | val += L"\""; 75 | SetValue(bm.Name.c_str(), L"replaceString", val.c_str()); 76 | SetValue(bm.Name.c_str(), L"useregex", bm.UseRegex ? L"true" : L"false"); 77 | SetValue(bm.Name.c_str(), L"casesensitive", bm.CaseSensitive ? L"true" : L"false"); 78 | SetValue(bm.Name.c_str(), L"dotmatchesnewline", bm.DotMatchesNewline ? L"true" : L"false"); 79 | SetValue(bm.Name.c_str(), L"backup", bm.Backup ? L"true" : L"false"); 80 | SetValue(bm.Name.c_str(), L"keepfiledate", bm.KeepFileDate ? L"true" : L"false"); 81 | SetValue(bm.Name.c_str(), L"wholewords", bm.WholeWords ? L"true" : L"false"); 82 | SetValue(bm.Name.c_str(), L"utf8", bm.Utf8 ? L"true" : L"false"); 83 | SetValue(bm.Name.c_str(), L"includesystem", bm.IncludeSystem ? L"true" : L"false"); 84 | SetValue(bm.Name.c_str(), L"includefolder", bm.IncludeFolder ? L"true" : L"false"); 85 | SetValue(bm.Name.c_str(), L"includesymlinks", bm.IncludeSymLinks ? L"true" : L"false"); 86 | SetValue(bm.Name.c_str(), L"includehidden", bm.IncludeHidden ? L"true" : L"false"); 87 | SetValue(bm.Name.c_str(), L"includebinary", bm.IncludeBinary ? L"true" : L"false"); 88 | val = L"\""; 89 | val += bm.ExcludeDirs; 90 | val += L"\""; 91 | SetValue(bm.Name.c_str(), L"excludedirs", val.c_str()); 92 | val = L"\""; 93 | val += bm.FileMatch; 94 | val += L"\""; 95 | SetValue(bm.Name.c_str(), L"filematch", val.c_str()); 96 | SetValue(bm.Name.c_str(), L"filematchregex", bm.FileMatchRegex ? L"true" : L"false"); 97 | SetValue(bm.Name.c_str(), L"searchpath", bm.Path.c_str()); 98 | } 99 | 100 | void CBookmarks::RemoveBookmark(const std::wstring& name) 101 | { 102 | Delete(name.c_str(), L"searchString", true); 103 | Delete(name.c_str(), L"replaceString", true); 104 | Delete(name.c_str(), L"useregex", true); 105 | Delete(name.c_str(), L"casesensitive", true); 106 | Delete(name.c_str(), L"dotmatchesnewline", true); 107 | Delete(name.c_str(), L"backup", true); 108 | Delete(name.c_str(), L"keepfiledate", true); 109 | Delete(name.c_str(), L"wholewords", true); 110 | Delete(name.c_str(), L"utf8", true); 111 | Delete(name.c_str(), L"includesystem", true); 112 | Delete(name.c_str(), L"includefolder", true); 113 | Delete(name.c_str(), L"includesymlinks", true); 114 | Delete(name.c_str(), L"includehidden", true); 115 | Delete(name.c_str(), L"includebinary", true); 116 | Delete(name.c_str(), L"excludedirs", true); 117 | Delete(name.c_str(), L"filematch", true); 118 | Delete(name.c_str(), L"filematchregex", true); 119 | Delete(name.c_str(), L"searchpath", true); 120 | } 121 | 122 | Bookmark CBookmarks::GetBookmark(const std::wstring& name) const 123 | { 124 | Bookmark bk; 125 | if (GetSectionSize(name.c_str()) >= 0) 126 | { 127 | bk.Name = name; 128 | bk.Search = GetValue(name.c_str(), L"searchString", L""); 129 | bk.Replace = GetValue(name.c_str(), L"replaceString", L""); 130 | bk.UseRegex = wcscmp(GetValue(name.c_str(), L"useregex", L"false"), L"true") == 0; 131 | bk.CaseSensitive = wcscmp(GetValue(name.c_str(), L"casesensitive", L"false"), L"true") == 0; 132 | bk.DotMatchesNewline = wcscmp(GetValue(name.c_str(), L"dotmatchesnewline", L"false"), L"true") == 0; 133 | bk.Backup = wcscmp(GetValue(name.c_str(), L"backup", L"false"), L"true") == 0; 134 | bk.KeepFileDate = wcscmp(GetValue(name.c_str(), L"keepfiledate", L"false"), L"true") == 0; 135 | bk.WholeWords = wcscmp(GetValue(name.c_str(), L"wholewords", L"false"), L"true") == 0; 136 | bk.Utf8 = wcscmp(GetValue(name.c_str(), L"utf8", L"false"), L"true") == 0; 137 | bk.IncludeSystem = wcscmp(GetValue(name.c_str(), L"includesystem", L"false"), L"true") == 0; 138 | bk.IncludeFolder = wcscmp(GetValue(name.c_str(), L"includefolder", L"false"), L"true") == 0; 139 | bk.IncludeSymLinks = wcscmp(GetValue(name.c_str(), L"includesymlinks", L"false"), L"true") == 0; 140 | bk.IncludeHidden = wcscmp(GetValue(name.c_str(), L"includehidden", L"false"), L"true") == 0; 141 | bk.IncludeBinary = wcscmp(GetValue(name.c_str(), L"includebinary", L"false"), L"true") == 0; 142 | bk.ExcludeDirs = GetValue(name.c_str(), L"excludedirs", L""); 143 | bk.FileMatch = GetValue(name.c_str(), L"filematch", L""); 144 | bk.FileMatchRegex = wcscmp(GetValue(name.c_str(), L"filematchregex", L"false"), L"true") == 0; 145 | bk.Path = GetValue(name.c_str(), L"searchpath", L""); 146 | 147 | RemoveQuotes(bk.Search); 148 | RemoveQuotes(bk.Replace); 149 | RemoveQuotes(bk.ExcludeDirs); 150 | RemoveQuotes(bk.FileMatch); 151 | } 152 | 153 | return bk; 154 | } 155 | 156 | void CBookmarks::RemoveQuotes(std::wstring& str) 157 | { 158 | if (!str.empty()) 159 | { 160 | if (str[0] == '"') 161 | str = str.substr(1); 162 | if (!str.empty()) 163 | { 164 | if (str[str.size() - 1] == '"') 165 | str = str.substr(0, str.size() - 1); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/Bookmarks.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2013, 2020-2023 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "SimpleIni.h" 21 | #include 22 | #include 23 | 24 | class Bookmark 25 | { 26 | public: 27 | Bookmark() 28 | : UseRegex(false) 29 | , CaseSensitive(false) 30 | , DotMatchesNewline(false) 31 | , Backup(false) 32 | , KeepFileDate(false) 33 | , WholeWords(false) 34 | , Utf8(false) 35 | , Binary(false) 36 | , IncludeSystem(false) 37 | , IncludeFolder(false) 38 | , IncludeSymLinks(false) 39 | , IncludeHidden(false) 40 | , IncludeBinary(false) 41 | , FileMatchRegex(false) 42 | { 43 | } 44 | 45 | ~Bookmark(){}; 46 | 47 | std::wstring Name; 48 | std::wstring Search; 49 | std::wstring Replace; 50 | std::wstring Path; 51 | bool UseRegex; 52 | bool CaseSensitive; 53 | bool DotMatchesNewline; 54 | bool Backup; 55 | bool KeepFileDate; 56 | bool WholeWords; 57 | bool Utf8; 58 | bool Binary; 59 | bool IncludeSystem; 60 | bool IncludeFolder; 61 | bool IncludeSymLinks; 62 | bool IncludeHidden; 63 | bool IncludeBinary; 64 | std::wstring ExcludeDirs; 65 | std::wstring FileMatch; 66 | bool FileMatchRegex; 67 | }; 68 | 69 | class CBookmarks : public CSimpleIni 70 | { 71 | public: 72 | CBookmarks(); 73 | ~CBookmarks(); 74 | 75 | void Load(); 76 | void Save() const; 77 | void AddBookmark(const Bookmark& bm); 78 | void RemoveBookmark(const std::wstring& name); 79 | Bookmark GetBookmark(const std::wstring& name) const; 80 | static void RemoveQuotes(std::wstring& str); 81 | 82 | protected: 83 | std::wstring m_iniPath; 84 | TNamesDepend m_sections; 85 | }; 86 | -------------------------------------------------------------------------------- /src/BookmarksDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2009, 2012-2013, 2016, 2019-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "DlgResizer.h" 22 | #include "Bookmarks.h" 23 | #include 24 | 25 | #define WM_BOOKMARK (WM_APP + 20) 26 | 27 | /** 28 | * bookmarks dialog. 29 | */ 30 | class CBookmarksDlg : public CDialog 31 | { 32 | public: 33 | CBookmarksDlg(HWND hParent); 34 | ~CBookmarksDlg() override; 35 | 36 | void InitBookmarks(); 37 | std::wstring GetName() const { return m_name; } 38 | std::wstring GetSelectedSearchString() const { return m_searchString; } 39 | std::wstring GetSelectedReplaceString() const { return m_replaceString; } 40 | std::wstring GetPath() const { return m_path; } 41 | bool GetSelectedUseRegex() const { return m_bUseRegex; } 42 | bool GetSelectedSearchCase() const { return m_bCaseSensitive; } 43 | bool GetSelectedDotMatchNewline() const { return m_bDotMatchesNewline; } 44 | bool GetSelectedBackup() const { return m_bBackup; } 45 | bool GetSelectedKeepFileDate() const { return m_bKeepFileDate; } 46 | bool GetSelectedWholeWords() const { return m_bWholeWords; } 47 | bool GetSelectedTreatAsUtf8() const { return m_bUtf8; } 48 | bool GetSelectedTreatAsBinary() const { return m_bForceBinary; } 49 | bool GetSelectedIncludeSystem() const { return m_bIncludeSystem; } 50 | bool GetSelectedIncludeFolder() const { return m_bIncludeFolder; } 51 | bool GetSelectedIncludeSymLinks() const { return m_bIncludeSymLinks; } 52 | bool GetSelectedIncludeHidden() const { return m_bIncludeHidden; } 53 | bool GetSelectedIncludeBinary() const { return m_bIncludeBinary; } 54 | std::wstring GetSelectedExcludeDirs() const { return m_sExcludeDirs; } 55 | std::wstring GetSelectedFileMatch() const { return m_sFileMatch; } 56 | bool GetSelectedFileMatchRegex() const { return m_bFileMatchRegex; } 57 | 58 | protected: 59 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 60 | LRESULT DoCommand(int id, int msg); 61 | void PrepareSelected(); 62 | 63 | private: 64 | HWND m_hParent; 65 | std::wstring m_name; 66 | CBookmarks m_bookmarks; 67 | 68 | std::wstring m_searchString; 69 | std::wstring m_replaceString; 70 | std::wstring m_path; 71 | bool m_bUseRegex; 72 | bool m_bCaseSensitive; 73 | bool m_bDotMatchesNewline; 74 | bool m_bBackup; 75 | bool m_bKeepFileDate; 76 | bool m_bWholeWords; 77 | bool m_bUtf8; 78 | bool m_bForceBinary; 79 | bool m_bIncludeSystem; 80 | bool m_bIncludeFolder; 81 | bool m_bIncludeSymLinks; 82 | bool m_bIncludeHidden; 83 | bool m_bIncludeBinary; 84 | std::wstring m_sExcludeDirs; 85 | std::wstring m_sFileMatch; 86 | bool m_bFileMatchRegex; 87 | 88 | int m_themeCallbackId; 89 | CDlgResizer m_resizer; 90 | }; 91 | -------------------------------------------------------------------------------- /src/COMPtrs.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2009, 2012-2013, 2016, 2019-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | _COM_SMARTPTR_TYPEDEF(IFileOpenDialog, __uuidof(IFileOpenDialog)); 27 | _COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); 28 | _COM_SMARTPTR_TYPEDEF(IShellItemArray, __uuidof(IShellItemArray)); 29 | _COM_SMARTPTR_TYPEDEF(IFileOperation, __uuidof(IFileOperation)); 30 | _COM_SMARTPTR_TYPEDEF(IStream, __uuidof(IStream)); 31 | _COM_SMARTPTR_TYPEDEF(IFileSaveDialog, __uuidof(IFileSaveDialog)); 32 | _COM_SMARTPTR_TYPEDEF(IShellItem, __uuidof(IShellItem)); 33 | _COM_SMARTPTR_TYPEDEF(IFileDialogCustomize, __uuidof(IFileDialogCustomize)); 34 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/ExplorerCommandVerb.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {585a1606-dc66-49ba-bffb-e6f0b63a66bf} 25 | ExplorerCommandVerb 26 | 27 | 28 | 29 | DynamicLibrary 30 | true 31 | v143 32 | Unicode 33 | 34 | 35 | DynamicLibrary 36 | false 37 | v143 38 | true 39 | Unicode 40 | 41 | 42 | DynamicLibrary 43 | true 44 | v143 45 | Unicode 46 | 47 | 48 | DynamicLibrary 49 | false 50 | v143 51 | true 52 | Unicode 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | true 74 | $(SolutionDir)bin\$(Configuration)\ 75 | $(SolutionDir)obj\$(Configuration)\$(ProjectName)\ 76 | 77 | 78 | false 79 | $(SolutionDir)bin\$(Configuration)\ 80 | $(SolutionDir)obj\$(Configuration)\$(ProjectName)\ 81 | 82 | 83 | true 84 | $(SolutionDir)bin\$(Configuration)64\ 85 | $(SolutionDir)obj\$(Configuration)64\$(ProjectName)\ 86 | 87 | 88 | false 89 | $(SolutionDir)bin\$(Configuration)64\ 90 | $(SolutionDir)obj\$(Configuration)64\$(ProjectName)\ 91 | 92 | 93 | 94 | Level3 95 | true 96 | WIN32;_DEBUG;EXPLORERCOMMANDVERB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 97 | true 98 | Use 99 | pch.h 100 | stdcpp20 101 | MultiThreadedDebug 102 | 103 | 104 | Windows 105 | true 106 | false 107 | runtimeobject.lib;%(AdditionalDependencies) 108 | source.def 109 | 110 | 111 | 112 | 113 | Level3 114 | true 115 | true 116 | true 117 | WIN32;NDEBUG;EXPLORERCOMMANDVERB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 118 | true 119 | Use 120 | pch.h 121 | stdcpp20 122 | MultiThreaded 123 | 124 | 125 | Windows 126 | true 127 | true 128 | true 129 | false 130 | runtimeobject.lib;%(AdditionalDependencies) 131 | source.def 132 | 133 | 134 | 135 | 136 | Level3 137 | true 138 | _DEBUG;EXPLORERCOMMANDVERB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 139 | true 140 | Use 141 | pch.h 142 | stdcpp20 143 | MultiThreadedDebug 144 | 145 | 146 | Windows 147 | true 148 | false 149 | runtimeobject.lib;%(AdditionalDependencies) 150 | source.def 151 | 152 | 153 | 154 | 155 | Level3 156 | true 157 | true 158 | true 159 | NDEBUG;EXPLORERCOMMANDVERB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 160 | true 161 | Use 162 | pch.h 163 | stdcpp20 164 | MultiThreaded 165 | 166 | 167 | Windows 168 | true 169 | true 170 | true 171 | false 172 | runtimeobject.lib;%(AdditionalDependencies) 173 | source.def 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | Create 184 | Create 185 | Create 186 | Create 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 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}. 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/ExplorerCommandVerb.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | 34 | 35 | Source Files 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/compatibility.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | // Windows Header Files 5 | #include 6 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /src/ExplorerCommandVerb/source.def: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | EXPORTS 3 | DllCanUnloadNow PRIVATE 4 | DllGetClassObject PRIVATE 5 | DllGetActivationFactory PRIVATE 6 | -------------------------------------------------------------------------------- /src/LineData.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2012 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | 23 | struct LineDataLine 24 | { 25 | DWORD number; 26 | DWORD column; 27 | std::wstring text; 28 | }; 29 | 30 | struct LineData 31 | { 32 | std::wstring path; 33 | std::vector lines; 34 | }; -------------------------------------------------------------------------------- /src/MultiLineEditDlg.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2011-2013, 2019-2021, 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "resource.h" 21 | #include "MultiLineEditDlg.h" 22 | 23 | #include "NewlinesDlg.h" 24 | #include "Theme.h" 25 | #include "../sktoolslib/StringUtils.h" 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | CMultiLineEditDlg::CMultiLineEditDlg(HWND hParent) 32 | : m_hParent(hParent) 33 | , m_themeCallbackId(0) 34 | , m_forReplace(false) 35 | , m_forRegex(false) 36 | { 37 | } 38 | 39 | CMultiLineEditDlg::~CMultiLineEditDlg() 40 | { 41 | } 42 | 43 | void CMultiLineEditDlg::setForReplace() 44 | { 45 | m_forReplace = true; 46 | } 47 | void CMultiLineEditDlg::setForRegex() 48 | { 49 | m_forRegex = true; 50 | } 51 | 52 | LRESULT CMultiLineEditDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 53 | { 54 | UNREFERENCED_PARAMETER(lParam); 55 | switch (uMsg) 56 | { 57 | case WM_INITDIALOG: 58 | { 59 | m_themeCallbackId = CTheme::Instance().RegisterThemeChangeCallback( 60 | [this]() { 61 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 62 | }); 63 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 64 | 65 | InitDialog(hwndDlg, IDI_GREPWIN); 66 | CLanguage::Instance().TranslateWindow(*this); 67 | // initialize the controls 68 | if (!m_forRegex) 69 | { 70 | ShowWindow(GetDlgItem(hwndDlg, IDC_CONVERTNEWLINES_BTN), SW_HIDE); 71 | ShowWindow(GetDlgItem(hwndDlg, IDC_INFOLABEL), SW_HIDE); 72 | } 73 | else 74 | { 75 | // does the string already contain newlines? 76 | if (m_regexText.find(L"\n") == std::wstring::npos) 77 | { 78 | // use boost regex to append all \\r\\n, \\r, \\n with newlines, but only if they're not already followed by newlines 79 | m_regexText = boost::regex_replace(m_regexText, boost::wregex(L"(\\\\r\\\\n)(?!\\r|\\n|\\||\\))"), L"\\\\r\\\\n\\r\\n"); 80 | m_regexText = boost::regex_replace(m_regexText, boost::wregex(L"(\\\\r)(?!\\\\n|\\r|\\n|\\||\\))"), L"\\\\r\\r\\n"); 81 | m_regexText = boost::regex_replace(m_regexText, boost::wregex(L"(\\\\n)(?!\\r|\\n|\\||\\))"), L"\\\\n\\r\\n"); 82 | m_regexText = boost::regex_replace(m_regexText, boost::wregex(L"(\\(\\\\r\\\\n\\|\\\\r\\|\\\\n\\))(?!\\r|\\n|\\||\\))"), L"\\(\\\\r\\\\n\\|\\\\r\\|\\\\n\\)\\r\\n"); 83 | } 84 | } 85 | 86 | SetDlgItemText(hwndDlg, IDC_TEXTCONTENT, m_regexText.c_str()); 87 | 88 | SetFocus(GetDlgItem(hwndDlg, IDC_TEXTCONTENT)); 89 | 90 | m_resizer.Init(hwndDlg); 91 | m_resizer.UseSizeGrip(!CTheme::Instance().IsDarkTheme()); 92 | m_resizer.AddControl(hwndDlg, IDC_TEXTCONTENT, RESIZER_TOPLEFTBOTTOMRIGHT); 93 | m_resizer.AddControl(hwndDlg, IDC_INFOLABEL, RESIZER_BOTTOMLEFTRIGHT); 94 | m_resizer.AddControl(hwndDlg, IDC_CONVERTNEWLINES_BTN, RESIZER_BOTTOMLEFT); 95 | m_resizer.AddControl(hwndDlg, IDOK, RESIZER_BOTTOMRIGHT); 96 | m_resizer.AddControl(hwndDlg, IDCANCEL, RESIZER_BOTTOMRIGHT); 97 | 98 | SendMessage(GetDlgItem(*this, IDC_TEXTCONTENT), EM_SETEVENTMASK, 0, ENM_CHANGE); 99 | SendMessage(GetDlgItem(*this, IDC_TEXTCONTENT), EM_EXLIMITTEXT, 0, 200 * 1024); 100 | } 101 | return FALSE; 102 | case WM_COMMAND: 103 | return DoCommand(LOWORD(wParam), HIWORD(wParam)); 104 | case WM_SIZE: 105 | { 106 | m_resizer.DoResize(LOWORD(lParam), HIWORD(lParam)); 107 | } 108 | break; 109 | case WM_GETMINMAXINFO: 110 | { 111 | MINMAXINFO* mmi = reinterpret_cast(lParam); 112 | mmi->ptMinTrackSize.x = m_resizer.GetDlgRect()->right; 113 | mmi->ptMinTrackSize.y = m_resizer.GetDlgRect()->bottom; 114 | return 0; 115 | } 116 | case WM_CLOSE: 117 | CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId); 118 | break; 119 | default: 120 | return FALSE; 121 | } 122 | return FALSE; 123 | } 124 | 125 | LRESULT CMultiLineEditDlg::DoCommand(int id, int msg) 126 | { 127 | switch (id) 128 | { 129 | case IDOK: 130 | { 131 | auto buf = GetDlgItemText(IDC_TEXTCONTENT); 132 | m_regexText = std::wstring(buf.get()); 133 | if (m_forRegex) 134 | { 135 | // remove formatting newlines 136 | SearchReplace(m_regexText, L"\n", L""); 137 | SearchReplace(m_regexText, L"\r", L""); 138 | } 139 | } 140 | [[fallthrough]]; 141 | case IDCANCEL: 142 | EndDialog(*this, id); 143 | break; 144 | case IDC_TEXTCONTENT: 145 | { 146 | if (msg == EN_CHANGE) 147 | { 148 | auto buf = GetDlgItemText(IDC_TEXTCONTENT); 149 | m_regexText = std::wstring(buf.get()); 150 | } 151 | } 152 | break; 153 | case IDC_CONVERTNEWLINES_BTN: 154 | CNewlinesDlg newLinesDlg(*this); 155 | newLinesDlg.setShowBoth(!m_forReplace); 156 | if (newLinesDlg.DoModal(hResource, IDD_NEWLINESDLG, *this) == IDOK) 157 | { 158 | auto buf = GetDlgItemText(IDC_TEXTCONTENT); 159 | m_regexText = std::wstring(buf.get()); 160 | // normalize newlines 161 | SearchReplace(m_regexText, L"\r\n", L"\n"); 162 | SearchReplace(m_regexText, L"\r", L"\n"); 163 | 164 | switch (newLinesDlg.getNewLines()) 165 | { 166 | case eNewlines::Linux: 167 | { 168 | // convert newlines to regex newlines 169 | SearchReplace(m_regexText, L"\n", L"\\n\r\n"); 170 | } 171 | break; 172 | case eNewlines::Windows: 173 | { 174 | // convert newlines to regex newlines 175 | SearchReplace(m_regexText, L"\n", L"\\r\\n\r\n"); 176 | } 177 | break; 178 | case eNewlines::Both: 179 | { 180 | // convert newlines to regex newlines 181 | SearchReplace(m_regexText, L"\n", L"(\\r\\n|\\r|\\n)\r\n"); 182 | } 183 | break; 184 | default: 185 | break; 186 | } 187 | SetDlgItemText(*this, IDC_TEXTCONTENT, m_regexText.c_str()); 188 | } 189 | break; 190 | } 191 | return 1; 192 | } 193 | -------------------------------------------------------------------------------- /src/MultiLineEditDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2011-2013, 2019-2021, 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "DlgResizer.h" 22 | #include 23 | 24 | #define ID_REGEXTIMER 100 25 | 26 | /** 27 | * regex test dialog. 28 | */ 29 | class CMultiLineEditDlg : public CDialog 30 | { 31 | public: 32 | CMultiLineEditDlg(HWND hParent); 33 | ~CMultiLineEditDlg() override; 34 | 35 | void SetString(const std::wstring& search) { m_regexText = search; } 36 | std::wstring GetSearchString() const { return m_regexText; } 37 | void setForReplace(); 38 | void setForRegex(); 39 | 40 | protected: 41 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 42 | LRESULT DoCommand(int id, int msg); 43 | 44 | private: 45 | HWND m_hParent; 46 | std::wstring m_regexText; 47 | int m_themeCallbackId; 48 | CDlgResizer m_resizer; 49 | bool m_forReplace; 50 | bool m_forRegex; 51 | }; 52 | -------------------------------------------------------------------------------- /src/NameDlg.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2013, 2019-2021, 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "resource.h" 21 | #include "NameDlg.h" 22 | #include "Theme.h" 23 | #include 24 | 25 | #include 26 | 27 | CNameDlg::CNameDlg(HWND hParent) 28 | : m_hParent(hParent) 29 | , m_bIncludePath(false) 30 | , m_themeCallbackId(0) 31 | { 32 | } 33 | 34 | CNameDlg::~CNameDlg() 35 | { 36 | } 37 | 38 | LRESULT CNameDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 39 | { 40 | UNREFERENCED_PARAMETER(lParam); 41 | switch (uMsg) 42 | { 43 | case WM_INITDIALOG: 44 | { 45 | m_themeCallbackId = CTheme::Instance().RegisterThemeChangeCallback( 46 | [this]() { 47 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 48 | }); 49 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 50 | 51 | InitDialog(hwndDlg, IDI_GREPWIN); 52 | CLanguage::Instance().TranslateWindow(*this); 53 | // initialize the controls 54 | 55 | SetDlgItemText(*this, IDC_NAME, m_name.c_str()); 56 | SetFocus(GetDlgItem(hwndDlg, IDC_NAME)); 57 | } 58 | return FALSE; 59 | case WM_COMMAND: 60 | return DoCommand(LOWORD(wParam), HIWORD(wParam)); 61 | case WM_CLOSE: 62 | CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId); 63 | break; 64 | default: 65 | return FALSE; 66 | } 67 | return FALSE; 68 | } 69 | 70 | LRESULT CNameDlg::DoCommand(int id, int /*msg*/) 71 | { 72 | switch (id) 73 | { 74 | case IDOK: 75 | { 76 | auto buf = GetDlgItemText(IDC_NAME); 77 | m_name = buf.get(); 78 | m_bIncludePath = IsDlgButtonChecked(*this, IDC_INCLUDEPATH); 79 | } 80 | [[fallthrough]]; 81 | case IDCANCEL: 82 | EndDialog(*this, id); 83 | break; 84 | default: 85 | break; 86 | } 87 | return 1; 88 | } 89 | -------------------------------------------------------------------------------- /src/NameDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2013, 2019-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "DlgResizer.h" 22 | #include 23 | 24 | /** 25 | * name dialog. 26 | */ 27 | class CNameDlg : public CDialog 28 | { 29 | public: 30 | CNameDlg(HWND hParent); 31 | ~CNameDlg() override; 32 | 33 | std::wstring GetName() const { return m_name; } 34 | void SetName(const std::wstring& n) { m_name = n; } 35 | bool IncludePath() const { return m_bIncludePath; } 36 | 37 | protected: 38 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 39 | LRESULT DoCommand(int id, int msg); 40 | 41 | private: 42 | HWND m_hParent; 43 | std::wstring m_name; 44 | bool m_bIncludePath; 45 | int m_themeCallbackId; 46 | }; 47 | -------------------------------------------------------------------------------- /src/NewlinesDlg.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "resource.h" 21 | #include "NewlinesDlg.h" 22 | #include "Theme.h" 23 | #include 24 | 25 | CNewlinesDlg::CNewlinesDlg(HWND hParent) 26 | : m_hParent(hParent) 27 | , m_themeCallbackId(0) 28 | , m_newLines(eNewlines::None) 29 | { 30 | } 31 | 32 | CNewlinesDlg::~CNewlinesDlg() 33 | { 34 | } 35 | void CNewlinesDlg::setNewLines(eNewlines nl) 36 | { 37 | m_newLines = nl; 38 | } 39 | eNewlines CNewlinesDlg::getNewLines() const 40 | { 41 | return m_newLines; 42 | } 43 | void CNewlinesDlg::setShowBoth(bool show) 44 | { 45 | m_showBoth = show; 46 | } 47 | 48 | LRESULT CNewlinesDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 49 | { 50 | UNREFERENCED_PARAMETER(lParam); 51 | switch (uMsg) 52 | { 53 | case WM_INITDIALOG: 54 | { 55 | m_themeCallbackId = CTheme::Instance().RegisterThemeChangeCallback( 56 | [this]() { 57 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 58 | }); 59 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 60 | 61 | InitDialog(hwndDlg, IDI_GREPWIN); 62 | CLanguage::Instance().TranslateWindow(*this); 63 | // initialize the controls 64 | switch (m_newLines) 65 | { 66 | case eNewlines::None: 67 | CheckRadioButton(hwndDlg, IDC_CRLF, IDC_BOTH, IDC_CRLF); 68 | 69 | break; 70 | case eNewlines::Linux: 71 | CheckRadioButton(hwndDlg, IDC_CRLF, IDC_BOTH, IDC_LF); 72 | break; 73 | case eNewlines::Windows: 74 | CheckRadioButton(hwndDlg, IDC_CRLF, IDC_BOTH, IDC_CRLF); 75 | break; 76 | case eNewlines::Both: 77 | CheckRadioButton(hwndDlg, IDC_CRLF, IDC_BOTH, IDC_BOTH); 78 | break; 79 | } 80 | if (!m_showBoth) 81 | { 82 | ShowWindow(GetDlgItem(hwndDlg, IDC_BOTH), SW_HIDE); 83 | } 84 | } 85 | return FALSE; 86 | case WM_COMMAND: 87 | return DoCommand(LOWORD(wParam), HIWORD(wParam)); 88 | case WM_CLOSE: 89 | CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId); 90 | break; 91 | default: 92 | return FALSE; 93 | } 94 | return FALSE; 95 | } 96 | 97 | LRESULT CNewlinesDlg::DoCommand(int id, int /*msg*/) 98 | { 99 | switch (id) 100 | { 101 | case IDOK: 102 | if (IsDlgButtonChecked(*this, IDC_LF) == BST_CHECKED) 103 | { 104 | m_newLines = eNewlines::Linux; 105 | } 106 | else if (IsDlgButtonChecked(*this, IDC_CRLF) == BST_CHECKED) 107 | { 108 | m_newLines = eNewlines::Windows; 109 | } 110 | else if (IsDlgButtonChecked(*this, IDC_BOTH) == BST_CHECKED) 111 | { 112 | m_newLines = eNewlines::Both; 113 | } 114 | [[fallthrough]]; 115 | case IDCANCEL: 116 | EndDialog(*this, id); 117 | break; 118 | } 119 | return 1; 120 | } 121 | -------------------------------------------------------------------------------- /src/NewlinesDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | 22 | enum class eNewlines 23 | { 24 | None, 25 | Linux, 26 | Windows, 27 | Both, 28 | }; 29 | 30 | class CNewlinesDlg : public CDialog 31 | { 32 | public: 33 | CNewlinesDlg(HWND hParent); 34 | ~CNewlinesDlg() override; 35 | 36 | void setNewLines(eNewlines nl); 37 | eNewlines getNewLines() const; 38 | void setShowBoth(bool show); 39 | 40 | protected: 41 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 42 | LRESULT DoCommand(int id, int msg); 43 | 44 | private: 45 | HWND m_hParent; 46 | int m_themeCallbackId; 47 | eNewlines m_newLines; 48 | bool m_showBoth; 49 | }; 50 | -------------------------------------------------------------------------------- /src/RegexReplaceFormatter.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2011, 2015, 2024-2025 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "RegexReplaceFormatter.h" 21 | #include 22 | 23 | std::wstring ExpandString(const std::wstring& replaceString) 24 | { 25 | // ${now,formatString} 26 | wchar_t buf[4096] = {}; 27 | GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, nullptr, nullptr, buf, _countof(buf)); 28 | std::wstring dateStr = buf; 29 | GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, buf, _countof(buf)); 30 | dateStr += L" - "; 31 | dateStr += buf; 32 | std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 33 | UINT syntaxFlags = boost::regex::normal; 34 | boost::wregex expression = boost::wregex(L"\\$\\{now\\s*,?([^}]*)\\}", syntaxFlags); 35 | boost::match_results whatC; 36 | boost::match_flag_type matchFlags = boost::match_default | boost::format_all; 37 | auto resultString = replaceString; 38 | SearchReplace(resultString, L"${now}", dateStr); 39 | 40 | try 41 | { 42 | auto start = resultString.cbegin(); 43 | auto end = resultString.cend(); 44 | while (regex_search(start, end, whatC, expression, matchFlags)) 45 | { 46 | if (whatC[0].matched) 47 | { 48 | auto fullMatch = whatC.str(); 49 | 50 | std::wstring formatStr; 51 | if (whatC.size() > 1) 52 | { 53 | formatStr = whatC[1].str(); 54 | if (!formatStr.empty()) 55 | { 56 | std::wstring formattedDateStr(4096, '\0'); 57 | struct tm locTime; 58 | _localtime64_s(&locTime, &now); 59 | try 60 | { 61 | std::wcsftime(&formattedDateStr[0], formattedDateStr.size(), formatStr.c_str(), &locTime); 62 | SearchReplace(resultString, fullMatch, formattedDateStr); 63 | } 64 | catch (const std::exception&) 65 | { 66 | } 67 | } 68 | } 69 | else 70 | { 71 | SearchReplace(resultString, fullMatch, dateStr); 72 | } 73 | } 74 | if (start == whatC[0].second) 75 | { 76 | if (start == end) 77 | break; 78 | ++start; 79 | } 80 | else 81 | start = whatC[0].second; 82 | } 83 | } 84 | catch (const std::exception&) 85 | { 86 | } 87 | return resultString; 88 | } -------------------------------------------------------------------------------- /src/RegexReplaceFormatter.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2011-2012, 2014-2015, 2021, 2023-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "StringUtils.h" 25 | #include 26 | 27 | template 28 | class NumberReplacer 29 | { 30 | public: 31 | NumberReplacer() 32 | : leadZero(false) 33 | , padding(0) 34 | , start(1) 35 | , increment(1) 36 | { 37 | } 38 | 39 | bool leadZero; 40 | int padding; 41 | int start; 42 | int increment; 43 | std::basic_string expression; 44 | }; 45 | 46 | std::wstring ExpandString(const std::wstring& replaceString); 47 | 48 | // Iter is the same as the BidirectionalIterator in which `regex_replace` it is used 49 | template ::const_iterator> 50 | class RegexReplaceFormatter 51 | { 52 | public: 53 | RegexReplaceFormatter(const std::basic_string& str) 54 | : m_sReplace(str) 55 | { 56 | m_incVec.clear(); 57 | // parse for ${count0L}, ${count0L(n)}, ${count0L(n,m)}, where 58 | // ${count} 59 | // is replaced later with numbers starting from 1, incremented by 1 60 | // ${count(n)} 61 | // is replaced with numbers starting from n, incremented by 1 62 | // ${count(n,m)} 63 | // is replaced with numbers starting from n, incremented by m 64 | // 0 and L are optional and specify the size of the right-aligned 65 | // number string. If 0 is specified, zeros are used for padding, otherwise spaces. 66 | // expr: "\\$\\{count(?0)?(?\\d+)?(\\((?[-0-9]+)\\)||\\((?[-0-9]+),(?[-0-9]+)\\))?\\}" 67 | constexpr CharT expr[] = { 68 | '\\', '$', '\\', '{', 69 | 'c', 'o', 'u', 'n', 't', 70 | '(', '?', '<', 'l', 'e', 'a', 'd', 'z', 'e', 'r', 'o', '>', '0', ')', '?', 71 | '(', '?', '<', 'l', 'e', 'n', 'g', 't', 'h', '>', '\\', 'd', '+', ')', '?', 72 | '(', 73 | '\\', '(', '(', '?', '<', 's', 't', 'a', 'r', 't', 'v', 'a', 'l', '>', '[', '-', '0', '-', '9', ']', '+', ')', '\\', ')', '|', '|', 74 | '\\', '(', '(', '?', '<', 's', 't', 'a', 'r', 't', 'v', 'a', 'l', '>', '[', '-', '0', '-', '9', ']', '+', ')', ',', 75 | '(', '?', '<', 'i', 'n', 'c', 'r', 'e', 'm', 'e', 'n', 't', '>', '[', '-', '0', '-', '9', ']', '+', ')', 76 | '\\', ')', 77 | ')', '?', 78 | '\\', '}', 0}; 79 | boost::basic_regex regEx = boost::basic_regex(expr, boost::regex::normal); 80 | boost::match_results::const_iterator> whatC; 81 | typename std::basic_string::const_iterator start = m_sReplace.begin(); 82 | typename std::basic_string::const_iterator end = m_sReplace.end(); 83 | boost::match_flag_type flags = boost::match_default | boost::format_all; 84 | while (boost::regex_search(start, end, whatC, regEx, flags)) 85 | { 86 | if (whatC[0].matched) 87 | { 88 | NumberReplacer nr; 89 | constexpr CharT leadzero[] = {'l', 'e', 'a', 'd', 'z', 'e', 'r', 'o', 0}; 90 | constexpr CharT zero[] = {'0', 0}; 91 | nr.leadZero = (static_cast>(whatC[leadzero]) == zero); 92 | constexpr CharT length[] = {'l', 'e', 'n', 'g', 't', 'h', 0}; 93 | nr.padding = t_ttoi(static_cast>(whatC[length]).c_str()); 94 | constexpr CharT startval[] = {'s', 't', 'a', 'r', 't', 'v', 'a', 'l', 0}; 95 | std::basic_string s = static_cast>(whatC[startval]); 96 | if (!s.empty()) 97 | nr.start = t_ttoi(s.c_str()); 98 | constexpr CharT increment[] = {'i', 'n', 'c', 'r', 'e', 'm', 'e', 'n', 't', 0}; 99 | s = static_cast>(whatC[increment]); 100 | if (!s.empty()) 101 | nr.increment = t_ttoi(s.c_str()); 102 | if (nr.increment == 0) 103 | nr.increment = 1; 104 | nr.expression = static_cast>(whatC[0]); 105 | m_incVec.push_back(nr); 106 | } 107 | // update search position: 108 | if (start == whatC[0].second) 109 | { 110 | if (start == end) 111 | break; 112 | ++start; 113 | } 114 | else 115 | start = whatC[0].second; 116 | // update flags: 117 | flags |= boost::match_prev_avail; 118 | flags |= boost::match_not_bob; 119 | } 120 | } 121 | 122 | void SetReplacePair(const std::basic_string& s1, const std::basic_string& s2) 123 | { 124 | m_replaceMap[s1] = s2; 125 | } 126 | 127 | std::basic_string operator()(boost::match_results what) 128 | { 129 | std::basic_string sReplace = what.format(m_sReplace); 130 | if (!m_replaceMap.empty()) 131 | { 132 | for (const auto& [key, value] : m_replaceMap) 133 | { 134 | auto itBegin = std::search(sReplace.begin(), sReplace.end(), key.begin(), key.end()); 135 | while (itBegin != sReplace.end()) 136 | { 137 | if ((itBegin == sReplace.begin()) || ((*(itBegin - 1)) != '\\')) 138 | { 139 | auto itEnd = itBegin + key.size(); 140 | sReplace.replace(itBegin, itEnd, value); 141 | } 142 | else if ((*(itBegin - 1)) == '\\') 143 | { 144 | sReplace.erase(itBegin - 1); 145 | }; 146 | itBegin = std::search(sReplace.begin(), sReplace.end(), key.begin(), key.end()); 147 | } 148 | } 149 | } 150 | if (!m_incVec.empty()) 151 | { 152 | for (auto& numberReplacer : m_incVec) 153 | { 154 | auto itBegin = std::search(sReplace.begin(), sReplace.end(), numberReplacer.expression.begin(), numberReplacer.expression.end()); 155 | if (itBegin != sReplace.end()) 156 | { 157 | if ((itBegin == sReplace.begin()) || ((*(itBegin - 1)) != '\\')) 158 | { 159 | auto itEnd = itBegin + numberReplacer.expression.size(); 160 | CharT format[30] = {0}; 161 | if (numberReplacer.padding) 162 | { 163 | const CharT* fmt; 164 | constexpr CharT fmt1[] = {'%', '%', '0', '%', 'd', 'd', 0}; 165 | constexpr CharT fmt2[] = {'%', '%', '%', 'd', 'd', 0}; 166 | if (numberReplacer.leadZero) 167 | fmt = fmt1; 168 | else 169 | fmt = fmt2; 170 | t_stprintf_s(format, _countof(format), fmt, numberReplacer.padding); 171 | } 172 | else 173 | { 174 | constexpr CharT fmt[] = {'%', 'd', 0}; 175 | t_tcscpy_s(format, fmt); 176 | } 177 | if (numberReplacer.padding < 50) 178 | { 179 | // for small strings, reserve space on the stack 180 | CharT buf[128] = {0}; 181 | t_stprintf_s(buf, _countof(buf), format, numberReplacer.start); 182 | sReplace.replace(itBegin, itEnd, buf); 183 | } 184 | else 185 | { 186 | auto s = CStringUtils::Format(format, numberReplacer.start); 187 | sReplace.replace(itBegin, itEnd, s); 188 | } 189 | numberReplacer.start += numberReplacer.increment; 190 | } 191 | else if ((*(itBegin - 1)) == '\\') 192 | { 193 | sReplace.erase(itBegin - 1); 194 | }; 195 | } 196 | } 197 | } 198 | 199 | return sReplace; 200 | } 201 | 202 | private: 203 | static int t_ttoi(const wchar_t* str) 204 | { 205 | return _wtoi(str); 206 | } 207 | 208 | static int t_ttoi(const char* str) 209 | { 210 | return atoi(str); 211 | } 212 | 213 | static int t_stprintf_s(wchar_t* buffer, size_t sizeOfBuffer, const wchar_t* format, ...) 214 | { 215 | va_list argList; 216 | __crt_va_start(argList, format); 217 | int result = _vswprintf_s_l(buffer, sizeOfBuffer, format, nullptr, argList); 218 | __crt_va_end(argList); 219 | return result; 220 | } 221 | 222 | static int t_stprintf_s(char* buffer, size_t sizeOfBuffer, const char* format, ...) 223 | { 224 | va_list argList; 225 | __crt_va_start(argList, format); 226 | int result = _vsprintf_s_l(buffer, sizeOfBuffer, format, nullptr, argList); 227 | __crt_va_end(argList); 228 | return result; 229 | } 230 | 231 | template 232 | static errno_t t_tcscpy_s(wchar_t (&dest)[Size], const wchar_t* src) 233 | { 234 | return wcscpy_s(dest, Size, src); 235 | } 236 | 237 | template 238 | static errno_t t_tcscpy_s(char (&dest)[Size], const char* src) 239 | { 240 | return strcpy_s(dest, Size, src); 241 | } 242 | 243 | std::vector> m_incVec; 244 | std::basic_string m_sReplace; 245 | std::map, std::basic_string> m_replaceMap; 246 | }; 247 | -------------------------------------------------------------------------------- /src/RegexTestDlg.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2011-2013, 2019-2021, 2024-2025 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "resource.h" 21 | #include "RegexTestDlg.h" 22 | #include "RegexReplaceFormatter.h" 23 | #include "Theme.h" 24 | #include "DarkModeHelper.h" 25 | #include "ResString.h" 26 | #include 27 | #include 28 | #include 29 | 30 | CRegexTestDlg::CRegexTestDlg(HWND hParent) 31 | : bDotMatchesNewline(false) 32 | , bCaseSensitive(false) 33 | , m_hParent(hParent) 34 | , m_themeCallbackId(0) 35 | { 36 | } 37 | 38 | CRegexTestDlg::~CRegexTestDlg() 39 | { 40 | } 41 | 42 | LRESULT CRegexTestDlg::DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 43 | { 44 | UNREFERENCED_PARAMETER(lParam); 45 | switch (uMsg) 46 | { 47 | case WM_INITDIALOG: 48 | { 49 | m_themeCallbackId = CTheme::Instance().RegisterThemeChangeCallback( 50 | [this]() { 51 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 52 | DarkModeHelper::Instance().AllowDarkModeForWindow(GetToolTipHWND(), CTheme::Instance().IsDarkTheme()); 53 | }); 54 | CTheme::Instance().SetThemeForDialog(*this, CTheme::Instance().IsDarkTheme()); 55 | DarkModeHelper::Instance().AllowDarkModeForWindow(GetToolTipHWND(), CTheme::Instance().IsDarkTheme()); 56 | 57 | InitDialog(hwndDlg, IDI_GREPWIN); 58 | CLanguage::Instance().TranslateWindow(*this); 59 | // initialize the controls 60 | SetDlgItemText(hwndDlg, IDC_SEARCHTEXT, m_searchText.c_str()); 61 | SetDlgItemText(hwndDlg, IDC_REPLACETEXT, m_replaceText.c_str()); 62 | 63 | SetFocus(GetDlgItem(hwndDlg, IDC_SEARCHTEXT)); 64 | 65 | m_resizer.Init(hwndDlg); 66 | m_resizer.UseSizeGrip(!CTheme::Instance().IsDarkTheme()); 67 | m_resizer.AddControl(hwndDlg, IDC_TEXTCONTENT, RESIZER_TOPLEFTRIGHT); 68 | m_resizer.AddControl(hwndDlg, IDC_SEARCHTEXT, RESIZER_TOPLEFTRIGHT); 69 | m_resizer.AddControl(hwndDlg, IDC_REPLACETEXT, RESIZER_TOPLEFTRIGHT); 70 | m_resizer.AddControl(hwndDlg, IDC_REGEXMATCH, RESIZER_TOPLEFTRIGHT); 71 | m_resizer.AddControl(hwndDlg, IDC_REGEXREPLACED, RESIZER_TOPLEFTBOTTOMRIGHT); 72 | m_resizer.AddControl(hwndDlg, IDOK, RESIZER_BOTTOMRIGHT); 73 | m_resizer.AddControl(hwndDlg, IDCANCEL, RESIZER_BOTTOMRIGHT); 74 | 75 | SendMessage(GetDlgItem(*this, IDC_TEXTCONTENT), EM_SETEVENTMASK, 0, ENM_CHANGE); 76 | SendMessage(GetDlgItem(*this, IDC_TEXTCONTENT), EM_EXLIMITTEXT, 0, 200 * 1024); 77 | SendMessage(GetDlgItem(*this, IDC_REGEXREPLACED), EM_EXLIMITTEXT, 0, 200 * 1024); 78 | } 79 | return FALSE; 80 | case WM_COMMAND: 81 | return DoCommand(LOWORD(wParam), HIWORD(wParam)); 82 | case WM_SIZE: 83 | { 84 | m_resizer.DoResize(LOWORD(lParam), HIWORD(lParam)); 85 | } 86 | break; 87 | case WM_GETMINMAXINFO: 88 | { 89 | MINMAXINFO* mmi = reinterpret_cast(lParam); 90 | mmi->ptMinTrackSize.x = m_resizer.GetDlgRect()->right; 91 | mmi->ptMinTrackSize.y = m_resizer.GetDlgRect()->bottom; 92 | return 0; 93 | } 94 | case WM_TIMER: 95 | { 96 | if (wParam == ID_REGEXTIMER) 97 | { 98 | KillTimer(*this, ID_REGEXTIMER); 99 | DoRegex(); 100 | } 101 | } 102 | break; 103 | case WM_CLOSE: 104 | CTheme::Instance().RemoveRegisteredCallback(m_themeCallbackId); 105 | break; 106 | default: 107 | return FALSE; 108 | } 109 | return FALSE; 110 | } 111 | 112 | LRESULT CRegexTestDlg::DoCommand(int id, int msg) 113 | { 114 | switch (id) 115 | { 116 | case IDOK: 117 | { 118 | auto buf = GetDlgItemText(IDC_SEARCHTEXT); 119 | m_searchText = buf.get(); 120 | buf = GetDlgItemText(IDC_REPLACETEXT); 121 | m_replaceText = buf.get(); 122 | } 123 | [[fallthrough]]; 124 | case IDCANCEL: 125 | EndDialog(*this, id); 126 | break; 127 | case IDC_TEXTCONTENT: 128 | { 129 | if (msg == EN_CHANGE) 130 | { 131 | auto buf = GetDlgItemText(IDC_TEXTCONTENT); 132 | m_textContent = std::wstring(buf.get()); 133 | 134 | SetTimer(*this, ID_REGEXTIMER, 300, nullptr); 135 | } 136 | } 137 | break; 138 | case IDC_SEARCHTEXT: 139 | { 140 | if (msg == EN_CHANGE) 141 | { 142 | auto buf = GetDlgItemText(IDC_SEARCHTEXT); 143 | m_searchText = buf.get(); 144 | 145 | SetTimer(*this, ID_REGEXTIMER, 300, nullptr); 146 | } 147 | } 148 | break; 149 | case IDC_REPLACETEXT: 150 | { 151 | if (msg == EN_CHANGE) 152 | { 153 | auto buf = GetDlgItemText(IDC_REPLACETEXT); 154 | m_replaceText = buf.get(); 155 | 156 | SetTimer(*this, ID_REGEXTIMER, 300, nullptr); 157 | } 158 | } 159 | break; 160 | default: 161 | break; 162 | } 163 | return 1; 164 | } 165 | 166 | void CRegexTestDlg::SetStrings(const std::wstring& search, const std::wstring& replace) 167 | { 168 | m_replaceText = replace; 169 | m_searchText = search; 170 | } 171 | 172 | void CRegexTestDlg::DoRegex() 173 | { 174 | if (m_textContent.empty()) 175 | { 176 | SetDlgItemText(*this, IDC_REGEXMATCH, TranslatedString(hResource, IDS_NOTESTTEXTAVAILABLE).c_str()); 177 | SetDlgItemText(*this, IDC_REGEXREPLACED, TranslatedString(hResource, IDS_NOTESTTEXTAVAILABLE).c_str()); 178 | } 179 | else if (m_searchText.empty()) 180 | { 181 | SetDlgItemText(*this, IDC_REGEXMATCH, TranslatedString(hResource, IDS_SEARCHSTRINGEMPTY).c_str()); 182 | SetDlgItemText(*this, IDC_REGEXREPLACED, TranslatedString(hResource, IDS_SEARCHSTRINGEMPTY).c_str()); 183 | } 184 | else if (m_replaceText.empty()) 185 | { 186 | SetDlgItemText(*this, IDC_REGEXREPLACED, TranslatedString(hResource, IDS_NOREPLACETEXT).c_str()); 187 | } 188 | 189 | if (!m_textContent.empty()) 190 | { 191 | std::wstring searchResult; 192 | std::wstring replaceResult; 193 | if (!m_searchText.empty()) 194 | { 195 | std::wstring::const_iterator start, end; 196 | start = m_textContent.begin(); 197 | end = m_textContent.end(); 198 | boost::match_results what; 199 | try 200 | { 201 | int ft = boost::regex::normal; 202 | if (!bCaseSensitive) 203 | ft |= boost::regbase::icase; 204 | boost::wregex expression = boost::wregex(m_searchText, ft); 205 | boost::match_results whatc; 206 | boost::match_flag_type flags = boost::match_default; 207 | if (!bDotMatchesNewline) 208 | flags |= boost::match_not_dot_newline; 209 | 210 | boost::match_flag_type rflags = boost::match_default | boost::format_all; 211 | if (!bDotMatchesNewline) 212 | rflags |= boost::match_not_dot_newline; 213 | 214 | m_replaceText = ExpandString(m_replaceText); 215 | RegexReplaceFormatter replaceFmt(m_replaceText); 216 | replaceFmt.SetReplacePair(L"${filepath}", L"c:\\grepwintest\\file.txt"); 217 | replaceFmt.SetReplacePair(L"${filename}", L"file"); 218 | replaceFmt.SetReplacePair(L"${fileext}", L"txt"); 219 | 220 | replaceResult = regex_replace(m_textContent, expression, std::ref(replaceFmt), rflags); 221 | 222 | while (boost::regex_search(start, end, whatc, expression, flags)) 223 | { 224 | if (!searchResult.empty()) 225 | searchResult = searchResult + L"\r\n----------------------------\r\n"; 226 | std::wstring c(whatc[0].first, whatc[0].second); 227 | searchResult = searchResult + c; 228 | // update search position: 229 | if (start == whatc[0].second) 230 | { 231 | if (start == end) 232 | break; 233 | ++start; 234 | } 235 | else 236 | start = whatc[0].second; 237 | // update flags: 238 | flags |= boost::match_prev_avail; 239 | flags |= boost::match_not_bob; 240 | } 241 | } 242 | catch (const std::exception&) 243 | { 244 | } 245 | if (searchResult.empty()) 246 | SetDlgItemText(*this, IDC_REGEXMATCH, TranslatedString(hResource, IDS_NOMATCH).c_str()); 247 | else 248 | SetDlgItemText(*this, IDC_REGEXMATCH, searchResult.c_str()); 249 | } 250 | if (!searchResult.empty()) 251 | SetDlgItemText(*this, IDC_REGEXMATCH, searchResult.c_str()); 252 | if (!replaceResult.empty()) 253 | SetDlgItemText(*this, IDC_REGEXREPLACED, replaceResult.c_str()); 254 | } 255 | } -------------------------------------------------------------------------------- /src/RegexTestDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2013, 2019-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "DlgResizer.h" 22 | #include 23 | 24 | #define ID_REGEXTIMER 100 25 | 26 | /** 27 | * regex test dialog. 28 | */ 29 | class CRegexTestDlg : public CDialog 30 | { 31 | public: 32 | CRegexTestDlg(HWND hParent); 33 | ~CRegexTestDlg() override; 34 | 35 | void SetStrings(const std::wstring& search, const std::wstring& replace); 36 | std::wstring GetSearchString() const { return m_searchText; } 37 | std::wstring GetReplaceString() const { return m_replaceText; } 38 | 39 | bool bDotMatchesNewline; 40 | bool bCaseSensitive; 41 | 42 | protected: 43 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 44 | LRESULT DoCommand(int id, int msg); 45 | void DoRegex(); 46 | 47 | private: 48 | HWND m_hParent; 49 | std::wstring m_searchText; 50 | std::wstring m_replaceText; 51 | std::wstring m_textContent; 52 | int m_themeCallbackId; 53 | CDlgResizer m_resizer; 54 | }; 55 | -------------------------------------------------------------------------------- /src/Resources/GitHub-socialpreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/GitHub-socialpreview.png -------------------------------------------------------------------------------- /src/Resources/grepWin.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepWin.ico -------------------------------------------------------------------------------- /src/Resources/grepWin.rc2: -------------------------------------------------------------------------------- 1 | // 2 | // grepWin.rc2 - resources Microsoft Visual C++ does not edit directly 3 | // 4 | 5 | #ifdef APSTUDIO_INVOKED 6 | #error this file is not editable by Microsoft Visual C++ 7 | #endif //APSTUDIO_INVOKED 8 | 9 | 10 | ///////////////////////////////////////////////////////////////////////////// 11 | // Add manually edited resources here... 12 | ///////////////////////////////////////////////////////////////////////////// 13 | // 14 | // Version 15 | // 16 | #include "version.h" 17 | VS_VERSION_INFO VERSIONINFO 18 | FILEVERSION FILEVER 19 | PRODUCTVERSION PRODUCTVER 20 | FILEFLAGSMASK 0x3fL 21 | #ifdef _DEBUG 22 | FILEFLAGS 0x1L 23 | #else 24 | FILEFLAGS 0x0L 25 | #endif 26 | FILEOS 0x4L 27 | FILETYPE 0x1L 28 | FILESUBTYPE 0x0L 29 | BEGIN 30 | BLOCK "StringFileInfo" 31 | BEGIN 32 | BLOCK "040904e4" 33 | BEGIN 34 | VALUE "CompanyName", "http://tools.stefankueng.com" 35 | VALUE "FileDescription", "grepWin" 36 | VALUE "FileVersion", STRFILEVER 37 | VALUE "InternalName", "grepWin.exe" 38 | VALUE "LegalCopyright", "Copyright © 2007-2022, Stefan Küng" 39 | VALUE "OriginalFilename", "grepWin.exe" 40 | VALUE "ProductName", "grepWin" 41 | VALUE "ProductVersion", STRPRODUCTVER 42 | END 43 | END 44 | BLOCK "VarFileInfo" 45 | BEGIN 46 | VALUE "Translation", 0x409, 1252 47 | END 48 | END 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | -------------------------------------------------------------------------------- /src/Resources/grepWin_search-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepWin_search-small.png -------------------------------------------------------------------------------- /src/Resources/grepWin_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepWin_search.png -------------------------------------------------------------------------------- /src/Resources/grepwin.svg: -------------------------------------------------------------------------------- 1 | grepwin -------------------------------------------------------------------------------- /src/Resources/grepwin_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_128.png -------------------------------------------------------------------------------- /src/Resources/grepwin_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_16.png -------------------------------------------------------------------------------- /src/Resources/grepwin_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_24.png -------------------------------------------------------------------------------- /src/Resources/grepwin_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_256.png -------------------------------------------------------------------------------- /src/Resources/grepwin_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_32.png -------------------------------------------------------------------------------- /src/Resources/grepwin_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_48.png -------------------------------------------------------------------------------- /src/Resources/grepwin_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/grepwin_64.png -------------------------------------------------------------------------------- /src/Resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/logo.png -------------------------------------------------------------------------------- /src/Resources/vs9-tools-grepwin-prj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/vs9-tools-grepwin-prj.png -------------------------------------------------------------------------------- /src/Resources/vs9-tools-grepwin-sln.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Resources/vs9-tools-grepwin-sln.png -------------------------------------------------------------------------------- /src/SearchDlg.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "SearchInfo.h" 22 | #include "BookmarksDlg.h" 23 | #include "DlgResizer.h" 24 | #include "FileDropTarget.h" 25 | #include "AutoComplete.h" 26 | #include "Registry.h" 27 | #include "EditDoubleClick.h" 28 | #include "InfoRtfDialog.h" 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | using namespace Microsoft::WRL; 38 | 39 | #define SEARCH_FOUND (WM_APP + 1) 40 | #define SEARCH_START (WM_APP + 2) 41 | #define SEARCH_PROGRESS (WM_APP + 3) 42 | #define SEARCH_END (WM_APP + 4) 43 | #define WM_GREPWIN_THREADEND (WM_APP + 5) 44 | 45 | #define ID_ABOUTBOX 0x0010 46 | #define ID_CLONE 0x0011 47 | 48 | enum class ExecuteAction 49 | { 50 | None, 51 | Search, 52 | Replace, 53 | Capture 54 | }; 55 | 56 | /** 57 | * search dialog. 58 | */ 59 | class CSearchDlg : public CDialog 60 | { 61 | public: 62 | CSearchDlg(HWND hParent); 63 | ~CSearchDlg() override; 64 | 65 | DWORD SearchThread(); 66 | void SetSearchPath(const std::wstring& path); 67 | void SetSearchString(const std::wstring& search) { m_searchString = search; } 68 | void SetFileMask(const std::wstring& mask, bool reg); 69 | void SetDirExcludeRegexMask(const std::wstring& mask); 70 | void SetReplaceWith(const std::wstring& replace) { m_replaceString = replace; } 71 | void SetUseRegex(bool reg); 72 | void SetPreset(const std::wstring& preset); 73 | void SetCaseSensitive(bool bSet); 74 | void SetMatchesNewline(bool bSet); 75 | void SetCreateBackups(bool bSet); 76 | void SetCreateBackupsInFolders(bool bSet); 77 | void SetKeepFileDate(bool bSet); 78 | void SetWholeWords(bool bSet); 79 | void SetUTF8(bool bSet); 80 | void SetBinary(bool bSet); 81 | void SetSize(uint64_t size, int cmp); 82 | void SetIncludeSystem(bool bSet); 83 | void SetIncludeHidden(bool bSet); 84 | void SetIncludeSubfolders(bool bSet); 85 | void SetIncludeSymLinks(bool bSet); 86 | void SetIncludeBinary(bool bSet); 87 | void SetDateLimit(int dateLimit, FILETIME t1, FILETIME t2); 88 | void SetNoSaveSettings(bool noSave) { m_bNoSaveSettings = noSave; } 89 | 90 | void SetExecute(ExecuteAction execute) { m_executeImmediately = execute; } 91 | void SetEndDialog() { m_endDialog = true; } 92 | void SetShowContent() 93 | { 94 | m_showContent = true; 95 | m_showContentSet = true; 96 | } 97 | bool isSearchPathValid() const; 98 | bool isSearchValid() const; 99 | bool isExcludeDirsRegexValid() const; 100 | bool isFileNameMatchRegexValid() const; 101 | 102 | protected: 103 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 104 | LRESULT DoCommand(int id, int msg); 105 | bool PreTranslateMessage(MSG* pMsg) override; 106 | 107 | std::wstring BackupFile(const std::wstring& destParentDir, const std::wstring& filePath, bool bMove); 108 | int AdoptTempResultFile(CSearchInfo& sInfo, const std::wstring& searchRoot, const std::wstring& tempFilePath); 109 | int SearchOnTextFile(CSearchInfo& sInfo, const std::wstring& searchRoot, const std::wstring& searchExpression, const std::wstring& replaceExpression, UINT syntaxFlags, UINT matchFlags, CTextFile& textFile); 110 | template 111 | int SearchByFilePath(CSearchInfo& sInfo, const std::wstring& searchRoot, const std::wstring& searchExpression, const std::wstring& replaceExpression, UINT syntaxFlags, UINT matchFlags, bool misaligned, CharT* dummy = nullptr); 112 | void SendResult(const CSearchInfo& sInfo, const int nCount); 113 | void SearchFile(CSearchInfo sInfo, const std::wstring& searchRoot); 114 | 115 | bool InitResultList(); 116 | void FillResultList(); 117 | void SetSearchModeUI(bool isTextMode); 118 | bool AddFoundEntry(const CSearchInfo* pInfo, bool bOnlyListControl = false); 119 | void ShowContextMenu(HWND hWnd, int x, int y); 120 | LRESULT ColorizeMatchResultProc(LPNMLVCUSTOMDRAW lpLVCD); 121 | LRESULT DoListNotify(LPNMITEMACTIVATE lpNMItemActivate); 122 | void OpenFileAtListIndex(int listIndex); 123 | void UpdateInfoLabel(); 124 | bool SaveSettings(); 125 | void SaveWndPosition(); 126 | static void formatDate(wchar_t dateNative[], const FILETIME& fileTime, bool forceShortFmt); 127 | bool MatchPath(LPCTSTR pathBuf) const; 128 | void AutoSizeAllColumns(); 129 | int GetSelectedListIndex(int index); 130 | int GetSelectedListIndex(bool fileList, int index) const; 131 | static bool FailedShowMessage(HRESULT hr); 132 | void CheckForUpdates(bool force = false); 133 | void ShowUpdateAvailable(); 134 | static bool IsVersionNewer(const std::wstring& sVer); 135 | bool CloneWindow(); 136 | void doFilter(); 137 | void filterItemsList(const wchar_t* filterString); 138 | 139 | struct ListItemsItem 140 | { 141 | int itemsIndex; 142 | int itemsSubIndex; 143 | }; 144 | 145 | private: 146 | HWND m_hParent; 147 | std::atomic_bool m_dwThreadRunning; 148 | std::atomic_bool m_cancelled; 149 | bool m_bBlockUpdate; 150 | 151 | std::unique_ptr m_bookmarksDlg; 152 | ComPtr m_pTaskbarList; 153 | 154 | std::wstring m_searchPath; 155 | std::wstring m_searchString; 156 | std::wstring m_replaceString; 157 | std::vector m_patterns; 158 | std::wstring m_patternRegex; 159 | bool m_patternRegexC; 160 | std::wstring m_excludeDirsPatternRegex; 161 | bool m_excludeDirsPatternRegexC; 162 | bool m_bUseRegex; 163 | bool m_bUseRegexC; 164 | bool m_bUseRegexForPaths; 165 | bool m_bAllSize; 166 | uint64_t m_lSize; 167 | int m_sizeCmp; 168 | bool m_bIncludeSystem; 169 | bool m_bIncludeSystemC; 170 | bool m_bIncludeHidden; 171 | bool m_bIncludeHiddenC; 172 | bool m_bIncludeSubfolders; 173 | bool m_bIncludeSubfoldersC; 174 | bool m_bIncludeSymLinks; 175 | bool m_bIncludeSymLinksC; 176 | bool m_bIncludeBinary; 177 | bool m_bIncludeBinaryC; 178 | bool m_bCreateBackup; 179 | bool m_bCreateBackupC; 180 | bool m_bCreateBackupInFolders; 181 | bool m_bCreateBackupInFoldersC; 182 | bool m_bKeepFileDate; 183 | bool m_bKeepFileDateC; 184 | bool m_bWholeWords; 185 | bool m_bWholeWordsC; 186 | bool m_bUTF8; 187 | bool m_bUTF8C; 188 | bool m_bForceBinary; 189 | bool m_bCaseSensitive; 190 | bool m_bCaseSensitiveC; 191 | bool m_bDotMatchesNewline; 192 | bool m_bDotMatchesNewlineC; 193 | bool m_bNotSearch; 194 | bool m_bCaptureSearch; 195 | bool m_bSizeC; 196 | bool m_endDialog; 197 | ExecuteAction m_executeImmediately; 198 | int m_dateLimit; 199 | bool m_bDateLimitC; 200 | FILETIME m_date1; 201 | FILETIME m_date2; 202 | bool m_bNoSaveSettings; 203 | bool m_bReplace; 204 | bool m_bConfirmationOnReplace; 205 | bool m_showContent; 206 | bool m_showContentSet; 207 | std::deque m_origItems; 208 | std::deque m_items; 209 | std::deque m_listItems; 210 | std::set m_backupAndTempFiles; 211 | std::mutex m_backupAndTempFilesMutex; 212 | int m_totalItems; 213 | int m_searchedItems; 214 | int m_totalMatches; 215 | int m_selectedItems; 216 | bool m_bAscending; 217 | std::wstring m_toolTipReplaceString; 218 | std::unique_ptr m_rtfDialog; 219 | 220 | bool m_hasSearchDir; 221 | bool m_bSearchPathValid; 222 | int m_searchValidLength; 223 | int m_replaceValidLength; 224 | bool m_bExcludeDirsRegexValid; 225 | bool m_bFileNameMatchingRegexValid; 226 | 227 | CDlgResizer m_resizer; 228 | int m_themeCallbackId; 229 | 230 | std::unique_ptr m_pDropTarget; 231 | 232 | static UINT m_grepwinStartupmsg; 233 | 234 | std::thread m_updateCheckThread; 235 | 236 | CAutoComplete m_autoCompleteFilePatterns; 237 | CAutoComplete m_autoCompleteExcludeDirsPatterns; 238 | CAutoComplete m_autoCompleteSearchPatterns; 239 | CAutoComplete m_autoCompleteReplacePatterns; 240 | CAutoComplete m_autoCompleteSearchPaths; 241 | 242 | CEditDoubleClick m_editFilePatterns; 243 | CEditDoubleClick m_editExcludeDirsPatterns; 244 | CEditDoubleClick m_editSearchPatterns; 245 | CEditDoubleClick m_editReplacePatterns; 246 | CEditDoubleClick m_editSearchPaths; 247 | CEditDoubleClick m_editFilter; 248 | 249 | CRegStdDWORD m_regUseRegex; 250 | CRegStdDWORD m_regAllSize; 251 | CRegStdString m_regSize; 252 | CRegStdDWORD m_regSizeCombo; 253 | CRegStdDWORD m_regIncludeSystem; 254 | CRegStdDWORD m_regIncludeHidden; 255 | CRegStdDWORD m_regIncludeSubfolders; 256 | CRegStdDWORD m_regIncludeSymLinks; 257 | CRegStdDWORD m_regIncludeBinary; 258 | CRegStdDWORD m_regCreateBackup; 259 | CRegStdDWORD m_regKeepFileDate; 260 | CRegStdDWORD m_regWholeWords; 261 | CRegStdDWORD m_regUTF8; 262 | CRegStdDWORD m_regBinary; 263 | CRegStdDWORD m_regCaseSensitive; 264 | CRegStdDWORD m_regDotMatchesNewline; 265 | CRegStdDWORD m_regUseRegexForPaths; 266 | CRegStdString m_regPattern; 267 | CRegStdString m_regExcludeDirsPattern; 268 | CRegStdString m_regSearchPath; 269 | CRegStdString m_regEditorCmd; 270 | CRegStdDWORD m_regBackupInFolder; 271 | CRegStdDWORD m_regDateLimit; 272 | CRegStdDWORD m_regDate1Low; 273 | CRegStdDWORD m_regDate1High; 274 | CRegStdDWORD m_regDate2Low; 275 | CRegStdDWORD m_regDate2High; 276 | CRegStdDWORD m_regShowContent; 277 | }; -------------------------------------------------------------------------------- /src/SearchInfo.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2012-2014, 2021-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #include "stdafx.h" 20 | #include "SearchInfo.h" 21 | 22 | CSearchInfo::CSearchInfo() 23 | : fileSize(0) 24 | , matchCount(0) 25 | , modifiedTime{} 26 | , encoding(CTextFile::UnicodeType::AutoType) 27 | , hasBackedup(false) 28 | , readError(false) 29 | , folder(false) 30 | { 31 | } 32 | 33 | CSearchInfo::CSearchInfo(const std::wstring& path) 34 | : filePath(path) 35 | , fileSize(0) 36 | , matchCount(0) 37 | , modifiedTime{} 38 | , encoding(CTextFile::UnicodeType::AutoType) 39 | , hasBackedup(false) 40 | , readError(false) 41 | , folder(false) 42 | { 43 | } 44 | 45 | CSearchInfo::~CSearchInfo() 46 | { 47 | } 48 | 49 | bool CSearchInfo::NameCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 50 | { 51 | std::wstring name1 = entry1->filePath.substr(entry1->filePath.find_last_of('\\') + 1); 52 | std::wstring name2 = entry2->filePath.substr(entry2->filePath.find_last_of('\\') + 1); 53 | return StrCmpLogicalW(name1.c_str(), name2.c_str()) < 0; 54 | } 55 | 56 | bool CSearchInfo::SizeCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 57 | { 58 | return entry1->fileSize < entry2->fileSize; 59 | } 60 | 61 | bool CSearchInfo::MatchesCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 62 | { 63 | return entry1->matchCount < entry2->matchCount; 64 | } 65 | 66 | bool CSearchInfo::PathCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 67 | { 68 | std::wstring name1 = entry1->filePath.substr(entry1->filePath.find_last_of('\\') + 1); 69 | std::wstring name2 = entry2->filePath.substr(entry2->filePath.find_last_of('\\') + 1); 70 | std::wstring path1 = entry1->filePath.substr(0, entry1->filePath.size() - name1.size() - 1); 71 | std::wstring path2 = entry2->filePath.substr(0, entry2->filePath.size() - name2.size() - 1); 72 | int cmp = path1.compare(path2); 73 | if (cmp != 0) 74 | return cmp < 0; 75 | return StrCmpLogicalW(name1.c_str(), name2.c_str()) < 0; 76 | } 77 | 78 | bool CSearchInfo::EncodingCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 79 | { 80 | return entry1->encoding < entry2->encoding; 81 | } 82 | 83 | bool CSearchInfo::ModifiedTimeCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 84 | { 85 | return CompareFileTime(&entry1->modifiedTime, &entry2->modifiedTime) < 0; 86 | } 87 | 88 | bool CSearchInfo::ExtCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2) 89 | { 90 | auto dotPos1 = entry1->filePath.find_last_of('.'); 91 | auto dotPos2 = entry2->filePath.find_last_of('.'); 92 | std::wstring ext1 = dotPos1 != std::wstring::npos ? entry1->filePath.substr(dotPos1 + 1) : L""; 93 | std::wstring ext2 = dotPos2 != std::wstring::npos ? entry2->filePath.substr(dotPos2 + 1) : L""; 94 | return StrCmpLogicalW(ext1.c_str(), ext2.c_str()) < 0; 95 | } 96 | 97 | bool CSearchInfo::NameCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 98 | { 99 | std::wstring name1 = entry1->filePath.substr(entry1->filePath.find_last_of('\\') + 1); 100 | std::wstring name2 = entry2->filePath.substr(entry2->filePath.find_last_of('\\') + 1); 101 | return StrCmpLogicalW(name1.c_str(), name2.c_str()) > 0; 102 | } 103 | 104 | bool CSearchInfo::SizeCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 105 | { 106 | return entry1->fileSize > entry2->fileSize; 107 | } 108 | 109 | bool CSearchInfo::MatchesCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 110 | { 111 | return entry1->matchCount > entry2->matchCount; 112 | } 113 | 114 | bool CSearchInfo::PathCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 115 | { 116 | std::wstring name1 = entry1->filePath.substr(entry1->filePath.find_last_of('\\') + 1); 117 | std::wstring name2 = entry2->filePath.substr(entry2->filePath.find_last_of('\\') + 1); 118 | std::wstring path1 = entry1->filePath.substr(0, entry1->filePath.size() - name1.size() - 1); 119 | std::wstring path2 = entry2->filePath.substr(0, entry2->filePath.size() - name2.size() - 1); 120 | int cmp = path1.compare(path2); 121 | if (cmp != 0) 122 | return cmp > 0; 123 | return StrCmpLogicalW(name1.c_str(), name2.c_str()) > 0; 124 | } 125 | 126 | bool CSearchInfo::EncodingCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 127 | { 128 | return entry1->encoding > entry2->encoding; 129 | } 130 | 131 | bool CSearchInfo::ModifiedTimeCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 132 | { 133 | return CompareFileTime(&entry1->modifiedTime, &entry2->modifiedTime) > 0; 134 | } 135 | 136 | bool CSearchInfo::ExtCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2) 137 | { 138 | auto dotPos1 = entry1->filePath.find_last_of('.'); 139 | auto dotPos2 = entry2->filePath.find_last_of('.'); 140 | std::wstring ext1 = dotPos1 != std::wstring::npos ? entry1->filePath.substr(dotPos1 + 1) : L""; 141 | std::wstring ext2 = dotPos2 != std::wstring::npos ? entry2->filePath.substr(dotPos2 + 1) : L""; 142 | return StrCmpLogicalW(ext1.c_str(), ext2.c_str()) > 0; 143 | } 144 | 145 | bool CSearchInfo::operator<(const CSearchInfo& other) const 146 | { 147 | if (auto res = _wcsicmp(filePath.c_str(), other.filePath.c_str())) 148 | return res < 0; 149 | if (fileSize != other.fileSize) 150 | return fileSize < other.fileSize; 151 | if (matchCount != other.matchCount) 152 | return matchCount < other.matchCount; 153 | if (readError != other.readError) 154 | return readError != other.readError; 155 | if (folder != other.folder) 156 | return folder != other.folder; 157 | if (CompareFileTime(&modifiedTime, &other.modifiedTime) != 0) 158 | return CompareFileTime(&modifiedTime, &other.modifiedTime) < 0; 159 | if (matchLinesNumbers != other.matchLinesNumbers) 160 | return matchLinesNumbers < other.matchLinesNumbers; 161 | if (matchLinesMap != other.matchLinesMap) 162 | return matchLinesMap < other.matchLinesMap; 163 | return false; 164 | } 165 | -------------------------------------------------------------------------------- /src/SearchInfo.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2010, 2012-2013, 2021-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | #include 23 | #include "TextFile.h" 24 | 25 | class CSearchInfo 26 | { 27 | public: 28 | CSearchInfo(); 29 | CSearchInfo(const std::wstring& path); 30 | CSearchInfo(const CSearchInfo& other) = default; 31 | CSearchInfo& operator=(const CSearchInfo& other) = default; 32 | CSearchInfo(CSearchInfo&& other) = default; 33 | CSearchInfo& operator=(CSearchInfo&& other) = default; 34 | ~CSearchInfo(); 35 | 36 | static bool NameCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 37 | static bool SizeCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 38 | static bool MatchesCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 39 | static bool PathCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 40 | static bool EncodingCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 41 | static bool ModifiedTimeCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 42 | static bool ExtCompareAsc(const CSearchInfo* entry1, const CSearchInfo* entry2); 43 | 44 | static bool NameCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 45 | static bool SizeCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 46 | static bool MatchesCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 47 | static bool PathCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 48 | static bool EncodingCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 49 | static bool ModifiedTimeCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 50 | static bool ExtCompareDesc(const CSearchInfo* entry1, const CSearchInfo* entry2); 51 | 52 | bool operator<(const CSearchInfo& other) const; 53 | 54 | std::wstring filePath; 55 | __int64 fileSize; 56 | std::deque matchLinesNumbers; 57 | std::deque matchColumnsNumbers; 58 | std::deque matchLengths; 59 | std::map matchLinesMap; 60 | __int64 matchCount; 61 | FILETIME modifiedTime; 62 | CTextFile::UnicodeType encoding; 63 | bool hasBackedup; 64 | bool readError; 65 | bool folder; 66 | std::wstring exception; 67 | }; 68 | -------------------------------------------------------------------------------- /src/Settings.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2012-2013, 2019-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "BaseDialog.h" 21 | #include "DlgResizer.h" 22 | #include "Registry.h" 23 | #include 24 | 25 | /** 26 | * bookmarks dialog. 27 | */ 28 | class CSettingsDlg : public CDialog 29 | { 30 | public: 31 | CSettingsDlg(HWND hParent); 32 | ~CSettingsDlg() override; 33 | 34 | protected: 35 | LRESULT CALLBACK DlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) override; 36 | LRESULT DoCommand(int id, int msg); 37 | 38 | private: 39 | HWND m_hParent; 40 | CRegStdString m_regEditorCmd; 41 | std::vector m_langPaths; 42 | CRegStdDWORD m_regEsc; 43 | int m_themeCallbackId; 44 | CDlgResizer m_resizer; 45 | }; 46 | -------------------------------------------------------------------------------- /src/Setup/AppXManifest.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 14 | 17 | 18 | grepWin 19 | Assets\StoreLogo.png 20 | Stefan Kueng 21 | true 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/Setup/Banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Setup/Banner.jpg -------------------------------------------------------------------------------- /src/Setup/CustomActions/CustomActions.cpp: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | 20 | /* BIG FAT WARNING: Do not use any functions which require the C-Runtime library 21 | in this custom action dll! The runtimes might not be installed yet! 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #pragma comment(lib, "windowsapp.lib") 34 | 35 | using namespace winrt::Windows::Foundation; 36 | using namespace winrt::Windows::Management::Deployment; 37 | 38 | BOOL APIENTRY DllMain(HANDLE /*hModule*/, 39 | DWORD /*ul_reason_for_call*/, 40 | LPVOID /*lpReserved*/ 41 | ) 42 | { 43 | return TRUE; 44 | } 45 | 46 | UINT __stdcall MsgBox(MSIHANDLE /*hModule*/) 47 | { 48 | MessageBox(nullptr, L"CustomAction \"MsgBox\" running", L"Installer", MB_ICONINFORMATION); 49 | return ERROR_SUCCESS; 50 | } 51 | 52 | UINT __stdcall RegisterSparsePackage(MSIHANDLE hModule) 53 | { 54 | DWORD len = 0; 55 | wchar_t emptyString[1]{}; 56 | MsiGetPropertyW(hModule, L"APPLICATIONFOLDER", emptyString, &len); 57 | auto sparseExtPath = std::make_unique(len + 1LL); 58 | len += 1; 59 | MsiGetPropertyW(hModule, L"APPLICATIONFOLDER", sparseExtPath.get(), &len); 60 | 61 | len = 0; 62 | MsiGetPropertyW(hModule, L"SPARSEPACKAGEFILE", emptyString, &len); 63 | auto sparsePackageFile = std::make_unique(len + 1LL); 64 | len += 1; 65 | MsiGetPropertyW(hModule, L"SPARSEPACKAGEFILE", sparsePackageFile.get(), &len); 66 | 67 | std::wstring sSparsePackagePath = sparseExtPath.get(); 68 | sSparsePackagePath += L"\\"; 69 | sSparsePackagePath += sparsePackageFile.get(); 70 | 71 | PackageManager manager; 72 | AddPackageOptions options; 73 | Uri externalUri(sparseExtPath.get()); 74 | Uri packageUri(sSparsePackagePath.c_str()); 75 | options.ExternalLocationUri(externalUri); 76 | auto deploymentOperation = manager.AddPackageByUriAsync(packageUri, options); 77 | 78 | auto deployResult = deploymentOperation.get(); 79 | 80 | if (!SUCCEEDED(deployResult.ExtendedErrorCode())) 81 | { 82 | // Deployment failed 83 | PMSIHANDLE hRecord = MsiCreateRecord(0); 84 | std::wstring error = L"AddPackageByUriAsync failed (Errorcode: "; 85 | error += std::to_wstring(deployResult.ExtendedErrorCode()); 86 | error += L"):\n"; 87 | error += deployResult.ErrorText(); 88 | MsiRecordSetStringW(hRecord, 0, error.c_str()); 89 | MsiProcessMessage(hModule, INSTALLMESSAGE_ERROR, hRecord); 90 | MsiCloseHandle(hRecord); 91 | } 92 | return ERROR_SUCCESS; 93 | } 94 | 95 | UINT __stdcall UnregisterSparsePackage(MSIHANDLE hModule) 96 | { 97 | DWORD len = 0; 98 | wchar_t emptyString[1]{}; 99 | MsiGetPropertyW(hModule, L"SPARSEPACKAGENAME", emptyString, &len); 100 | auto sparsePackageName = std::make_unique(len + 1LL); 101 | len += 1; 102 | MsiGetPropertyW(hModule, L"SPARSEPACKAGENAME", sparsePackageName.get(), &len); 103 | 104 | PackageManager packageManager; 105 | Collections::IIterable packages; 106 | try 107 | { 108 | packages = packageManager.FindPackagesForUser(L""); 109 | } 110 | catch (winrt::hresult_error const& ex) 111 | { 112 | PMSIHANDLE hRecord = MsiCreateRecord(0); 113 | std::wstring error = L"FindPackagesForUser failed (Errorcode: "; 114 | error += std::to_wstring(ex.code().value); 115 | error += L"):\n"; 116 | error += ex.message(); 117 | MsiRecordSetStringW(hRecord, 0, error.c_str()); 118 | MsiProcessMessage(hModule, INSTALLMESSAGE_ERROR, hRecord); 119 | MsiCloseHandle(hRecord); 120 | } 121 | 122 | for (const auto& package : packages) 123 | { 124 | if (package.Id().Name() != sparsePackageName.get()) 125 | continue; 126 | 127 | winrt::hstring fullName = package.Id().FullName(); 128 | auto deploymentOperation = packageManager.RemovePackageAsync(fullName, RemovalOptions::None); 129 | auto deployResult = deploymentOperation.get(); 130 | if (SUCCEEDED(deployResult.ExtendedErrorCode())) 131 | break; 132 | 133 | // Undeployment failed 134 | PMSIHANDLE hRecord = MsiCreateRecord(0); 135 | std::wstring error = L"RemovePackageAsync failed (Errorcode: "; 136 | error += std::to_wstring(deployResult.ExtendedErrorCode()); 137 | error += L"):\n"; 138 | error += deployResult.ErrorText(); 139 | MsiRecordSetStringW(hRecord, 0, error.c_str()); 140 | MsiProcessMessage(hModule, INSTALLMESSAGE_ERROR, hRecord); 141 | MsiCloseHandle(hRecord); 142 | } 143 | 144 | return ERROR_SUCCESS; 145 | } -------------------------------------------------------------------------------- /src/Setup/CustomActions/CustomActions.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | MsgBox 3 | RegisterSparsePackage 4 | UnregisterSparsePackage 5 | -------------------------------------------------------------------------------- /src/Setup/CustomActions/CustomActions.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Release 6 | Win32 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {454D5FCC-E25A-4B45-9CA2-01ABB0FA5181} 15 | CustomActions 16 | Win32Proj 17 | 10.0 18 | 19 | 20 | 21 | DynamicLibrary 22 | Unicode 23 | v143 24 | 25 | 26 | DynamicLibrary 27 | Unicode 28 | v143 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | $(SolutionDir)bin\$(Configuration)\ 42 | 43 | 44 | $(SolutionDir)bin\$(Configuration)64\ 45 | $(SolutionDir)obj\$(Configuration)64\$(ProjectName)\ 46 | 47 | 48 | $(SolutionDir)obj\$(Configuration)\$(ProjectName)\ 49 | 50 | 51 | 52 | _USRDLL;CUSTOMACTIONS_EXPORTS;%(PreprocessorDefinitions) 53 | MultiThreaded 54 | NotUsing 55 | stdcpp20 56 | 57 | 58 | CustomActions.def 59 | Msi.lib;%(AdditionalDependencies) 60 | 61 | 62 | 63 | 64 | _USRDLL;CUSTOMACTIONS_EXPORTS;%(PreprocessorDefinitions) 65 | MultiThreaded 66 | NotUsing 67 | stdcpp20 68 | 69 | 70 | CustomActions.def 71 | Msi.lib;%(AdditionalDependencies) 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /src/Setup/CustomActions/CustomActions.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | 10 | 11 | Source Files 12 | 13 | 14 | 15 | 16 | Source Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Setup/CustomActions/CustomActions.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Setup/Dialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Setup/Dialog.jpg -------------------------------------------------------------------------------- /src/Setup/License.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252 2 | {\fonttbl {\f0\fswiss\fcharset0 Arial;}} 3 | \f0\sa100\fs18\lang1033 4 | 5 | Copyright (C) 2007-2021 - grepWin 6 | 7 | \par\ql 8 | grepWin is free. You don't have to pay for it, and you can use it 9 | any way you want. It is developed as an Open Source project under the 10 | GNU General Public License (GPL). That means you have full access to 11 | the source code of this program. You can find it on our website at 12 | http://tools.stefankueng.com 13 | 14 | \par 15 | Should you wish to modify or redistribute this program, or any part of it, 16 | you should read the full terms and conditions set out in the license 17 | agreement before doing so. A copy of the license is available on our website. 18 | 19 | \par 20 | If you simply wish to install and use this software, you need only be aware of 21 | the disclaimer conditions in the license, which are set out below. 22 | 23 | \par\b 24 | NO WARRANTY 25 | 26 | \par\b0 27 | Because the program is licensed free of charge, there is no warranty 28 | for the program, to the extent permitted by applicable law. Except when 29 | otherwise stated in writing the copyright holders and/or other parties 30 | provide the program "as is" without warranty of any kind, either expressed 31 | or implied, including, but not limited to, the implied warranties of 32 | merchantability and fitness for a particular purpose. The entire risk as 33 | to the quality and performance of the program is with you. Should the 34 | program prove defective, you assume the cost of all necessary servicing, 35 | repair or correction. 36 | 37 | \par 38 | In no event unless required by applicable law or agreed to in writing 39 | will any copyright holder, or any other party who may modify and/or 40 | redistribute the program as permitted above, be liable to you for damages, 41 | including any general, special, incidental or consequential damages arising 42 | out of the use or inability to use the program (including but not limited 43 | to loss of data or data being rendered inaccurate or losses sustained by 44 | you or third parties or a failure of the program to operate with any other 45 | programs), even if such holder or other party has been advised of the 46 | possibility of such damages. 47 | } 48 | -------------------------------------------------------------------------------- /src/Setup/StefansTools_setupdialog.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/src/Setup/StefansTools_setupdialog.pdn -------------------------------------------------------------------------------- /src/Setup/VersionNumberInclude.in.wxi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Setup/setup.build: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sets the version information as properties, env variables 7 | and sets up the different version specific files. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/Setup/website.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://tools.stefankueng.com/ -------------------------------------------------------------------------------- /src/ShellContextMenu.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2007-2008, 2011-2015, 2021, 2023-2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // ReSharper disable once CppInconsistentNaming 26 | class CIShellFolderHook; 27 | class CSearchInfo; 28 | struct LineData; 29 | 30 | class CShellContextMenu 31 | { 32 | public: 33 | void SetObjects(std::vector&& strVector, std::vector&& lineVector); 34 | UINT ShowContextMenu(HWND hWnd, POINT pt); 35 | CShellContextMenu(); 36 | virtual ~CShellContextMenu(); 37 | 38 | private: 39 | BOOL bDelete; 40 | HMENU m_menu; 41 | IShellFolder *m_psfFolder; 42 | LPITEMIDLIST *m_pidlArray; 43 | int m_pidlArrayItems; 44 | std::vector m_strVector; 45 | std::vector m_lineVector; 46 | 47 | static void InvokeCommand(LPCONTEXTMENU pContextMenu, UINT idCommand); 48 | BOOL GetContextMenu(HWND hWnd, void **ppContextMenu, int &iMenuType); 49 | static LRESULT CALLBACK HookWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 50 | static void FreePIDLArray(LPITEMIDLIST *pidlArray, int nItems); 51 | 52 | static HRESULT CALLBACK dfmCallback(IShellFolder *psf, HWND hwnd, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam); 53 | 54 | std::unique_ptr m_pFolderHook; 55 | 56 | friend class CIShellFolderHook; 57 | }; 58 | 59 | // ReSharper disable once CppInconsistentNaming 60 | class CIShellFolderHook : public IShellFolder 61 | { 62 | public: 63 | CIShellFolderHook(LPSHELLFOLDER sf, CShellContextMenu *pShellContextMenu) 64 | { 65 | sf->AddRef(); 66 | m_iSf = sf; 67 | m_pShellContextMenu = pShellContextMenu; 68 | } 69 | 70 | virtual ~CIShellFolderHook() { m_iSf->Release(); } 71 | 72 | // IUnknown methods -------- 73 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void **ppvObject) override { return m_iSf->QueryInterface(riid, ppvObject); } 74 | ULONG STDMETHODCALLTYPE AddRef() override { return m_iSf->AddRef(); } 75 | ULONG STDMETHODCALLTYPE Release() override { return m_iSf->Release(); } 76 | 77 | // IShellFolder methods ---- 78 | HRESULT STDMETHODCALLTYPE GetUIObjectOf(HWND hwndOwner, UINT cidl, LPCITEMIDLIST *apidl, REFIID riid, UINT *rgfReserved, void **ppv) override; 79 | 80 | HRESULT STDMETHODCALLTYPE CompareIDs(LPARAM lParam, __RPC__in PCUIDLIST_RELATIVE pidl1, __RPC__in PCUIDLIST_RELATIVE pidl2) override { return m_iSf->CompareIDs(lParam, pidl1, pidl2); } 81 | HRESULT STDMETHODCALLTYPE GetDisplayNameOf(__RPC__in_opt PCUITEMID_CHILD pidl, SHGDNF uFlags, __RPC__out STRRET *pName) override { return m_iSf->GetDisplayNameOf(pidl, uFlags, pName); } 82 | HRESULT STDMETHODCALLTYPE CreateViewObject(__RPC__in_opt HWND hwndOwner, __RPC__in REFIID riid, __RPC__deref_out_opt void **ppv) override { return m_iSf->CreateViewObject(hwndOwner, riid, ppv); } 83 | HRESULT STDMETHODCALLTYPE EnumObjects(__RPC__in_opt HWND hwndOwner, SHCONTF grfFlags, __RPC__deref_out_opt IEnumIDList **ppenumIDList) override { return m_iSf->EnumObjects(hwndOwner, grfFlags, ppenumIDList); } 84 | HRESULT STDMETHODCALLTYPE BindToObject(__RPC__in PCUIDLIST_RELATIVE pidl, __RPC__in_opt IBindCtx *pbc, __RPC__in REFIID riid, __RPC__deref_out_opt void **ppv) override { return m_iSf->BindToObject(pidl, pbc, riid, ppv); } 85 | HRESULT STDMETHODCALLTYPE ParseDisplayName(__RPC__in_opt HWND hwnd, __RPC__in_opt IBindCtx *pbc, __RPC__in_string LPWSTR pszDisplayName, __reserved ULONG *pchEaten, __RPC__deref_out_opt PIDLIST_RELATIVE *ppidl, __RPC__inout_opt ULONG *pdwAttributes) override { return m_iSf->ParseDisplayName(hwnd, pbc, pszDisplayName, pchEaten, ppidl, pdwAttributes); } 86 | HRESULT STDMETHODCALLTYPE GetAttributesOf(UINT cidl, __RPC__in_ecount_full_opt(cidl) PCUITEMID_CHILD_ARRAY apidl, __RPC__inout SFGAOF *rgfInOut) override { return m_iSf->GetAttributesOf(cidl, apidl, rgfInOut); } 87 | HRESULT STDMETHODCALLTYPE BindToStorage(__RPC__in PCUIDLIST_RELATIVE pidl, __RPC__in_opt IBindCtx *pbc, __RPC__in REFIID riid, __RPC__deref_out_opt void **ppv) override { return m_iSf->BindToStorage(pidl, pbc, riid, ppv); } 88 | HRESULT STDMETHODCALLTYPE SetNameOf(__in_opt HWND hwnd, __in PCUITEMID_CHILD pidl, __in LPCWSTR pszName, __in SHGDNF uFlags, __deref_opt_out PITEMID_CHILD *ppidlOut) override { return m_iSf->SetNameOf(hwnd, pidl, pszName, uFlags, ppidlOut); } 89 | 90 | protected: 91 | LPSHELLFOLDER m_iSf; 92 | CShellContextMenu *m_pShellContextMenu; 93 | }; 94 | -------------------------------------------------------------------------------- /src/TextOffset.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2024 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include 21 | #include 22 | 23 | template 24 | class TextOffset 25 | { 26 | private: 27 | long lenBOM; // by the encoding 28 | bool bBigEndian; 29 | std::vector linePositions; 30 | 31 | public: 32 | TextOffset() 33 | : lenBOM(0) 34 | , bBigEndian(false) 35 | { 36 | } 37 | 38 | // forcibly treated as char 39 | const char* SkipBOM(const char* start, const char* end) 40 | { 41 | char BOM[] = "\xEF\xBB\xBF"; 42 | if (end - start > 2 && memcmp(start, BOM, 3) == 0) 43 | { 44 | lenBOM = 3; 45 | return start + 3; 46 | } 47 | else if (end - start > 1) 48 | { 49 | const wchar_t* startW = reinterpret_cast(start); 50 | if (*startW == 0xFEFF || (bBigEndian = *startW == 0xFFFE) == true) 51 | { 52 | lenBOM = 2; 53 | return start + 2; 54 | } 55 | } 56 | return start; 57 | } 58 | 59 | bool CalculateLines(const CharT* start, const CharT* end, const std::atomic_bool& bCancelled) 60 | { 61 | if (start >= end) 62 | return false; 63 | 64 | linePositions.clear(); 65 | linePositions.reserve((end - start) / 10); 66 | 67 | size_t pos = 0; 68 | bool bGot = false; 69 | for (auto it = start; it < end && !bCancelled; ++it) 70 | { 71 | bGot = false; 72 | if (*it == '\r' || (bBigEndian && *it == 0x0d00)) 73 | { 74 | // cr lineending 75 | bGot = true; 76 | if (it + 1 < end) 77 | { 78 | if (it[1] == '\n' || (bBigEndian && *it == 0x0a00)) 79 | { 80 | // crlf lineending 81 | ++it; 82 | ++pos; 83 | } 84 | } 85 | } 86 | else if (*it == '\n' || (bBigEndian && *it == 0x0a00)) 87 | { 88 | // lf lineending 89 | bGot = true; 90 | } 91 | ++pos; 92 | if (bGot) 93 | linePositions.push_back(pos); 94 | } 95 | if (!bGot) 96 | linePositions.push_back(pos); 97 | return true; 98 | } 99 | 100 | long LineFromPosition(long pos) const 101 | { 102 | auto lb = std::ranges::lower_bound(linePositions, static_cast(pos)); 103 | auto lbLine = lb - linePositions.begin(); 104 | return static_cast(lbLine + 1); 105 | } 106 | 107 | std::tuple PositionsFromLine(long line) const 108 | { 109 | if (line > 0 && static_cast(line) <= linePositions.size()) 110 | return std::make_tuple(line > 1 ? linePositions[line - 2] - lenBOM : 0, linePositions[line - 1] - lenBOM); 111 | return std::make_tuple(-1, -1); 112 | } 113 | 114 | long ColumnFromPosition(long pos, long line) const 115 | { 116 | if (line < 0) 117 | line = LineFromPosition(pos); 118 | long lastLineEnd = -1; 119 | if (line > 1) 120 | lastLineEnd = static_cast(linePositions[line - 2]) - lenBOM; 121 | else 122 | lastLineEnd = lenBOM; 123 | return pos - lastLineEnd; 124 | } 125 | }; 126 | -------------------------------------------------------------------------------- /src/Theme.h: -------------------------------------------------------------------------------- 1 | // grepWin - regex search and replace for Windows 2 | 3 | // Copyright (C) 2020-2021 - Stefan Kueng 4 | 5 | // This program is free software; you can redistribute it and/or 6 | // modify it under the terms of the GNU General Public License 7 | // as published by the Free Software Foundation; either version 2 8 | // of the License, or (at your option) any later version. 9 | 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program; if not, write to the Free Software Foundation, 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | #pragma once 20 | #include "registry.h" 21 | #include 22 | #include 23 | 24 | using ThemeChangeCallback = std::function; 25 | 26 | /** 27 | * Singleton to handle Theme related methods. 28 | * provides callbacks to allow different parts of the app 29 | * to receive notifications when the theme changes. 30 | */ 31 | class CTheme 32 | { 33 | private: 34 | CTheme(); 35 | ~CTheme(); 36 | 37 | public: 38 | static CTheme& Instance(); 39 | 40 | /// call this on every WM_SYSCOLORCHANGED message 41 | void OnSysColorChanged(); 42 | /// returns true if dark mode is even allowed. We only allow dark mode on Win10 1809 or later. 43 | bool IsDarkModeAllowed(); 44 | /// sets the theme and calls all registered callbacks. 45 | /// if \force is true, all Callback functions are called whether the mode changed or not 46 | void SetDarkTheme(bool b = true, bool force = false); 47 | /// returns true if dark theme is enabled. If false, then the normal theme is active. 48 | bool IsDarkTheme() const; 49 | /// returns true if high contrast mode is on 50 | bool IsHighContrastMode() const; 51 | /// returns true if high contrast mode is on, and the color scheme is dark 52 | bool IsHighContrastModeDark() const; 53 | /// converts a color to the theme color. For normal theme the \b clr is returned unchanged. 54 | /// for dark theme, the color is adjusted in brightness. 55 | COLORREF GetThemeColor(COLORREF clr, bool fixed = false) const; 56 | /// registers a callback function that's called for every theme change. 57 | /// returns an id that can be used to unregister the callback function. 58 | int RegisterThemeChangeCallback(ThemeChangeCallback&& cb); 59 | /// unregisters a callback function. 60 | bool RemoveRegisteredCallback(int id); 61 | 62 | /// sets the theme for a whole dialog. For dark mode, the 63 | /// windows are subclassed if necessary. For normal mode, 64 | /// subclassing is removed to ensure the behavior is 65 | /// identical to the original. 66 | bool SetThemeForDialog(HWND hWnd, bool bDark); 67 | 68 | static void RGBToHSB(COLORREF rgb, BYTE& hue, BYTE& saturation, BYTE& brightness); 69 | static void RGBtoHSL(COLORREF color, float& h, float& s, float& l); 70 | static COLORREF HSLtoRGB(float h, float s, float l); 71 | 72 | private: 73 | void Load(); 74 | static BOOL CALLBACK AdjustThemeForChildrenProc(HWND hwnd, LPARAM lParam); 75 | static LRESULT CALLBACK ListViewSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 76 | static LRESULT CALLBACK ComboBoxSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 77 | static LRESULT CALLBACK MainSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 78 | static LRESULT CALLBACK ButtonSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 79 | static LRESULT CALLBACK AutoSuggestSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); 80 | 81 | private: 82 | bool m_bLoaded; 83 | bool m_dark; 84 | bool m_isHighContrastMode; 85 | bool m_isHighContrastModeDark; 86 | bool m_bDarkModeIsAllowed; 87 | std::unordered_map m_themeChangeCallbacks; 88 | int m_lastThemeChangeCallbackId; 89 | CRegStdDWORD m_regDarkTheme; 90 | static HBRUSH m_sBackBrush; 91 | }; 92 | -------------------------------------------------------------------------------- /src/compatibility.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/grepWin.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | {cf0213c9-090b-4d7b-b520-15dfdc2a8dc9} 18 | 19 | 20 | {3c7375ef-2b6e-4733-9c3c-40d59a7a0975} 21 | 22 | 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | sktoolslib 62 | 63 | 64 | sktoolslib 65 | 66 | 67 | sktoolslib 68 | 69 | 70 | sktoolslib 71 | 72 | 73 | sktoolslib 74 | 75 | 76 | sktoolslib 77 | 78 | 79 | sktoolslib 80 | 81 | 82 | sktoolslib 83 | 84 | 85 | sktoolslib 86 | 87 | 88 | sktoolslib 89 | 90 | 91 | sktoolslib 92 | 93 | 94 | sktoolslib 95 | 96 | 97 | sktoolslib 98 | 99 | 100 | sktoolslib 101 | 102 | 103 | sktoolslib 104 | 105 | 106 | sktoolslib 107 | 108 | 109 | sktoolslib 110 | 111 | 112 | sktoolslib 113 | 114 | 115 | sktoolslib 116 | 117 | 118 | Source Files 119 | 120 | 121 | sktoolslib 122 | 123 | 124 | sktoolslib 125 | 126 | 127 | sktoolslib 128 | 129 | 130 | sktoolslib 131 | 132 | 133 | Source Files 134 | 135 | 136 | sktoolslib 137 | 138 | 139 | sktoolslib 140 | 141 | 142 | sktoolslib 143 | 144 | 145 | sktoolslib 146 | 147 | 148 | sktoolslib 149 | 150 | 151 | Source Files 152 | 153 | 154 | 155 | 156 | Header Files 157 | 158 | 159 | Header Files 160 | 161 | 162 | Header Files 163 | 164 | 165 | Header Files 166 | 167 | 168 | Header Files 169 | 170 | 171 | Header Files 172 | 173 | 174 | Header Files 175 | 176 | 177 | Header Files 178 | 179 | 180 | Header Files 181 | 182 | 183 | Header Files 184 | 185 | 186 | Header Files 187 | 188 | 189 | Header Files 190 | 191 | 192 | Header Files 193 | 194 | 195 | sktoolslib 196 | 197 | 198 | sktoolslib 199 | 200 | 201 | sktoolslib 202 | 203 | 204 | sktoolslib 205 | 206 | 207 | sktoolslib 208 | 209 | 210 | sktoolslib 211 | 212 | 213 | sktoolslib 214 | 215 | 216 | sktoolslib 217 | 218 | 219 | sktoolslib 220 | 221 | 222 | sktoolslib 223 | 224 | 225 | sktoolslib 226 | 227 | 228 | sktoolslib 229 | 230 | 231 | sktoolslib 232 | 233 | 234 | sktoolslib 235 | 236 | 237 | sktoolslib 238 | 239 | 240 | sktoolslib 241 | 242 | 243 | sktoolslib 244 | 245 | 246 | sktoolslib 247 | 248 | 249 | sktoolslib 250 | 251 | 252 | sktoolslib 253 | 254 | 255 | Header Files 256 | 257 | 258 | sktoolslib 259 | 260 | 261 | sktoolslib 262 | 263 | 264 | sktoolslib 265 | 266 | 267 | sktoolslib 268 | 269 | 270 | sktoolslib 271 | 272 | 273 | Header Files 274 | 275 | 276 | sktoolslib 277 | 278 | 279 | Header Files 280 | 281 | 282 | sktoolslib 283 | 284 | 285 | sktoolslib 286 | 287 | 288 | sktoolslib 289 | 290 | 291 | sktoolslib 292 | 293 | 294 | sktoolslib 295 | 296 | 297 | sktoolslib 298 | 299 | 300 | Header Files 301 | 302 | 303 | Header Files 304 | 305 | 306 | 307 | 308 | Resource Files 309 | 310 | 311 | Scripts 312 | 313 | 314 | Scripts 315 | 316 | 317 | Scripts 318 | 319 | 320 | Scripts 321 | 322 | 323 | Header Files 324 | 325 | 326 | Resource Files 327 | 328 | 329 | 330 | 331 | 332 | Resource Files 333 | 334 | 335 | 336 | 337 | Resource Files 338 | 339 | 340 | -------------------------------------------------------------------------------- /src/last/version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define __STR2__(x) #x 4 | #define __STR1__(x) __STR2__(x) 5 | #define __LOC__ __FILE__ "("__STR1__(__LINE__)") : Info : " 6 | 7 | #pragma message(__LOC__"Run the NAnt script to get proper version info") 8 | 9 | #define FILEVER 1, 0, 0, 0 10 | #define PRODUCTVER 1, 0, 0, 0 11 | #define STRFILEVER "1.0.0.0\0" 12 | #define STRPRODUCTVER "1.0.0.0\0" 13 | 14 | #define GREPWIN_VERMAJOR 1 15 | #define GREPWIN_VERMINOR 0 16 | #define GREPWIN_VERMICRO 0 17 | #define GREPWIN_VERBUILD 0 18 | #define GREPWIN_VERDATE "no date" 19 | -------------------------------------------------------------------------------- /src/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by D:\Development\grepWin\src\Resources\grepWin.rc 4 | // 5 | #define IDS_APP_TITLE 103 6 | #define IDS_NAME 104 7 | #define IDS_SEARCHSTRING 105 8 | #define IDS_REPLACESTRING 106 9 | #define IDI_GREPWIN 107 10 | #define IDS_NOTESTTEXTAVAILABLE 107 11 | #define IDS_SEARCHSTRINGEMPTY 108 12 | #define IDC_GREPWIN 109 13 | #define IDS_NOREPLACETEXT 110 14 | #define IDS_NOMATCH 111 15 | #define IDS_PATTERN_TT 112 16 | #define IDS_EXCLUDEDIR_TT 113 17 | #define IDS_SEARCHPATH_TT 114 18 | #define IDS_DOTMATCHNEWLINE_TT 115 19 | #define IDS_SEARCHTEXT_TT 116 20 | #define IDS_ONLYONE_TT 117 21 | #define IDS_EDITMULTILINE_TT 118 22 | #define IDS_ABOUT 119 23 | #define IDS_LESSTHAN 120 24 | #define IDS_EQUALTO 121 25 | #define IDS_GREATERTHAN 122 26 | #define IDS_SEARCH 123 27 | #define IDS_REPLACECONFIRM 124 28 | #define IDS_ANEMPTYSTRING 125 29 | #define IDS_STOP 126 30 | #define IDS_SELECTPATHTOSEARCH 127 31 | #define IDS_INFOLABEL 128 32 | #define IDD_SEARCHDLG 129 33 | #define IDS_READERROR 129 34 | #define IDD_REGEXTEST 130 35 | #define IDS_BINARY 130 36 | #define IDD_NAME 131 37 | #define IDS_REGEXOK 131 38 | #define IDD_BOOKMARKS 132 39 | #define IDS_REGEXINVALID 132 40 | #define IDC_BKPOPUP 133 41 | #define IDS_SIZE 133 42 | #define IDS_LINE 134 43 | #define IDD_ABOUT 135 44 | #define IDS_MATCHES 135 45 | #define IDR_SEARCHDLG 136 46 | #define IDS_TEXT 136 47 | #define IDD_MULTILINEEDIT 137 48 | #define IDS_PATH 137 49 | #define IDD_SETTINGS 138 50 | #define IDS_ENCODING 138 51 | #define IDS_DATEMODIFIED 139 52 | #define IDR_RTF1 139 53 | #define IDR_INFODLG 139 54 | #define IDS_SELECTEDITOR 140 55 | #define IDD_NEWLINESDLG 140 56 | #define IDS_OPENWITHEDITOR 141 57 | #define IDS_OPENCONTAININGFOLDER 142 58 | #define IDS_COPYPATH 143 59 | #define IDS_COPYPATHS 144 60 | #define IDS_COPYFILENAME 145 61 | #define IDS_COPYFILENAMES 146 62 | #define IDS_COPYRESULT 147 63 | #define IDS_COPYRESULTS 148 64 | #define IDS_XMOREMATCHES 149 65 | #define IDS_CONTEXTLINE 150 66 | #define IDS_INFOLABELFILE 151 67 | #define IDS_ERR_RELATIVEPATH 152 68 | #define IDS_ERR_INVALID_PATH 153 69 | #define IDS_PROGRAMS 154 70 | #define IDS_ALLFILES 155 71 | #define IDS_BACKUPINFOLDER_TT 156 72 | #define IDS_SHIFT_NOTSEARCH 157 73 | #define IDS_FILEEXT 158 74 | #define IDS_DARKMODE_TT 159 75 | #define IDS_ERR_PATHNOTEXIST 160 76 | #define IDS_INVERSESEARCH 161 77 | #define IDS_SEARCHINFOUNDFILES 162 78 | #define IDS_EXPORT_TT 163 79 | #define IDS_EXPORTTITLE 164 80 | #define IDS_EXPORTPATHS 165 81 | #define IDS_EXPORTMATCHLINENUMBER 166 82 | #define IDS_EXPORTMATCHLINECONTENT 167 83 | #define IDS_UPDATEAVAILABLE 168 84 | #define IDS_CAPTURESEARCH 169 85 | #define IDS_CLONE 170 86 | #define IDS_NEWINSTANCE_TT 171 87 | #define IDS_REPLACEUTF8 172 88 | #define IDS_INFOLABELSEL 173 89 | #define IDS_INFOLABELEMPTY 174 90 | #define IDS_INFOLABELSELEMPTY 175 91 | #define IDS_OPEN_MRU 176 92 | #define IDS_COPY_COLUMN 177 93 | #define IDS_COPY_COLUMN_SEL 178 94 | #define IDS_REGEXEXCEPTION 179 95 | #define IDS_COLUMN 180 96 | #define IDS_FILTER_CUE 181 97 | #define IDC_SEARCHTEXT 1000 98 | #define IDC_REGEXRADIO 1001 99 | #define IDC_TEXTRADIO 1002 100 | #define IDC_WHOLEWORDS 1003 101 | #define IDC_REGEXOKLABEL 1004 102 | #define IDC_ALLSIZERADIO 1005 103 | #define IDC_SIZERADIO 1006 104 | #define IDC_SIZECOMBO 1007 105 | #define IDC_SIZEEDIT 1008 106 | #define IDC_INCLUDESYSTEM 1009 107 | #define IDC_INCLUDEHIDDEN 1010 108 | #define IDC_INCLUDESUBFOLDERS 1011 109 | #define IDC_SEARCHPATH 1012 110 | #define IDC_SEARCHPATHBROWSE 1013 111 | #define IDC_RESULTLIST 1014 112 | #define IDC_GROUPSEARCHIN 1015 113 | #define IDC_GROUPSEARCHFOR 1016 114 | #define IDC_GROUPLIMITSEARCH 1017 115 | #define IDC_GROUPSEARCHRESULTS 1018 116 | #define IDC_KBTEXT 1019 117 | #define IDC_SEARCHINFOLABEL 1020 118 | #define IDC_ADDTOBOOKMARKS 1021 119 | #define IDC_BOOKMARKS 1022 120 | #define IDC_REPLACETEXT 1023 121 | #define IDC_NEWINSTANCE 1024 122 | #define IDC_SEARCHPATHBROWSE2 1025 123 | #define IDC_SEARCHPATHMULTILINEEDIT 1025 124 | #define IDC_SEARCHFORLABEL 1026 125 | #define IDC_REPLACEWITHLABEL 1027 126 | #define IDC_TESTREGEX 1028 127 | #define IDC_CREATEBACKUP 1029 128 | #define IDC_TEXTCONTENT 1030 129 | #define IDC_REGEXMATCH 1031 130 | #define IDC_REGEXREPLACED 1032 131 | #define IDC_NAME 1037 132 | #define IDC_PATTERNLABEL 1039 133 | #define IDC_PATTERN 1040 134 | #define IDC_EXCLUDE_DIRS_PATTERNLABEL 1041 135 | #define IDC_CASE_SENSITIVE 1042 136 | #define IDC_VERSIONINFO 1043 137 | #define IDC_EXCLUDEDIRSPATTERN 1043 138 | #define IDC_DATE 1044 139 | #define IDC_WEBLINK 1045 140 | #define IDC_FILEPATTERNREGEX 1046 141 | #define IDC_FILEPATTERNTEXT 1048 142 | #define IDC_REPLACE 1049 143 | #define IDC_INCLUDEBINARY 1050 144 | #define IDC_DOTMATCHNEWLINE 1051 145 | #define IDC_ABOUTLINK 1052 146 | #define IDC_UTF8 1053 147 | #define IDC_UTF9 1054 148 | #define IDC_BINARY 1054 149 | #define IDC_ABOUTLINK2 1055 150 | #define IDC_INFOLABEL 1056 151 | #define IDC_RESULTFILES 1059 152 | #define IDC_RADIO2 1060 153 | #define IDC_RESULTCONTENT 1060 154 | #define IDC_HELPBUTTON 1061 155 | #define IDC_EDITMULTILINE1 1061 156 | #define IDC_CONVERTNEWLINES_BTN 1061 157 | #define IDC_CHECK1 1062 158 | #define IDC_ESCKEY 1062 159 | #define IDC_INCLUDEPATH 1062 160 | #define IDC_KEEPFILEDATECHECK 1062 161 | #define IDC_EDITMULTILINE2 1063 162 | #define IDC_ONLYONE 1063 163 | #define IDC_PATHMRU 1064 164 | #define IDC_DARKMODE 1064 165 | #define IDC_HELPLABEL 1065 166 | #define IDC_EXCLUDEDIRMRU 1066 167 | #define IDC_EDITORCMD 1066 168 | #define IDC_PATTERNMRU 1067 169 | #define IDC_EDITORGROUP 1067 170 | #define IDC_STATIC1 1068 171 | #define IDC_STATIC2 1069 172 | #define IDC_SETTINGSBUTTON 1071 173 | #define IDC_PROGRESS 1072 174 | #define IDC_LANGUAGE 1073 175 | #define IDC_STATIC3 1074 176 | #define IDC_STATIC4 1075 177 | #define IDC_DWM 1076 178 | #define IDC_BACKUPINFOLDER 1077 179 | #define IDC_RADIO_DATE_ALL 1078 180 | #define IDC_BACKUPINFOLDER2 1078 181 | #define IDC_NOWARNINGIFNOBACKUP 1078 182 | #define IDC_RADIO_DATE_NEWER 1079 183 | #define IDC_RADIO_DATE_OLDER 1080 184 | #define IDC_RADIO_DATE_BETWEEN 1081 185 | #define IDC_DATEPICK1 1082 186 | #define IDC_DATEPICK2 1083 187 | #define IDC_DARKMODEINFO 1083 188 | #define IDC_INVERSESEARCH 1084 189 | #define IDC_SEARCHINFOUNDFILES 1085 190 | #define IDC_EXPORT 1086 191 | #define IDC_UPDATELINK 1087 192 | #define IDC_DOUPDATECHECKS 1088 193 | #define IDC_CAPTURESEARCH 1089 194 | #define IDC_EDIT1 1090 195 | #define IDC_NUMNULL 1090 196 | #define IDC_FILTER 1090 197 | #define IDC_SYSLINK1 1091 198 | #define IDC_INCLUDESYMLINK 1092 199 | #define IDC_CRLF 1093 200 | #define IDC_LF 1094 201 | #define IDC_BOTH 1095 202 | #define ID_REMOVEBOOKMARK 32771 203 | #define ID_DUMMY_RENAMEPRESET 32774 204 | #define ID_RENAMEBOOKMARK 32775 205 | #define IDC_STATIC -1 206 | 207 | // Next default values for new objects 208 | // 209 | #ifdef APSTUDIO_INVOKED 210 | #ifndef APSTUDIO_READONLY_SYMBOLS 211 | #define _APS_NO_MFC 1 212 | #define _APS_NEXT_RESOURCE_VALUE 141 213 | #define _APS_NEXT_COMMAND_VALUE 32776 214 | #define _APS_NEXT_CONTROL_VALUE 1097 215 | #define _APS_NEXT_SYMED_VALUE 110 216 | #endif 217 | #endif 218 | -------------------------------------------------------------------------------- /src/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // grepWin.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /src/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | #include 14 | 15 | // C RunTime Header Files 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include "Language.h" 24 | #include "SimpleIni.h" 25 | 26 | #define BOOST_REGEX_BLOCKSIZE 4096 27 | #define BOOST_REGEX_MAX_BLOCKS (1024 * 32) 28 | #define BOOST_REGEX_MAX_CACHE_BLOCKS (16 * 32) 29 | 30 | extern HINSTANCE g_hInst; 31 | extern bool bPortable; 32 | extern CSimpleIni g_iniFile; 33 | extern std::wstring g_iniPath; 34 | 35 | #define DEBUGOUTPUTREGPATH L"Software\\grepWin\\DebugOutput" 36 | 37 | #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") -------------------------------------------------------------------------------- /src/version.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define FILEVER $MajorVersion$, $MinorVersion$, $MicroVersion$, $WCREV$ 4 | #define PRODUCTVER $MajorVersion$, $MinorVersion$, $MicroVersion$, $WCREV$ 5 | #define STRFILEVER "$MajorVersion$.$MinorVersion$.$MicroVersion$.$WCREV$\0" 6 | #define STRPRODUCTVER "$MajorVersion$.$MinorVersion$.$MicroVersion$.$WCREV$\0" 7 | 8 | #define GREPWIN_VERMAJOR $MajorVersion$ 9 | #define GREPWIN_VERMINOR $MinorVersion$ 10 | #define GREPWIN_VERMICRO $MicroVersion$ 11 | #define GREPWIN_VERBUILD $WCREV$ 12 | #define GREPWIN_VERDATE "$WCDATE$" 13 | -------------------------------------------------------------------------------- /tools/ResText.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefankueng/grepWin/25539ce753e1a0f7804691be2b03d9b9bb21ed4f/tools/ResText.exe -------------------------------------------------------------------------------- /tools/checkyear.js: -------------------------------------------------------------------------------- 1 | /* This script is a local pre-commit hook script. 2 | * It's used to check whether the copyright year of modified files has been 3 | * bumped up to the current year. 4 | * 5 | * Only *.cpp, *.h and *.idl files are checked 6 | * 7 | * Set the local hook scripts like this (pre-commit hook): 8 | * WScript path/to/this/script/file.js 9 | * and set "Wait for the script to finish" 10 | */ 11 | 12 | var forReading = 1; 13 | var objArgs = WScript.Arguments; 14 | var num = objArgs.length; 15 | 16 | if (num !== 4 && num !== 3) 17 | { 18 | WScript.Echo("Usage: [CScript | WScript] checkyear.js path/to/pathsfile depth path/to/messagefile path/to/CWD"); 19 | WScript.Quit(1); 20 | } 21 | 22 | var currentyear = new Date().getFullYear(); 23 | var re = new RegExp('^(\\\/\\\/|#) Copyright.+(' + currentyear + ')(.*)'); 24 | var basere = /^\/\/ Copyright(.*)/; 25 | var filere = /(\.cpp$)|(\.h$)|(\.idl$)/; 26 | 27 | // readFileLines 28 | function readPaths(path) 29 | { 30 | var retPaths = []; 31 | var fileSystem = new ActiveXObject("Scripting.FileSystemObject"); 32 | 33 | if (fileSystem.FileExists(path)) 34 | { 35 | var textFile = fileSystem.OpenTextFile(path, forReading); 36 | 37 | while (!textFile.AtEndOfStream) 38 | { 39 | var line = textFile.ReadLine(); 40 | 41 | retPaths.push(line); 42 | } 43 | textFile.Close(); 44 | } 45 | return retPaths; 46 | } 47 | 48 | var found = true; 49 | var files = readPaths(objArgs(0)); 50 | var fileIndex = files.length; 51 | var errorMessage = ""; 52 | 53 | while (fileIndex--) 54 | { 55 | var f = files[fileIndex]; 56 | var fso = new ActiveXObject("Scripting.FileSystemObject"); 57 | 58 | if (f.match(filere) !== null) 59 | { 60 | if (fso.FileExists(f)) 61 | { 62 | var a = fso.OpenTextFile(f, forReading, false); 63 | var copyrightFound = false; 64 | var yearFound = false; 65 | 66 | while (!a.AtEndOfStream && !yearFound) 67 | { 68 | var r = a.ReadLine(); 69 | var rv = r.match(basere); 70 | 71 | if (rv !== null) 72 | { 73 | rv = r.match(re); 74 | if (rv !== null) 75 | { 76 | yearFound = true; 77 | } 78 | 79 | copyrightFound = true; 80 | } 81 | } 82 | a.Close(); 83 | 84 | if (copyrightFound && !yearFound) 85 | { 86 | if (errorMessage !== "") 87 | { 88 | errorMessage += "\n"; 89 | } 90 | errorMessage += f; 91 | found = false; 92 | } 93 | } 94 | } 95 | } 96 | 97 | if (found === false) 98 | { 99 | errorMessage = "the file(s):\n" + errorMessage + "\nhave not the correct copyright year!"; 100 | WScript.stderr.writeLine(errorMessage); 101 | } 102 | 103 | WScript.Quit(!found); 104 | -------------------------------------------------------------------------------- /tools/coverity.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | pushd %~dp0 5 | 6 | rem you can set the COVDIR variable to your coverity path 7 | if not defined COVDIR set "COVDIR=C:\cov-analysis" 8 | if defined COVDIR if not exist "%COVDIR%" ( 9 | echo. 10 | echo ERROR: Coverity not found in "%COVDIR%" 11 | goto End 12 | ) 13 | 14 | rem add the tools paths in PATH 15 | set "NANT_PATH=C:\nant\bin" 16 | set "PERL_PATH=C:\Perl\perl\bin" 17 | set "PYTHON_PATH=C:\Python27" 18 | set "PATH=%NANT_PATH%;%PERL_PATH%;%PYTHON_PATH%;%PATH%" 19 | 20 | 21 | :cleanup 22 | if exist "cov-int" rd /q /s "cov-int" 23 | if exist "grepWin.lzma" del "grepWin.lzma" 24 | if exist "grepWin.tar" del "grepWin.tar" 25 | if exist "grepWin.tgz" del "grepWin.tgz" 26 | 27 | 28 | :main 29 | call "%VS140COMNTOOLS%\vsvars32.bat" 30 | if %ERRORLEVEL% neq 0 ( 31 | echo vsvars32.bat call failed. 32 | goto End 33 | ) 34 | 35 | rem the actual coverity command 36 | title "%COVDIR%\bin\cov-build.exe" --dir "cov-int" nant -buildfile:../default.build grepWin 37 | "%COVDIR%\bin\cov-build.exe" --dir "cov-int" nant -buildfile:../default.build grepWin 38 | 39 | 40 | :tar 41 | rem try the tar tool in case it's in PATH 42 | set PATH=C:\MSYS\bin;%PATH% 43 | tar --version 1>&2 2>nul || (echo. & echo ERROR: tar not found & goto SevenZip) 44 | title Creating "grepWin.lzma"... 45 | tar caf "grepWin.lzma" "cov-int" 46 | goto End 47 | 48 | 49 | :SevenZip 50 | call :SubDetectSevenzipPath 51 | 52 | rem Coverity is totally bogus with lzma... 53 | rem And since I cannot replicate the arguments with 7-Zip, just use tar/gzip. 54 | if exist "%SEVENZIP%" ( 55 | title Creating "grepWin.tar"... 56 | "%SEVENZIP%" a -ttar "grepWin.tar" "cov-int" 57 | "%SEVENZIP%" a -tgzip "grepWin.tgz" "grepWin.tar" 58 | if exist "grepWin.tar" del "grepWin.tar" 59 | goto End 60 | ) 61 | 62 | 63 | :SubDetectSevenzipPath 64 | for %%g in (7z.exe) do (set "SEVENZIP_PATH=%%~$path:g") 65 | if exist "%SEVENZIP_PATH%" (set "SEVENZIP=%SEVENZIP_PATH%" & exit /b) 66 | 67 | for %%g in (7za.exe) do (set "SEVENZIP_PATH=%%~$path:g") 68 | if exist "%SEVENZIP_PATH%" (set "SEVENZIP=%SEVENZIP_PATH%" & exit /b) 69 | 70 | for /f "tokens=2*" %%a in ( 71 | 'reg query "HKLM\SOFTWARE\7-Zip" /v "path" 2^>nul ^| find "REG_SZ" ^|^| 72 | reg query "HKLM\SOFTWARE\Wow6432Node\7-Zip" /v "path" 2^>nul ^| find "REG_SZ"') do set "SEVENZIP=%%b\7z.exe" 73 | exit /b 74 | 75 | 76 | :End 77 | popd 78 | echo. & echo Press any key to close this window... 79 | pause >nul 80 | endlocal 81 | exit /b 82 | -------------------------------------------------------------------------------- /version.build.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 2.1.9.1420 2 | https://tools.stefankueng.com/grepWin.html 3 | -------------------------------------------------------------------------------- /versioninfo.build: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | --------------------------------------------------------------------------------