OSDN Git Service

Merge remote-tracking branch 'upstream/master' into jp
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 23 Sep 2023 23:01:20 +0000 (08:01 +0900)
committerTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sat, 23 Sep 2023 23:01:20 +0000 (08:01 +0900)
# Conflicts:
# SetVersion.cmd
# Version.h

92 files changed:
BuildArc.cmd
Docs/Users/ChangeLog.html
Docs/Users/ChangeLog.md
Docs/Users/ReleaseNotes.html
Docs/Users/ReleaseNotes.md
DownloadDeps.cmd
Externals/crystaledit/editlib/ccrystaltextview.cpp
Externals/jq
Externals/versions.txt
Installer/InnoSetup/WinMergeARM64.is6.iss
Installer/InnoSetup/WinMergeX64.is6.iss
Installer/InnoSetup/WinMergeX64.iss
Installer/InnoSetup/WinMergeX64NonAdmin.iss
Installer/InnoSetup/WinMergeX86.iss
SetVersion.cmd
Src/Common/ShellContextMenu.cpp
Src/Common/ShellContextMenu.h
Src/CompareEngines/ByteComparator.cpp
Src/CompareEngines/ByteCompare.cpp
Src/CompareEngines/ByteCompare.h
Src/CompareEngines/Wrap_DiffUtils.cpp
Src/CompareEngines/Wrap_DiffUtils.h
Src/CompareOptions.cpp
Src/DiffTextBuffer.cpp
Src/DiffWrapper.cpp
Src/DiffWrapper.h
Src/DirActions.h
Src/DirScan.cpp
Src/DirView.cpp
Src/DirView.h
Src/DirViewColItems.cpp
Src/DirWatcher.cpp
Src/DropHandler.cpp
Src/FileFilter.cpp
Src/FileFilterMgr.cpp
Src/FilterList.cpp
Src/FolderCmp.cpp
Src/LocationView.cpp
Src/MainFrm.cpp
Src/Merge.rc
Src/Merge.vcxproj
Src/MergeDoc.h
Src/MergeDocDiffSync.cpp
Src/MergeEditView.cpp
Src/SubstitutionFiltersList.cpp
Src/resource.h
Src/xdiff_gnudiff_compat.cpp
Src/xdiff_gnudiff_compat.h
Testing/GoogleTest/ByteCompare/ByteCompare_test.cpp
Testing/GoogleTest/UnitTests/UnitTests.vcxproj
Testing/GoogleTest/UnitTests/UnitTests.vcxproj.filters
Translations/InnoSetup/Unbundled.is6/Korean.isl
Translations/TranslationsStatus.md
Translations/WinMerge/Arabic.po
Translations/WinMerge/Basque.po
Translations/WinMerge/Brazilian.po
Translations/WinMerge/Bulgarian.po
Translations/WinMerge/Catalan.po
Translations/WinMerge/ChineseSimplified.po
Translations/WinMerge/ChineseTraditional.po
Translations/WinMerge/Corsican.po
Translations/WinMerge/Croatian.po
Translations/WinMerge/Czech.po
Translations/WinMerge/Danish.po
Translations/WinMerge/Dutch.po
Translations/WinMerge/English.pot
Translations/WinMerge/Finnish.po
Translations/WinMerge/French.po
Translations/WinMerge/Galician.po
Translations/WinMerge/German.po
Translations/WinMerge/Greek.po
Translations/WinMerge/Hungarian.po
Translations/WinMerge/Italian.po
Translations/WinMerge/Japanese.po
Translations/WinMerge/Korean.po
Translations/WinMerge/Lithuanian.po
Translations/WinMerge/Norwegian.po
Translations/WinMerge/Persian.po
Translations/WinMerge/Polish.po
Translations/WinMerge/Portuguese.po
Translations/WinMerge/Romanian.po
Translations/WinMerge/Russian.po
Translations/WinMerge/Serbian.po
Translations/WinMerge/Sinhala.po
Translations/WinMerge/Slovak.po
Translations/WinMerge/Slovenian.po
Translations/WinMerge/Spanish.po
Translations/WinMerge/Swedish.po
Translations/WinMerge/Tamil.po
Translations/WinMerge/Turkish.po
Translations/WinMerge/Ukrainian.po
Version.h

index 441ed15..d2b62ce 100644 (file)
@@ -187,7 +187,7 @@ xcopy /s/y Build\msys2 "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\msys2
 rem Copy jq...
 echo Copy jq...
 copy Build\jq\jq-win32.exe "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\jq\jq.exe" > NUL
-copy Build\jq\jq-jq-1.6\COPYING "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\jq\" > NUL
+copy Build\jq\jq-jq-1.7\COPYING "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\jq\" > NUL
 
 rem Copy tidy-html5...
 echo Copy tidy-html5...
index fa16dc1..809f6a1 100644 (file)
 </head>
 <body>
 <h1 id="change-log">Change log</h1>
-<h2 id="winmerge-21632---2023-07-27">WinMerge 2.16.32 - 2023-07-27</h2>
+<h2 id="winmerge-21633---2023-09-20">WinMerge 2.16.33 - 2023-09-20</h2>
 <h3 id="general">General</h3>
 <ul>
-<li>BugFix: Export/Import settings bug with Substitution Filters (#1925)</li>
+<li>Reduce startup time and decrease the usage of Win32 user objects.</li>
 </ul>
 <h3 id="file-compare">File compare</h3>
 <ul>
+<li>BugFix: Cannot compare one-line file (#1972)</li>
+<li>BugFix: &quot;Current Difference&quot; specified by double-clicking cannot merge using the &quot;Copy to Right (or Left)&quot; menu. (#1980)</li>
+<li>BugFix: Wimerge saves changes to the wrong file (#1985) (PR #1988)</li>
+<li>BugFix: &quot;Ignore comment differences&quot; still compares inline comments (#2008)</li>
+<li>Update Rust syntax highlighting keyword list. (PR #1998)</li>
+<li>[Feature Request] Both Shell Menu (#1986) (PR #2021)</li>
+</ul>
+<h3 id="table-compare">Table compare</h3>
+<ul>
+<li>When &quot;Use First Line as Header&quot; is enabled, make the header display the first line regardless of the scroll position when the first line is hidden.</li>
+<li>Generate reports in tabular format for table comparisons. (PR #1983)</li>
+</ul>
+<h3 id="folder-compare">Folder compare</h3>
+<ul>
+<li>BugFix: Fixed an issue where Differences, Left/Right EOL columns, etc. were displayed as undefined values when the file comparison method was Full Contents or Quick Contents and the file size exceeded 64MB.</li>
+<li>BugFix: Fix the problem that when comparing with the BinaryContents compare method, the contents of the files are identical, but if one side is a symbolic link, it is judged to be different. (#1976)</li>
+<li>BugFix: Fixed an issue where values in the Left/Right EOL column may not display correctly when using the Quick contents compare method.</li>
+<li>Add Expand Different Subfolders menu item (#1382) (PR #1964)</li>
+<li>Allow Diff algorithms (patience, histogram) other than default to be applied to folder comparisons (PR #2015) (#2002)</li>
+<li>Show confirmation message when closing a window that took a long time to compare folders</li>
+</ul>
+<h3 id="line-filters">Line filters</h3>
+<ul>
+<li>Improve line filters and substitution filters (PR #2032) (#796) (#1620)</li>
+</ul>
+<h3 id="substitution-filters">Substitution filters</h3>
+<ul>
+<li>Avoid infinite loops in the RegularExpression::subst() function when the length of the string matching the pattern is 0</li>
+<li>Improve line filters and substitution filters (PR #2032) (#796) (#1620)</li>
+</ul>
+<h3 id="options-dialog">Options dialog</h3>
+<ul>
+<li>Execute the &quot;pause&quot; command to prevent the error message from disappearing if the registration of the ShellExtension for Windows 11 fails</li>
+</ul>
+<h3 id="plugins">Plugins</h3>
+<ul>
+<li>BugFix: WinMerge cannot successfully disable some of its Plugins (#2012)</li>
+<li>Update jq to version 1.7</li>
+</ul>
+<h3 id="manual">Manual</h3>
+<ul>
+<li>Manual: Use po4a for manual translation (PR #1994) (#499)</li>
+</ul>
+<h3 id="translations">Translations</h3>
+<ul>
+<li>Translation updates:
+<ul>
+<li>Brazilian (PR #1969,#2001,#2025)</li>
+<li>Chinese Traditional (PR #1953,#1971,#2017,#2026)</li>
+<li>Corsican (PR #2022)</li>
+<li>German (PR #1952,#1977,#1989)</li>
+<li>Hungarian (PR #1968,#1999)</li>
+<li>Japanese</li>
+<li>Korean (PR #1979,#2030)</li>
+<li>Lithuanian (PR #1974,#2018,#2027)</li>
+<li>Polish (PR #1990)</li>
+<li>Portuguese (PR #1973,#2014)</li>
+<li>Slovenian</li>
+<li>Ukrainian (PR #1955)</li>
+</ul></li>
+</ul>
+<h3 id="internals">Internals</h3>
+<ul>
+<li>Optimize inserts in std containers using reserve (PR #2000)</li>
+</ul>
+<h2 id="winmerge-21632---2023-07-27">WinMerge 2.16.32 - 2023-07-27</h2>
+<h3 id="general-1">General</h3>
+<ul>
+<li>BugFix: Export/Import settings bug with Substitution Filters (#1925)</li>
+</ul>
+<h3 id="file-compare-1">File compare</h3>
+<ul>
 <li>BugFix: Save function doesn&#39;t work if the path length exceeds 248 characters (#1923)</li>
 <li>BugFix: Redundant confirmation &quot;The selected files are identical&quot; (#1902)</li>
 <li>Update Python syntax highlighting keyword list. (PR #1938)</li>
 </ul>
-<h3 id="folder-compare">Folder compare</h3>
+<h3 id="folder-compare-1">Folder compare</h3>
 <ul>
 <li>BugFix: Treeview scrolls to the wrong position. (#1915)</li>
 <li>Allow changing the number of CPU cores to use while doing folder comparison (PR #1945)</li>
 <ul>
 <li>Update 7-Zip to 23.01 (PR #1913)</li>
 </ul>
-<h3 id="translations">Translations</h3>
+<h3 id="translations-1">Translations</h3>
 <ul>
 <li>New translation: Tamil (PR #1946)</li>
 <li>Translation updates:
 </ul></li>
 </ul>
 <h2 id="winmerge-21631---2023-06-20">WinMerge 2.16.31 - 2023-06-20</h2>
-<h3 id="general-1">General</h3>
+<h3 id="general-2">General</h3>
 <ul>
 <li>BugFix: Some Substitution filter doesn&#39;t work (#1861)</li>
 <li>Add tasks to Jump List (PR #1828)</li>
 <li>Update DirCmpReport.cpp (PR #1892)</li>
 </ul>
-<h3 id="file-compare-1">File compare</h3>
+<h3 id="file-compare-2">File compare</h3>
 <ul>
 <li>BugFix: Fix input range check processing in &quot;Go to&quot; dialog. (PR #1826)</li>
 <li>BugFix: End of line diff is a bit wanky (#1838, PR #1849)</li>
 <li>Confirm copy all in file merge (PR #1827)</li>
 <li>Modify the &quot;Go to&quot; dialog. (PR #1896)</li>
 </ul>
-<h3 id="folder-compare-1">Folder compare</h3>
+<h3 id="folder-compare-2">Folder compare</h3>
 <ul>
 <li>BugFix: Display problem with Item totals : (#1840)</li>
 <li>BugFix: Bug in ignore whitespace ? (#1882)</li>
 </ul>
-<h3 id="plugins">Plugins</h3>
+<h3 id="plugins-1">Plugins</h3>
 <ul>
 <li>PrettifyJSON: Update jq to version 1.6 (#1871)</li>
 <li>Translate some plugin error messages (PR #1873)</li>
 <ul>
 <li>Silent install blocked (#1852)</li>
 </ul>
-<h3 id="translations-1">Translations</h3>
+<h3 id="translations-2">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 </ul></li>
 </ul>
 <h2 id="winmerge-21630---2023-04-27">WinMerge 2.16.30 - 2023-04-27</h2>
-<h3 id="general-2">General</h3>
+<h3 id="general-3">General</h3>
 <ul>
 <li>BugFix: When using an ini file all differences are displayed as black sections (#1799)</li>
 <li>Reduced file size of WinMergeU.exe for 32-bit version</li>
 </ul>
-<h3 id="file-compare-2">File compare</h3>
+<h3 id="file-compare-3">File compare</h3>
 <ul>
 <li>BugFix: Fixed an issue where XML format files, such as vcxproj, were not being syntax highlighted.</li>
 <li>BugFix: Fixed an issue where the EOL character was not being displayed in the ARM64 version.</li>
 <ul>
 <li>Updated file filters to allow UTF-8 without BOM.</li>
 </ul>
-<h3 id="options-dialog">Options dialog</h3>
+<h3 id="options-dialog-1">Options dialog</h3>
 <ul>
 <li>BugFix: Fixed an issue where the shell integration category page in the Options dialog was not displaying correctly in version 2.16.29.</li>
 <li>BugFix: Fixed an issue where plugin settings were not exported when exporting from the Options dialog.</li>
 </ul>
-<h3 id="plugins-1">Plugins</h3>
+<h3 id="plugins-2">Plugins</h3>
 <ul>
 <li>BugFix: Fixed an issue where the ApplyPatch plugin was not functioning correctly when the &#39;Plugins -&gt; Manual Unpacking&#39; menu item was checked.</li>
 <li>BugFix: Fixed the problem that the plug-in setting window cannot be opened on 32-bit OS</li>
 <ul>
 <li>BugFix: Unsuccessful installation, Portable Win32 version (#1802)</li>
 </ul>
-<h3 id="translations-2">Translations</h3>
+<h3 id="translations-3">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 </ul></li>
 </ul>
 <h2 id="winmerge-21629---2023-03-21">WinMerge 2.16.29 - 2023-03-21</h2>
-<h3 id="file-compare-3">File compare</h3>
+<h3 id="file-compare-4">File compare</h3>
 <ul>
 <li>BugFix: 3-way compare does not properly align identical lines when resolving conflicts, and show false highlights (#1696)</li>
 <li>BugFix: Failure to indent lines properly (#1740)</li>
 <li>BugFix: Fixed a bug with Match whole word only options of Substitution filters</li>
 <li>Add MATLAB syntax highlighting. (PR #1766)</li>
 </ul>
-<h3 id="table-compare">Table compare</h3>
+<h3 id="table-compare-1">Table compare</h3>
 <ul>
 <li>The &quot;View &gt; Wrap Lines&quot; menu item in the Table Compare window is now &quot;Wrap Text&quot; and its check status is saved separately from the same menu item in the Text Compare window. (osdn #47553)</li>
 <li>Added an option to change the CSV file separator from comma to semicolon or another character.</li>
 <ul>
 <li>BugFix: Fixed issue with missing file path in header bar</li>
 </ul>
-<h3 id="folder-compare-2">Folder compare</h3>
+<h3 id="folder-compare-3">Folder compare</h3>
 <ul>
 <li>BugFix: After I collapse a folder, the arrow next to it stays turned down (#1747)</li>
 <li>BugFix: Fixed an issue where the Left/Right Date and Left/Right Size columns would not update when deleting files on one side.</li>
 <li>Implement issue #1413: &quot;Move&quot; needs options &quot;Left to Right&quot; or &quot;Right to Left&quot; like &quot;Copy&quot; (PR #1732,#1720)</li>
 <li>Pressing F2 or Rename should not select file extension (#1735)</li>
 </ul>
-<h3 id="options-dialog-1">Options dialog</h3>
+<h3 id="options-dialog-2">Options dialog</h3>
 <ul>
 <li>Added Enable Compare As menu option in Shell integration category</li>
 </ul>
-<h3 id="plugins-2">Plugins</h3>
+<h3 id="plugins-3">Plugins</h3>
 <ul>
 <li>BugFix: Plugin IgnoreLeadingLineNumbers hangs (#1715)</li>
 </ul>
 <li>The ShellExtension*.dll file is now renamed before installation to prevent installation failure when Explorer is loading ShellExtension*.dll.</li>
 <li>Added IgnoreLeadingLineNumbers plugin to non-x86 installers</li>
 </ul>
-<h3 id="translations-3">Translations</h3>
+<h3 id="translations-4">Translations</h3>
 <ul>
 <li>BugFix: Fix an issue where some messages are not translated. (PR #1712)</li>
 <li>Translation updates:
 </ul></li>
 </ul>
 <h2 id="winmerge-21628---2023-02-15">WinMerge 2.16.28 - 2023-02-15</h2>
-<h3 id="folder-compare-3">Folder compare</h3>
+<h3 id="folder-compare-4">Folder compare</h3>
 <ul>
 <li>BugFix: Fixed an issue where files with no extension were not compared if they were in a folder with a &#39;.&#39; in the folder name.</li>
 </ul>
 <h2 id="winmerge-21626---2023-01-27">WinMerge 2.16.26 - 2023-01-27</h2>
-<h3 id="general-3">General</h3>
+<h3 id="general-4">General</h3>
 <ul>
 <li>Fixed issue where the program would crash when certain path names were set in the file path bar.</li>
 </ul>
-<h3 id="file-compare-4">File compare</h3>
+<h3 id="file-compare-5">File compare</h3>
 <ul>
 <li>Feature request: Allow pasting when editing caption of pages (PR #1651)</li>
 </ul>
-<h3 id="folder-compare-4">Folder compare</h3>
+<h3 id="folder-compare-5">Folder compare</h3>
 <ul>
 <li>BugFix: Filters aren&#39;t saved anywhere (#1638)</li>
 <li>BugFix: Fixed issue where the Open menu item in file path bar of folder comparison window was disabled.</li>
 <li>BugFix: Deleted color of Word Difference in Options dialog was not used.</li>
 <li>Implemented Ignore numbers comparison option.</li>
 </ul>
-<h3 id="options-dialog-2">Options dialog</h3>
+<h3 id="options-dialog-3">Options dialog</h3>
 <ul>
 <li>Modify the &quot;Options (Compare &gt; Folder)&quot; dialog. (PR #1645)</li>
 </ul>
-<h3 id="plugins-3">Plugins</h3>
+<h3 id="plugins-4">Plugins</h3>
 <ul>
 <li>Add PreviewMarkdown plugin (PR #1641)</li>
 <li>Add PreviewPlantUML plugin (PR #1666)</li>
 <li>ApacheTika: Updated Apache Tika to version 2.6.0</li>
 <li>ApacheTika: If Java is not installed, OpenJDK 19.0.2 will now be downloaded and used.</li>
 </ul>
-<h3 id="translations-4">Translations</h3>
+<h3 id="translations-5">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 </ul></li>
 </ul>
 <h2 id="winmerge-21625---2022-12-27">WinMerge 2.16.25 - 2022-12-27</h2>
-<h3 id="file-compare-5">File compare</h3>
+<h3 id="file-compare-6">File compare</h3>
 <ul>
 <li>BugFix: Selection in &quot;Replace&quot; by regular expression doesn&#39;t work with <code>\n</code> (#1556)</li>
 <li>BugFix: WinMerge hangs for a certain regex search &amp; replace action for clearing all lines not containing &#39;%&#39; (#1575)</li>
 <li>BugFix: Crash 0xc0000409 (#1544)</li>
 <li>Binary compare: Allow 64bit versions to open files larger than 2GB (PR #1549)</li>
 </ul>
-<h3 id="folder-compare-5">Folder compare</h3>
+<h3 id="folder-compare-6">Folder compare</h3>
 <ul>
 <li>BugFix: Fix the problem that WinMerge crashes when pressing the &quot;OK&quot; button in the &quot;Display Columns&quot; dialog in the debug version. (PR #1568)</li>
 <li>BugFix: Crash when copying files/folders (#1558)</li>
 <li>Changes the display processing of the &quot;Comparison result&quot; column for a 3-way folder comparison. (PR #1545)</li>
 <li>Add &quot;Copy All Displayed Columns&quot; to the context menu of the folder compare window. (PR #1615)</li>
 </ul>
-<h3 id="options-dialog-3">Options dialog</h3>
+<h3 id="options-dialog-4">Options dialog</h3>
 <ul>
 <li>Added Auto-reload modified files option (PR #1611)</li>
 </ul>
-<h3 id="translations-5">Translations</h3>
+<h3 id="translations-6">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Add a feature for debugging. (PR #1595)</li>
 </ul>
 <h2 id="winmerge-21624---2022-10-27">WinMerge 2.16.24 - 2022-10-27</h2>
-<h3 id="general-4">General</h3>
+<h3 id="general-5">General</h3>
 <ul>
 <li>BugFix: Fixed crash when displaying file menu if jump list contains invalid title (osdn.net #45916)</li>
 </ul>
-<h3 id="file-compare-6">File compare</h3>
+<h3 id="file-compare-7">File compare</h3>
 <ul>
 <li>Changed operation of displaying dialogs and context menus from status bar from double-click to single-click.</li>
 </ul>
-<h3 id="table-compare-1">Table compare</h3>
+<h3 id="table-compare-2">Table compare</h3>
 <ul>
 <li>BugFix: when TSV files were displayed in table mode with word wrap enabled, clicking on a character would not move the caret to that character&#39;s position</li>
 </ul>
-<h3 id="folder-compare-6">Folder compare</h3>
+<h3 id="folder-compare-7">Folder compare</h3>
 <ul>
 <li>Fixed memory leak in folder comparison when PDF files were targeted for image comparison.</li>
 </ul>
-<h3 id="options-dialog-4">Options dialog</h3>
+<h3 id="options-dialog-5">Options dialog</h3>
 <ul>
 <li>Improved translation regarding CPU cores (PR #1513)</li>
 </ul>
 <ul>
 <li>Made it possible to specify Prediffer plugin</li>
 </ul>
-<h3 id="plugins-4">Plugins</h3>
+<h3 id="plugins-5">Plugins</h3>
 <ul>
 <li>BugFix: Select Plugin dialog: Fixed that &quot;Display all plugins&quot; checkbox did not work</li>
 </ul>
 <ul>
 <li>BugFix: The command line section in the generated patch file was garbled (osdn.net #45935)</li>
 </ul>
-<h3 id="translations-6">Translations</h3>
+<h3 id="translations-7">Translations</h3>
 <ul>
 <li>BugFix: Fix an issue where the following message displayed when two files are identical in a 3-way folder comparison is not translated. (PR #1535)</li>
 <li>Translation updates:
 <li>BugFix: Fix typo in lwdisp.c (PR #1515)</li>
 </ul>
 <h2 id="winmerge-21623---2022-09-26">WinMerge 2.16.23 - 2022-09-26</h2>
-<h3 id="general-5">General</h3>
+<h3 id="general-6">General</h3>
 <ul>
 <li>BugFix: Fix an issue where filenames containing &quot;&amp;&quot; are not displayed properly in the MDI tab bar and its tooltips. (PR #1466)</li>
 </ul>
 <ul>
 <li>Create Midnight.ini (PR #1430)</li>
 </ul>
-<h3 id="file-compare-7">File compare</h3>
+<h3 id="file-compare-8">File compare</h3>
 <ul>
 <li>BugFix: Non existing backup directory should be automatically created (#1438)</li>
 <li>BugFix: Bug: Can&#39;t copy selected text, if it has non-changed lines (#1507)</li>
 <li>The feature will allow the user to right-click the selected lines and… add them to Line Filter so that those lines added to the Line Filter will be ignored if found in any file. (PR #1481)</li>
 <li>CrystalEdit/parsers/SQL: Added more keywords (PR #1493)</li>
 </ul>
-<h3 id="table-compare-2">Table compare</h3>
+<h3 id="table-compare-3">Table compare</h3>
 <ul>
 <li>Bugfix: Inline differences ware not displayed even if the caret is moved to the position of an inline difference that is hidden due to the narrow column width.</li>
 </ul>
 <ul>
 <li>[EXPERIMENTAL] Webpage Compare: Highlight differences (PR #1357)</li>
 </ul>
-<h3 id="folder-compare-7">Folder compare</h3>
+<h3 id="folder-compare-8">Folder compare</h3>
 <ul>
 <li>BugFix: Disable rename operations when in read-only mode in the folder compare window. (PR #1434)</li>
 <li>BugFix: Fix an issue where renaming to a file name or directory name containing &quot;&quot; or &quot;/&quot; is not done properly. (PR #1451)</li>
 <ul>
 <li>Update 7-Zip to 22.01 (#1425)</li>
 </ul>
-<h3 id="translations-7">Translations</h3>
+<h3 id="translations-8">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 </ul></li>
 </ul>
 <h2 id="winmerge-21622---2022-07-27">WinMerge 2.16.22 - 2022-07-27</h2>
-<h3 id="general-6">General</h3>
+<h3 id="general-7">General</h3>
 <ul>
 <li>Allow renaming of untitled pages (#1395)</li>
 </ul>
-<h3 id="file-compare-8">File compare</h3>
+<h3 id="file-compare-9">File compare</h3>
 <ul>
 <li>BugFix: &quot;Replace All&quot; doesn&#39;t work when Replace in &quot;Selection&quot; and the new string contains the old string. (#1376)</li>
 <li>BugFix: “Match case” in Search always enabled (#1380)</li>
 <li>BugFix: replace text using regular expressions behaves incorrectly if multiple matches on the same line (#1387, PR #1388)</li>
 <li>Optimize snake function (PR #1411)</li>
 </ul>
-<h3 id="folder-compare-8">Folder compare</h3>
+<h3 id="folder-compare-9">Folder compare</h3>
 <ul>
 <li>BugFix: Fix an issue where paths with different case are not displayed correctly in the folder column of the folder compare window when comparing three directories. (PR #1372)</li>
 <li>BugFix: Fix renaming process in folder compare window. (PR #1392)</li>
 <li>BugFix: Elapsed time was no longer displayed in the status bar after folder comparison.</li>
 <li>BugFix: Fix an issue where the folder column is not updated for child items after renaming a directory in the folder compare window. (PR #1408)</li>
 </ul>
-<h3 id="plugins-5">Plugins</h3>
+<h3 id="plugins-6">Plugins</h3>
 <ul>
 <li>Modify textbox behavior (CompareMSExcelFiles options dialog) (PR #1374)</li>
 <li>Make wsc files available as plug-in (PR #1390)</li>
 <ul>
 <li>Add a feature to save/restore hidden items to/from a project file.(PR #1377)</li>
 </ul>
-<h3 id="options-dialog-5">Options dialog</h3>
+<h3 id="options-dialog-6">Options dialog</h3>
 <ul>
 <li>New setting to decide when to save/restore hidden items when project is saved/loaded (PR #1377)</li>
 </ul>
-<h3 id="translations-8">Translations</h3>
+<h3 id="translations-9">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Portuguese (PR #1416)</li>
 </ul></li>
 </ul>
-<h3 id="internals">Internals</h3>
+<h3 id="internals-1">Internals</h3>
 <ul>
 <li>Fix typo in SuperComboBox.cpp (PR #1379)</li>
 </ul>
 <h2 id="winmerge-21621---2022-06-20">WinMerge 2.16.21 - 2022-06-20</h2>
-<h3 id="general-7">General</h3>
+<h3 id="general-8">General</h3>
 <ul>
 <li>In windows 11 i have error 78 sidebyside with the winmerge manifest (#1312)</li>
 </ul>
-<h3 id="file-compare-9">File compare</h3>
+<h3 id="file-compare-10">File compare</h3>
 <ul>
 <li>BugFix: Copy left/right different behavior (#1334)</li>
 <li>BugFix: Line difference coloring in “Word-level” mode does not work correctly for Cyrillic-based languages (#1362)</li>
 <li>ResourceTree compare: Set the last-modified date and time in resource files</li>
 <li>Added Ctrl+L keyboard shortcut</li>
 </ul>
-<h3 id="folder-compare-9">Folder compare</h3>
+<h3 id="folder-compare-10">Folder compare</h3>
 <ul>
 <li>BugFix: Alt/Shift key highlighting issue not resetting start point from move. (#1335)</li>
 <li>BugFix: Refresh Selected Marks Unscanned Folders as Identical (#1349)</li>
 <ul>
 <li>BugFix: [Bug Report] WinMerge does not recognize Win 11 (#1192)</li>
 </ul>
-<h3 id="plugins-6">Plugins</h3>
+<h3 id="plugins-7">Plugins</h3>
 <ul>
 <li>BugFix: CompareMSExcelFiles Plugins did not compare folders when opening .xlsx files from Plugins-&gt; Edit with Unpacker menu item even though the &quot;Extract workbook data to multiple files&quot; option is enabled in the plugin settings (osdn.net #44522)</li>
 <li>BugFix: Fix a problem where the &quot;Open files in the same window type after unpacking&quot; checkbox was checked, but the checkbox was not checked the next time the dialog was opened.</li>
 <li>BugFix: Fix an issue where the WinMerge menu displayed in the&quot;Show more options&quot; menu of the Windows 11 Explorer context menu is not an advanced menu, even though the advanced menu is enabled.</li>
 <li>BugFix: Fix the problem that the WinMerge icon is not correctly displayed on the taskbar when WinMerge is started from the Windows 11 context menu.</li>
 </ul>
-<h3 id="translations-9">Translations</h3>
+<h3 id="translations-10">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Russian (PR #1310)</li>
 </ul></li>
 </ul>
-<h3 id="internals-1">Internals</h3>
+<h3 id="internals-2">Internals</h3>
 <ul>
 <li>Fix typo in BCMenu.cpp (PR #1313)</li>
 <li>Fix type: GPL (PR #1342)</li>
 <li>Initialize variables defined at &quot;diff.h&quot; (PR #1360)</li>
 </ul>
 <h2 id="winmerge-21620---2022-04-27">WinMerge 2.16.20 - 2022-04-27</h2>
-<h3 id="general-8">General</h3>
+<h3 id="general-9">General</h3>
 <ul>
 <li>BugFix: New filter (F) display (#1281 a))</li>
 </ul>
-<h3 id="file-compare-10">File compare</h3>
+<h3 id="file-compare-11">File compare</h3>
 <ul>
 <li>BugFix: Fixed a problem where the caret would not display in the correct position on lines containing tab characters, depending on the font in use (osdn.net #44417)</li>
 </ul>
 </ul></li>
 </ul></li>
 </ul>
-<h3 id="folder-compare-10">Folder compare</h3>
+<h3 id="folder-compare-11">Folder compare</h3>
 <ul>
 <li>BugFix: Fix an issue where items with different case are not displayed correctly in the folder compare window when comparing three directories. (PR #1299)</li>
 </ul>
-<h3 id="options-dialog-6">Options dialog</h3>
+<h3 id="options-dialog-7">Options dialog</h3>
 <ul>
 <li>Allow resizing Options dialog box in both directions (#1265)</li>
 </ul>
-<h3 id="plugins-7">Plugins</h3>
+<h3 id="plugins-8">Plugins</h3>
 <ul>
 <li>BugFix: CompareMSExcelFiles.sct: Date formats interpreted inconsistently (#279)</li>
 <li>Add URL handler plugins (PR #1270)
 <ul>
 <li>Added <code>/t webpage</code> command line option</li>
 </ul>
-<h3 id="manual">Manual</h3>
+<h3 id="manual-1">Manual</h3>
 <ul>
 <li>BugFix: Help file: Small issue for plugins (#1309)</li>
 </ul>
-<h3 id="translations-10">Translations</h3>
+<h3 id="translations-11">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (PR #1264)</li>
 </ul></li>
 </ul>
-<h3 id="internals-2">Internals</h3>
+<h3 id="internals-3">Internals</h3>
 <ul>
 <li>Code refactor with C++17 features replace optimize create smart pointers (PR #1304)</li>
 <li>Fixed link errors occurring in Windows 10 SDK version 10.0.19041.0 and lower</li>
 </ul>
 <h2 id="winmerge-21619---2022-03-20">WinMerge 2.16.19 - 2022-03-20</h2>
-<h3 id="general-9">General</h3>
+<h3 id="general-10">General</h3>
 <ul>
 <li>Update Merge.rc (PR #1219,#1227,#1231,#1232)</li>
 </ul>
-<h3 id="file-compare-11">File compare</h3>
+<h3 id="file-compare-12">File compare</h3>
 <ul>
 <li>BugFix: Match similar lines breaks with Ignore whitespace change (#1209)</li>
 <li>BugFix: Copy &amp; Advance skips differences when moved block detection is on (#1235)</li>
 <li>Different exit procedure required for small vs. large files (#1218)</li>
 <li>Added View → View Top Margins menu item. (A ruler appears in the margin)</li>
 </ul>
-<h3 id="table-compare-3">Table compare</h3>
+<h3 id="table-compare-4">Table compare</h3>
 <ul>
 <li>Pinning first row of file (#999)
 <ul>
 <li>Added Use First Line as Headers menu item to the column header context menu.</li>
 </ul></li>
 </ul>
-<h3 id="folder-compare-11">Folder compare</h3>
+<h3 id="folder-compare-12">Folder compare</h3>
 <ul>
 <li>BugFix: Fix the problem that the status bar displays &quot;0 items selected&quot; even though multiple items are selected.</li>
 <li>BugFix: Change the file naming method of the file compare report to avoid duplication of the file compare report file name linked from the folder compare report. (PR #1171)</li>
 </ul></li>
 </ul></li>
 </ul>
-<h3 id="options-dialog-7">Options dialog</h3>
+<h3 id="options-dialog-8">Options dialog</h3>
 <ul>
 <li>BugFix: Help text is truncated (#1210)</li>
 <li>Improve vertical alignment string (#1200)</li>
 <li>Some improvements (#1212)</li>
 </ul>
-<h3 id="plugins-8">Plugins</h3>
+<h3 id="plugins-9">Plugins</h3>
 <ul>
 <li>BugFix: Select Plugin Dialog: Fix the problem that the plugin arguments are deleted by clicking the &quot;Add pipe&quot; button after entering them.</li>
 </ul>
-<h3 id="translations-11">Translations</h3>
+<h3 id="translations-12">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Ukrainian (PR #1172)</li>
 </ul></li>
 </ul>
-<h3 id="internals-3">Internals</h3>
+<h3 id="internals-4">Internals</h3>
 <ul>
 <li>Fix typo in ShellFileOperations.cpp (PR #1256)</li>
 <li>[Big PR - big changes] A lot of refactor and optimization commits (PR #1258)</li>
 <li>Tweak translations status (PR #1201)</li>
 </ul>
 <h2 id="winmerge-21618---2022-01-27">WinMerge 2.16.18 - 2022-01-27</h2>
-<h3 id="general-10">General</h3>
+<h3 id="general-11">General</h3>
 <ul>
 <li>BugFix: Crash when comparing files in Google Drive</li>
 <li>[Feature Request] Lengthen title of File Compare window or add tip (#960)</li>
 <li>added me to contributor list (PR #1094)</li>
 <li>Made it so that the parent window cannot be operated while the font selection dialog displayed from View→Select Font menu item is displayed.</li>
 </ul>
-<h3 id="file-compare-12">File compare</h3>
+<h3 id="file-compare-13">File compare</h3>
 <ul>
 <li>BugFix: wm 2.16.16.0 crashes with file attached (#1101)</li>
 <li>BugFix: Fix a problem that &#39;Encountered an improper argument&#39; error occurs when a pane split by Window→Split menu item is unsplit by drag operation.</li>
 <li>This feature is available on Windows 10 version 1809 or higher and WinMerge 64-bit version.</li>
 </ul></li>
 </ul>
-<h3 id="folder-compare-12">Folder compare</h3>
+<h3 id="folder-compare-13">Folder compare</h3>
 <ul>
 <li>BugFix: Sorting on Comparison Result being done incorectly (#483)</li>
 <li>BugFix: Fix an issue where WinMerge sometimes crashes when executing &quot;Refresh Selected&quot; in the folder compare window. (PR #1120)</li>
 <li>BugFix: Fixed a bug that the parent folder icon was not displayed in non-recursive mode.</li>
 <li>BugFix: Fixed the problem that the sort order is different from version 2.16.16 or earlier</li>
 </ul>
-<h3 id="plugins-9">Plugins</h3>
+<h3 id="plugins-10">Plugins</h3>
 <ul>
 <li>Fix for <a href="https://github.com/WinMerge/winmerge/discussions/1139">https://github.com/WinMerge/winmerge/discussions/1139</a> (#1139,PR #1140)</li>
 <li>Make plugin descriptions translatable</li>
 <li>BugFix: Add replacesameversion flag to 7z.dll</li>
 <li>Re-enabled the process of installing ShellExtension for Windows 11.</li>
 </ul>
-<h3 id="manual-1">Manual</h3>
+<h3 id="manual-2">Manual</h3>
 <ul>
 <li>BugFix: &quot;Quick compare limit&quot; and &quot;Binary compare limit&quot; settings don&#39;t have the expected (and documented) purpose (#1100)</li>
 </ul>
-<h3 id="translations-12">Translations</h3>
+<h3 id="translations-13">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (PR #1099)</li>
 </ul></li>
 </ul>
-<h3 id="internals-4">Internals</h3>
+<h3 id="internals-5">Internals</h3>
 <ul>
 <li>Fix typo in DirScan.cpp (PR #1118)</li>
 </ul>
 <h2 id="winmerge-21617---2021-12-19">WinMerge 2.16.17 - 2021-12-19</h2>
-<h3 id="general-11">General</h3>
+<h3 id="general-12">General</h3>
 <ul>
 <li>New Option to ignore numbers. (PR #1025,#923)</li>
 <li>Add the feature to display tooltips on the MDI tab. (PR #1038)</li>
 <li>Issue with closing WinMerge with Esc keyboard key (#1052)</li>
 <li>Add an &quot;Defaults&quot; section to the ini file (PR #1071)</li>
 </ul>
-<h3 id="file-compare-13">File compare</h3>
+<h3 id="file-compare-14">File compare</h3>
 <ul>
 <li>BugFix: Release 2.16.16 crashes when comparing large files - likely a regression (#1036)</li>
 <li>BugFix: Fixed C#(Java, JavaScript) keyword highlighting. (#1040)</li>
 <ul>
 <li>Added support for creating multi-page image compare report (osdn.net #43374)</li>
 </ul>
-<h3 id="folder-compare-13">Folder compare</h3>
+<h3 id="folder-compare-14">Folder compare</h3>
 <ul>
 <li>BugFix: Fixed a problem where Duplicate Group Numbers were not assigned to files with the same content but different file names.</li>
 <li>BugFix: Fix crash when comparing 3 folders if additional properties were added</li>
 <ul>
 <li>Put the diff patch to the clipboard rather than to files (#923)</li>
 </ul>
-<h3 id="plugins-10">Plugins</h3>
+<h3 id="plugins-11">Plugins</h3>
 <ul>
 <li>BugFix: Fixed the problem that Plugins-&gt;Reload Plugins menu item does not work.</li>
 </ul>
 <ul>
 <li>ShellExtension for Windows 11: Implemented advanced menu</li>
 </ul>
-<h3 id="translations-13">Translations</h3>
+<h3 id="translations-14">Translations</h3>
 <ul>
 <li>New translation:
 <ul>
 <li>Slovenian</li>
 </ul></li>
 </ul>
-<h3 id="internals-5">Internals</h3>
+<h3 id="internals-6">Internals</h3>
 <ul>
 <li>BugFix: Fix typo in BCMenu.cpp (PR #1054)</li>
 <li>BugFix: Return better HRESULTs (PR #1077)</li>
 <li>Make it buildable for ARM32 architecture</li>
 </ul>
 <h2 id="winmerge-21616---2021-10-28">WinMerge 2.16.16 - 2021-10-28</h2>
-<h3 id="general-12">General</h3>
+<h3 id="general-13">General</h3>
 <ul>
 <li>Fix a problem where the string in the Windows common dialog would not change to the language when switching languages.</li>
 </ul>
-<h3 id="file-compare-14">File compare</h3>
+<h3 id="file-compare-15">File compare</h3>
 <ul>
 <li>BugFix: Fix not getting the proper error message when saving failed</li>
 </ul>
-<h3 id="table-compare-4">Table compare</h3>
+<h3 id="table-compare-5">Table compare</h3>
 <ul>
 <li>BugFix: Cannot resize last column with UI (#998)</li>
 <li>Reloading a file that was changed by another application does not preserve column widths (#951)</li>
 <ul>
 <li>BugFix: Fix an issue where drag-and-drop of file would only work once.</li>
 </ul>
-<h3 id="folder-compare-14">Folder compare</h3>
+<h3 id="folder-compare-15">Folder compare</h3>
 <ul>
 <li>BugFix: Sync (Super Slow) (#771)</li>
 <li>BugFix: Fix an issue where filters are not applied correctly when opening a project file containing multiple items with different filters. (PR #995)</li>
 <li>[Feature Request] New Display Columns: Dimensions + Size Difference (#131)</li>
 <li>FolderCompare: Additional Properties (Windows Property System+Hash (MD5, SHA-1, SHA-256)) (PR #996)</li>
 </ul>
-<h3 id="options-dialog-8">Options dialog</h3>
+<h3 id="options-dialog-9">Options dialog</h3>
 <ul>
 <li>BugFix: Fix the problem that the &quot;Register Shell Extension for Windows 11 or later&quot; button is not enabled when another user has registered ShellExtension for Windows 11.</li>
 </ul>
-<h3 id="plugins-11">Plugins</h3>
+<h3 id="plugins-12">Plugins</h3>
 <ul>
 <li>BugFix: Plugin unpacked file extension problem (get_PluginUnpackedFileExtension) (#983)</li>
 <li>BugFix: Comparing broken lnk-files (windows shortcuts) freezes WinMerge (#1007)</li>
 <li>BugFix: Loop counter should be the same type as the count type. (PR #987)</li>
 <li>ShellExtension for Windows11: Disable Registry Write Virtualization</li>
 </ul>
-<h3 id="manual-2">Manual</h3>
+<h3 id="manual-3">Manual</h3>
 <ul>
 <li>Where to report documentation/help errors? (#1004)</li>
 </ul>
-<h3 id="translations-14">Translations</h3>
+<h3 id="translations-15">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (PR #980)</li>
 </ul></li>
 </ul>
-<h3 id="internals-6">Internals</h3>
+<h3 id="internals-7">Internals</h3>
 <ul>
 <li>BugFix: Missing packages.config (also outdated) and wrong NuGet packages path in the WinMergeContextMenu.vcxproj and .filters file (#985)</li>
 <li>Fix typo in OpenView.cpp (PR #1000)</li>
 </ul>
 <h2 id="winmerge-21615---2021-09-20">WinMerge 2.16.15 - 2021-09-20</h2>
-<h3 id="general-13">General</h3>
+<h3 id="general-14">General</h3>
 <ul>
 <li>BugFix: WinMerge would crash when launched if the registry or INI file contained invalid values.</li>
 <li>BugFix: Winmerge Crash when comparing 2 files from Windows Explorer context menu (#808, #908, #913)</li>
 <li>BugFix: 50% cpu use by winmergeu.exe after program closed (#903)</li>
 <li>Digitally sign packages (#152)</li>
 </ul>
-<h3 id="file-compare-15">File compare</h3>
+<h3 id="file-compare-16">File compare</h3>
 <ul>
 <li>BugFix: The mouse cursor did not change to an hourglass when the files or plugins were taking a long time to load.</li>
 <li>BugFix: Save Middle and Save Middle As menu items were not enabled when comparing three files.</li>
 <ul>
 <li>Add a feature to save/restore compare options to/from a project file.(#498) (PR #915)</li>
 </ul>
-<h3 id="options-dialog-9">Options dialog</h3>
+<h3 id="options-dialog-10">Options dialog</h3>
 <ul>
 <li>Add a feature to set items saved to or restored from the project file. (PR #953)</li>
 </ul>
-<h3 id="plugins-12">Plugins</h3>
+<h3 id="plugins-13">Plugins</h3>
 <ul>
 <li>New unpacker plugins:
 <ul>
 <li>BugFix: Right click - compare - is unclear (#249)</li>
 <li>Added a new DLL (WinMergeContextMenu.dll) for the Windows 11 Explorer context menu (currently unstable and not registered by default) (PR #954)</li>
 </ul>
-<h3 id="translations-15">Translations</h3>
+<h3 id="translations-16">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (PR #899)</li>
 </ul></li>
 </ul>
-<h3 id="internals-7">Internals</h3>
+<h3 id="internals-8">Internals</h3>
 <ul>
 <li>README.md: Make it clear that requirements are to build, not use the application (PR #942)</li>
 <li>compiler-calculated maximum value for <code>m_SourceDefs</code> (PR #966)</li>
 </ul>
 <h2 id="winmerge-21614---2021-07-25">WinMerge 2.16.14 - 2021-07-25</h2>
-<h3 id="general-14">General</h3>
+<h3 id="general-15">General</h3>
 <ul>
 <li>Fixed an issue where the WinMerge process might not terminate even though the WinMerge window was closed.</li>
 </ul>
-<h3 id="file-compare-16">File compare</h3>
+<h3 id="file-compare-17">File compare</h3>
 <ul>
 <li>BugFix: Fixed an infinite loop when &quot;find what&quot; in the substitution filters is empty.</li>
 </ul>
-<h3 id="folder-compare-15">Folder compare</h3>
+<h3 id="folder-compare-16">Folder compare</h3>
 <ul>
 <li>BugFix: Fix an issue where a file is deselected when returning to the folder compare window after opening the file compare window by double-clicking the file in the folder compare window. (PR #857)</li>
 <li>Right click context menu - Compare files or folders in a new tab (#232,#277)</li>
 <li>Flip Horizontally</li>
 </ul></li>
 </ul>
-<h3 id="options-dialog-10">Options dialog</h3>
+<h3 id="options-dialog-11">Options dialog</h3>
 <ul>
 <li>Add preference option to clear &quot;Don&#39;t ask this question again&quot; CompareLargeFiles choice (#772, PR #859)</li>
 </ul>
 <ul>
 <li>BugFix: Fix the Select Files or Folders dialog. (PR #882,#892)</li>
 </ul>
-<h3 id="plugins-13">Plugins</h3>
+<h3 id="plugins-14">Plugins</h3>
 <ul>
 <li>BugFix: CompareMSExcelFiles.sct: &quot;This picture only contains a bitmap&quot; was displayed when comparing Excel files that contain shapes.</li>
 <li>BugFix: CString rangestr = (argc &gt; 0) ? argv[0] : GetColumnRangeString(); (#853)</li>
 <ul>
 <li>Installer integrates with TortoiseGit and TortoiseSVN despite being told not to (#878)</li>
 </ul>
-<h3 id="translations-16">Translations</h3>
+<h3 id="translations-17">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (PR #848)</li>
 </ul></li>
 </ul>
-<h3 id="internals-8">Internals</h3>
+<h3 id="internals-9">Internals</h3>
 <ul>
 <li>BugFix: WinMerge doesn&#39;t build under Visual Studio 16.10.2 (#841)</li>
 <li>BugFix: x64: LINK : warning LNK4010: invalid subsystem version number 5.01; default subsystem version assumed (#855)</li>
 <li>Improvement: Add check and error mesage in DownloadDeps.cmd that path to 7-zip exists (#864)</li>
 </ul>
 <h2 id="winmerge-21613---2021-06-22">WinMerge 2.16.13 - 2021-06-22</h2>
-<h3 id="general-15">General</h3>
+<h3 id="general-16">General</h3>
 <ul>
 <li>BugFix: Register.bat did not work properly on the Chinese version of Windows XP (#780)</li>
 <li>Possibility to store settings in INI file (#248) (PR #750)</li>
 <li>FeatureRequest - Ignoring options - lack in &quot;button menu&quot; (#804)</li>
 </ul>
-<h3 id="file-compare-17">File compare</h3>
+<h3 id="file-compare-18">File compare</h3>
 <ul>
 <li>BugFix: Fix PHP syntax highlighting. (PR #782, PR #802)</li>
 <li>BugFix: BS key did not work at the beginning of the line after splitting the pane or clicking the OK button in the Options dialog.</li>
 <li>Add Smarty syntax highlighting. (PR #821)</li>
 <li>Thicken the caret in overwrite mode (osdn.net #42179)</li>
 </ul>
-<h3 id="folder-compare-16">Folder compare</h3>
+<h3 id="folder-compare-17">Folder compare</h3>
 <ul>
 <li>BugFix: Different Files are Identical? (#768) (When comparing files with only BOM and no contents, the comparison result became unstable because it referred to the uninitialized memory.)</li>
 <li>BugFix: Fix a crash when re-comparing folders (osdn.net #42219)</li>
 <li>BugFix: Error on try to show differences between two different gif (#784)</li>
 <li>Made Unpacker plugins available for image compare and binary compare</li>
 </ul>
-<h3 id="plugins-14">Plugins</h3>
+<h3 id="plugins-15">Plugins</h3>
 <ul>
 <li>Improve plugin system (PR #797)
 <ul>
 </ul></li>
 </ul></li>
 </ul>
-<h3 id="translations-17">Translations</h3>
+<h3 id="translations-18">Translations</h3>
 <ul>
 <li>BugFix: Fix an issue where a message is not translated.(PR #763)</li>
 <li>Translation updates:
 <li>Russian (PR #761)</li>
 </ul></li>
 </ul>
-<h3 id="internals-9">Internals</h3>
+<h3 id="internals-10">Internals</h3>
 <ul>
 <li>Update CWindowsManagerDialog (PR #811)</li>
 <li>Update CWindowsManagerDialog - check some pointers for null and made safe casts (PR #824)</li>
 </ul>
 <h2 id="winmerge-21612---2021-04-29">WinMerge 2.16.12 - 2021-04-29</h2>
-<h3 id="general-16">General</h3>
+<h3 id="general-17">General</h3>
 <ul>
 <li>GUI textstrings: grammatical corrections (PR #722)</li>
 <li>Added ARM64 support</li>
 </ul>
-<h3 id="file-compare-18">File compare</h3>
+<h3 id="file-compare-19">File compare</h3>
 <ul>
 <li>BugFix: Fix PHP syntax highlighting. (PR #751)</li>
 <li>BugFix: Strings in a multi-line diff block were not be replaced correctly when the substitution filters&#39; regular expression contained ^</li>
 <li>Make the color of characters that represent spaces and tabs lighter than other characters when the &quot;View Whitespace&quot; menu item is enabled</li>
 <li>Added &quot;Open Parent Folder&quot; menu item to the context menu</li>
 </ul>
-<h3 id="folder-compare-17">Folder compare</h3>
+<h3 id="folder-compare-18">Folder compare</h3>
 <ul>
 <li>BugFix: Copy confirmation dialog has overlapped Yes/No Button (#739)</li>
 <li>BugFix: Comparison result was not updated by Swap operation in 3-way folder comparison (osdn.net #41901)</li>
 <ul>
 <li>BugFix: Fixed a rare crash when decompressing an archive file</li>
 </ul>
-<h3 id="plugins-15">Plugins</h3>
+<h3 id="plugins-16">Plugins</h3>
 <ul>
 <li>BugFix: ATL: QIThunk - 2 LEAK in plugins e.g. DisplayBinaryFiles and DisplayXMLFiles (#755)</li>
 </ul>
-<h3 id="translations-18">Translations</h3>
+<h3 id="translations-19">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 </ul></li>
 </ul>
 <h2 id="winmerge-21611---2021-03-28">WinMerge 2.16.11 - 2021-03-28</h2>
-<h3 id="general-17">General</h3>
+<h3 id="general-18">General</h3>
 <ul>
 <li>Make all OK strings same case (PR #593)</li>
 <li>Tab bar: Added shadows to help distinguish between active and inactive tabs</li>
 <li>Added drop-down menu to Open and Save icon on toolbar</li>
 </ul>
-<h3 id="file-compare-19">File compare</h3>
+<h3 id="file-compare-20">File compare</h3>
 <ul>
 <li>BugFix: Basic syntax highlighter is broken (osdn.net #41440)</li>
 <li>BugFix: File is corrupted while saving differences in changed file (Ctrl+S) (#607)</li>
 <li>If -b or -w is also specified, -B now considers lines to be empty if they contain only white space (osdn.net #41355)</li>
 <li>Added BOM checkbox to the Codepage dialog.</li>
 </ul>
-<h3 id="folder-compare-18">Folder compare</h3>
+<h3 id="folder-compare-19">Folder compare</h3>
 <ul>
 <li>BugFix: Program crash if you close a tab with the folder from where you opened current file (#645)</li>
 <li>BugFix: The title bar path was not updated when swapping files in a Zip file.</li>
 <ul>
 <li>Rar5 support (#644)</li>
 </ul>
-<h3 id="options-dialog-11">Options dialog</h3>
+<h3 id="options-dialog-12">Options dialog</h3>
 <ul>
 <li>BugFix: Fix an issue where custom colors are not saved. (PR #648)</li>
 </ul>
-<h3 id="plugins-16">Plugins</h3>
+<h3 id="plugins-17">Plugins</h3>
 <ul>
 <li>RCLocalizationHelper: Fix memory leaks (PR #596)</li>
 </ul>
 <ul>
 <li>Installer issue with Polish diacritics characters (#589)</li>
 </ul>
-<h3 id="translations-19">Translations</h3>
+<h3 id="translations-20">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <ul>
 <li>Single instance mode does not work when launched from Visual Studio 2019 (#622) (Added /sw command line option)</li>
 </ul>
-<h3 id="internals-10">Internals</h3>
+<h3 id="internals-11">Internals</h3>
 <ul>
 <li>BugFix: Plugins\src_VCPP\VCPPPlugins.vs2017.sln can&#39;t open projects any more because in revision 69455da the projects were renamed. (#598)</li>
 <li>BugFix: OutputFile of plugin project DisplayXMLFiles is different that the other projects (#600)</li>
 <li>Plugins.cpp function SearchScriptForMethodName can be improved (#690)</li>
 </ul>
 <h2 id="winmerge-21610---2021-01-30">WinMerge 2.16.10 - 2021-01-30</h2>
-<h3 id="general-18">General</h3>
+<h3 id="general-19">General</h3>
 <ul>
 <li>BugFix: Fixed processing that uses GetAsyncKeyState(). (GitHub PR #505)</li>
 <li>BugFix: Fixed the problem that the language setting is not applied to the context menu of the MDI tab when the language setting is changed. (GitHub PR #523)</li>
 (GitHub #530)</li>
 <li>Added the command line option &quot;/s-&quot; to ensure that another instance is always executed, ignoring the value of the &#39;Allow only one instance to run&#39; option.</li>
 </ul>
-<h3 id="file-compare-20">File compare</h3>
+<h3 id="file-compare-21">File compare</h3>
 <ul>
 <li>BugFix: WinMerge crashes with mouse double click (GitHub #531)</li>
 <li>BugFix: Fixed an issue where the message box &quot;The report has been created successfully.&quot; was displayed even if the report creation failed.</li>
 <li>Feature Request: Move To Next File option while comparing files #475 (GitHub PR #561)</li>
 <li>A new feature &quot;Ignored Substutions&quot; (GitHub PR #544,#549,#560) (&quot;Ignored Substitutions&quot; was renamed to &quot;Substitution Filters&quot;)</li>
 </ul>
-<h3 id="folder-compare-19">Folder compare</h3>
+<h3 id="folder-compare-20">Folder compare</h3>
 <ul>
 <li>BugFix: Winmerge crashes consistently when deleting files (GitHub #491)</li>
 <li>BugFix: Copy Folder does not copy subfolders and I don&#39;t see any option for it (GitHub #537)</li>
 </ul>
-<h3 id="table-compare-5">Table compare</h3>
+<h3 id="table-compare-6">Table compare</h3>
 <ul>
 <li>Added File -&gt; New -&gt; Table menu item</li>
 </ul>
 <li>Added File -&gt; New -&gt; Image menu item</li>
 <li>Added Image -&gt; Compare Extracted Text From Image menu item</li>
 </ul>
-<h3 id="options-dialog-12">Options dialog</h3>
+<h3 id="options-dialog-13">Options dialog</h3>
 <ul>
 <li>Fix an issue where custom colors are not saved. (GitHub PR #648)</li>
 </ul>
 <ul>
 <li>BugFix: Crash when generating patch (GitHub #521)</li>
 </ul>
-<h3 id="translations-20">Translations</h3>
+<h3 id="translations-21">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Russian (GitHub PR #494)</li>
 </ul></li>
 </ul>
-<h3 id="manual-3">Manual</h3>
+<h3 id="manual-4">Manual</h3>
 <ul>
 <li>Update manual (GitHub PR #497,#513,#546)</li>
 <li>Small tweaks for the Manual (GitHub PR #508)</li>
 <li>Windows XP Pro SP0 vs Requirements (GitHub #515)</li>
 </ul>
-<h3 id="internals-11">Internals</h3>
+<h3 id="internals-12">Internals</h3>
 <ul>
 <li>Fix Various Warnings (GitHub PR #539)</li>
 <li>Various fixes to testing (GitHub PR #545)</li>
 <li>Some more files should be added to the .gitignore file (GitHub #559)</li>
 </ul>
 <h2 id="winmerge-2169---2020-11-29">WinMerge 2.16.9 - 2020-11-29</h2>
-<h3 id="general-19">General</h3>
+<h3 id="general-20">General</h3>
 <ul>
 <li>BugFix: MainFrm.cpp: Toolbar was leaking image lists (GitHub PR #432)</li>
 <li>BugFix: The icons on a 43&quot; 4K screen are too small (GitHub #276)</li>
 <li>Update Merge.rc (GitHub #487)</li>
 <li>Improved startup time</li>
 </ul>
-<h3 id="file-compare-21">File compare</h3>
+<h3 id="file-compare-22">File compare</h3>
 <ul>
 <li>BugFix: [UI] Pane enlargement was reset after changing tab (GitHub #403)</li>
 <li>BugFix: Non-comment differences were sometimes ignored when the comment filter was enabled, (osdn.net #40488)</li>
 <li>Add the feature &quot;Go to Moved Line&quot; requested by #278 (GitHub PR #484)</li>
 <li>how to show white space with linebreak hidden? (GitHub #265) (Added View-&gt;View EOL menu item)</li>
 </ul>
-<h3 id="folder-compare-20">Folder compare</h3>
+<h3 id="folder-compare-21">Folder compare</h3>
 <ul>
 <li>BugFix: Pausing comparing doesn&#39;t pause immediately (GitHub #342)</li>
 <li>BugFix: Sorting on Comparison Result being done incorectly (GitHub #483)</li>
 <ul>
 <li>BugFix: Scrolling binary files (GitHub #456)</li>
 </ul>
-<h3 id="options-dialog-13">Options dialog</h3>
+<h3 id="options-dialog-14">Options dialog</h3>
 <ul>
 <li>Added &quot;Automatically scroll to first inline difference&quot; option to Options dialog</li>
 </ul>
 <ul>
 <li>BugFix: Fixed the problem that the input to File1 or File2 comboboxes of the Patch Generator dialog is not applied when the Patch Generator dialog is opened by selecting multiple files. (GitHub PR #421)</li>
 </ul>
-<h3 id="translations-21">Translations</h3>
+<h3 id="translations-22">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (GitHub PR #425)</li>
 </ul></li>
 </ul>
-<h3 id="manual-4">Manual</h3>
+<h3 id="manual-5">Manual</h3>
 <ul>
 <li>Update Shortcut_keys.xml (GitHub PR #430)</li>
 <li>Update manual (GitHub PR #485,#492)</li>
 </ul>
-<h3 id="internals-12">Internals</h3>
+<h3 id="internals-13">Internals</h3>
 <ul>
 <li>Tweak output from BuildInstaller.cmd and BuildArc.cmd (GitHub PR #424)</li>
 <li>Fix typo in GhostTextBuffer.cpp (GitHub PR #472)</li>
 <li>Fix typo in memdc.h (GitHub PR #474)</li>
 </ul>
 <h2 id="winmerge-2168---2020-08-28">WinMerge 2.16.8 - 2020-08-28</h2>
-<h3 id="general-20">General</h3>
+<h3 id="general-21">General</h3>
 <ul>
 <li>BugFix: More space for some internationalized strings (GitHub #402)</li>
 <li>BugFix: Some improvements (GitHub #405,#411)</li>
 </ul>
-<h3 id="file-compare-22">File compare</h3>
+<h3 id="file-compare-23">File compare</h3>
 <ul>
 <li>BugFix: Ignore case option did not work when Diff algorithm was other than default</li>
 <li>BugFix: A white vertical rectangle was sometimes drawn in the selected area</li>
 <li>Extended F4 key movement range to the whole file</li>
 <li>Don&#39;t treat UTF-8 and UTF-8 with BOM the same when the &quot;Ignore codepage differences&quot; option is disabled</li>
 </ul>
-<h3 id="folder-compare-21">Folder compare</h3>
+<h3 id="folder-compare-22">Folder compare</h3>
 <ul>
 <li>BugFix: Appropriate error messages were not displayed when the file to be deleted no longer existed</li>
 <li>BugFix: &#39;Show Middle/Right Unique items&#39; menu item does not work properly in 3-way folder compare (osdn.net #40672)</li>
 <li>BugFix: Fix scrolling glitches (GitHub WinMerge/winimerge PR #8)</li>
 <li>Reduce flicker on resize (GitHub WinMerge/winimerge PR #9)</li>
 </ul>
-<h3 id="options-dialog-14">Options dialog</h3>
+<h3 id="options-dialog-15">Options dialog</h3>
 <ul>
 <li>Allow choosing image filename patterns from a multi-selection dropdown list (GitHub PR #391)</li>
 <li>WildcardDropList: Avoid the String instance as it could throw std::bad_alloc (GitHub PR #397)</li>
 <li>BugFix: Lithuanian.po is missing (GitHub PR #415)</li>
 <li>New installer for per-user installation (WinMerge-2.16.8-x64-PerUser-Setup.exe)</li>
 </ul>
-<h3 id="translations-22">Translations</h3>
+<h3 id="translations-23">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Russian (GitHub PR #387)</li>
 </ul></li>
 </ul>
-<h3 id="manual-5">Manual</h3>
+<h3 id="manual-6">Manual</h3>
 <ul>
 <li>Update manual for IgnoreCommentsC change (GitHub PR #384)</li>
 <li>Update Shortcut_keys.xml (GitHub PR #410)</li>
 </ul>
 <h2 id="winmerge-2167---2020-07-26">WinMerge 2.16.7 - 2020-07-26</h2>
-<h3 id="general-21">General</h3>
+<h3 id="general-22">General</h3>
 <ul>
 <li>BugFix: The icons on a 43&quot; 4K screen are too small (GitHub #276)</li>
 <li>BugFix: GUI glitches/bugs (GitHub #316)</li>
 <li>Add Solarized Dark/Light color scheme (GitHub #287)</li>
 <li>Compile WinMerge with ASLR and CFG enabled (GitHub #315)</li>
 </ul>
-<h3 id="file-compare-23">File compare</h3>
+<h3 id="file-compare-24">File compare</h3>
 <ul>
 <li>BugFix: Diff Pane issues (GitHub #307)</li>
 <li>BugFix: Codepage not updated on refresh (GitHub #320)</li>
 <li>Allow specifying default for EOL warning checkbox (GitHub #297)</li>
 <li>Only indent existing lines (GitHub #356)</li>
 </ul>
-<h3 id="table-compare-6">Table compare</h3>
+<h3 id="table-compare-7">Table compare</h3>
 <ul>
 <li>Made it possible to display the contents of CSV and TSV files like spreadsheet software.</li>
 </ul>
-<h3 id="folder-compare-22">Folder compare</h3>
+<h3 id="folder-compare-23">Folder compare</h3>
 <ul>
 <li>BugFix: DST causes incorrect dates shown in Date column (GitHub #299)</li>
 <li>BugFix: Long filename issue (GitHub #339)</li>
 <li>BugFix: Open dialogs are sometimes left as garbage (osdn.net #40487)</li>
 <li>Browse button in the file/dir selection show wrong path (GitHub #346)</li>
 </ul>
-<h3 id="options-dialog-15">Options dialog</h3>
+<h3 id="options-dialog-16">Options dialog</h3>
 <ul>
 <li>BugFix: Pressing the [Compare/Binary] category button in the Options dialog twice will cause a crash. (osdn.net #40308)</li>
 </ul>
-<h3 id="plugins-17">Plugins</h3>
+<h3 id="plugins-18">Plugins</h3>
 <ul>
 <li>BugFix: Fix handling of line breaks in SortAscending, SortDescending (osdn.net PR #40266)</li>
 <li>BugFix: Error when comparing images in the CompareMSExcelFiles.sct plugin (osdn.net #40472)</li>
 <ul>
 <li>Create the installer with Inno Setup 5.x since installers created with Inno Setup 6.0.x are identified as malware by multiple virus scanning engines</li>
 </ul>
-<h3 id="translations-23">Translations</h3>
+<h3 id="translations-24">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
 <li>Turkish (GitHub PR #335,#336,#337,#338)</li>
 </ul></li>
 </ul>
-<h3 id="manual-6">Manual</h3>
+<h3 id="manual-7">Manual</h3>
 <ul>
 <li>Minor changes to translations README.md file (GitHub #289)</li>
 <li>Update winmerge.org URL to HTTPS, many small improvements (GitHub PR #306)</li>
 </ul>
-<h3 id="internals-13">Internals</h3>
+<h3 id="internals-14">Internals</h3>
 <ul>
 <li>BugFix: Src\Common\MyCom.h unused? (GitHub #284)</li>
 <li>BugFix: Error on git repository cloning (GitHub #288)</li>
 </ul>
 <h2 id="winmerge-2166---2020-02-23">WinMerge 2.16.6 - 2020-02-23</h2>
-<h3 id="general-22">General</h3>
+<h3 id="general-23">General</h3>
 <ul>
 <li>Added CWindowsManagerDialog class for handling open tabs with Ctrl+Tab, now the application is behave just like professional editors (Visual Studio, Notepad++, etc.) to switch and activate the open tabs. (GitHub #247)</li>
 </ul>
-<h3 id="file-compare-24">File compare</h3>
+<h3 id="file-compare-25">File compare</h3>
 <ul>
 <li>BugFix: GhostTextBuffer: Don&#39;t unexpectedly bring back empty lines user wants to delete (GitHub #244)</li>
 <li>BugFix: Prevent silent abort with File Comparison of files whose size is an exact multiple of 2^32 bytes (GitHub #257)</li>
@@ -1814,7 +1886,7 @@ Demo2: <a href="https://gyazo.com/f5f267546db27f2dc801c00df8cb4251">https://gyaz
 <ul>
 <li>BugFix: Fix spelling of Git (GitHub #246)</li>
 </ul>
-<h3 id="translations-24">Translations</h3>
+<h3 id="translations-25">Translations</h3>
 <ul>
 <li>New translation: Arabic (sf.net #3038)</li>
 <li>Translation updates:
@@ -1827,18 +1899,18 @@ Demo2: <a href="https://gyazo.com/f5f267546db27f2dc801c00df8cb4251">https://gyaz
 <li>Spanish (GitHub #266)</li>
 </ul></li>
 </ul>
-<h3 id="manual-7">Manual</h3>
+<h3 id="manual-8">Manual</h3>
 <ul>
 <li>BugFix: Fix spelling of Git (GitHub #246)</li>
 <li>Update Configuration.xml (GitHub #262)</li>
 </ul>
-<h3 id="internals-14">Internals</h3>
+<h3 id="internals-15">Internals</h3>
 <ul>
 <li>Consolidate FolderCmp (GitHub #240, #242)</li>
 <li>Avoid some back and forth file path transcoding between UTF16 and UTF8 (GitHub #243)</li>
 </ul>
 <h2 id="winmerge-2165---2019-12-09">WinMerge 2.16.5 - 2019-12-09</h2>
-<h3 id="file-compare-25">File compare</h3>
+<h3 id="file-compare-26">File compare</h3>
 <ul>
 <li>BugFix: Suspicious lack of Release() calls in lwdisp.c (GitHub #171)</li>
 <li>BugFix: Performance using Unpacker (GitHub #180)</li>
@@ -1851,7 +1923,7 @@ Demo2: <a href="https://gyazo.com/f5f267546db27f2dc801c00df8cb4251">https://gyaz
 <li>Add support for color emoji (Only available in 64bit version) (To enable color emoji support, select DirectWrite* in Rendering mode combobox on Editor page in the Options dialog)<br />
 Demo: <a href="https://gyazo.com/7cbbbd2c1de195fcd214d588b21b21d4">https://gyazo.com/7cbbbd2c1de195fcd214d588b21b21d4</a></li>
 </ul>
-<h3 id="folder-compare-23">Folder compare</h3>
+<h3 id="folder-compare-24">Folder compare</h3>
 <ul>
 <li>BugFix: Crash when clicking Next Difference button after unchecking Show Different Items menu item</li>
 <li>Changed symbols in Newer/Older column for better visual clarity (GitHub #169)</li>
@@ -1873,7 +1945,7 @@ Demo: <a href="https://gyazo.com/7cbbbd2c1de195fcd214d588b21b21d4">https://gyazo
 <li>BugFix: Windows 10 shell integration not working (GitHub #176)</li>
 <li>Installer - Proposal - Separate Inno Setup strings from WinMerge installer strings (GitHub #167)</li>
 </ul>
-<h3 id="translations-25">Translations</h3>
+<h3 id="translations-26">Translations</h3>
 <ul>
 <li>Update Italian translation (GitHub #164, #165)</li>
 <li>Update Russian translation (GitHub #166)</li>
@@ -1889,46 +1961,46 @@ Demo: <a href="https://gyazo.com/7cbbbd2c1de195fcd214d588b21b21d4">https://gyazo
 <li>Update English.pot (#216)</li>
 <li>Add Japanese manual (GitHub #183)</li>
 </ul>
-<h3 id="manual-8">Manual</h3>
+<h3 id="manual-9">Manual</h3>
 <ul>
 <li>Small Manual tweaks (GitHub #190)</li>
 </ul>
 <h2 id="winmerge-2164---2019-07-28">WinMerge 2.16.4 - 2019-07-28</h2>
-<h3 id="file-compare-26">File compare</h3>
+<h3 id="file-compare-27">File compare</h3>
 <ul>
 <li>BugFix: coretools.cpp: linelen() should not truncate lines with embedded NULs (GitHub #156)</li>
 <li>BugFix: file compare : right-click doesn&#39;t select the diff under the mouse (GitHub #159)</li>
 <li>BugFix: Avoid an exception in GuessCodepageEncoding() when filepath equals &quot;NUL&quot; (GitHub #162)</li>
 <li>BugFix: Auto-indent did not work if the EOL-style was not CRLF</li>
 </ul>
-<h3 id="folder-compare-24">Folder compare</h3>
+<h3 id="folder-compare-25">Folder compare</h3>
 <ul>
 <li>BugFix: Generating HTML Folder Compare report including File Compare report did not complete (Bitbucket #15)</li>
 <li>BugFix: Compare Statistics dialog: The number of diff folders was counted in the number of diff files</li>
 </ul>
-<h3 id="plugins-18">Plugins</h3>
+<h3 id="plugins-19">Plugins</h3>
 <ul>
 <li>BugFix: PrediffLineFilter.sct: Wrong encoding for settings dialog (Bitbucket #16)</li>
 </ul>
-<h3 id="translations-26">Translations</h3>
+<h3 id="translations-27">Translations</h3>
 <ul>
 <li>Update Russian translation (Bitbucket PR #51)</li>
 <li>Update Italian translation (Bitbucket PR #52)</li>
 </ul>
-<h3 id="internals-15">Internals</h3>
+<h3 id="internals-16">Internals</h3>
 <ul>
 <li>Favor PathContext::GetSize() over PathContext::size() (GitHub #157)</li>
 <li>Consolidate FolderCmp (GitHub #158, #160, #161)</li>
 <li>Avoid some InnoSetup compiler warnings (Bitbucket PR #53)</li>
 </ul>
 <h2 id="winmerge-2163---2019-06-29">WinMerge 2.16.3 - 2019-06-29</h2>
-<h3 id="general-23">General</h3>
+<h3 id="general-24">General</h3>
 <ul>
 <li>BugFix: Slow startup with documents folder redirected to high-latency network drive (Bitbucket #155)</li>
 <li>Add VisualElementsManifest for Windows 10 start menu (Bitbucket PR #47)</li>
 <li>Reduce the size of the executable file</li>
 </ul>
-<h3 id="file-compare-27">File compare</h3>
+<h3 id="file-compare-28">File compare</h3>
 <ul>
 <li>BugFix: Location and Diff pane visibility broken in 2.16.1 (GitHub #138, Bitbucket #163, sf.net #2228)</li>
 <li>BugFix: Temporary files could not be created (GitHub #143, sf.net #2220)</li>
@@ -1940,7 +2012,7 @@ Demo: <a href="https://gyazo.com/7cbbbd2c1de195fcd214d588b21b21d4">https://gyazo
 <li>Add support for merging word level diffs in selection<br />
 Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif</a></li>
 </ul>
-<h3 id="folder-compare-25">Folder compare</h3>
+<h3 id="folder-compare-26">Folder compare</h3>
 <ul>
 <li>BugFix: WinMerge 3-Way Compare Bugs: Always Shows Unique Items. (GitHub #154)</li>
 <li>BugFix: WinMerge could not compare files that are opened in other applications</li>
@@ -1959,7 +2031,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Implement Insertion/Deletion Detection<br />
 Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80</a></li>
 </ul>
-<h3 id="options-dialog-16">Options dialog</h3>
+<h3 id="options-dialog-17">Options dialog</h3>
 <ul>
 <li>Tweak size of combobox &quot;codepage&quot; in options (GitHub #144)</li>
 <li>Sort combobox codepage and add manual codepage (GitHub #145)</li>
@@ -1969,14 +2041,14 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <li>Allow per-user installation (only x64 installer)</li>
 <li>Don&#39;t install Files.txt and don&#39;t add &quot;Uninstall WinMerge&quot; to the start menu (Bitbuket #38)</li>
 </ul>
-<h3 id="translations-27">Translations</h3>
+<h3 id="translations-28">Translations</h3>
 <ul>
 <li>Update French translation (GitHub #149, #150)</li>
 <li>Update Lithuanian translation (Bitbucket PR #36, #40, #43, #46, #48, #50)</li>
 <li>Update Russian translation (Bitbucket PR #41, #42)</li>
 </ul>
 <h2 id="winmerge-2162---2019-04-04">WinMerge 2.16.2 - 2019-04-04</h2>
-<h3 id="file-compare-28">File compare</h3>
+<h3 id="file-compare-29">File compare</h3>
 <ul>
 <li>BugFix: Edit &gt; Replace &gt; All, Undo: should undo all (sf.net #2113)</li>
 <li>BugFix: Save As: default directory should be file&#39;s original directory (sf.net #2163)</li>
@@ -1987,7 +2059,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <li>BugFix: Crash when failed to load file</li>
 <li>Add syntax highlight for Lua (Bitbucket #114)</li>
 </ul>
-<h3 id="folder-compare-26">Folder compare</h3>
+<h3 id="folder-compare-27">Folder compare</h3>
 <ul>
 <li>BugFix: Compare results refresh incorrectly after deletions (sf.net #2217)</li>
 </ul>
@@ -2008,7 +2080,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <ul>
 <li>Allow quoted filenames in &quot;Select Files or Folders&quot; (sf.net #1240, GitHub #137)</li>
 </ul>
-<h3 id="manual-9">Manual</h3>
+<h3 id="manual-10">Manual</h3>
 <ul>
 <li>Some tweaks for the manual (Bitbucket PR #35)</li>
 </ul>
@@ -2016,7 +2088,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <ul>
 <li>BugFix: Gibberish language during installation (Bitbucket #147)</li>
 </ul>
-<h3 id="translations-28">Translations</h3>
+<h3 id="translations-29">Translations</h3>
 <ul>
 <li>Update Catalan translation (Bitbucket PR #29)</li>
 <li>Update Italian translation (Bitbucket PR #32)</li>
@@ -2024,7 +2096,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <li>Update Simplified Chinese translation (Bitbucket PR #34)</li>
 </ul>
 <h2 id="winmerge-2161---2019-02-24">WinMerge 2.16.1 - 2019-02-24</h2>
-<h3 id="general-24">General</h3>
+<h3 id="general-25">General</h3>
 <ul>
 <li>Updated the copyright year to 2019, actually (GitHub #110)</li>
 <li>Prevent splitter view from claiming input focus (GitHub #127)</li>
@@ -2036,7 +2108,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <li>Expose cleaner moving/resizing behavior esp. in non-maximized state (GitHub #119)</li>
 <li>Avoid retaining bogus filetype icons from previous selections (GitHub #122)</li>
 </ul>
-<h3 id="file-compare-29">File compare</h3>
+<h3 id="file-compare-30">File compare</h3>
 <ul>
 <li>BugFix: Extra blank displayed after left/right single/double quotes (Bitbucket #134)</li>
 <li>BugFix: Click doesn&#39;t trigger document to scroll in Location pane under circumstance (Bitbucket #140)</li>
@@ -2050,7 +2122,7 @@ Demo: <a href="https://gyazo.com/17d8773354d23b5ae51262f28b0f1f80">https://gyazo
 <li>Add support for merging word level diffs in selection<br />
 Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif</a></li>
 </ul>
-<h3 id="folder-compare-27">Folder compare</h3>
+<h3 id="folder-compare-28">Folder compare</h3>
 <ul>
 <li>BugFix: Unique files are not shown (Bitbucket #138)</li>
 <li>BugFix: Improve Hard-IO error handling, other bug fixes, cleanup, tweaks (GitHub #120)</li>
@@ -2059,7 +2131,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>Upgraded to 7-zip 18.06 (Bitbucket #119)</li>
 </ul>
-<h3 id="options-dialog-17">Options dialog</h3>
+<h3 id="options-dialog-18">Options dialog</h3>
 <ul>
 <li>BugFix: Widen the width of labels in Options dialog (GitHub#108)</li>
 <li>BugFix: view settings make winmerge crash (Bitbucket #109)</li>
@@ -2071,7 +2143,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>BugFix: CreateTranslatedRcFiles needs an update (GitHub #113)</li>
 </ul>
-<h3 id="translations-29">Translations</h3>
+<h3 id="translations-30">Translations</h3>
 <ul>
 <li>Update Brazilian Portuguese translation (GitHub #108)</li>
 <li>Update Swedish translation (sf.net #3035, GitHub #112, #114)</li>
@@ -2082,13 +2154,13 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Update Japanese translation</li>
 <li>Remove now unneeded MergeLang.dll</li>
 </ul>
-<h3 id="manual-10">Manual</h3>
+<h3 id="manual-11">Manual</h3>
 <ul>
 <li>BugFix: Some fixes in the manual (GitHub #116)</li>
 <li>Bugifx: end of line documentation (sf.net #2211)</li>
 <li>Clarification as per <a href="https://github.com/WinMerge/winmerge-v2/issues/41">https://github.com/WinMerge/winmerge-v2/issues/41</a> (GitHub #126)</li>
 </ul>
-<h3 id="internals-16">Internals</h3>
+<h3 id="internals-17">Internals</h3>
 <ul>
 <li>Remove <code>nFinalNullLines</code> checking, disabled by an earlier commit (GitHub #111)</li>
 <li>Various minor updates, plus preparation for VS2019 (GitHub #115)</li>
@@ -2096,11 +2168,11 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Don&#39;t pass <code>DIFFITEM *</code> by casting to <code>uintptr_t</code> (GitHub #124, #125)</li>
 </ul>
 <h2 id="winmerge-2160---2018-11-23">WinMerge 2.16.0 - 2018-11-23</h2>
-<h3 id="general-25">General</h3>
+<h3 id="general-26">General</h3>
 <ul>
 <li>BugFix: Disabled icon on toolbar not gray out when running on XP</li>
 </ul>
-<h3 id="file-compare-30">File compare</h3>
+<h3 id="file-compare-31">File compare</h3>
 <ul>
 <li>BugFix: Copy to X and Advance&quot; not work in 3way-compare (Bitbucket #123)</li>
 <li>BugFix: File compare always showing different ending (GitHub #106)</li>
@@ -2116,13 +2188,13 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>Drop ClearCase integration (Bitbucket PR #6)</li>
 </ul>
-<h3 id="translations-30">Translations</h3>
+<h3 id="translations-31">Translations</h3>
 <ul>
 <li>Add Lithuanian translation (Bitbucket #124)</li>
 <li>Update Portuguese translation (GitHub #102,#103)</li>
 </ul>
 <h2 id="winmerge-2155---2018-10-28">WinMerge 2.15.5 - 2018-10-28</h2>
-<h3 id="general-26">General</h3>
+<h3 id="general-27">General</h3>
 <ul>
 <li>Add support for very long path and file names (GitHub #87,#95,#99)</li>
 <li>Enable Ctrl+C shortcut key on the file path bar</li>
@@ -2132,7 +2204,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Improve visual layout of Open dialog (GitHub #97)</li>
 <li>Add icon for &quot;New (3 panes)&quot; menu item (GitHub #97)</li>
 </ul>
-<h3 id="file-compare-31">File compare</h3>
+<h3 id="file-compare-32">File compare</h3>
 <ul>
 <li>Add Window/Split menu item</li>
 <li>Improve handling of last lines in files (GitHub #89,#90,#93)</li>
@@ -2143,7 +2215,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>BugFix: Various problems reading of files &gt; 2GB (GitHub #81)</li>
 <li>BugFix: Selecting files &quot;From MRU list&quot; again works correctly</li>
 </ul>
-<h3 id="translations-31">Translations</h3>
+<h3 id="translations-32">Translations</h3>
 <ul>
 <li>Update Italian translation (GitHub #86)</li>
 <li>Update Japanese translation (Bitbucket #3)</li>
@@ -2151,7 +2223,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Update German translation</li>
 <li>BugFix: Spanish translation error (Bitbucket Issue #108)</li>
 </ul>
-<h3 id="internals-17">Internals</h3>
+<h3 id="internals-18">Internals</h3>
 <ul>
 <li>Various diffengine and compilation/build fixes (GitHub #89,#90,#91,#92,#94)</li>
 </ul>
@@ -2160,7 +2232,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>BugFix: Dot icon in a drop-down menu is not drawn correctly</li>
 </ul>
-<h3 id="file-compare-32">File compare</h3>
+<h3 id="file-compare-33">File compare</h3>
 <ul>
 <li>BugFix: Crash when reading a file in Google Drive File Stream (sf.net#2206)</li>
 <li>BugFix: Crash when removing ghost lines (GitHub #80)</li>
@@ -2168,7 +2240,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Add Ctrl++/Ctrl+-(not numpad key) shortcut key to zoom in/out (sf.net#1727)</li>
 <li>Remove 2GB file size limit for 64-bit build (GitHub #81, #82)</li>
 </ul>
-<h3 id="folder-compare-28">Folder compare</h3>
+<h3 id="folder-compare-29">Folder compare</h3>
 <ul>
 <li>Add Pause button to Folder Compare Progress dialog (sf.net#828,#1222,#1237)</li>
 <li>Re-detect the file encoding when opening files (sf.net#2131)</li>
@@ -2186,22 +2258,22 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>BugFix: Garbled text was copied to the clipboard when generating a report on the clipboard (sf.net#2200)</li>
 </ul>
-<h3 id="plugins-19">Plugins</h3>
+<h3 id="plugins-20">Plugins</h3>
 <ul>
 <li>Add PrediffLineFilter.sct plugin</li>
 <li>Make ignored lines by Prediffer plugin colored</li>
 </ul>
-<h3 id="translations-32">Translations</h3>
+<h3 id="translations-33">Translations</h3>
 <ul>
 <li>Update Slovak translation (sf.net#2902)</li>
 <li>Update Portuguese translation (GitHub #84,#85)</li>
 </ul>
-<h3 id="internals-18">Internals</h3>
+<h3 id="internals-19">Internals</h3>
 <ul>
 <li>Adapt to VS2017 version 15.6.1 (GitHub #79)</li>
 </ul>
 <h2 id="winmerge-2153---2018-03-04">WinMerge 2.15.3 - 2018-03-04</h2>
-<h3 id="file-compare-33">File compare</h3>
+<h3 id="file-compare-34">File compare</h3>
 <ul>
 <li>Fix assertion error when started on Windows XP</li>
 <li>Fix a problem that moved blocks are sometimes shown as normal diff blocks</li>
@@ -2210,7 +2282,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Fix infinite loop when replacing ^ (sf.net#2094)</li>
 <li>Fix to show text that contains &amp; on message box, correctly (sf.net#2067)</li>
 </ul>
-<h3 id="folder-compare-29">Folder compare</h3>
+<h3 id="folder-compare-30">Folder compare</h3>
 <ul>
 <li>Fix a problem that unique files are invisible when comparing files using &#39;Date&#39; compare method</li>
 <li>Remove trailing garbage from a dragged text (Github#75)</li>
@@ -2227,7 +2299,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>Add support for HiDPI screens (Github #54)</li>
 </ul>
-<h3 id="plugins-20">Plugins</h3>
+<h3 id="plugins-21">Plugins</h3>
 <ul>
 <li>CompareMSExcelFiles.sct: Add &quot;Compare headers and footers&quot; checkbox to settings dialog (sf.net#2102)</li>
 </ul>
@@ -2236,7 +2308,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Remove extra space in installer: &quot; Launch WinMerge&quot; (sf.net#2144)</li>
 <li>Add &quot;How to Apply These Terms to Your New Programs&quot; section into GPL.rtf (sf.net#2098)</li>
 </ul>
-<h3 id="translations-33">Translations</h3>
+<h3 id="translations-34">Translations</h3>
 <ul>
 <li>Add Finnish translation (sf.net#3031)</li>
 <li>Add Sinhala translation (sf.net#3032)</li>
@@ -2275,7 +2347,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Show close button when hovering over tabs</li>
 <li>Add icons to each tab</li>
 </ul>
-<h3 id="options-dialog-18">Options dialog</h3>
+<h3 id="options-dialog-19">Options dialog</h3>
 <ul>
 <li>Add &quot;Close Select Files or Folders Dialog on clicking OK button&quot; checkbox to &quot;General&quot; page</li>
 <li>Add &quot;Language&quot; combobox to &quot;General&quot; page and remove Language dialog</li>
@@ -2299,7 +2371,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>Remove &quot;Add Shell menu to context menu&quot; from &quot;Shell Integration&quot; page (WinMerge now always adds shell menu to context menu in Folder window)</li>
 <li>Add &quot;Register shell extension&quot; button to &quot;Shell Integration&quot; page</li>
 </ul>
-<h3 id="folder-compare-30">Folder Compare</h3>
+<h3 id="folder-compare-31">Folder Compare</h3>
 <ul>
 <li>Add Multi-thread compare support for Full Contents or Quick Contents method</li>
 <li>Color the background of items in list view</li>
@@ -2320,7 +2392,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>BugFix: Properly handle 3-way comparison of Binary files (Github #23)</li>
 <li>BugFix: Use proper font for View&gt;Use Default Font menu item (GitHub #24)</li>
 </ul>
-<h3 id="file-compare-34">File Compare</h3>
+<h3 id="file-compare-35">File Compare</h3>
 <ul>
 <li>Add support for 3-way compare/merge</li>
 <li>Add &quot;Diff Context&quot; menu to View menu to adjust the number of displayed diff context lines</li>
@@ -2364,7 +2436,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>Accept drag&amp;droped files or folders from various places like: Zip folder, FTP folder, Recycle bin, images in Web browser</li>
 </ul>
-<h3 id="plugins-21">Plugins</h3>
+<h3 id="plugins-22">Plugins</h3>
 <ul>
 <li>Introduce new plugin type FILE_FOLDER_PACK_UNPACKER which allows unpacking data in a file to multiple files in a folder</li>
 <li>Use FILE_FOLDER_PACK_UNPACKER plugin for decompressing archives</li>
@@ -2389,7 +2461,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <li>64-bit version of WinMerge is available</li>
 <li>Install plugins by default</li>
 </ul>
-<h3 id="translations-34">Translations</h3>
+<h3 id="translations-35">Translations</h3>
 <ul>
 <li>Update Portuguese translation (GitHub #2-17)</li>
 <li>Update Korean translation (GitHub #45)</li>
@@ -2405,7 +2477,7 @@ Demo: <a href="https://i.gyazo.com/af18960bd1f121213a2cd9287cae9cf4.gif">https:/
 <ul>
 <li>Add support for jump list introduced in Windows 7</li>
 </ul>
-<h3 id="internals-19">Internals</h3>
+<h3 id="internals-20">Internals</h3>
 <ul>
 <li>Use POCO C++ libraries instead of pcre, expat and scew. They use pcre, expat internally</li>
 <li>Link statically with MFC and VC runtime libraries</li>
index 4450ee3..c5b1f67 100644 (file)
@@ -1,5 +1,87 @@
 # Change log
 
+## WinMerge 2.16.33 - 2023-09-20
+
+### General
+
+- Reduce startup time and decrease the usage of Win32 user objects.
+
+### File compare
+
+- BugFix: Cannot compare one-line file (#1972)
+- BugFix:  "Current Difference" specified by double-clicking cannot merge
+    using the "Copy to Right (or Left)" menu. (#1980)
+- BugFix: Wimerge saves changes to the wrong file (#1985) (PR #1988)
+- BugFix: "Ignore comment differences" still compares inline comments (#2008)
+- Update Rust syntax highlighting keyword list. (PR #1998)
+- [Feature Request] Both Shell Menu (#1986) (PR #2021)
+
+### Table compare
+
+- When "Use First Line as Header" is enabled, make the header display the
+    first line regardless of the scroll position when the first line is hidden.
+- Generate reports in tabular format for table comparisons. (PR #1983)
+
+### Folder compare
+
+- BugFix: Fixed an issue where Differences, Left/Right EOL columns, etc. were
+    displayed as undefined values when the file comparison method was
+    Full Contents or Quick Contents and the file size exceeded 64MB.
+- BugFix: Fix the problem that when comparing with the BinaryContents compare
+    method, the contents of the files are identical, but if one side is a
+    symbolic link, it is judged to be different. (#1976)
+- BugFix: Fixed an issue where values in the Left/Right EOL column may not
+    display correctly when using the Quick contents compare method.
+- Add Expand Different Subfolders menu item (#1382) (PR #1964)
+- Allow Diff algorithms (patience, histogram) other than default to be applied
+    to folder comparisons (PR #2015) (#2002)
+- Show confirmation message when closing a window that took a long time
+    to compare folders
+
+### Line filters
+
+- Improve line filters and substitution filters (PR #2032) (#796) (#1620)
+
+### Substitution filters
+
+- Avoid infinite loops in the RegularExpression::subst() function when 
+    the length of the string matching the pattern is 0
+- Improve line filters and substitution filters (PR #2032) (#796) (#1620)
+
+### Options dialog
+
+-  Execute the "pause" command to prevent the error message from disappearing
+     if the registration of the ShellExtension for Windows 11 fails
+
+### Plugins
+
+- BugFix: WinMerge cannot successfully disable some of its Plugins (#2012)
+- Update jq to version 1.7
+
+### Manual
+
+- Manual: Use po4a for manual translation (PR #1994) (#499)
+
+### Translations
+
+- Translation updates:
+  - Brazilian (PR #1969,#2001,#2025)
+  - Chinese Traditional (PR #1953,#1971,#2017,#2026)
+  - Corsican (PR #2022)
+  - German (PR #1952,#1977,#1989)
+  - Hungarian (PR #1968,#1999)
+  - Japanese
+  - Korean (PR #1979,#2030)
+  - Lithuanian (PR #1974,#2018,#2027)
+  - Polish (PR #1990)
+  - Portuguese (PR #1973,#2014)
+  - Slovenian
+  - Ukrainian (PR #1955)
+
+### Internals
+
+- Optimize inserts in std containers using reserve (PR #2000)
+
 ## WinMerge 2.16.32 - 2023-07-27
 
 ### General
index 81996dc..0b86151 100644 (file)
   <![endif]-->
 </head>
 <body>
-<h1 id="winmerge-21632-release-notes">WinMerge 2.16.32 Release Notes</h1>
+<h1 id="winmerge-21633-beta-release-notes">WinMerge 2.16.33 Beta Release Notes</h1>
 <ul>
 <li><a href="#about-this-release">About This Release</a></li>
-<li><a href="#what-is-new-in-21632">What Is New in 2.16.32?</a></li>
-<li><a href="#what-is-new-in-21631-beta">What Is New in 2.16.31 beta?</a></li>
+<li><a href="#what-is-new-in-21633-beta">What Is New in 2.16.33 beta?</a></li>
 <li><a href="#known-issues">Known issues</a></li>
 </ul>
-<p>July 2023</p>
+<p>September 2023</p>
 <h2 id="about-this-release">About This Release</h2>
-<p>This is a WinMerge 2.16.32 stable release. This release replaces earlier WinMerge stable releases as a recommended release.</p>
+<p>This is a WinMerge beta release which is meant for preview the current state of WinMerge development. This release is not recommended for the production.</p>
 <p>Please submit bug reports to our bug-tracker.</p>
-<h2 id="what-is-new-in-21632">What Is New in 2.16.32</h2>
+<h2 id="what-is-new-in-21633-beta">What Is New in 2.16.33 Beta</h2>
 <h3 id="general">General</h3>
 <ul>
-<li>BugFix: Export/Import settings bug with Substitution Filters (#1925)</li>
+<li>Reduce startup time and decrease the usage of Win32 user objects.</li>
 </ul>
 <h3 id="file-compare">File compare</h3>
 <ul>
-<li>BugFix: Save function doesn&#39;t work if the path length exceeds 248 characters (#1923)</li>
-<li>BugFix: Redundant confirmation &quot;The selected files are identical&quot; (#1902)</li>
-<li>Update Python syntax highlighting keyword list. (PR #1938)</li>
+<li>BugFix: Cannot compare one-line file (#1972)</li>
+<li>BugFix: &quot;Current Difference&quot; specified by double-clicking cannot merge using the &quot;Copy to Right (or Left)&quot; menu. (#1980)</li>
+<li>BugFix: Wimerge saves changes to the wrong file (#1985) (PR #1988)</li>
+<li>BugFix: &quot;Ignore comment differences&quot; still compares inline comments (#2008)</li>
+<li>Update Rust syntax highlighting keyword list. (PR #1998)</li>
+<li>[Feature Request] Both Shell Menu (#1986) (PR #2021)</li>
 </ul>
-<h3 id="folder-compare">Folder compare</h3>
-<ul>
-<li>BugFix: Treeview scrolls to the wrong position. (#1915)</li>
-<li>Allow changing the number of CPU cores to use while doing folder comparison (PR #1945)</li>
-</ul>
-<h3 id="webpage-compare">Webpage compare</h3>
-<ul>
-<li>Add support for generating report files (PR #1941)</li>
-</ul>
-<h3 id="command-line">Command line</h3>
+<h3 id="table-compare">Table compare</h3>
 <ul>
-<li>Compare folders recursively if &quot;Include subfolders&quot; is checked in the Options dialog even if the /r command line option is not specified. (PR #1914)</li>
+<li>When &quot;Use First Line as Header&quot; is enabled, make the header display the first line regardless of the scroll position when the first line is hidden.</li>
+<li>Generate reports in tabular format for table comparisons. (PR #1983)</li>
 </ul>
-<h3 id="archive-support">Archive support</h3>
-<ul>
-<li>Update 7-Zip to 23.01 (PR #1913)</li>
-</ul>
-<h3 id="translations">Translations</h3>
-<ul>
-<li>New translation: Tamil (PR #1946)</li>
-<li>Translation updates:
+<h3 id="folder-compare">Folder compare</h3>
 <ul>
-<li>Brazilian (PR #1948)</li>
-<li>Chinese Traditional (PR #1940)</li>
-<li>Corsican (PR #1933)</li>
-<li>French (PR #1927,#1928,#1951)</li>
-<li>Korean (PR #1908)</li>
-<li>Lithuanian (PR #1949)</li>
-<li>Portuguese (PR #1930)</li>
-<li>Slovenian</li>
-<li>Turkish (#1931)</li>
-</ul></li>
+<li>BugFix: Fixed an issue where Differences, Left/Right EOL columns, etc. were displayed as undefined values when the file comparison method was Full Contents or Quick Contents and the file size exceeded 64MB.</li>
+<li>BugFix: Fix the problem that when comparing with the BinaryContents compare method, the contents of the files are identical, but if one side is a symbolic link, it is judged to be different. (#1976)</li>
+<li>BugFix: Fixed an issue where values in the Left/Right EOL column may not display correctly when using the Quick contents compare method.</li>
+<li>Add Expand Different Subfolders menu item (#1382) (PR #1964)</li>
+<li>Allow Diff algorithms (patience, histogram) other than default to be applied to folder comparisons (PR #2015) (#2002)</li>
+<li>Show confirmation message when closing a window that took a long time to compare folders</li>
 </ul>
-<h2 id="what-is-new-in-21631-beta">What Is New in 2.16.31 Beta</h2>
-<h3 id="general-1">General</h3>
+<h3 id="line-filters">Line filters</h3>
 <ul>
-<li>BugFix: Some Substitution filter doesn&#39;t work (#1861)</li>
-<li>Add tasks to Jump List (PR #1828)</li>
-<li>Update DirCmpReport.cpp (PR #1892)</li>
+<li>Improve line filters and substitution filters (PR #2032) (#796) (#1620)</li>
 </ul>
-<h3 id="file-compare-1">File compare</h3>
+<h3 id="substitution-filters">Substitution filters</h3>
 <ul>
-<li>BugFix: Fix input range check processing in &quot;Go to&quot; dialog. (PR #1826)</li>
-<li>BugFix: End of line diff is a bit wanky (#1838, PR #1849)</li>
-<li>Confirm copy all in file merge (PR #1827)</li>
-<li>Modify the &quot;Go to&quot; dialog. (PR #1896)</li>
+<li>Avoid infinite loops in the RegularExpression::subst() function when the length of the string matching the pattern is 0</li>
+<li>Improve line filters and substitution filters (PR #2032) (#796) (#1620)</li>
 </ul>
-<h3 id="folder-compare-1">Folder compare</h3>
+<h3 id="options-dialog">Options dialog</h3>
 <ul>
-<li>BugFix: Display problem with Item totals : (#1840)</li>
-<li>BugFix: Bug in ignore whitespace ? (#1882)</li>
+<li>Execute the &quot;pause&quot; command to prevent the error message from disappearing if the registration of the ShellExtension for Windows 11 fails</li>
 </ul>
 <h3 id="plugins">Plugins</h3>
 <ul>
-<li>PrettifyJSON: Update jq to version 1.6 (#1871)</li>
-<li>Translate some plugin error messages (PR #1873)</li>
-<li>ApplyPatch: Update GNU patch to 2.7.6-1 (PR #1897)(#1871)</li>
+<li>BugFix: WinMerge cannot successfully disable some of its Plugins (#2012)</li>
+<li>Update jq to version 1.7</li>
 </ul>
-<h3 id="installer">Installer</h3>
+<h3 id="manual">Manual</h3>
 <ul>
-<li>Silent install blocked (#1852)</li>
+<li>Manual: Use po4a for manual translation (PR #1994) (#499)</li>
 </ul>
-<h3 id="translations-1">Translations</h3>
+<h3 id="translations">Translations</h3>
 <ul>
 <li>Translation updates:
 <ul>
-<li>Brazilian (PR #1829,#1837,#1876,#1903)</li>
-<li>Bulgarian (PR #1822)</li>
-<li>Chinese Simplified (PR #1835,#1846,#1885,#1906)</li>
-<li>Dutch (PR #1831)</li>
-<li>French (PR #1841,#1842,#1894)</li>
-<li>Galician (PR #1833)</li>
-<li>German (PR #1850,#1875,#1907)</li>
-<li>Hungarian (PR #1832,#1839,#1845,#1878,#1905)</li>
+<li>Brazilian (PR #1969,#2001,#2025)</li>
+<li>Chinese Traditional (PR #1953,#1971,#2017,#2026)</li>
+<li>Corsican (PR #2022)</li>
+<li>German (PR #1952,#1977,#1989)</li>
+<li>Hungarian (PR #1968,#1999)</li>
 <li>Japanese</li>
-<li>Korean (PR #1820,#1821,#1877)</li>
-<li>Lithuanian (PR #1847,#1889,#1904)</li>
-<li>Polish (PR #1869,#1870,#1884)</li>
-<li>Portuguese (PR #1843,#1895)</li>
-<li>Spanish (PR #1834)</li>
-<li>Russian (PR #1824,#1825,#1862)</li>
+<li>Korean (PR #1979,#2030)</li>
+<li>Lithuanian (PR #1974,#2018,#2027)</li>
+<li>Polish (PR #1990)</li>
+<li>Portuguese (PR #1973,#2014)</li>
+<li>Slovenian</li>
+<li>Ukrainian (PR #1955)</li>
 </ul></li>
 </ul>
+<h3 id="internals">Internals</h3>
+<ul>
+<li>Optimize inserts in std containers using reserve (PR #2000)</li>
+</ul>
 <h2 id="known-issues">Known issues</h2>
 <ul>
 <li>Suggestion to make the result of image comparison more reliable (#1391)</li>
index a0043ba..3e0a78a 100644 (file)
-# WinMerge 2.16.32 Release Notes
+# WinMerge 2.16.33 Beta Release Notes
 
 - [About This Release](#about-this-release)
-- [What Is New in 2.16.32?](#what-is-new-in-21632)
-- [What Is New in 2.16.31 beta?](#what-is-new-in-21631-beta)
+- [What Is New in 2.16.33 beta?](#what-is-new-in-21633-beta)
 - [Known issues](#known-issues)
 
-July 2023
+September 2023
 
 ## About This Release
 
-This is a WinMerge 2.16.32 stable release.
-This release replaces earlier WinMerge stable releases as a recommended release.
+This is a WinMerge beta release which is meant for preview the current state of
+WinMerge development. This release is not recommended for the production.
 
 Please submit bug reports to our bug-tracker.
 
-## What Is New in 2.16.32
+## What Is New in 2.16.33 Beta
 
 ### General
 
-- BugFix: Export/Import settings bug with Substitution Filters (#1925)
+- Reduce startup time and decrease the usage of Win32 user objects.
 
 ### File compare
 
-- BugFix: Save function doesn't work if the path length exceeds 248
-    characters (#1923)
-- BugFix: Redundant confirmation "The selected files are identical" (#1902)
-- Update Python syntax highlighting keyword list. (PR #1938)
+- BugFix: Cannot compare one-line file (#1972)
+- BugFix:  "Current Difference" specified by double-clicking cannot merge
+    using the "Copy to Right (or Left)" menu. (#1980)
+- BugFix: Wimerge saves changes to the wrong file (#1985) (PR #1988)
+- BugFix: "Ignore comment differences" still compares inline comments (#2008)
+- Update Rust syntax highlighting keyword list. (PR #1998)
+- [Feature Request] Both Shell Menu (#1986) (PR #2021)
 
-### Folder compare
-
-- BugFix: Treeview scrolls to the wrong position. (#1915)
-- Allow changing the number of CPU cores to use while doing folder comparison
-    (PR #1945)
-
-### Webpage compare
-
-- Add support for generating report files (PR #1941)
-
-### Command line
+### Table compare
 
-- Compare folders recursively if "Include subfolders" is checked in the
-    Options dialog even if the /r command line option is not specified.
-    (PR #1914)
+- When "Use First Line as Header" is enabled, make the header display the
+    first line regardless of the scroll position when the first line is hidden.
+- Generate reports in tabular format for table comparisons. (PR #1983)
 
-### Archive support
-
-- Update 7-Zip to 23.01 (PR #1913)
-
-### Translations
-
-- New translation: Tamil (PR #1946)
-- Translation updates:
-  - Brazilian (PR #1948)
-  - Chinese Traditional (PR #1940)
-  - Corsican (PR #1933)
-  - French (PR #1927,#1928,#1951)
-  - Korean (PR #1908)
-  - Lithuanian (PR #1949)
-  - Portuguese (PR #1930)
-  - Slovenian
-  - Turkish (#1931)
+### Folder compare
 
-## What Is New in 2.16.31 Beta
+- BugFix: Fixed an issue where Differences, Left/Right EOL columns, etc. were
+    displayed as undefined values when the file comparison method was
+    Full Contents or Quick Contents and the file size exceeded 64MB.
+- BugFix: Fix the problem that when comparing with the BinaryContents compare
+    method, the contents of the files are identical, but if one side is a
+    symbolic link, it is judged to be different. (#1976)
+- BugFix: Fixed an issue where values in the Left/Right EOL column may not
+    display correctly when using the Quick contents compare method.
+- Add Expand Different Subfolders menu item (#1382) (PR #1964)
+- Allow Diff algorithms (patience, histogram) other than default to be applied
+    to folder comparisons (PR #2015) (#2002)
+- Show confirmation message when closing a window that took a long time
+    to compare folders
 
-### General
+### Line filters
 
-- BugFix: Some Substitution filter doesn't work (#1861)
-- Add tasks to Jump List (PR #1828)
-- Update DirCmpReport.cpp (PR #1892)
+- Improve line filters and substitution filters (PR #2032) (#796) (#1620)
 
-### File compare
+### Substitution filters
 
-- BugFix: Fix input range check processing in "Go to" dialog. (PR #1826)
-- BugFix: End of line diff is a bit wanky (#1838, PR #1849)
-- Confirm copy all in file merge (PR #1827)
-- Modify the "Go to" dialog. (PR #1896)
+- Avoid infinite loops in the RegularExpression::subst() function when 
+    the length of the string matching the pattern is 0
+- Improve line filters and substitution filters (PR #2032) (#796) (#1620)
 
-### Folder compare
+### Options dialog
 
-- BugFix: Display problem with Item totals : (#1840)
-- BugFix: Bug in ignore whitespace ? (#1882)
+-  Execute the "pause" command to prevent the error message from disappearing
+     if the registration of the ShellExtension for Windows 11 fails
 
 ### Plugins
 
-- PrettifyJSON: Update jq to version 1.6 (#1871)
-- Translate some plugin error messages (PR #1873)
-- ApplyPatch: Update GNU patch to 2.7.6-1 (PR #1897)(#1871)
+- BugFix: WinMerge cannot successfully disable some of its Plugins (#2012)
+- Update jq to version 1.7
 
-### Installer
+### Manual
 
-- Silent install blocked (#1852)
+- Manual: Use po4a for manual translation (PR #1994) (#499)
 
 ### Translations
 
 - Translation updates:
-  - Brazilian (PR #1829,#1837,#1876,#1903)
-  - Bulgarian (PR #1822)
-  - Chinese Simplified (PR #1835,#1846,#1885,#1906)
-  - Dutch (PR #1831)
-  - French (PR #1841,#1842,#1894)
-  - Galician (PR #1833)
-  - German (PR #1850,#1875,#1907)
-  - Hungarian (PR #1832,#1839,#1845,#1878,#1905)
+  - Brazilian (PR #1969,#2001,#2025)
+  - Chinese Traditional (PR #1953,#1971,#2017,#2026)
+  - Corsican (PR #2022)
+  - German (PR #1952,#1977,#1989)
+  - Hungarian (PR #1968,#1999)
   - Japanese
-  - Korean (PR #1820,#1821,#1877)
-  - Lithuanian (PR #1847,#1889,#1904)
-  - Polish (PR #1869,#1870,#1884)
-  - Portuguese (PR #1843,#1895)
-  - Spanish (PR #1834)
-  - Russian (PR #1824,#1825,#1862)
+  - Korean (PR #1979,#2030)
+  - Lithuanian (PR #1974,#2018,#2027)
+  - Polish (PR #1990)
+  - Portuguese (PR #1973,#2014)
+  - Slovenian
+  - Ukrainian (PR #1955)
+
+### Internals
+
+- Optimize inserts in std containers using reserve (PR #2000)
+
 
 ## Known issues
 
index fd4c65f..d33c6a1 100644 (file)
@@ -29,8 +29,8 @@ https://github.com/WinMerge/winwebdiff/releases/download/v1.0.7/winwebdiff-1.0.7
 https://github.com/WinMerge/winwebdiff/releases/download/v1.0.7/winwebdiff-1.0.7.0-ARM64.zip!Build\ARM64\Release ^
 https://github.com/htacg/tidy-html5/releases/download/5.4.0/tidy-5.4.0-w32-mt-XP.zip!Build\tidy-html5 ^
 https://github.com/htacg/tidy-html5/archive/refs/tags/5.4.0.zip!Build\tidy-html5 ^
-https://github.com/stedolan/jq/releases/download/jq-1.6/jq-win32.exe!Build\jq ^
-https://github.com/stedolan/jq/archive/refs/tags/jq-1.6.zip!Build\jq ^
+https://github.com/jqlang/jq/releases/download/jq-1.7/jq-win32.exe!Build\jq ^
+https://github.com/jqlang/jq/archive/refs/tags/jq-1.7.zip!Build\jq ^
 https://github.com/facebook/zstd/releases/download/v1.5.2/zstd-v1.5.2-win64.zip!Build\zstd ^
 https://mirror.msys2.org/mingw/mingw32/mingw-w64-i686-md4c-0.4.8-2-any.pkg.tar.zst!Build\md4c ^
 https://mirror.msys2.org/msys/i686/gcc-libs-10.2.0-1-i686.pkg.tar.zst!Build\msys2_tmp ^
index 1bf5098..6e2b1db 100644 (file)
@@ -2491,7 +2491,8 @@ GetTopMarginText (const CRect& rect, CString& text, std::vector<int>& nWidths)
     {
       int nColumnWidth = m_pTextBuffer->GetColumnWidth (nColumn);
       CString columnName;
-      if (m_nTopSubLine > 0 && m_nLineNumberUsedAsHeaders >= 0 && m_nLineNumberUsedAsHeaders < m_pTextBuffer->GetLineCount())
+      if (m_nLineNumberUsedAsHeaders >= 0 && m_nLineNumberUsedAsHeaders < m_pTextBuffer->GetLineCount() && 
+          (m_nTopSubLine > 0 || (m_pTextBuffer->GetLineFlags(m_nLineNumberUsedAsHeaders) & LF_INVISIBLE)))
         columnName = replaceControlChars (m_pTextBuffer->GetCellText (m_nLineNumberUsedAsHeaders, nColumn).c_str ()); // Use std::basic_string<tchar_t> instead of CString
       if (columnName.IsEmpty())
         columnName = GetColumnName (nColumn);
index 2e01ff1..11c528d 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2e01ff1fb69609540b2bdc4e62a60499f2b2fb8e
+Subproject commit 11c528d04d76c9b9553781aa76b073e4f40da008
index 43fadd9..97aabde 100644 (file)
@@ -18,6 +18,6 @@ This file lists versions of the external components we are using.
 - 7-zip: 23.01
 - LibXDiff: 611e42a on Nov 2, 2018 (https://github.com/git/git/tree/master/xdiff)
 - html-tidy5: 5.4.0
-- jq: 1.6
+- jq: 1.7
 - wil: 209ff9c7e30e71bf6d1405557bf78544920f8157 on Sep 9, 2021
 - md4c: 0.4.8
index b84d709..ef922ba 100644 (file)
@@ -621,7 +621,7 @@ Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flag
 Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Plugins
 ; jq
 Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Plugins
-Source: ..\..\Build\jq\jq-jq-1.6\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins
+Source: ..\..\Build\jq\jq-jq-1.7\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins
 ; md4c
 Source: ..\..\Build\md4c\mingw32\bin\*.*; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins
 Source: ..\..\Build\md4c\mingw32\share\licenses\md4c\LICENSE.md; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins
index a28b27f..ae7f90a 100644 (file)
@@ -620,7 +620,7 @@ Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flag
 Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Plugins\r
 ; jq\r
 Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Plugins\r
-Source: ..\..\Build\jq\jq-jq-1.6\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
+Source: ..\..\Build\jq\jq-jq-1.7\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
 ; md4c\r
 Source: ..\..\Build\md4c\mingw32\bin\*.*; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
 Source: ..\..\Build\md4c\mingw32\share\licenses\md4c\LICENSE.md; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
index dae159e..086c789 100644 (file)
@@ -612,7 +612,7 @@ Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flag
 Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Plugins\r
 ; jq\r
 Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Plugins\r
-Source: ..\..\Build\jq\jq-jq-1.6\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
+Source: ..\..\Build\jq\jq-jq-1.7\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
 ; md4c\r
 Source: ..\..\Build\md4c\mingw32\bin\*.*; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
 Source: ..\..\Build\md4c\mingw32\share\licenses\md4c\LICENSE.md; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
index c131b65..a7db29f 100644 (file)
@@ -611,7 +611,7 @@ Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flag
 Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Plugins
 ; jq
 Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Plugins
-Source: ..\..\Build\jq\jq-jq-1.6\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins
+Source: ..\..\Build\jq\jq-jq-1.7\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins
 ; md4c
 Source: ..\..\Build\md4c\mingw32\bin\*.*; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins
 Source: ..\..\Build\md4c\mingw32\share\licenses\md4c\LICENSE.md; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins
index 1c76a2e..18c717c 100755 (executable)
@@ -636,7 +636,7 @@ Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flag
 Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Plugins\r
 ; jq\r
 Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Plugins\r
-Source: ..\..\Build\jq\jq-jq-1.6\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
+Source: ..\..\Build\jq\jq-jq-1.7\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Plugins\r
 ; md4c\r
 Source: ..\..\Build\md4c\mingw32\bin\*.*; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
 Source: ..\..\Build\md4c\mingw32\share\licenses\md4c\LICENSE.md; DestDir: {app}\Commands\md4c; Flags: recursesubdirs; Components: Plugins\r
index b416b4c..efa78ed 100644 (file)
@@ -1,8 +1,8 @@
 set MAJOR=2
 set MINOR=16
 set REVISION=32
-set PATCHLEVEL=2
-set STRPRIVATEBUILD="jp-2"
+set PATCHLEVEL=3
+set STRPRIVATEBUILD="jp-3"
 
 set RCVER=%MAJOR%.%MINOR%.%REVISION%.%PATCHLEVEL%
 rem set STRVER=%MAJOR%.%MINOR%.%REVISION%.%PATCHLEVEL%
index bf1ee90..0a464e8 100644 (file)
 #include "pch.h"
 #include "ShellContextMenu.h"
 #include "PidlContainer.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
+#include <Shlwapi.h>
 
 CShellContextMenu::CShellContextMenu(UINT cmdFirst, UINT cmdLast)
 : m_pPreferredMenu(nullptr)
@@ -45,15 +42,15 @@ void CShellContextMenu::Initialize()
        m_files.clear();
 }
 
-void CShellContextMenu::AddItem(const FileEntry& fileEntry)
+void CShellContextMenu::AddItem(const std::wstring& fullpath)
 {
-       m_files.insert(m_files.end(), fileEntry);
+       m_files.insert(m_files.end(), fullpath);
 }
 
-void CShellContextMenu::AddItem(const String& path,
-                                                               const String& filename)
+void CShellContextMenu::AddItem(const std::wstring& path,
+                                                               const std::wstring& filename)
 {
-       AddItem(FileEntry(path, filename));
+       AddItem(path + L"\\" + filename);
 }
 
 HMENU CShellContextMenu::GetHMENU() const
@@ -109,6 +106,20 @@ bool CShellContextMenu::HandleMenuMessage(UINT message, WPARAM wParam, LPARAM lP
        return false;
 }
 
+static HRESULT _stdcall dfmCallback(IShellFolder* /*psf*/, HWND /*hwnd*/, IDataObject* /*pdtobj*/, UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
+{
+       switch (uMsg)
+       {
+       case DFM_MERGECONTEXTMENU:
+               return S_OK;
+       case DFM_INVOKECOMMAND:
+       case DFM_INVOKECOMMANDEX:
+       case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
+               return S_FALSE;
+       }
+       return E_NOTIMPL;
+}
+
 bool CShellContextMenu::QueryShellContextMenu()
 {
        //HRESULT hr = E_FAIL;
@@ -116,56 +127,22 @@ bool CShellContextMenu::QueryShellContextMenu()
        if (FAILED(/*hr = */SHGetDesktopFolder(&pDesktop)))
                return false;
 
-       String parentDir; // use it to track that all selected files are in the same parent directory
-       IShellFolderPtr pCurrFolder;
        CPidlContainer pidls;
 
        for (FilenamesContainer::const_iterator iter = m_files.begin(); iter != m_files.end(); ++iter)
        {
-               const FileEntry& file = *iter;
-
-               String currentDir = file.path;
-
-               if (parentDir.empty()) // first iteration, initialize parentDir and pCurrFolder
-               {
-                       parentDir = currentDir;
-
-                       LPITEMIDLIST dirPidl;
-                       if (FAILED(/*hr = */pDesktop->ParseDisplayName(nullptr,                            // hwnd
-                                                                                                          nullptr,                                        // pbc
-                                                                                                          const_cast<wchar_t *>(currentDir.c_str()),   // pszDisplayName
-                                                                                                          nullptr,                                        // pchEaten
-                                                                                                          &dirPidl,                               // ppidl
-                                                                                                          nullptr                                         // pdwAttributes
-                                                                                                          )))
-                       {
-                               return false;
-                       }
-
-                       if (FAILED(/*hr = */pDesktop->BindToObject(dirPidl,                      // pidl
-                                                                                                  nullptr,                              // pbc
-                                                                                                  IID_IShellFolder,     // riid
-                                                                                                  reinterpret_cast<void**>(&pCurrFolder))))
-                       {
-                               return false;
-                       }
-               }
-               else if (currentDir != parentDir) // check whether file belongs to the same parentDir, break otherwise
-               {
-                       return false;
-               }
-
+               const std::wstring& path = *iter;
                LPITEMIDLIST pidl;
-               if (FAILED(/*hr = */pCurrFolder->ParseDisplayName(nullptr,
-                                                                                                         nullptr,
-                                                                                                         const_cast<wchar_t *>(file.filename.c_str()), 
-                                                                                                         nullptr,
-                                                                                                         &pidl,
-                                                                                                         nullptr)))
+               if (FAILED(/*hr = */pDesktop->ParseDisplayName(nullptr,                            // hwnd
+                                                                                                  nullptr,                                        // pbc
+                                                                                                  const_cast<wchar_t *>(path.c_str()), // pszDisplayName
+                                                                                                  nullptr,                                        // pchEaten
+                                                                                                  &pidl,                                          // ppidl
+                                                                                                  nullptr                                         // pdwAttributes
+                                                                                                  )))
                {
                        return false;
                }
-               
                pidls.Add(pidl);
        } // for (FilenamesContainer::const_iterator iter = m_files.begin(); iter != m_files.end(); ++iter)
        
@@ -174,13 +151,37 @@ bool CShellContextMenu::QueryShellContextMenu()
                return false;
        }
 
+       // The following was created with reference to https://github.com/stefankueng/grepWin/blob/main/src/ShellContextMenu.cpp.
+       HKEY ahkeys[16]{};
+       int nKeys = 0;
+       const std::wstring& path = m_files.front();
+       nKeys += RegOpenKey(HKEY_CLASSES_ROOT, L"*", &ahkeys[nKeys]) == ERROR_SUCCESS ? 1 : 0;
+       nKeys += RegOpenKey(HKEY_CLASSES_ROOT, L"AllFileSystemObjects", &ahkeys[nKeys]) == ERROR_SUCCESS ? 1 : 0;
+       if (PathIsDirectory(path.c_str()))
+       {
+               nKeys += RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", &ahkeys[nKeys]) == ERROR_SUCCESS ? 1 : 0;
+               nKeys += RegOpenKey(HKEY_CLASSES_ROOT, L"Directory", &ahkeys[nKeys]) == ERROR_SUCCESS ? 1 : 0;
+       }
+       HKEY hkey;
+       const wchar_t* ext = PathFindExtension(path.c_str());
+       if (ext && *ext == '.' && RegOpenKey(HKEY_CLASSES_ROOT, ext, &hkey) == ERROR_SUCCESS)
+       {
+               wchar_t buf[MAX_PATH] = { 0 };
+               DWORD dwSize = MAX_PATH;
+               if (RegQueryValueEx(hkey, L"", nullptr, nullptr, reinterpret_cast<LPBYTE>(buf), &dwSize) == ERROR_SUCCESS)
+                       nKeys += RegOpenKey(HKEY_CLASSES_ROOT, buf, &ahkeys[nKeys]) == ERROR_SUCCESS ? 1 : 0;
+               RegCloseKey(hkey);
+       }
+
        IContextMenuPtr pCMenu1;
-       if (FAILED(/*hr = */pCurrFolder->GetUIObjectOf(nullptr,
-                                                                                          static_cast<unsigned>(pidls.Size()),
-                                                                                          pidls.GetList(),
-                                                                                          IID_IContextMenu,
-                                                                                          0, 
-                                                                                          reinterpret_cast<void**>(&pCMenu1))))
+       HRESULT hr = CDefFolderMenu_Create2(nullptr, nullptr,
+               static_cast<unsigned>(pidls.Size()),
+               pidls.GetList(), pDesktop, dfmCallback, nKeys, ahkeys, &pCMenu1);
+
+       for (int i = 0; i < nKeys; ++i)
+               RegCloseKey(ahkeys[i]);
+
+       if (FAILED(hr))
        {
                return false;
        }
index 7c16e7b..581d9ae 100644 (file)
@@ -16,7 +16,6 @@
 #pragma warning (pop)
 #include <comdef.h>
 #include <list>
-#include "UnicodeString.h"
 
 struct __declspec(uuid("000214e4-0000-0000-c000-000000000046")) IContextMenu;
 struct __declspec(uuid("000214f4-0000-0000-c000-000000000046")) IContextMenu2;
@@ -55,17 +54,6 @@ class CShellContextMenu
 {
 public:
        /**
-        * @brief       Helper describing file entry in the group of files to show shell context menu for
-        */
-       struct FileEntry
-       {
-               FileEntry(const String& aPath, const String& aFilename)
-                       : path(aPath), filename(aFilename) {}
-               String path; /**< path to file, including all but file name */
-               String filename; /**< file name */
-       };
-
-       /**
         * @brief Constructor
         *
         * @param[in]   cmdFirst        minimum value for a menu item identifier
@@ -92,9 +80,9 @@ public:
        /**
         * @brief       Adds a file to a group of files for which shell context menu is queried
         *
-        * @param[in]   fileEntry       FileEntry object describing a file to add
+        * @param[in]   fullpath        Full path to file to set to item.
         */
-       void AddItem(const FileEntry& fileEntry);
+       void AddItem(const std::wstring& fullpath);
 
        /**
         * @brief       Adds a file to a group of files for which shell context menu is queried
@@ -102,8 +90,8 @@ public:
         * @param[in]   path            path to file, including all but file name
         * @param[in]   filename        file name without path
         */
-       void AddItem(const String& path,
-                                const String& filename);
+       void AddItem(const std::wstring& path,
+                                const std::wstring& filename);
 
        /**
         * @brief       Returns HMENU handle to context menu
@@ -167,7 +155,7 @@ private:
        bool QueryShellContextMenu();
 
 private:
-       typedef std::list<FileEntry> FilenamesContainer;
+       typedef std::list<std::wstring> FilenamesContainer;
 
        FilenamesContainer m_files; /**< List of files to show context menu for */
 
index 40e9534..e6d7a72 100644 (file)
@@ -353,7 +353,8 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers(
                                        if ((!m_eol0 || !m_eol1) && (orig0 == end0 || orig1 == end1))
                                        {
                                                // one side had an end-of-line, but the other didn't
-                                               return RESULT_DIFF;
+                                               result = RESULT_DIFF;
+                                               goto exit;
                                        }
                                        if (ptr0 != end0 && ptr1 != end1)
                                                // This continue statement is needed to handle blank lines
@@ -383,7 +384,10 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers(
                                if (!eof0 || !eof1)
                                        goto need_more;
                                else
-                                       return RESULT_SAME;
+                               {
+                                       result = RESULT_SAME;
+                                       goto exit;
+                               }
                        }
                        else
                        {
@@ -393,7 +397,10 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers(
                                        goto need_more;
                                }
                                else
-                                       return RESULT_DIFF;
+                               {
+                                       result = RESULT_DIFF;
+                                       goto exit;
+                               }
                        }
                }
 
@@ -404,7 +411,10 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers(
                        c1 = tc::istupper(c1) ? tc::totlower(c1) : c1;
                }
                if (c0 != c1)
-                       return RESULT_DIFF; // buffers are different
+               {
+                       result = RESULT_DIFF; // buffers are different
+                       goto exit;
+               }
                if (ptr0 < end0 && ptr1 < end1)
                {
                        m_bol0 = iseolch(c0);
@@ -417,14 +427,8 @@ ByteComparator::COMP_RESULT ByteComparator::CompareBuffers(
        }
 
 need_more:
-       if (ptr0 - 1 >= orig0 && *(ptr0 - 1) == '\r')
-               m_cr0 = true;
-       else
-               m_cr0 = false;
-       if (ptr1 - 1 >= orig1 && *(ptr1 - 1) == '\r')
-               m_cr1 = true;
-       else
-               m_cr1 = false;
+       m_cr0 = (ptr0 - 1 >= orig0 && *(ptr0 - 1) == '\r');
+       m_cr1 = (ptr1 - 1 >= orig1 && *(ptr1 - 1) == '\r');
        if (ptr0 == end0 && !eof0)
        {
                if (ptr1 == end1 && !eof1)
@@ -440,6 +444,11 @@ need_more:
        {
                return result;
        }
+
+exit:
+       m_cr0 = (end0 > orig0) && *(end0 - 1) == '\r';
+       m_cr1 = (end1 > orig1) && *(end1 - 1) == '\r';
+       return result;
 }
 
 /**
index 9e285fe..c0f2b80 100644 (file)
@@ -15,6 +15,7 @@
 #include "DiffContext.h"
 #include "diff.h"
 #include "ByteComparator.h"
+#include "DiffFileData.h"
 
 namespace CompareEngines
 {
@@ -24,15 +25,12 @@ static const int KILO = 1024; // Kilo(byte)
 /** @brief Quick contents compare's file buffer size. */
 static const int WMCMPBUFF = 32 * KILO;
 
-static void CopyTextStats(const FileTextStats * stats, FileTextStats * myTextStats);
-
 /**
  * @brief Default constructor.
  */
 ByteCompare::ByteCompare()
                : m_pOptions(nullptr)
                , m_piAbortable(nullptr)
-               , m_inf(nullptr)
 {
 }
 
@@ -69,29 +67,14 @@ void ByteCompare::SetAbortable(const IAbortable * piAbortable)
 }
 
 /**
- * @brief Set filedata.
- * @param [in] items Count of filedata items to set.
- * @param [in] data File data.
- * @note Path names are set by SetPaths() function.
- */
-void ByteCompare::SetFileData(int items, file_data *data)
-{
-       // We support only two files currently!
-       assert(items == 2);
-       m_inf = data;
-       m_textStats[0].clear();
-       m_textStats[1].clear();
-}
-
-
-/**
  * @brief Compare two specified files, byte-by-byte
- * @param [in] bStopAfterFirstDiff Stop compare after we find first difference?
- * @param [in] piAbortable Interface allowing to abort compare
  * @return DIFFCODE
  */
-int ByteCompare::CompareFiles(FileLocation *location)
+int ByteCompare::CompareFiles(DiffFileData* diffData)
 {
+       diffData->m_textStats[0].clear();
+       diffData->m_textStats[1].clear();
+
        // TODO
        // Right now, we assume files are in 8-bit encoding
        // because transform code converted any UCS-2 files to UTF-8
@@ -137,18 +120,18 @@ int ByteCompare::CompareFiles(FileLocation *location)
                        {
                                // Assume our blocks are in range of int
                                int space = sizeof(buff[i])/sizeof(buff[i][0]) - (int) bfend[i];
-                               int rtn = cio::read_i(m_inf[i].desc, &buff[i][bfend[i]], space);
+                               int rtn = cio::read_i(diffData->m_inf[i].desc, &buff[i][bfend[i]], space);
                                if (rtn == -1)
                                        return DIFFCODE::CMPERR;
                                if (rtn < space)
                                        eof[i] = true;
                                bfend[i] += rtn;
-                               if (m_inf[0].desc == m_inf[1].desc)
+                               if (diffData->m_inf[0].desc == diffData->m_inf[1].desc)
                                {
                                        bfstart[1] = bfstart[0];
                                        bfend[1] = bfend[0];
                                        eof[1] = eof[0];
-                                       location[1] = location[0];
+                                       diffData->m_FileLocation[1] = diffData->m_FileLocation[0];
                                        memcpy(&buff[1][bfend[1] - rtn], &buff[0][bfend[0] - rtn], rtn);
                                        break;
                                }
@@ -170,7 +153,7 @@ int ByteCompare::CompareFiles(FileLocation *location)
                int64_t offset1 = (ptr1 - &buff[1][0]);
 
                // are these two buffers the same?
-               int result = comparator.CompareBuffers(m_textStats[0], m_textStats[1],
+               int result = comparator.CompareBuffers(diffData->m_textStats[0], diffData->m_textStats[1],
                                ptr0, ptr1, end0, end1, eof[0], eof[1], offset0, offset1);
                if (result == ByteComparator::RESULT_DIFF)
                {
@@ -253,8 +236,8 @@ int ByteCompare::CompareFiles(FileLocation *location)
                // then the result is reliable.
                if (eof[0] && eof[1])
                {
-                       bool bBin0 = (m_textStats[0].nzeros > 0);
-                       bool bBin1 = (m_textStats[1].nzeros > 0);
+                       bool bBin0 = (diffData->m_textStats[0].nzeros > 0);
+                       bool bBin1 = (diffData->m_textStats[1].nzeros > 0);
 
                        if (bBin0 && bBin1)
                                diffcode |= DIFFCODE::BIN | DIFFCODE::BINSIDE1 | DIFFCODE::BINSIDE2;
@@ -277,25 +260,4 @@ int ByteCompare::CompareFiles(FileLocation *location)
        return diffcode;
 }
 
-/**
- * @brief Copy text stat results from diffutils back into the FileTextStats structure
- */
-static void CopyTextStats(const FileTextStats * stats, FileTextStats * myTextStats)
-{
-       myTextStats->ncrlfs = stats->ncrlfs;
-       myTextStats->ncrs = stats->ncrs;
-       myTextStats->nlfs = stats->nlfs;
-       myTextStats->nzeros = stats->nzeros;
-}
-
-/**
- * @brief Return text statistics for last compare.
- * @param [in] side For which file to return statistics.
- * @param [out] stats Stats as asked.
- */
-void ByteCompare::GetTextStats(int side, FileTextStats *stats) const
-{
-       CopyTextStats(&m_textStats[side], stats);
-}
-
 } // namespace CompareEngines
index 39bac53..154ca2a 100644 (file)
@@ -11,8 +11,7 @@
 class CompareOptions;
 class QuickCompareOptions;
 class IAbortable;
-struct FileLocation;
-struct file_data;
+struct DiffFileData;
 
 namespace CompareEngines
 {
@@ -31,16 +30,12 @@ public:
        void SetCompareOptions(const CompareOptions & options);
        void SetAdditionalOptions(bool stopAfterFirstDiff);
        void SetAbortable(const IAbortable * piAbortable);
-       void SetFileData(int items, file_data *data);
-       int CompareFiles(FileLocation *location);
-       void GetTextStats(int side, FileTextStats *stats) const;
+
+       int CompareFiles(DiffFileData* diffData);
 
 private:
        std::unique_ptr<QuickCompareOptions> m_pOptions; /**< Compare options for diffutils. */
        IAbortable * m_piAbortable;
-       file_data * m_inf; /**< Compared files data (for diffutils). */
-       FileTextStats m_textStats[2];
-
 };
 
 } // namespace CompareEngines
index 3f3e625..be9b6c4 100644 (file)
 #include "coretools.h"
 #include "DiffList.h"
 #include "DiffWrapper.h"
+#include "xdiff_gnudiff_compat.h"
 #include "unicoder.h"
+#include "DiffFileData.h"
 
 namespace CompareEngines
 {
-static void CopyTextStats(const file_data * inf, FileTextStats * myTextStats);
 
 /**
  * @brief Default constructor.
  */
 DiffUtils::DiffUtils()
-               : m_pOptions(nullptr)
-               , m_inf(nullptr)
-               , m_pDiffWrapper(new ::CDiffWrapper)
+               :  m_pDiffWrapper(new ::CDiffWrapper)
                , m_ndiffs(0)
                , m_ntrivialdiffs(0)
 {
@@ -48,10 +47,11 @@ DiffUtils::~DiffUtils()
  * @brief Set compare options from general compare options.
  * @param [in ]options General compare options.
  */
-void DiffUtils::SetCompareOptions(const CompareOptions & options)
+void DiffUtils::SetCompareOptions(const CompareOptions& options)
 {
-       m_pOptions.reset(new DiffutilsOptions(static_cast<const DiffutilsOptions&>(options)));
-       m_pOptions->SetToDiffUtils();
+       DIFFOPTIONS doptions;
+       static_cast<const DiffutilsOptions&>(options).GetAsDiffOptions(doptions);
+       m_pDiffWrapper->SetOptions(&doptions);
 }
 
 /**
@@ -88,29 +88,17 @@ void DiffUtils::SetCodepage(int codepage)
 }
 
 /**
- * @brief Set filedata.
- * @param [in] items Count of filedata items to set.
- * @param [in] data File data.
- */
-void DiffUtils::SetFileData(int items, file_data *data)
-{
-       // We support only two files currently!
-       assert(items == 2);
-       m_inf = data;
-}
-
-/**
  * @brief Compare two files (as earlier specified).
  * @return DIFFCODE as a result of compare.
  */
-int DiffUtils::diffutils_compare_files()
+int DiffUtils::CompareFiles(DiffFileData* diffData)
 {
        int bin_flag = 0;
        int bin_file = 0; // bitmap for binary files
 
        // Do the actual comparison (generating a change script)
        struct change *script = nullptr;
-       bool success = Diff2Files(&script, 0, &bin_flag, false, &bin_file);
+       bool success = m_pDiffWrapper->Diff2Files(&script, diffData, & bin_flag, & bin_file);
        if (!success)
        {
                return DIFFCODE::FILE | DIFFCODE::TEXT | DIFFCODE::CMPERR;
@@ -124,19 +112,16 @@ int DiffUtils::diffutils_compare_files()
 
        if (script != nullptr)
        {
-               const bool usefilters = m_pOptions->m_filterCommentsLines ||
+               const bool usefilters = m_pDiffWrapper->GetOptions().m_filterCommentsLines ||
                        (m_pDiffWrapper->GetFilterList() && m_pDiffWrapper->GetFilterList()->HasRegExps()) ||
                        (m_pDiffWrapper->GetSubstitutionList() && m_pDiffWrapper->GetSubstitutionList()->HasRegExps());
        
                PostFilterContext ctxt{};
-               String Ext = ucr::toTString(m_inf[0].name);
+               String Ext = ucr::toTString(diffData->m_inf[0].name);
                size_t PosOfDot = Ext.rfind('.');
                if (PosOfDot != String::npos)
                        Ext.erase(0, PosOfDot + 1);
 
-               DIFFOPTIONS options = {0};
-               m_pOptions->GetAsDiffOptions(options);
-               m_pDiffWrapper->SetOptions(&options);
                m_pDiffWrapper->SetFilterCommentsSourceDef(Ext);
 
                struct change *next = script;
@@ -158,33 +143,20 @@ int DiffUtils::diffutils_compare_files()
                        {
                                /* Determine range of line numbers involved in each file.  */
                                int first0 = 0, last0 = 0, first1 = 0, last1 = 0, deletes = 0, inserts = 0;
-                               analyze_hunk (thisob, &first0, &last0, &first1, &last1, &deletes, &inserts, m_inf);
+                               analyze_hunk (thisob, &first0, &last0, &first1, &last1, &deletes, &inserts, diffData->m_inf);
+
+                               /* Reconnect the script so it will all be freed properly.  */
+                               end->link = next;
+
                                if (deletes!=0 || inserts!=0 || thisob->trivial!=0)
                                {
-                                       /* Print the lines that the first file has.  */
-                                       int trans_a0 = 0, trans_b0 = 0, trans_a1 = 0, trans_b1 = 0;
-                                       translate_range(&m_inf[0], first0, last0, &trans_a0, &trans_b0);
-                                       translate_range(&m_inf[1], first1, last1, &trans_a1, &trans_b1);
-       
-                                       //Determine quantity of lines in this block for both sides
-                                       int QtyLinesLeft = (trans_b0 - trans_a0) + 1;
-                                       int QtyLinesRight = (trans_b1 - trans_a1) + 1;
-                                       if (usefilters)
+                                       OP_TYPE op = (deletes == 0 && inserts == 0) ? OP_TRIVIAL : OP_DIFF;
+
+                                       if (op != OP_TRIVIAL && usefilters)
                                        {
-                                               OP_TYPE op = OP_NONE;
-                                               if (deletes == 0 && inserts == 0)
-                                                       op = OP_TRIVIAL;
-                                               else
-                                                       op = OP_DIFF;
-                                               m_pDiffWrapper->PostFilter(ctxt, trans_a0 - 1, QtyLinesLeft, trans_a1 - 1, QtyLinesRight, op, m_inf);
-                                               if(op == OP_TRIVIAL)
-                                               {
-                                                       thisob->trivial = 1;
-                                               }
+                                               m_pDiffWrapper->PostFilter(ctxt, thisob, diffData->m_inf);
                                        }
                                }
-                               /* Reconnect the script so it will all be freed properly.  */
-                               end->link = next;
                        }
                }
        }
@@ -260,32 +232,10 @@ int DiffUtils::diffutils_compare_files()
     second file if first is binary).
  * @return `true` when compare succeeds, `false` if error happened during compare.
  */
-bool DiffUtils::Diff2Files(struct change ** diffs, int depth,
-               int * bin_status, bool bMovedBlocks, int * bin_file) const
+bool DiffUtils::Diff2Files(struct change ** diffs, DiffFileData *diffData,
+               int * bin_status, int * bin_file) const
 {
-       bool bRet = true;
-       SE_Handler seh;
-       try
-       {
-               *diffs = diff_2_files(m_inf, depth, bin_status, bMovedBlocks, bin_file);
-       }
-       catch (SE_Exception&)
-       {
-               *diffs = nullptr;
-               bRet = false;
-       }
-       return bRet;
-}
-
-/**
- * @brief Copy text stat results from diffutils back into the FileTextStats structure
- */
-static void CopyTextStats(const file_data * inf, FileTextStats * myTextStats)
-{
-       myTextStats->ncrlfs = inf->count_crlfs;
-       myTextStats->ncrs = inf->count_crs;
-       myTextStats->nlfs = inf->count_lfs;
-       myTextStats->nzeros = inf->count_zeros;
+       return m_pDiffWrapper->Diff2Files(diffs, diffData, bin_status, bin_file);
 }
 
 /**
@@ -299,14 +249,5 @@ void DiffUtils::GetDiffCounts(int & diffs, int & trivialDiffs) const
        trivialDiffs = m_ntrivialdiffs;
 }
 
-/**
- * @brief Return text statistics for last compare.
- * @param [in] side For which file to return statistics.
- * @param [out] stats Stats as asked.
- */
-void DiffUtils::GetTextStats(int side, FileTextStats *stats) const
-{
-       CopyTextStats(&m_inf[side], stats);
-}
 
 } // namespace CompareEngines
index a7dda80..7ed6c51 100644 (file)
@@ -7,13 +7,12 @@
 
 #include <memory>
 
-class CompareOptions;
 class FilterList;
 class SubstitutionList;
-class DiffutilsOptions;
-struct file_data;
+class CompareOptions;
 struct FileTextStats;
 class CDiffWrapper;
+struct DiffFileData;
 
 namespace CompareEngines
 {
@@ -31,22 +30,21 @@ class DiffUtils
 public:
        DiffUtils();
        ~DiffUtils();
-       void SetCompareOptions(const CompareOptions & options);
+
+       void SetCodepage(int codepage);
+       void SetCompareOptions(const CompareOptions& options);
        void SetFilterList(std::shared_ptr<FilterList> plist);
        void ClearFilterList();
        void SetSubstitutionList(std::shared_ptr<SubstitutionList> plist);
        void ClearSubstitutionList();
-       void SetFileData(int items, file_data *data);
-       int diffutils_compare_files();
+
+       int CompareFiles(DiffFileData* diffData);
+       bool Diff2Files(struct change ** diffs, DiffFileData *diffData,
+                       int * bin_status, int * bin_file) const;
+
        void GetDiffCounts(int & diffs, int & trivialDiffs) const;
-       void GetTextStats(int side, FileTextStats *stats) const;
-       bool Diff2Files(struct change ** diffs, int depth,
-                       int * bin_status, bool bMovedBlocks, int * bin_file) const;
-       void SetCodepage(int codepage);
 
 private:
-       std::unique_ptr<DiffutilsOptions> m_pOptions; /**< Compare options for diffutils. */
-       file_data * m_inf; /**< Compared files data (for diffutils). */
        int m_ndiffs; /**< Real diffs found. */
        int m_ntrivialdiffs; /**< Ignored diffs found. */
        std::unique_ptr<CDiffWrapper> m_pDiffWrapper;
index ca4b143..879ded5 100644 (file)
@@ -186,6 +186,7 @@ void DiffutilsOptions::GetAsDiffOptions(DIFFOPTIONS &options) const
        options.bIgnoreCase = m_bIgnoreCase;
        options.bIgnoreEol = m_bIgnoreEOLDifference;
        options.bIgnoreNumbers = m_bIgnoreNumbers;
+       options.nDiffAlgorithm = m_diffAlgorithm;
 
        switch (m_ignoreWhitespace)
        {
index 39562a8..2731016 100644 (file)
@@ -414,7 +414,7 @@ int CDiffTextBuffer::SaveToFile (const String& pszFileName,
        if (bTempFile)
        {
                file.SetUnicoding(ucr::UTF8);
-               file.SetBom(GetOptionsMgr()->GetInt(OPT_CMP_DIFF_ALGORITHM) == 0);
+               file.SetBom(true);
                bOpenSuccess = !!file.OpenCreate(pszFileName);
        }
        else
index 38ca907..726bf15 100644 (file)
@@ -61,6 +61,8 @@ extern "C" int is_blank_line(char const* pch, char const* limit);
 static void CopyTextStats(const file_data * inf, FileTextStats * myTextStats);
 static void CopyDiffutilTextStats(file_data *inf, DiffFileData * diffData);
 
+constexpr char* FILTERED_LINE = "!" "c0d5089f" "-" "3d91" "-" "4d69" "-" "b406" "-" "dc5a5b51a4f8";
+
 /**
  * @brief Default constructor.
  * Initializes members.
@@ -80,6 +82,7 @@ CDiffWrapper::CDiffWrapper()
 , m_bPluginsEnabled(false)
 , m_status()
 , m_codepage(ucr::CP_UTF_8)
+, m_xdlFlags(0)
 {
        // character that ends a line.  Currently this is always `\n'
        line_end_char = '\n';
@@ -156,6 +159,7 @@ void CDiffWrapper::SetOptions(const DIFFOPTIONS *options)
 {
        assert(options != nullptr);
        m_options.SetFromDiffOptions(*options);
+       m_xdlFlags = make_xdl_flags(m_options);
 }
 
 void CDiffWrapper::SetPrediffer(const PrediffingInfo * prediffer /*= nullptr*/)
@@ -282,6 +286,15 @@ static unsigned GetCommentsFilteredText(unsigned dwCookie, int startLine, int en
                                                filteredT.append(text.c_str() + block.m_nCharPos, blocklen);
                                        }
                                }
+
+                               if (blocks[nActualItems - 1].m_nColorIndex == COLORINDEX_COMMENT)
+                               {
+                                       // If there is an inline comment, the EOL for that line will be deleted, so add the EOL.
+                                       size_t fullLen = linbuf[i + 1] - linbuf[i];
+                                       size_t len = linelen(linbuf[i], fullLen);
+                                       for (size_t j = len; j < fullLen; ++j)
+                                               filteredT += linbuf[i][j];
+                               }
                        }
                }
        }
@@ -334,133 +347,332 @@ static void ReplaceChars(std::string & str, const char* chars, const char *rep)
 }
 
 /**
- * @brief Remove blank lines
+ * @brief The main entry for post filtering.  Performs post-filtering, by setting comment blocks to trivial
+ * @param [in, out]  thisob    Current change
+ * @return Number of trivial diffs inserted
  */
-void RemoveBlankLines(std::string &str)
-{
-       size_t pos = 0;
-       while (pos < str.length())
-       {
-               size_t posend = str.find_first_of("\r\n", pos);
-               if (posend != std::string::npos)
-                       posend = str.find_first_not_of("\r\n", posend);
-               if (posend == std::string::npos)
-                       posend = str.length();
-               if (is_blank_line(str.data() + pos, str.data() + posend))
-                       str.erase(pos, posend - pos);
-               else
-                       pos = posend;
-       }
-}
-
-/**
-@brief The main entry for post filtering.  Performs post-filtering, by setting comment blocks to trivial
-@param [in]  LineNumberLeft            - First line number to read from left file
-@param [in]  QtyLinesLeft              - Number of lines in the block for left file
-@param [in]  LineNumberRight           - First line number to read from right file
-@param [in]  QtyLinesRight             - Number of lines in the block for right file
-@param [in,out]  Op                            - This variable is set to trivial if block should be ignored.
-*/
-void CDiffWrapper::PostFilter(PostFilterContext& ctxt, int LineNumberLeft, int QtyLinesLeft, int LineNumberRight,
-       int QtyLinesRight, OP_TYPE &Op, const file_data *file_data_ary) const
+int CDiffWrapper::PostFilter(PostFilterContext& ctxt, change* thisob, const file_data *file_data_ary) const
 {
-       if (Op == OP_TRIVIAL)
-               return;
-
-       if (m_pFilterList != nullptr && m_pFilterList->HasRegExps())
-       {
-               // Match lines against regular expression filters
-               // Our strategy is that every line in both sides must
-               // match regexp before we mark difference as ignored.
-               bool match2 = false;
-               bool match1 = RegExpFilter(LineNumberLeft + file_data_ary[0].linbuf_base, LineNumberLeft + file_data_ary[0].linbuf_base + QtyLinesLeft - 1, &file_data_ary[0]);
-               if (match1)
-                       match2 = RegExpFilter(LineNumberRight + file_data_ary[1].linbuf_base, LineNumberRight + file_data_ary[1].linbuf_base + QtyLinesRight - 1, &file_data_ary[1]);
-               if (match1 && match2)
-               {
-                       Op = OP_TRIVIAL;
-                       return;
-               }
-       }
-
-       std::string LineDataLeft, LineDataRight;
+       const int first0 = thisob->line0;
+       const int first1 = thisob->line1;
+       const int last0 = first0 + thisob->deleted - 1;
+       const int last1 = first1 + thisob->inserted - 1;
+       int trans_a0 = 0, trans_b0 = 0, trans_a1 = 0, trans_b1 = 0;
+       translate_range(&file_data_ary[0], first0, last0, &trans_a0, &trans_b0);
+       translate_range(&file_data_ary[1], first1, last1, &trans_a1, &trans_b1);
+       const int qtyLinesLeft = (trans_b0 - trans_a0) + 1; //Determine quantity of lines in this block for left side
+       const int qtyLinesRight = (trans_b1 - trans_a1) + 1;//Determine quantity of lines in this block for right side
+       const int lineNumberLeft = trans_a0 - 1;
+       const int lineNumberRight = trans_a1 - 1;
+       
+       std::string lineDataLeft, lineDataRight;
 
        if (m_options.m_filterCommentsLines)
        {
                ctxt.dwCookieLeft = GetLastLineCookie(ctxt.dwCookieLeft,
-                       ctxt.nParsedLineEndLeft + 1, LineNumberLeft - 1, file_data_ary[0].linbuf + file_data_ary[0].linbuf_base, m_pFilterCommentsDef);
+                       ctxt.nParsedLineEndLeft + 1, lineNumberLeft - 1, file_data_ary[0].linbuf + file_data_ary[0].linbuf_base, m_pFilterCommentsDef);
                ctxt.dwCookieRight = GetLastLineCookie(ctxt.dwCookieRight,
-                       ctxt.nParsedLineEndRight + 1, LineNumberRight - 1, file_data_ary[1].linbuf + file_data_ary[1].linbuf_base, m_pFilterCommentsDef);
+                       ctxt.nParsedLineEndRight + 1, lineNumberRight - 1, file_data_ary[1].linbuf + file_data_ary[1].linbuf_base, m_pFilterCommentsDef);
 
-               ctxt.nParsedLineEndLeft = LineNumberLeft + QtyLinesLeft - 1;
-               ctxt.nParsedLineEndRight = LineNumberRight + QtyLinesRight - 1;;
+               ctxt.nParsedLineEndLeft = lineNumberLeft + qtyLinesLeft - 1;
+               ctxt.nParsedLineEndRight = lineNumberRight + qtyLinesRight - 1;;
 
                ctxt.dwCookieLeft = GetCommentsFilteredText(ctxt.dwCookieLeft,
-                       LineNumberLeft, ctxt.nParsedLineEndLeft, file_data_ary[0].linbuf + file_data_ary[0].linbuf_base, LineDataLeft, m_pFilterCommentsDef);
+                       lineNumberLeft, ctxt.nParsedLineEndLeft, file_data_ary[0].linbuf + file_data_ary[0].linbuf_base, lineDataLeft, m_pFilterCommentsDef);
                ctxt.dwCookieRight = GetCommentsFilteredText(ctxt.dwCookieRight,
-                       LineNumberRight, ctxt.nParsedLineEndRight, file_data_ary[1].linbuf + file_data_ary[1].linbuf_base, LineDataRight, m_pFilterCommentsDef);
+                       lineNumberRight, ctxt.nParsedLineEndRight, file_data_ary[1].linbuf + file_data_ary[1].linbuf_base, lineDataRight, m_pFilterCommentsDef);
        }
        else
        {
-               LineDataLeft.assign(file_data_ary[0].linbuf[LineNumberLeft + file_data_ary[0].linbuf_base],
-                       file_data_ary[0].linbuf[LineNumberLeft + QtyLinesLeft + file_data_ary[0].linbuf_base]
-                       - file_data_ary[0].linbuf[LineNumberLeft + file_data_ary[0].linbuf_base]);
-               LineDataRight.assign(file_data_ary[1].linbuf[LineNumberRight + file_data_ary[1].linbuf_base],
-                       file_data_ary[1].linbuf[LineNumberRight + QtyLinesRight + file_data_ary[1].linbuf_base]
-                       - file_data_ary[1].linbuf[LineNumberRight + file_data_ary[1].linbuf_base]);
+               lineDataLeft.assign(file_data_ary[0].linbuf[lineNumberLeft + file_data_ary[0].linbuf_base],
+                       file_data_ary[0].linbuf[lineNumberLeft + qtyLinesLeft + file_data_ary[0].linbuf_base]
+                       - file_data_ary[0].linbuf[lineNumberLeft + file_data_ary[0].linbuf_base]);
+               lineDataRight.assign(file_data_ary[1].linbuf[lineNumberRight + file_data_ary[1].linbuf_base],
+                       file_data_ary[1].linbuf[lineNumberRight + qtyLinesRight + file_data_ary[1].linbuf_base]
+                       - file_data_ary[1].linbuf[lineNumberRight + file_data_ary[1].linbuf_base]);
+       }
+
+       if (m_pFilterList != nullptr && m_pFilterList->HasRegExps())
+       {
+               // Match lines against regular expression filters
+               // Our strategy is that every line in both sides must
+               // match regexp before we mark difference as ignored.
+               bool match1 = RegExpFilter(lineDataLeft);
+               bool match2 = RegExpFilter(lineDataRight);
+               if (match1 && match2)
+               {
+                       thisob->trivial = 1;
+                       return 0;
+               }
        }
 
        if (m_pSubstitutionList)
        {
-               LineDataLeft = m_pSubstitutionList->Subst(LineDataLeft);
-               LineDataRight = m_pSubstitutionList->Subst(LineDataRight);
+               lineDataLeft = m_pSubstitutionList->Subst(lineDataLeft, m_codepage);
+               lineDataRight = m_pSubstitutionList->Subst(lineDataRight, m_codepage);
        }
 
        if (m_options.m_ignoreWhitespace == WHITESPACE_IGNORE_ALL)
        {
                //Ignore character case
-               ReplaceChars(LineDataLeft, " \t", "");
-               ReplaceChars(LineDataRight, " \t", "");
+               ReplaceChars(lineDataLeft, " \t", "");
+               ReplaceChars(lineDataRight, " \t", "");
        }
        else if (m_options.m_ignoreWhitespace == WHITESPACE_IGNORE_CHANGE)
        {
                //Ignore change in whitespace char count
-               ReplaceChars(LineDataLeft, " \t", " ");
-               ReplaceChars(LineDataRight, " \t", " ");
+               ReplaceChars(lineDataLeft, " \t", " ");
+               ReplaceChars(lineDataRight, " \t", " ");
        }
 
-       if (m_options.m_bIgnoreNumbers )
+       if (m_options.m_bIgnoreNumbers)
        {
                //Ignore number character case
-               ReplaceChars(LineDataLeft, "0123456789", "");
-               ReplaceChars(LineDataRight, "0123456789", "");
+               ReplaceChars(lineDataLeft, "0123456789", "");
+               ReplaceChars(lineDataRight, "0123456789", "");
        }
        if (m_options.m_bIgnoreCase)
        {
                //ignore case
-               // std::transform(LineDataLeft.begin(),  LineDataLeft.end(),  LineDataLeft.begin(),  ::toupper);
-               for (std::string::iterator pb = LineDataLeft.begin(), pe = LineDataLeft.end(); pb != pe; ++pb) 
+               for (std::string::iterator pb = lineDataLeft.begin(), pe = lineDataLeft.end(); pb != pe; ++pb) 
                        *pb = static_cast<char>(::toupper(*pb));
-               // std::transform(LineDataRight.begin(), LineDataRight.end(), LineDataRight.begin(), ::toupper);
-               for (std::string::iterator pb = LineDataRight.begin(), pe = LineDataRight.end(); pb != pe; ++pb) 
+               for (std::string::iterator pb = lineDataRight.begin(), pe = lineDataRight.end(); pb != pe; ++pb) 
                        *pb = static_cast<char>(::toupper(*pb));
        }
        if (m_options.m_bIgnoreEOLDifference)
        {
-               Replace(LineDataLeft, "\r\n", "\n");
-               Replace(LineDataLeft, "\r", "\n");
-               Replace(LineDataRight, "\r\n", "\n");
-               Replace(LineDataRight, "\r", "\n");
+               Replace(lineDataLeft, "\r\n", "\n");
+               Replace(lineDataLeft, "\r", "\n");
+               Replace(lineDataRight, "\r\n", "\n");
+               Replace(lineDataRight, "\r", "\n");
        }
-       if (m_options.m_bIgnoreBlankLines)
+
+       // If both match after filtering, mark this diff hunk as trivial and return.
+       if (lineDataLeft == lineDataRight)
        {
-               RemoveBlankLines(LineDataLeft);
-               RemoveBlankLines(LineDataRight);
+               //only difference is trival
+               thisob->trivial = 1;
+               return 0;
        }
-       if (LineDataLeft != LineDataRight)
-               return;
-       //only difference is trival
-       Op = OP_TRIVIAL;
+
+       auto SplitLines = [](const std::string& lines) -> std::vector<std::string_view>
+               {
+                       std::vector<std::string_view> result;
+                       const char* line = lines.c_str();
+                       for (size_t i = 0; i < lines.length(); ++i)
+                       {
+                               char c = lines[i];
+                               if (c == '\r')
+                               {
+                                       if (i + 1 < lines.length() && lines[i + 1] == '\n')
+                                               i++;
+                                       result.emplace_back(line, lines.c_str() + i + 1 - line);
+                                       line = lines.c_str() + i + 1;
+                               }
+                               else if (c == '\n')
+                               {
+                                       result.emplace_back(line, lines.c_str() + i + 1 - line);
+                                       line = lines.c_str() + i + 1;
+                               }
+                       }
+                       if (!lines.empty() && (lines.back() != '\r' && lines.back() != '\n'))
+                               result.emplace_back(line, lines.c_str() + lines.length() - line);
+                       return result; 
+               };
+
+       std::vector<std::string_view> leftLines = SplitLines(lineDataLeft);
+       std::vector<std::string_view> rightLines = SplitLines(lineDataRight);
+
+       if (qtyLinesLeft != leftLines.size() || qtyLinesRight != rightLines.size())
+               return 0;
+
+       // If both do not match as a result of filtering, some lines may match,
+       // so diff calculation is performed again using the filtered lines.
+       change* script = diff_2_buffers_xdiff(
+               lineDataLeft.c_str(), lineDataLeft.length(),
+               lineDataRight.c_str(), lineDataRight.length(), m_xdlFlags);
+
+       auto TranslateLineNumbers = [](change* thisob, change* script)
+               {
+                       assert(thisob && script);
+                       for (change* cur = script; cur; cur = cur->link)
+                       {
+                               cur->line0 += thisob->line0;
+                               cur->line1 += thisob->line1;
+                       }
+               };
+
+       // Insert lines with no differences as trivial diffs after filtering
+       auto InsertTrivialChanges = [](change* thisob, change* script) -> int
+               {
+                       assert(thisob && script);
+                       int l0 = thisob->line0;
+                       int l1 = thisob->line1;
+                       change* first = script;
+                       change* prev = nullptr;
+                       int nTrivialInserts = 0;
+                       for (change* cur = script; cur; cur = cur->link)
+                       {
+                               if (l0 < cur->line0 || l1 < cur->line1)
+                               {
+                                       nTrivialInserts++;
+                                       change *newob = (change *)xmalloc(sizeof (change));
+                                       newob->line0 = l0;
+                                       newob->line1 = l1;
+                                       newob->deleted = cur->line0 - l0;
+                                       newob->inserted = cur->line1 - l1;
+                                       newob->trivial = 1;
+                                       newob->match0 = -1;
+                                       newob->match1 = -1;
+                                       if (cur == first)
+                                       {
+                                               std::swap(newob->line0, cur->line0);
+                                               std::swap(newob->line1, cur->line1);
+                                               std::swap(newob->deleted, cur->deleted);
+                                               std::swap(newob->inserted, cur->inserted);
+                                               std::swap(newob->trivial, cur->trivial);
+                                               std::swap(newob->match0, cur->match0);
+                                               std::swap(newob->match1, cur->match1);
+                                               newob->link = cur->link;
+                                               cur->link = newob;
+                                       }
+                                       else
+                                       {
+                                               prev->link = newob;
+                                               newob->link = cur;
+                                       }
+                               }
+                               l0 = cur->line0 + cur->deleted;
+                               l1 = cur->line1 + cur->inserted;
+                               prev = cur;
+                       }
+                       if (l0 < thisob->line0 + thisob->deleted || l1 < thisob->line1 + thisob->inserted)
+                       {
+                               nTrivialInserts++;
+                               change *newob = (change *)xmalloc(sizeof (change));
+                               prev->link = newob;
+                               newob->line0 = l0;
+                               newob->line1 = l1;
+                               newob->deleted = thisob->line0 + thisob->deleted - l0;
+                               newob->inserted = thisob->line1 + thisob->inserted - l1;
+                               newob->trivial = 1;
+                               newob->match0 = -1;
+                               newob->match1 = -1;
+                               newob->link = nullptr;
+                       }
+                       return nTrivialInserts;
+               };
+
+       // Insert blank lines or filtered lines that are only on one side as trivial diffs. 
+       auto InsertTrivialChanges2 =
+               [](change* thisob, change* script, bool ignoreBlankLines,
+                  const std::vector<std::string_view>& leftLines,
+                  const std::vector<std::string_view>& rightLines) -> int
+               {
+                       assert(thisob && script);
+                       auto IsBlankLine = [](const std::string_view& line)
+                               {
+                                       for (char c : line)
+                                       {
+                                               if (!std::isspace(static_cast<unsigned char>(c)))
+                                                       return false;
+                                       }
+                                       return true;
+                               };
+                       int nTrivialInserts = 0;
+                       for (change* cur = script; cur; cur = cur->link)
+                       {
+                               if (!cur->trivial && cur->deleted != cur->inserted)
+                               {
+                                       bool ignorable = true;
+                                       if (cur->deleted > cur->inserted)
+                                       {
+                                               for (int i = cur->line0 + cur->inserted - thisob->line0; i < cur->line0 + cur->deleted - thisob->line0; ++i)
+                                               {
+                                                       if (!(ignoreBlankLines && IsBlankLine(leftLines[i])) && leftLines[i] != FILTERED_LINE)
+                                                               ignorable = false;
+                                               }
+                                               if (ignorable)
+                                               {
+                                                       if (cur->inserted == 0)
+                                                       {
+                                                               cur->trivial = 1;
+                                                       }
+                                                       else
+                                                       {
+                                                               nTrivialInserts++;
+                                                               change* newob = (change*)xmalloc(sizeof(change));
+                                                               newob->line0 = cur->line0 + cur->inserted;
+                                                               newob->line1 = cur->line1 + cur->inserted;
+                                                               newob->deleted = cur->deleted - cur->inserted;
+                                                               newob->inserted = 0;
+                                                               newob->trivial = 1;
+                                                               newob->match0 = -1;
+                                                               newob->match1 = -1;
+                                                               newob->link = cur->link;
+                                                               cur->link = newob;
+                                                               cur->deleted = cur->inserted;
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               for (int i = cur->line1 + cur->deleted - thisob->line1; i < cur->line1 + cur->inserted - thisob->line1; ++i)
+                                               {
+                                                       if (!(ignoreBlankLines && IsBlankLine(rightLines[i])) && rightLines[i] != FILTERED_LINE)
+                                                               ignorable = false;
+                                               }
+                                               if (ignorable)
+                                               {
+                                                       if (cur->deleted == 0)
+                                                       {
+                                                               cur->trivial = 1;
+                                                       }
+                                                       else
+                                                       {
+                                                               nTrivialInserts++;
+                                                               change* newob = (change*)xmalloc(sizeof(change));
+                                                               newob->line0 = cur->line0 + cur->deleted;
+                                                               newob->line1 = cur->line1 + cur->deleted;
+                                                               newob->deleted = 0;
+                                                               newob->inserted = cur->inserted - cur->deleted;
+                                                               newob->trivial = 1;
+                                                               newob->match0 = -1;
+                                                               newob->match1 = -1;
+                                                               newob->link = cur->link;
+                                                               cur->link = newob;
+                                                               cur->inserted = cur->deleted;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       return nTrivialInserts;
+               };
+
+       auto ReplaceChanges = [](change* thisob, change* script)
+               {
+                       assert(thisob && script);
+                       change* last = nullptr;
+                       for (change* cur = script; cur; cur = cur->link)
+                               last = cur;
+                       last->link = thisob->link;
+                       thisob->link = script->link;
+                       thisob->line0 = script->line0;
+                       thisob->line1 = script->line1;
+                       thisob->deleted = script->deleted;
+                       thisob->inserted = script->inserted;
+                       thisob->trivial = script->trivial;
+                       thisob->match0 = script->match0;
+                       thisob->match1 = script->match1;
+                       free(script);
+               };
+
+       TranslateLineNumbers(thisob, script);
+       int nTrivialInserts = InsertTrivialChanges(thisob, script);
+       nTrivialInserts += InsertTrivialChanges2(thisob, script, m_options.m_bIgnoreBlankLines, leftLines, rightLines);
+       ReplaceChanges(thisob, script);
+       return nTrivialInserts;
 }
 
 /**
@@ -882,8 +1094,9 @@ bool CDiffWrapper::Diff2Files(struct change ** diffs, DiffFileData *diffData,
        {
                if (m_options.m_diffAlgorithm != DIFF_ALGORITHM_DEFAULT)
                {
-                       unsigned xdl_flags = make_xdl_flags(m_options);
-                       *diffs = diff_2_files_xdiff(diffData->m_inf, (m_pMovedLines[0] != nullptr), xdl_flags);
+                       const unsigned xdl_flags = make_xdl_flags(m_options);
+                       *diffs = diff_2_files_xdiff(diffData->m_inf, bin_status,
+                               (m_pMovedLines[0] != nullptr), bin_file, xdl_flags);
                        files[0] = diffData->m_inf[0];
                        files[1] = diffData->m_inf[1];
                }
@@ -930,7 +1143,7 @@ CDiffWrapper::FreeDiffUtilsScript(struct change * & script)
  * @param [in] FileNo File to match.
  * return true if any of the expressions matches.
  */
-bool CDiffWrapper::RegExpFilter(int StartPos, int EndPos, const file_data *pinf) const
+bool CDiffWrapper::RegExpFilter(std::string& lines) const
 {
        if (m_pFilterList == nullptr)
        {       
@@ -939,19 +1152,32 @@ bool CDiffWrapper::RegExpFilter(int StartPos, int EndPos, const file_data *pinf)
        }
 
        bool linesMatch = true; // set to false when non-matching line is found.
-       int line = StartPos;
 
-       while (line <= EndPos && linesMatch)
-       {
-               size_t len = pinf->linbuf[line + 1] - pinf->linbuf[line];
-               const char *string = pinf->linbuf[line];
-               size_t stringlen = linelen(string, len);
-               if (!m_pFilterList->Match(std::string(string, stringlen), m_codepage))
+       std::string replaced;
+       replaced.reserve(lines.length());
+       size_t pos = 0;
+       while (pos < lines.length())
+       {
+               const char* string = lines.c_str() + pos;
+               while (pos < lines.length() && (lines[pos] != '\r' && lines[pos] != '\n'))
+                       pos++;
+               size_t stringlen = lines.c_str() + pos - string;
+               std::string line = std::string(string, stringlen);
+               if (!m_pFilterList->Match(line, m_codepage))
                {
                        linesMatch = false;
+                       replaced += line;
+               }
+               else
+               {
+                       replaced += FILTERED_LINE;
                }
-               ++line;
+               std::string eol;
+               while (pos < lines.length() && (lines[pos] == '\r' || lines[pos] == '\n'))
+                       eol += lines[pos++];
+               replaced += eol;
        }
+       lines = replaced;
        return linesMatch;
 }
 
@@ -990,6 +1216,10 @@ CDiffWrapper::LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const
                        /* Determine range of line numbers involved in each file.  */
                        int first0=0, last0=0, first1=0, last1=0, deletes=0, inserts=0;
                        analyze_hunk (thisob, &first0, &last0, &first1, &last1, &deletes, &inserts, file_data_ary);
+               
+                       /* Reconnect the script so it will all be freed properly.  */
+                       end->link = next;
+
                        if (deletes || inserts || thisob->trivial)
                        {
                                OP_TYPE op = OP_NONE;
@@ -1029,35 +1259,64 @@ CDiffWrapper::LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const
                                                }
                                        }
                                }
-                               const int QtyLinesLeft = (trans_b0 - trans_a0) + 1; //Determine quantity of lines in this block for left side
-                               const int QtyLinesRight = (trans_b1 - trans_a1) + 1;//Determine quantity of lines in this block for right side
-                               if (usefilters)
-                                       PostFilter(ctxt, trans_a0 - 1, QtyLinesLeft, trans_a1 - 1, QtyLinesRight, op, file_data_ary);
-
-                               if (op == OP_TRIVIAL && m_options.m_bCompletelyBlankOutIgnoredDiffereneces)
+                               int nTrivialInserts = 0;
+                               if (op != OP_TRIVIAL && usefilters)
+                                       nTrivialInserts = PostFilter(ctxt, thisob, file_data_ary);
+                               if (nTrivialInserts > 0)
                                {
-                                       if (QtyLinesLeft == QtyLinesRight)
+                                       while (thisob != next)
                                        {
-                                               op = OP_NONE;
-                                       }
-                                       else if (QtyLinesLeft < QtyLinesRight)
-                                       {
-                                               trans_a0 += QtyLinesLeft;
-                                               trans_a1 += QtyLinesLeft;
+                                               op = (thisob->trivial) ? OP_TRIVIAL : OP_DIFF;
+                                               first0 = thisob->line0;
+                                               first1 = thisob->line1;
+                                               last0 = first0 + thisob->deleted - 1;
+                                               last1 = first1 + thisob->inserted - 1;
+                                               translate_range (&file_data_ary[0], first0, last0, &trans_a0, &trans_b0);
+                                               translate_range (&file_data_ary[1], first1, last1, &trans_a1, &trans_b1);
+                                               const int qtyLinesLeft = (trans_b0 - trans_a0) + 1; //Determine quantity of lines in this block for left side
+                                               const int qtyLinesRight = (trans_b1 - trans_a1) + 1;//Determine quantity of lines in this block for right side
+
+                                               if (op == OP_TRIVIAL && m_options.m_bCompletelyBlankOutIgnoredDiffereneces)
+                                               {
+                                                       if (qtyLinesLeft == qtyLinesRight)
+                                                       {
+                                                               op = OP_NONE;
+                                                       }
+                                                       else
+                                                       {
+                                                               trans_a0 += qtyLinesLeft < qtyLinesRight ? qtyLinesLeft : qtyLinesRight;
+                                                               trans_a1 += qtyLinesLeft < qtyLinesRight ? qtyLinesLeft : qtyLinesRight;
+                                                       }
+                                               }
+                                               if (op != OP_NONE)
+                                                       AddDiffRange(m_pDiffList, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
+
+                                               thisob = thisob->link;
                                        }
-                                       else
+                               }
+                               else
+                               {
+                                       if (thisob->trivial)
+                                               op = OP_TRIVIAL;
+                                       const int qtyLinesLeft = (trans_b0 - trans_a0) + 1; //Determine quantity of lines in this block for left side
+                                       const int qtyLinesRight = (trans_b1 - trans_a1) + 1;//Determine quantity of lines in this block for right side
+                                       if (op == OP_TRIVIAL && m_options.m_bCompletelyBlankOutIgnoredDiffereneces)
                                        {
-                                               trans_a0 += QtyLinesRight;
-                                               trans_a1 += QtyLinesRight;
+                                               if (qtyLinesLeft == qtyLinesRight)
+                                               {
+                                                       op = OP_NONE;
+                                               }
+                                               else
+                                               {
+                                                       trans_a0 += qtyLinesLeft < qtyLinesRight ? qtyLinesLeft : qtyLinesRight;
+                                                       trans_a1 += qtyLinesLeft < qtyLinesRight ? qtyLinesLeft : qtyLinesRight;
+                                               }
                                        }
+                                       if (op != OP_NONE)
+                                               AddDiffRange(m_pDiffList, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
                                }
-                               if (op != OP_NONE)
-                                       AddDiffRange(m_pDiffList, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
                        }
                }
-               
-               /* Reconnect the script so it will all be freed properly.  */
-               end->link = next;
        }
 }
 
@@ -1143,6 +1402,10 @@ CDiffWrapper::LoadWinMergeDiffsFromDiffUtilsScript3(
                        {                                       
                                /* Determine range of line numbers involved in each file.  */
                                analyze_hunk (thisob, &first0, &last0, &first1, &last1, &deletes, &inserts, pinf);
+                       
+                               /* Reconnect the script so it will all be freed properly.  */
+                               end->link = next;
+
                                if (deletes || inserts || thisob->trivial)
                                {
                                        if (deletes && inserts)
@@ -1195,17 +1458,33 @@ CDiffWrapper::LoadWinMergeDiffsFromDiffUtilsScript3(
                                                }
                                        }
 
-                                       const int QtyLinesLeft = (trans_b0 - trans_a0) + 1; //Determine quantity of lines in this block for left side
-                                       const int QtyLinesRight = (trans_b1 - trans_a1) + 1;//Determine quantity of lines in this block for right side
-                                       if (usefilters)
-                                               PostFilter(ctxt, trans_a0 - 1, QtyLinesLeft, trans_a1 - 1, QtyLinesRight, op, pinf);
-
-                                       AddDiffRange(pdiff, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
+                                       int nTrivialInserts = 0;
+                                       if (op != OP_TRIVIAL && usefilters)
+                                               nTrivialInserts = PostFilter(ctxt, thisob, pinf);
+                                       if (nTrivialInserts)
+                                       {
+                                               while (thisob != next)
+                                               {
+                                                       op = (thisob->trivial) ? OP_TRIVIAL : OP_DIFF;
+                                                       first0 = thisob->line0;
+                                                       first1 = thisob->line1;
+                                                       last0 = first0 + thisob->deleted - 1;
+                                                       last1 = first1 + thisob->inserted - 1;
+                                                       translate_range (&pinf[0], first0, last0, &trans_a0, &trans_b0);
+                                                       translate_range (&pinf[1], first1, last1, &trans_a1, &trans_b1);
+
+                                                       AddDiffRange(pdiff, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
+                                                       thisob = thisob->link;
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if (thisob->trivial)
+                                                       op = OP_TRIVIAL;
+                                               AddDiffRange(pdiff, trans_a0-1, trans_b0-1, trans_a1-1, trans_b1-1, op);
+                                       }
                                }
                        }
-                       
-                       /* Reconnect the script so it will all be freed properly.  */
-                       end->link = next;
                }
        }
 
index 77b69da..308ece0 100644 (file)
@@ -163,6 +163,7 @@ public:
        void SetCreatePatchFile(const String &filename);
        void SetCreateDiffList(DiffList *diffList);
        void GetOptions(DIFFOPTIONS *options) const;
+       const DiffutilsOptions& GetOptions() const { return m_options; }
        void SetOptions(const DIFFOPTIONS *options);
        void SetTextForAutomaticPrediff(const String &text);
        void SetPrediffer(const PrediffingInfo * prediffer = nullptr);
@@ -191,13 +192,12 @@ public:
        void SetFilterCommentsSourceDef(const String& ext);
        void SetCodepage(int codepage) { m_codepage = codepage; }
        void EnablePlugins(bool enable);
-       void PostFilter(PostFilterContext& ctxt, int LineNumberLeft, int QtyLinesLeft, int LineNumberRight,
-               int QtyLinesRight, OP_TYPE &Op, const file_data *file_data_ary) const;
+       int PostFilter(PostFilterContext& ctxt, change* thisob, const file_data* file_data_ary) const;
+       bool Diff2Files(struct change ** diffs, DiffFileData *diffData,
+               int * bin_status, int * bin_file) const;
 
 protected:
        String FormatSwitchString() const;
-       bool Diff2Files(struct change ** diffs, DiffFileData *diffData,
-               int * bin_status, int * bin_file) const;
        void LoadWinMergeDiffsFromDiffUtilsScript(struct change * script, const file_data * inf);
        void WritePatchFile(struct change * script, file_data * inf);
 public:
@@ -205,10 +205,11 @@ public:
                struct change * script10, struct change * script12,
                const file_data * inf10, const file_data * inf12);
        static void FreeDiffUtilsScript(struct change * & script);
-       bool RegExpFilter(int StartPos, int EndPos, const file_data * pinf) const;
+       bool RegExpFilter(std::string& lines) const;
 
 private:
        DiffutilsOptions m_options;
+       int m_xdlFlags;
        DIFFSTATUS m_status; /**< Status of last compare */
        std::shared_ptr<FilterList> m_pFilterList; /**< List of linefilters. */
        std::shared_ptr<SubstitutionList> m_pSubstitutionList;
index 8b18377..4ebb755 100644 (file)
@@ -711,7 +711,8 @@ void ApplyFolderNameAndFileName(const InputIterator& begin, const InputIterator&
        for (InputIterator it = begin; it != end; ++it)
        {
                const DIFFITEM& di = *it;
-               if (di.diffcode.diffcode == 0) // Invalid value, this must be special item
+               if (di.diffcode.diffcode == 0 /* Invalid value, this must be special item */ ||
+                   !di.diffcode.exists(index)) 
                        continue;
                String filename = di.diffFileInfo[index].filename;
                String currentDir = di.getFilepath(index, ctxt.GetNormalizedPath(index));
index 880ef2e..103d9ca 100644 (file)
@@ -498,6 +498,7 @@ int DirScan_CompareItems(DiffFuncStruct *myStruct, DIFFITEM *parentdiffpos)
        std::vector<DiffWorkerPtr> workers;
        NotificationQueue queue;
        myStruct->context->m_pCompareStats->SetCompareThreadCount(nworkers);
+       workers.reserve(nworkers);
        for (int i = 0; i < nworkers; ++i)
        {
                workers.emplace_back(std::make_shared<DiffWorker>(queue, myStruct->context, i));
index f809354..651aabc 100644 (file)
@@ -64,15 +64,17 @@ using namespace std::placeholders;
  * If compare takes longer than this value (in seconds) we inform
  * user about it. Current implementation uses MessageBeep(IDOK).
  */
-const int TimeToSignalCompare = 3;
-
-// The resource ID constants/limits for the Shell context menu
-const UINT LeftCmdFirst = 0x9000; // this should be greater than any of already defined command IDs
-const UINT RightCmdLast = 0xffff; // maximum available value
-const UINT LeftCmdLast = LeftCmdFirst + (RightCmdLast - LeftCmdFirst) / 3; // divide available range equally between two context menus
-const UINT MiddleCmdFirst = LeftCmdLast + 1;
-const UINT MiddleCmdLast = MiddleCmdFirst + (RightCmdLast - LeftCmdFirst) / 3;
-const UINT RightCmdFirst = MiddleCmdLast + 1;
+constexpr int TimeToSignalCompare = 3;
+
+// The resource ID constexprants/limits for the Shell context menu
+constexpr UINT LeftCmdFirst = 0x9000; // this should be greater than any of already defined command IDs
+constexpr UINT BothCmdLast = 0xffff; // maximum available value
+constexpr UINT LeftCmdLast = LeftCmdFirst + (BothCmdLast - LeftCmdFirst) / 4; // divide available range equally between two context menus
+constexpr UINT MiddleCmdFirst = LeftCmdLast + 1;
+constexpr UINT MiddleCmdLast = MiddleCmdFirst + (BothCmdLast - LeftCmdFirst) / 4;
+constexpr UINT RightCmdFirst = MiddleCmdLast + 1;
+constexpr UINT RightCmdLast = RightCmdFirst + (BothCmdLast - LeftCmdFirst) / 4;
+constexpr UINT BothCmdFirst = RightCmdLast + 1;
 
 /////////////////////////////////////////////////////////////////////////////
 // CDirView
@@ -92,6 +94,7 @@ CDirView::CDirView()
                , m_pShellContextMenuLeft(nullptr)
                , m_pShellContextMenuMiddle(nullptr)
                , m_pShellContextMenuRight(nullptr)
+               , m_pShellContextMenuBoth(nullptr)
                , m_hCurrentMenu(nullptr)
                , m_pSavedTreeState(nullptr)
                , m_pColItems(nullptr)
@@ -347,9 +350,7 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_UPDATE_COMMAND_UI(ID_DIR_ZIP_ALL, OnUpdateCtxtDirCopyBothTo)
        ON_UPDATE_COMMAND_UI(ID_DIR_ZIP_BOTH_DIFFS_ONLY, OnUpdateCtxtDirCopyBothDiffsOnlyTo)
        // Context menu -> Left/Middle/Right Shell menu
-       ON_COMMAND(ID_DIR_SHELL_CONTEXT_MENU_LEFT, OnCtxtDirShellContextMenu<SIDE_LEFT>)
-       ON_COMMAND(ID_DIR_SHELL_CONTEXT_MENU_MIDDLE, OnCtxtDirShellContextMenu<SIDE_MIDDLE>)
-       ON_COMMAND(ID_DIR_SHELL_CONTEXT_MENU_RIGHT, OnCtxtDirShellContextMenu<SIDE_RIGHT>)
+       ON_COMMAND_RANGE(ID_DIR_SHELL_CONTEXT_MENU_LEFT, ID_DIR_SHELL_CONTEXT_MENU_ALL, OnCtxtDirShellContextMenu)
        // Context menu -> Plugin settings
        ON_COMMAND_RANGE(ID_PREDIFFER_SETTINGS_NONE, ID_PREDIFFER_SETTINGS_SELECT, OnPluginSettings)
        ON_COMMAND_RANGE(ID_UNPACKER_SETTINGS_NONE, ID_UNPACKER_SETTINGS_SELECT, OnPluginSettings)
@@ -757,6 +758,7 @@ void CDirView::ListContextMenu(CPoint point, int /*i*/)
                pPopup->RemoveMenu(ID_DIR_ZIP_MIDDLE, MF_BYCOMMAND);
                pPopup->RemoveMenu(ID_DIR_ZIP_ALL, MF_BYCOMMAND);
                pPopup->RemoveMenu(ID_DIR_SHELL_CONTEXT_MENU_MIDDLE, MF_BYCOMMAND);
+               pPopup->RemoveMenu(ID_DIR_SHELL_CONTEXT_MENU_ALL, MF_BYCOMMAND);
                pPopup->RemoveMenu(ID_MERGE_COMPARE_NONHORIZONTALLY, MF_BYCOMMAND);
        }
        else
@@ -765,6 +767,7 @@ void CDirView::ListContextMenu(CPoint point, int /*i*/)
                pPopup->RemoveMenu(ID_DIR_COPY_BOTH_TO_CLIPBOARD, MF_BYCOMMAND);
                pPopup->RemoveMenu(ID_DIR_ZIP_BOTH, MF_BYCOMMAND);
                pPopup->RemoveMenu(ID_DIR_DEL_BOTH, MF_BYCOMMAND);
+               pPopup->RemoveMenu(ID_DIR_SHELL_CONTEXT_MENU_BOTH, MF_BYCOMMAND);
                pPopup->RemoveMenu(2, MF_BYPOSITION); // Compare Non-horizontally
        }
 
@@ -806,31 +809,6 @@ void CDirView::HeaderContextMenu(CPoint point, int /*i*/)
 }
 
 /**
- * @brief Gets Explorer's context menu for a group of selected files.
- *
- * @param [in] Side whether to get context menu for the files from the left or
- *   right side.
- * @retval true menu successfully retrieved.
- * @retval falsea an error occurred while retrieving the menu.
- */
-bool CDirView::ListShellContextMenu(SIDE_TYPE stype)
-{
-       CShellContextMenu* shellContextMenu;
-       switch (stype) {
-       case SIDE_MIDDLE:
-               shellContextMenu = m_pShellContextMenuMiddle.get(); break;
-       case SIDE_RIGHT:
-               shellContextMenu = m_pShellContextMenuRight.get(); break;
-       default:
-               shellContextMenu = m_pShellContextMenuLeft.get(); break;
-       }
-       shellContextMenu->Initialize();
-       ApplyFolderNameAndFileName(SelBegin(), SelEnd(), stype, GetDiffContext(),
-               [&](const String& path, const String& filename) { shellContextMenu->AddItem(path, filename); });
-       return shellContextMenu->RequeryShellContextMenu();
-}
-
-/**
  * @brief User chose (main menu) Copy from right to left
  */
 void CDirView::OnDirCopy(UINT id)
@@ -3038,33 +3016,56 @@ void CDirView::OnCtxtDirZip(int flag)
        ).CompressArchive();
 }
 
-void CDirView::ShowShellContextMenu(SIDE_TYPE stype)
+void CDirView::ShowShellContextMenu(UINT id)
 {
+       std::vector<SIDE_TYPE> stypes;
        CShellContextMenu *pContextMenu = nullptr;
-       switch (stype)
+       switch (id)
        {
-       case SIDE_LEFT:
+       case ID_DIR_SHELL_CONTEXT_MENU_LEFT:
                if (m_pShellContextMenuLeft == nullptr)
                        m_pShellContextMenuLeft.reset(new CShellContextMenu(LeftCmdFirst, LeftCmdLast));
                pContextMenu = m_pShellContextMenuLeft.get();
+               stypes = { SIDE_LEFT };
                break;
-       case SIDE_MIDDLE:
+       case ID_DIR_SHELL_CONTEXT_MENU_MIDDLE:
                if (m_pShellContextMenuMiddle == nullptr)
                        m_pShellContextMenuMiddle.reset(new CShellContextMenu(MiddleCmdFirst, MiddleCmdLast));
                pContextMenu = m_pShellContextMenuMiddle.get();
+               stypes = { SIDE_MIDDLE };
                break;
-       case SIDE_RIGHT:
+       case ID_DIR_SHELL_CONTEXT_MENU_RIGHT:
                if (m_pShellContextMenuRight == nullptr)
                        m_pShellContextMenuRight.reset(new CShellContextMenu(RightCmdFirst, RightCmdLast));
                pContextMenu = m_pShellContextMenuRight.get();
+               stypes = { SIDE_RIGHT };
                break;
+       default:
+               if (m_pShellContextMenuBoth == nullptr)
+                       m_pShellContextMenuBoth.reset(new CShellContextMenu(BothCmdFirst, BothCmdLast));
+               pContextMenu = m_pShellContextMenuBoth.get();
+               if (GetDocument()->m_nDirs < 3)
+                       stypes = { SIDE_LEFT, SIDE_RIGHT };
+               else
+                       stypes = { SIDE_LEFT, SIDE_MIDDLE, SIDE_RIGHT };
+               break;
+       }
+
+       if (!pContextMenu)
+               return;
+
+       pContextMenu->Initialize();
+       for (const auto stype : stypes)
+       {
+               ApplyFolderNameAndFileName(SelBegin(), SelEnd(), stype, GetDiffContext(),
+                       [&](const String& path, const String& filename) { pContextMenu->AddItem(path, filename); });
        }
-       if (pContextMenu!=nullptr && ListShellContextMenu(stype))
+       if (pContextMenu->RequeryShellContextMenu())
        {
                CPoint point;
                GetCursorPos(&point);
                HWND hWnd = GetSafeHwnd();
-               CFrameWnd *pFrame = GetTopLevelFrame();
+               CFrameWndpFrame = GetTopLevelFrame();
                ASSERT(pFrame != nullptr);
                BOOL bAutoMenuEnableOld = pFrame->m_bAutoMenuEnable;
                pFrame->m_bAutoMenuEnable = FALSE;
index 331c2a8..f381d3e 100644 (file)
@@ -218,6 +218,7 @@ protected:
        std::unique_ptr<CShellContextMenu> m_pShellContextMenuLeft; /**< Shell context menu for group of left files */
        std::unique_ptr<CShellContextMenu> m_pShellContextMenuMiddle; /**< Shell context menu for group of middle files */
        std::unique_ptr<CShellContextMenu> m_pShellContextMenuRight; /**< Shell context menu for group of right files */
+       std::unique_ptr<CShellContextMenu> m_pShellContextMenuBoth; /**< Shell context menu for group of both files */
        HMENU m_hCurrentMenu; /**< Current shell context menu (either left or right) */
        std::unique_ptr<DirViewTreeState> m_pSavedTreeState;
        std::unique_ptr<DirViewColItems> m_pColItems;
@@ -305,8 +306,7 @@ protected:
        afx_msg void OnCtxtDirZip(int flag);
        template<int flag>
        afx_msg void OnCtxtDirZip() { OnCtxtDirZip(flag); }
-       template<SIDE_TYPE stype>
-       afx_msg void OnCtxtDirShellContextMenu() { ShowShellContextMenu(stype); }
+       afx_msg void OnCtxtDirShellContextMenu(UINT id) { ShowShellContextMenu(id); }
        afx_msg void OnSelectAll();
        afx_msg void OnUpdateSelectAll(CCmdUI* pCmdUI);
        afx_msg void OnPluginSettings(UINT nID);
@@ -428,8 +428,7 @@ private:
        void FixReordering();
        void HeaderContextMenu(CPoint point, int i);
        void ListContextMenu(CPoint point, int i);
-       bool ListShellContextMenu(SIDE_TYPE side);
-       void ShowShellContextMenu(SIDE_TYPE side);
+       void ShowShellContextMenu(UINT id);
        CShellContextMenu* GetCorrespondingShellContextMenu(HMENU hMenu) const;
        void ReloadColumns();
        bool IsLabelEdit() const;
index 72a4392..49ca082 100644 (file)
@@ -1560,6 +1560,10 @@ DirViewColItems::AddAdditionalPropertyName(const String& propertyName)
        String cList = (m_nDirs < 3) ? String(_T("ADLR")) : String(_T("ADLMR"));
        if (propertyName.substr(0, 5) == _T("Hash."))
                cList += (m_nDirs < 3) ? String(_T("Nlr")) : String(_T("lmr"));
+       const size_t count = cList.size();
+       m_cols.reserve(count);
+       m_invcolorder.reserve(count);
+       m_colorder.reserve(count);
        for (auto c : cList)
        {
                m_cols.emplace_back(DirColInfo{});
index bd833f6..3d41ce8 100644 (file)
@@ -324,6 +324,7 @@ unsigned DirWatcher::Impl::DirWatcherThreadProc()
                        }
 
                        handles.clear();
+                       handles.reserve(watchedDirs.size() + 1);
                        handles.push_back(m_hEventReq);
                        for (auto& watchedDir : watchedDirs)
                                handles.push_back(watchedDir.pOverlapped->hEvent);
index 15eea35..1c1aaa9 100644 (file)
@@ -46,6 +46,7 @@ namespace
                UINT wNumFilesDropped = DragQueryFile(dropInfo, 0xFFFFFFFF, nullptr, 0);
 
                // get all file names. but we'll only need the first one.
+               files.reserve(wNumFilesDropped);
                for (UINT x = 0; x < wNumFilesDropped; x++)
                {
                        // Get the number of bytes required by the file's full pathname
index 16ce405..7549c20 100644 (file)
@@ -50,6 +50,7 @@ void FileFilter::CloneFrom(const FileFilter* filter)
 
        filefilters.clear();
        size_t count = filter->filefilters.size();
+       filefilters.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                filefilters.emplace_back(std::make_shared<FileFilterElement>(filter->filefilters[i].get()));
@@ -57,12 +58,14 @@ void FileFilter::CloneFrom(const FileFilter* filter)
 
        dirfilters.clear();
        count = filter->dirfilters.size();
+       dirfilters.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                dirfilters.emplace_back(std::make_shared<FileFilterElement>(filter->dirfilters[i].get()));
        }
        filefiltersExclude.clear();
        count = filter->filefiltersExclude.size();
+       filefiltersExclude.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                filefiltersExclude.emplace_back(std::make_shared<FileFilterElement>(filter->filefiltersExclude[i].get()));
@@ -70,6 +73,7 @@ void FileFilter::CloneFrom(const FileFilter* filter)
 
        dirfiltersExclude.clear();
        count = filter->dirfiltersExclude.size();
+       dirfiltersExclude.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                dirfiltersExclude.emplace_back(std::make_shared<FileFilterElement>(filter->dirfiltersExclude[i].get()));
index c8b0576..415d631 100644 (file)
@@ -429,6 +429,7 @@ void FileFilterMgr::CloneFrom(const FileFilterMgr* fileFilterMgr)
        m_filters.clear();
 
        size_t count = fileFilterMgr->m_filters.size();
+       m_filters.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                auto ptr = std::make_shared<FileFilter>(FileFilter());
index 5f3b349..ba48145 100644 (file)
@@ -136,15 +136,19 @@ void FilterList::CloneFrom(const FilterList* filterList)
                return;
 
        m_list.clear();
-       m_listExclude.clear();
 
        size_t count = filterList->m_list.size();
+       m_list.reserve(count);
        for (size_t i = 0; i < count; i++)
        {
                m_list.emplace_back(std::make_shared<filter_item>(filterList->m_list[i].get()));
        }
-       size_t countExclude = filterList->m_listExclude.size();
-       for (size_t i = 0; i < countExclude; i++)
+
+       m_listExclude.clear();
+
+       count = filterList->m_listExclude.size();
+       m_listExclude.reserve(count);
+       for (size_t i = 0; i < count; i++)
        {
                m_listExclude.emplace_back(std::make_shared<filter_item>(filterList->m_listExclude[i].get()));
        }
index ba09ae0..4a3fd5e 100644 (file)
@@ -71,6 +71,15 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
 
        if (nCompMethod == CMP_CONTENT || nCompMethod == CMP_QUICK_CONTENT)
        {
+               // Reset text stats
+               for (nIndex = 0; nIndex < nDirs; nIndex++)
+               {
+                       m_diffFileData.m_textStats[nIndex].clear();
+                       m_diffFileData.m_FileLocation[nIndex].encoding.Clear();
+               }
+               m_ndiffs = CDiffContext::DIFFS_UNKNOWN;
+               m_ntrivialdiffs = CDiffContext::DIFFS_UNKNOWN;
+
                if ((di.diffFileInfo[0].size > m_pCtxt->m_nBinaryCompareLimit && di.diffFileInfo[0].size != DirItem::FILE_SIZE_NONE) ||
                        (di.diffFileInfo[1].size > m_pCtxt->m_nBinaryCompareLimit && di.diffFileInfo[1].size != DirItem::FILE_SIZE_NONE) ||
                        (nDirs > 2 && di.diffFileInfo[2].size > m_pCtxt->m_nBinaryCompareLimit && di.diffFileInfo[2].size != DirItem::FILE_SIZE_NONE))
@@ -92,11 +101,6 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
        if (nCompMethod == CMP_CONTENT ||
                nCompMethod == CMP_QUICK_CONTENT)
        {
-
-               // Reset text stats
-               for (nIndex = 0; nIndex < nDirs; nIndex++)
-                       m_diffFileData.m_textStats[nIndex].clear();
-
                PathContext tFiles;
                m_pCtxt->GetComparePaths(di, tFiles);
                struct change *script10 = nullptr;
@@ -216,11 +220,8 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        }
                        if (tFiles.GetSize() == 2)
                        {
-                               m_pDiffUtilsEngine->SetFileData(2, m_diffFileData.m_inf);
-                               code = m_pDiffUtilsEngine->diffutils_compare_files();
+                               code = m_pDiffUtilsEngine->CompareFiles(&m_diffFileData);
                                m_pDiffUtilsEngine->GetDiffCounts(m_ndiffs, m_ntrivialdiffs);
-                               m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[1]);
 
                                // If unique item, it was being compared to itself to determine encoding
                                // and the #diffs is invalid
@@ -235,20 +236,12 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                                bool bRet;
                                int bin_flag10 = 0, bin_flag12 = 0, bin_flag02 = 0;
 
-                               m_pDiffUtilsEngine->SetFileData(2, diffdata10.m_inf);
-                               bRet = m_pDiffUtilsEngine->Diff2Files(&script10, 0, &bin_flag10, false, nullptr);
-                               m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[1]);
-                               m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[0]);
-
-                               m_pDiffUtilsEngine->SetFileData(2, diffdata12.m_inf);
-                               bRet = m_pDiffUtilsEngine->Diff2Files(&script12, 0, &bin_flag12, false, nullptr);
-                               m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[1]);
-                               m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[2]);
-
-                               m_pDiffUtilsEngine->SetFileData(2, diffdata02.m_inf);
-                               bRet = m_pDiffUtilsEngine->Diff2Files(&script02, 0, &bin_flag02, false, nullptr);
-                               m_pDiffUtilsEngine->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pDiffUtilsEngine->GetTextStats(1, &m_diffFileData.m_textStats[2]);
+                               bRet = m_pDiffUtilsEngine->Diff2Files(&script10, &diffdata10, &bin_flag10, nullptr);
+                               bRet = m_pDiffUtilsEngine->Diff2Files(&script12, &diffdata12, &bin_flag12, nullptr);
+                               bRet = m_pDiffUtilsEngine->Diff2Files(&script02, &diffdata02, &bin_flag02, nullptr);
+                               m_diffFileData.m_textStats[0] = diffdata10.m_textStats[1];
+                               m_diffFileData.m_textStats[1] = diffdata12.m_textStats[0];
+                               m_diffFileData.m_textStats[2] = diffdata02.m_textStats[1];
 
                                code = DIFFCODE::FILE;
 
@@ -332,13 +325,8 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        }
                        if (tFiles.GetSize() == 2)
                        {
-                               m_pByteCompare->SetFileData(2, m_diffFileData.m_inf);
-
                                // use our own byte-by-byte compare
-                               code = m_pByteCompare->CompareFiles(m_diffFileData.m_FileLocation);
-
-                               m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[1]);
+                               code = m_pByteCompare->CompareFiles(&m_diffFileData);
 
                                // Quick contents doesn't know about diff counts
                                // Set to special value to indicate invalid
@@ -347,32 +335,17 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        }
                        else
                        {
-                               // 10
-                               m_pByteCompare->SetFileData(2, diffdata10.m_inf);
-
                                // use our own byte-by-byte compare
-                               int code10 = m_pByteCompare->CompareFiles(diffdata10.m_FileLocation);
-
-                               m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[1]);
-                               m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[0]);
-
+                               // 10
+                               int code10 = m_pByteCompare->CompareFiles(&diffdata10);
                                // 12
-                               m_pByteCompare->SetFileData(2, diffdata12.m_inf);
-
-                               // use our own byte-by-byte compare
-                               int code12 = m_pByteCompare->CompareFiles(diffdata12.m_FileLocation);
-
-                               m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[1]);
-                               m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[2]);
-
+                               int code12 = m_pByteCompare->CompareFiles(&diffdata12);
                                // 02
-                               m_pByteCompare->SetFileData(2, diffdata02.m_inf);
-
-                               // use our own byte-by-byte compare
-                               int code02 = m_pByteCompare->CompareFiles(diffdata02.m_FileLocation);
+                               int code02 = m_pByteCompare->CompareFiles(&diffdata02);
 
-                               m_pByteCompare->GetTextStats(0, &m_diffFileData.m_textStats[0]);
-                               m_pByteCompare->GetTextStats(1, &m_diffFileData.m_textStats[2]);
+                               m_diffFileData.m_textStats[0] = diffdata10.m_textStats[1];
+                               m_diffFileData.m_textStats[1] = diffdata12.m_textStats[0];
+                               m_diffFileData.m_textStats[2] = diffdata02.m_textStats[1];
 
                                code = DIFFCODE::FILE;
                                if (DIFFCODE::isResultError(code10) || DIFFCODE::isResultError(code12) || DIFFCODE::isResultError(code02))
index 4467c6d..20bc37c 100644 (file)
@@ -252,7 +252,7 @@ void CLocationView::CalculateBlocks()
        CMergeDoc *pDoc = GetDocument();
        const int nDiffs = pDoc->m_diffList.GetSize();
        if (nDiffs > 0)
-               m_diffBlocks.reserve(nDiffs); // Pre-allocate space for the list.
+               m_diffBlocks.reserve(nDiffs * 3 / 2); // Roughly pre-allocate space for the list.
 
        int nGroup = pDoc->GetActiveMergeView()->m_nThisGroup;
        int nLineCount = pDoc->GetView(nGroup, 0)->GetLineCount();
index c6b4bd4..07bfef3 100644 (file)
@@ -1101,6 +1101,7 @@ bool CMainFrame::ShowTextMergeDoc(CDirDoc* pDirDoc, int nBuffers, const String t
        fileopenflags_t dwFlags[3] = {};
        CDirDoc* pDirDoc2 = pDirDoc->GetMainView() ? pDirDoc :
                static_cast<CDirDoc*>(theApp.GetDirTemplate()->CreateNewDocument());
+       m_tempFiles.reserve(nBuffers);
        for (int nBuffer = 0; nBuffer < nBuffers; ++nBuffer)
        {
                auto wTemp = std::make_shared<TempFile>(TempFile());
index 41d096b..7fc4fb7 100644 (file)
@@ -948,6 +948,8 @@ BEGIN
         MENUITEM "Left Shell menu",             ID_DIR_SHELL_CONTEXT_MENU_LEFT\r
         MENUITEM "Middle Shell menu",           ID_DIR_SHELL_CONTEXT_MENU_MIDDLE\r
         MENUITEM "Right Shell menu",            ID_DIR_SHELL_CONTEXT_MENU_RIGHT\r
+        MENUITEM "Both Shell menu",             ID_DIR_SHELL_CONTEXT_MENU_BOTH\r
+        MENUITEM "All Shell menu",              ID_DIR_SHELL_CONTEXT_MENU_ALL\r
         MENUITEM SEPARATOR\r
         MENUITEM "&File Encoding...",           ID_FILE_ENCODING\r
     END\r
@@ -1703,7 +1705,7 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,120,239,10\r
     CONTROL         "E&nable moved block detection",IDC_MOVED_BLOCKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,132,269,10\r
     CONTROL         "Align &similar lines",IDC_MATCH_SIMILAR_LINES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,144,269,10\r
-    LTEXT           "Diff &algorithm (Experimental):",IDC_STATIC,7,156,269,10\r
+    LTEXT           "Diff &algorithm:",IDC_STATIC,7,156,269,10\r
     COMBOBOX        IDC_DIFF_ALGORITHM,6,168,270,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Enable indent &heuristic",IDC_INDENT_HEURISTIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,186,269,10\r
     CONTROL         "Completely unhighlight the ignored differences",IDC_COMPLETELY_BLANK_OUT_IGNORED_DIFFERENCES,\r
index a91ee99..666120a 100644 (file)
     </Manifest>\r
   </ItemDefinitionGroup>\r
   <ItemGroup>\r
-    <ClCompile Include="..\Externals\gtest\src\gtest-all.cc">\r
+    <ClCompile Include="..\Externals\googletest\googletest\src\gtest-all.cc">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClCompile>\r
     <ClCompile Include="7zCommon.cpp">\r
     <ClInclude Include="..\Externals\boost\boost\config.hpp" />\r
     <ClInclude Include="..\Externals\boost\boost\config\compiler\visualc.hpp" />\r
     <ClInclude Include="..\Externals\boost\boost\config\select_compiler_config.hpp" />\r
-    <ClInclude Include="..\Externals\gtest\include\gtest\gtest-printers.h">\r
+    <ClInclude Include="..\Externals\googletest\googletest\include\gtest\gtest-printers.h">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClInclude>\r
-    <ClInclude Include="..\Externals\gtest\include\gtest\gtest.h">\r
+    <ClInclude Include="..\Externals\googletest\googletest\include\gtest\gtest.h">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClInclude>\r
-    <ClInclude Include="..\Externals\gtest\include\gtest\internal\gtest-port.h">\r
+    <ClInclude Include="..\Externals\googletest\googletest\include\gtest\internal\gtest-port.h">\r
       <ExcludedFromBuild>true</ExcludedFromBuild>\r
     </ClInclude>\r
     <ClInclude Include="..\Version.h" />\r
       <UserProperties RESOURCE_FILE="Merge.rc" />\r
     </VisualStudio>\r
   </ProjectExtensions>\r
-</Project>
\ No newline at end of file
+</Project>\r
index 47f8023..8d3fe46 100644 (file)
@@ -205,13 +205,20 @@ public:
        std::vector<CMergeEditView *> GetViewList(int nGroup = -1, int nBuffer = -1) const {
                std::vector<CMergeEditView *> list;
                if (nGroup != -1)
+               {
+                       list.reserve(m_nBuffers);
                        for (int nBuffer2 = 0; nBuffer2 < m_nBuffers; ++nBuffer2)
                                list.push_back(m_pView[nGroup][nBuffer2]);
+               }
                else if (nBuffer != -1)
+               {
+                       list.reserve(m_nGroups);
                        for (int nGroup2 = 0; nGroup2 < m_nGroups; ++nGroup2)
                                list.push_back(m_pView[nGroup2][nBuffer]);
+               }
                else
                {
+                       list.reserve(m_nGroups * m_nBuffers);
                        for (int nGroup3 = 0; nGroup3 < m_nGroups; nGroup3++)
                                for (int nBuffer3 = 0; nBuffer3 < m_nBuffers; ++nBuffer3)
                                        list.push_back(m_pView[nGroup3][nBuffer3]);
index 8a9a8b6..ca8bc99 100644 (file)
@@ -59,6 +59,7 @@ PrintVirtualLineToRealLineMap(
        {
                String str = strutils::format(_T("vline%d: "), static_cast<int>(i));
                std::vector<String> ary;
+               ary.reserve(npanes);
                for (int j = 0; j < npanes; ++j)
                        ary.push_back(vlines[i][j] == DiffMap::GHOST_MAP_ENTRY ? _T("-----") : strutils::format(_T("%5d"), vlines[i][j]));
                str += strutils::join(ary.begin(), ary.end(), _T(",")) + _T("\n");
@@ -93,6 +94,7 @@ CreateVirtualLineToRealLineMap(
        const DiffMap& diffmap, int nlines0, int nlines1)
 {
        std::vector<std::array<int, 2>> vlines;
+       vlines.reserve((std::max)(nlines0, nlines1) * 3 / 2); // Roughly pre-allocate space for the list.
        int line0 = 0, line1 = 0;
        while (line0 < nlines0)
        {
@@ -129,6 +131,7 @@ CreateVirtualLineToRealLineMap3way(
        std::vector<std::array<int, 2>> vlines12 = CreateVirtualLineToRealLineMap(diffmap12, nlines1, nlines2);
        std::vector<std::array<int, 2>> vlines20 = CreateVirtualLineToRealLineMap(diffmap20, nlines2, nlines0);
        std::vector<std::array<int, 3>> vlines;
+       vlines.reserve((std::max)({ nlines0, nlines1, nlines2 }) * 3 / 2);  // Roughly pre-allocate space for the list.
        size_t i01 = 0, i12 = 0, i20 = 0;
        int line0 = 0, line1 = 0, line2 = 0;
        bool is_vlines20_usable = true;
index ed3810d..f0369aa 100644 (file)
@@ -3239,7 +3239,7 @@ void CMergeEditView::OnShellMenu()
        String path = GetDocument()->m_filePaths[m_nThisPane];
        auto pContextMenu = std::make_unique<CShellContextMenu>(CShellContextMenu(0x9000, 0x9FFF));
        pContextMenu->Initialize();
-       pContextMenu->AddItem(paths::GetParentPath(path), paths::FindFileName(path));
+       pContextMenu->AddItem(path);
        pContextMenu->RequeryShellContextMenu();
        CPoint point;
        ::GetCursorPos(&point);
index 0ae6caf..09cdbe7 100644 (file)
@@ -276,7 +276,7 @@ std::shared_ptr<SubstitutionList> SubstitutionFiltersList::MakeSubstitutionList(
                                if (throwIfInvalid)
                                {
                                        plist.reset();
-                                       const String msg = strutils::format(_T("#%d: %s"), i + 1, e.message().c_str());
+                                       const String msg = strutils::format(_T("#%d: %S"), i + 1, e.message().c_str());
                                        throw Poco::RegularExpressionException(ucr::toUTF8(msg).c_str(), e.code());
                                }
                        }
index 2c43483..5eb7321 100644 (file)
 #define ID_DIR_SHELL_CONTEXT_MENU_LEFT  33008\r
 #define ID_DIR_SHELL_CONTEXT_MENU_MIDDLE 33009\r
 #define ID_DIR_SHELL_CONTEXT_MENU_RIGHT 33010\r
+#define ID_DIR_SHELL_CONTEXT_MENU_BOTH  33011\r
+#define ID_DIR_SHELL_CONTEXT_MENU_ALL   33012\r
 #define ID_DISPLAY_MOVED_NONE           33111\r
 #define ID_DISPLAY_MOVED_ALL            33112\r
 #define ID_LOCBAR_GOTODIFF              33114\r
index 08d708f..d1f5969 100644 (file)
@@ -5,22 +5,6 @@ extern "C" {
 #include "../Externals/xdiff/xinclude.h"\r
 }\r
 \r
-static bool read_mmfile(int fd, mmfile_t& mmfile)\r
-{\r
-       cio::stat st;\r
-       if (cio::fstat(fd, &st) == -1)\r
-               return false;\r
-       if (st.st_size < 0 || st.st_size > INT32_MAX)\r
-               return false;\r
-       size_t sz = static_cast<size_t>(st.st_size);\r
-       mmfile.ptr = static_cast<char *>(malloc(sz ? sz : 1));\r
-       if (sz && cio::read(fd, mmfile.ptr, sz) == -1) {\r
-               return false;\r
-       }\r
-       mmfile.size = static_cast<long>(sz);\r
-       return true;\r
-}\r
-\r
 unsigned long make_xdl_flags(const DiffutilsOptions& options)\r
 {\r
        unsigned long xdl_flags = 0;\r
@@ -70,115 +54,22 @@ static int hunk_func(long start_a, long count_a, long start_b, long count_b, voi
        return 0;\r
 }\r
 \r
-static void append_equivs(const xdfile_t& xdf, struct file_data& filevec, std::vector<xrecord_t *>& equivs, unsigned xdl_flags)\r
-{\r
-       std::unordered_map<unsigned long, std::vector<int>> equivs_map;\r
-       for (int i = 0; i < static_cast<int>(equivs.size()); ++i)\r
-       {\r
-               unsigned long ha = equivs[i]->ha;\r
-               if (equivs_map.find(ha) != equivs_map.end())\r
-                       equivs_map[ha].push_back(i);\r
-               else\r
-                       equivs_map.emplace(ha, std::vector<int>{i});\r
-       }\r
-\r
-       for (int i = 0; i < xdf.nrec; ++i)\r
-       {\r
-               unsigned long ha = xdf.recs[i]->ha;\r
-               if (equivs_map.find(ha) != equivs_map.end())\r
-               {\r
-                       bool found = false;\r
-                       for (auto j: equivs_map[ha])\r
-                       {\r
-                               if (xdl_recmatch(equivs[j]->ptr, equivs[j]->size, xdf.recs[i]->ptr, xdf.recs[i]->size, xdl_flags))\r
-                               {\r
-                                       found = true;\r
-                                       filevec.equivs[i] = j;\r
-                                       equivs_map.emplace(ha, std::vector<int>{j});\r
-                                       break;\r
-                               }\r
-                       }\r
-                       if (!found)\r
-                       {\r
-                               filevec.equivs[i] = static_cast<int>(equivs.size());\r
-                               equivs_map[ha].push_back(filevec.equivs[i]);\r
-                               equivs.push_back(xdf.recs[i]);\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       filevec.equivs[i] = static_cast<int>(equivs.size());\r
-                       equivs_map.emplace(ha, std::vector<int>{filevec.equivs[i]});\r
-                       equivs.push_back(xdf.recs[i]);\r
-               }\r
-       }\r
-}\r
-\r
-static int is_missing_newline(const mmfile_t& mmfile)\r
-{\r
-       if (mmfile.size == 0 || mmfile.ptr[mmfile.size - 1] == '\r' || mmfile.ptr[mmfile.size - 1] == '\n')\r
-               return 0;\r
-       return 1;\r
-}\r
-\r
-struct change * diff_2_files_xdiff (struct file_data filevec[], int bMoved_blocks_flag, unsigned xdl_flags)\r
+struct change* diff_2_buffers_xdiff(const char* ptr1, size_t size1, const char* ptr2, size_t size2, unsigned xdl_flags)\r
 {\r
-       mmfile_t mmfile1 = { 0 }, mmfile2 = { 0 };\r
        change *script = nullptr;\r
        xdfenv_t xe;\r
        xdchange_t *xscr;\r
        xpparam_t xpp = { 0 };\r
        xdemitconf_t xecfg = { 0 };\r
        xdemitcb_t ecb = { 0 };\r
-\r
-       if (!read_mmfile(filevec[0].desc, mmfile1))\r
-               goto abort;\r
-       if (!read_mmfile(filevec[1].desc, mmfile2))\r
-               goto abort;\r
+       mmfile_t mmfile1 = { const_cast<char*>(ptr1), static_cast<long>(size1) };\r
+       mmfile_t mmfile2 = { const_cast<char*>(ptr2), static_cast<long>(size2) };\r
 \r
        xpp.flags = xdl_flags;\r
        xecfg.hunk_func = hunk_func;\r
+\r
        if (xdl_diff_modified(&mmfile1, &mmfile2, &xpp, &xecfg, &ecb, &xe, &xscr) == 0)\r
        {\r
-               filevec[0].buffer = mmfile1.ptr;\r
-               filevec[1].buffer = mmfile2.ptr;\r
-               filevec[0].bufsize = mmfile1.size;\r
-               filevec[1].bufsize = mmfile2.size;\r
-               filevec[0].buffered_chars = mmfile1.size;\r
-               filevec[1].buffered_chars = mmfile2.size;\r
-               filevec[0].linbuf_base = 0;\r
-               filevec[1].linbuf_base = 0;\r
-               filevec[0].valid_lines = xe.xdf1.nrec;\r
-               filevec[1].valid_lines = xe.xdf2.nrec;\r
-               filevec[0].linbuf = static_cast<const char **>(malloc(sizeof(char *) * (xe.xdf1.nrec + 1)));\r
-               if (!filevec[0].linbuf)\r
-                       goto abort;\r
-               filevec[1].linbuf = static_cast<const char **>(malloc(sizeof(char *) * (xe.xdf2.nrec + 1)));\r
-               if (!filevec[1].linbuf)\r
-                       goto abort;\r
-               filevec[0].equivs = static_cast<int *>(malloc(sizeof(int) * xe.xdf1.nrec));\r
-               if (!filevec[0].equivs)\r
-                       goto abort;\r
-               filevec[1].equivs = static_cast<int *>(malloc(sizeof(int) * xe.xdf2.nrec));\r
-               if (!filevec[1].equivs)\r
-                       goto abort;\r
-               for (int i = 0; i < xe.xdf1.nrec; ++i)\r
-               {\r
-                       filevec[0].linbuf[i] = xe.xdf1.recs[i]->ptr;\r
-                       filevec[0].equivs[i] = -1;\r
-               }\r
-               if (xe.xdf1.nrec > 0)\r
-                       filevec[0].linbuf[xe.xdf1.nrec] = xe.xdf1.recs[xe.xdf1.nrec - 1]->ptr + xe.xdf1.recs[xe.xdf1.nrec - 1]->size;\r
-               for (int i = 0; i < xe.xdf2.nrec; ++i)\r
-               {\r
-                       filevec[1].linbuf[i] = xe.xdf2.recs[i]->ptr;\r
-                       filevec[1].equivs[i] = -1;\r
-               }\r
-               if (xe.xdf2.nrec > 0)\r
-                       filevec[1].linbuf[xe.xdf2.nrec] = xe.xdf2.recs[xe.xdf2.nrec - 1]->ptr + xe.xdf2.recs[xe.xdf2.nrec - 1]->size;\r
-               filevec[0].missing_newline = is_missing_newline(mmfile1);\r
-               filevec[1].missing_newline = is_missing_newline(mmfile2);\r
-\r
                change *prev = nullptr;\r
                for (xdchange_t* xcur = xscr; xcur; xcur = xcur->next)\r
                {\r
@@ -201,14 +92,6 @@ struct change * diff_2_files_xdiff (struct file_data filevec[], int bMoved_block
                        prev = e;\r
                }\r
 \r
-               if (bMoved_blocks_flag)\r
-               {\r
-                       std::vector<xrecord_t *> equivs;\r
-                       append_equivs(xe.xdf1, filevec[0], equivs, xdl_flags);\r
-                       append_equivs(xe.xdf2, filevec[1], equivs, xdl_flags);\r
-                       moved_block_analysis(&script, filevec);\r
-               }\r
-\r
                xdl_free_script(xscr);\r
                xdl_free_env(&xe);\r
        }\r
@@ -216,7 +99,96 @@ struct change * diff_2_files_xdiff (struct file_data filevec[], int bMoved_block
        return script;\r
 \r
 abort:\r
-       free(mmfile1.ptr);\r
-       free(mmfile2.ptr);\r
        return nullptr;\r
 }\r
+\r
+struct change * diff_2_files_xdiff (struct file_data filevec[], int* bin_status, int bMoved_blocks_flag, int* bin_file, unsigned xdl_flags)\r
+{\r
+       change *script = nullptr;\r
+\r
+       if (read_files(filevec, no_details_flag & ~ignore_some_changes, bin_file))\r
+       {\r
+               int i;\r
+               int changes;\r
+               // copy from analyze.c\r
+               //  We can now safely assume to have a pair of Binary files.\r
+\r
+               // Are both files Open and Regular (no Pipes, Directories, Devices (e.g. NUL))\r
+               if (filevec[0].desc < 0 || filevec[1].desc < 0 ||\r
+                       !(S_ISREG (filevec[0].stat.st_mode)) || !(S_ISREG (filevec[1].stat.st_mode))   )\r
+                       changes = 1;\r
+               else\r
+               //  Files with different lengths must be different.  \r
+               if (filevec[0].stat.st_size != filevec[1].stat.st_size)\r
+                       changes = 1;\r
+               else\r
+               //  Identical descriptor implies identical files\r
+               if (filevec[0].desc == filevec[1].desc)\r
+                       changes = 0;\r
+               //  Scan both files, a buffer at a time, looking for a difference.  \r
+               else\r
+               {\r
+                       //  Same-sized buffers for both files were allocated in read_files().  \r
+                       size_t buffer_size = filevec[0].bufsize;\r
+                       \r
+                       for (;;)\r
+                       {\r
+                               //  Read a buffer's worth from both files.  \r
+                               for (i = 0; i < 2; i++)\r
+                                       while (filevec[i].buffered_chars < buffer_size)\r
+                                         {\r
+                                               cio::ssize_t r = cio::read (filevec[i].desc,\r
+                                                                          filevec[i].buffer    + filevec[i].buffered_chars,\r
+                                                                          buffer_size - filevec[i].buffered_chars);\r
+                                               if (r == 0)\r
+                                                       break;\r
+                                               if (r < 0)\r
+                                                       pfatal_with_name (filevec[i].name);\r
+                                               filevec[i].buffered_chars += r;\r
+                                         }\r
+                                               \r
+                               //  If the buffers have different number of chars, the files differ.  \r
+                               if (filevec[0].buffered_chars != filevec[1].buffered_chars)\r
+                               {\r
+                                       changes = 1;\r
+                                       break;\r
+                               }\r
+\r
+                               //  If we reach end-of-file, the files are the same.  \r
+                               if (filevec[0].buffered_chars==0) // therefore: filevec[1].buffered_chars==0\r
+                               {\r
+                                       changes = 0;\r
+                                       break;\r
+                               }       \r
+\r
+                               //      If buffers have different contents, the files are different.\r
+                               if (memcmp (filevec[0].buffer,\r
+                                                       filevec[1].buffer,\r
+                                                       filevec[0].buffered_chars) != 0)\r
+                               {\r
+                                       changes = 1;\r
+                                       break;\r
+                               }\r
+\r
+                               //      Files appear identical so far...\r
+                               //      Prepare to loop again for the next pair of buffers.\r
+                               filevec[0].buffered_chars = filevec[1].buffered_chars = 0;\r
+                       }\r
+               }\r
+               if (bin_status != NULL)\r
+                       *bin_status = (changes != 0 ? -1 : 1);\r
+       }\r
+       else\r
+       {\r
+               script = diff_2_buffers_xdiff(\r
+                       filevec[0].prefix_end,\r
+                       filevec[0].suffix_begin - filevec[0].prefix_end,\r
+                       filevec[1].prefix_end,\r
+                       filevec[1].suffix_begin - filevec[1].prefix_end,\r
+                       xdl_flags);\r
+               if (bMoved_blocks_flag)\r
+                       moved_block_analysis(&script, filevec);\r
+       }\r
+\r
+       return script;\r
+}\r
index 7fe8d3a..228640d 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once\r
 \r
 class DiffutilsOptions;\r
+\r
 unsigned long make_xdl_flags(const DiffutilsOptions& options);\r
-struct change * diff_2_files_xdiff(struct file_data filevec[], int bMoved_blocks_flag, unsigned xdl_flags);\r
+struct change* diff_2_buffers_xdiff(const char* ptr1, size_t size1, const char* ptr2, size_t size2, unsigned xdl_flags);\r
+struct change * diff_2_files_xdiff(struct file_data filevec[], int* bin_status, int bMoved_blocks_flag, int* bin_file, unsigned xdl_flags);\r
index ca8eafe..803964c 100644 (file)
@@ -5,6 +5,7 @@
 #include "CompareOptions.h"
 #include "FileLocation.h"
 #include "DiffItem.h"
+#include "DiffFileData.h"
 #include "cio.h"
 #include "unicoder.h"
 #include <fstream>
@@ -31,18 +32,14 @@ namespace
        {
                FilePair(const std::string& left, const std::string& right)
                {
-                       cio::tsopen_s(&filedata[0].desc, ucr::toTString(left),  O_RDONLY | O_BINARY, _SH_DENYWR, _S_IREAD);
-                       cio::tsopen_s(&filedata[1].desc, ucr::toTString(right), O_RDONLY | O_BINARY, _SH_DENYWR, _S_IREAD);
+                       diffData.OpenFiles(ucr::toTString(left), ucr::toTString(right));
                }
 
                ~FilePair()
                {
-                       cio::close(filedata[0].desc);
-                       cio::close(filedata[1].desc);
                }
 
-               FileLocation location[2];
-               file_data filedata[2];
+               DiffFileData diffData;
        };
 
        // The fixture for testing paths functions.
@@ -118,13 +115,12 @@ namespace
                TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                FilePair pair(filename_left, filename_right);
-               bc.SetFileData(2, pair.filedata);
 
                bc.SetCompareOptions(option);
-               EXPECT_EQ(DIFFCODE::BIN|DIFFCODE::BINSIDE1|DIFFCODE::BINSIDE2|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+               EXPECT_EQ(DIFFCODE::BIN|DIFFCODE::BINSIDE1|DIFFCODE::BINSIDE2|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                FileTextStats stats[2];
-               bc.GetTextStats(0, &stats[0]);
-               bc.GetTextStats(1, &stats[1]);
+               stats[0] = pair.diffData.m_textStats[0];
+               stats[1] = pair.diffData.m_textStats[1];
 
 //             EXPECT_EQ(3, stats[0].nzeros);
 //             EXPECT_EQ(3, stats[1].nzeros);
@@ -176,9 +172,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// diff
@@ -188,9 +183,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {// all space
@@ -201,9 +195,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// empty right
@@ -213,9 +206,8 @@ namespace
                        TempFile file_right(filename_right, "", 0);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// empty left
@@ -225,9 +217,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -238,9 +229,8 @@ namespace
                        TempFile file_right(filename_right, "A", 1);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -251,9 +241,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
        }
@@ -300,9 +289,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// diff
@@ -313,9 +301,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {// same2
@@ -337,9 +324,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// same3
@@ -361,9 +347,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
        }
@@ -391,8 +376,7 @@ namespace
                        }               
 
                        FilePair pair(filename_crlf, filename_lf);
-                       bc.SetFileData(2, pair.filedata);
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                // diff
@@ -409,8 +393,7 @@ namespace
                        }
 
                        FilePair pair(filename_crlf, filename_lf);
-                       bc.SetFileData(2, pair.filedata);
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                remove(filename_crlf.c_str());
@@ -443,9 +426,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// diff
@@ -456,9 +438,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
        }
 
@@ -484,9 +465,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, strlen(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// diff 
@@ -498,9 +478,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, strlen(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
        }
 
@@ -527,9 +506,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, strlen(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::SAME, bc.CompareFiles(&pair.diffData));
                }
 
                {// diff 
@@ -541,9 +519,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, strlen(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
        }
 
@@ -566,9 +543,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right) - 1);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -576,9 +552,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right)    );
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -586,9 +561,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right));
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -596,9 +570,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, WMCMPBUFF);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -606,9 +579,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, sizeof(buf_right) - 1);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
                {
@@ -616,9 +588,8 @@ namespace
                        TempFile file_right(filename_right, buf_right, WMCMPBUFF + 1);
 
                        FilePair pair(filename_left, filename_right);
-                       bc.SetFileData(2, pair.filedata);
 
-                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(pair.location));
+                       EXPECT_EQ(DIFFCODE::TEXT|DIFFCODE::DIFF, bc.CompareFiles(&pair.diffData));
                }
 
        }
index 4370895..5caf85c 100644 (file)
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
     </ClCompile>
+    <ClCompile Include="..\..\..\Src\DiffFileData.cpp">
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
+    </ClCompile>
     <ClCompile Include="..\..\..\Src\DiffFileInfo.cpp">
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
     </ClCompile>
+    <ClCompile Include="..\..\..\Src\diffutils\src\analyze.c" />
     <ClCompile Include="..\..\..\Src\diffutils\src\context.c" />
     <ClCompile Include="..\..\..\Src\diffutils\src\Diff.cpp">
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
     </ClCompile>
+    <ClCompile Include="..\..\..\Src\diffutils\src\io.c" />
     <ClCompile Include="..\..\..\Src\diffutils\src\mystat.cpp">
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
     </ClCompile>
+    <ClCompile Include="..\..\..\Src\MovedBlocks.cpp">
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
+    </ClCompile>
     <ClCompile Include="..\..\..\Src\pch.cpp">
       <PrecompiledHeader>Create</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
     <ClInclude Include="..\..\..\Src\CompareOptions.h" />
     <ClInclude Include="..\..\..\Src\Common\coretools.h" />
     <ClInclude Include="..\..\..\Src\CompareEngines\DiffUtils.h" />
+    <ClInclude Include="..\..\..\Src\DiffFileData.h" />
     <ClInclude Include="..\..\..\Src\DiffItem.h" />
     <ClInclude Include="..\..\..\Src\DiffItemList.h" />
     <ClInclude Include="..\..\..\Src\DirItem.h" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index fe4cace..dbacaf6 100644 (file)
     <ClCompile Include="..\..\..\Src\Common\cio.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\DirFilter\DirFilters_test.cpp">
-      <Filter>Tests</Filter>
-    </ClCompile>
     <ClCompile Include="..\SubstitutionList\SubstitutionList_test.cpp">
       <Filter>Tests</Filter>
     </ClCompile>
     <ClCompile Include="..\..\..\Src\SubstitutionList.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\Src\DiffFileData.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\Src\diffutils\src\analyze.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\Src\diffutils\src\io.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\Src\MovedBlocks.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\Src\CompareEngines\ByteComparator.h">
     <ClInclude Include="..\..\..\Src\SubstitutionList.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\Src\DiffFileData.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
index 178758e..e91014b 100644 (file)
@@ -374,7 +374,7 @@ ShutdownBlockReasonUninstallingApp=%1
 \r
 NameAndVersion=%1 ¹öÀü %2\r
 AdditionalIcons=¹Ù·Î°¡±â Ãß°¡:\r
-CreateDesktopIcon=¹ÙÅÁÈ­¸é¿¡ ¹Ù·Î°¡±â ¸¸µé±â(&D)\r
+CreateDesktopIcon=¹ÙÅÁ È­¸é¿¡ ¹Ù·Î°¡±â ¸¸µé±â(&D)\r
 CreateQuickLaunchIcon=ºü¸¥ ½ÇÇà ¾ÆÀÌÄÜ ¸¸µé±â(&Q)\r
 ProgramOnTheWeb=%1 À¥ÆäÀÌÁö\r
 UninstallProgram=%1 Á¦°Å\r
index a30622c..705aa00 100644 (file)
@@ -1,49 +1,49 @@
 # Translations Status
 
-Status from **2023-08-23**:
+Status from **2023-09-11**:
 
 ## WinMerge
 
 | Language             | Total | Translated | Fuzzy | Untranslated | Complete | Last Update |
 |:---------------------|------:|-----------:|------:|-------------:|---------:|:-----------:|
-| Arabic               |  1308 |        895 |     0 |          413 |     68 % |  2019-12-30 |
-| Basque               |  1308 |        638 |     0 |          670 |     48 % |  2013-02-03 |
-| Brazilian            |  1308 |       1308 |     0 |            0 |    100 % |  2023-07-25 |
-| Bulgarian            |  1308 |       1038 |     0 |          270 |     79 % |  2021-06-28 |
-| Catalan              |  1308 |       1179 |     0 |          129 |     90 % |             |
-| ChineseSimplified    |  1308 |       1308 |     0 |            0 |    100 % |             |
-| ChineseTraditional   |  1308 |       1298 |     0 |           10 |     99 % |  2022-02-19 |
-| Corsican             |  1308 |       1298 |     0 |           10 |     99 % |  2023-07-06 |
-| Croatian             |  1308 |        630 |     1 |          677 |     48 % |  2009-02-13 |
-| Czech                |  1308 |        605 |     0 |          703 |     46 % |             |
-| Danish               |  1308 |        639 |     0 |          669 |     48 % |  2013-01-13 |
-| Dutch                |  1308 |       1285 |     0 |           23 |     98 % |  2023-05-02 |
-| English              |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-05 |
-| Finnish              |  1308 |       1190 |     0 |          118 |     90 % |             |
-| French               |  1308 |       1299 |     0 |            9 |     99 % |  2023-07-27 |
-| Galician             |  1308 |       1284 |     0 |           24 |     98 % |  2023-05-01 |
-| German               |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-08 |
-| Greek                |  1308 |        605 |     0 |          703 |     46 % |             |
-| Hungarian            |  1308 |       1308 |     0 |            0 |    100 % |  2021-03-15 |
-| Italian              |  1308 |       1101 |     0 |          207 |     84 % |  2022-06-01 |
-| Japanese             |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-05 |
-| Korean               |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-12 |
-| Lithuanian           |  1308 |       1263 |     0 |           45 |     96 % |  2023-08-08 |
-| Norwegian            |  1308 |        730 |     0 |          578 |     55 % |             |
-| Persian              |  1308 |        641 |     0 |          667 |     49 % |  2013-08-15 |
-| Polish               |  1308 |       1301 |     0 |            7 |     99 % |  2023-05-24 |
-| Portuguese           |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-07 |
-| Romanian             |  1308 |        561 |    44 |          703 |     46 % |             |
-| Russian              |  1308 |       1284 |     0 |           24 |     98 % |  2023-04-27 |
-| Serbian              |  1308 |        632 |     0 |          676 |     48 % |             |
-| Sinhala              |  1308 |        563 |    58 |          687 |     47 % |  2010-12-12 |
-| Slovak               |  1308 |       1189 |     0 |          119 |     90 % |  2022-02-17 |
-| Slovenian            |  1308 |       1308 |     0 |            0 |    100 % |  2023-08-11 |
-| Spanish              |  1308 |       1284 |     0 |           24 |     98 % |  2023-05-02 |
-| Swedish              |  1308 |       1237 |     2 |           69 |     94 % |  2023-02-08 |
-| Tamil                |  1308 |       1223 |     0 |           85 |     93 % |  2023-07-24 |
-| Turkish              |  1308 |       1298 |     0 |           10 |     99 % |  2023-07-06 |
-| Ukrainian            |  1308 |        708 |     0 |          600 |     54 % |  2009-06-13 |
+| Arabic               |  1311 |        895 |     0 |          416 |     68 % |  2019-12-30 |
+| Basque               |  1311 |        638 |     0 |          673 |     48 % |  2013-02-03 |
+| Brazilian            |  1311 |       1311 |     0 |            0 |    100 % |  2023-09-10 |
+| Bulgarian            |  1311 |       1038 |     0 |          273 |     79 % |  2021-06-28 |
+| Catalan              |  1311 |       1179 |     0 |          132 |     89 % |             |
+| ChineseSimplified    |  1311 |       1311 |     0 |            0 |    100 % |             |
+| ChineseTraditional   |  1311 |       1298 |     0 |           13 |     99 % |  2022-02-19 |
+| Corsican             |  1311 |       1311 |     0 |            0 |    100 % |  2023-09-10 |
+| Croatian             |  1311 |        630 |     1 |          680 |     48 % |  2009-02-13 |
+| Czech                |  1311 |        605 |     0 |          706 |     46 % |             |
+| Danish               |  1311 |        639 |     0 |          672 |     48 % |  2013-01-13 |
+| Dutch                |  1311 |       1285 |     0 |           26 |     98 % |  2023-05-02 |
+| English              |  1311 |       1311 |     0 |            0 |    100 % |  2023-09-08 |
+| Finnish              |  1311 |       1190 |     0 |          121 |     90 % |             |
+| French               |  1311 |       1299 |     0 |           12 |     99 % |  2023-07-27 |
+| Galician             |  1311 |       1284 |     0 |           27 |     97 % |  2023-05-01 |
+| German               |  1311 |       1308 |     0 |            3 |     99 % |  2023-08-08 |
+| Greek                |  1311 |        605 |     0 |          706 |     46 % |             |
+| Hungarian            |  1311 |       1309 |     0 |            2 |     99 % |  2021-03-15 |
+| Italian              |  1311 |       1101 |     0 |          210 |     83 % |  2022-06-01 |
+| Japanese             |  1311 |       1311 |     0 |            0 |    100 % |  2023-08-05 |
+| Korean               |  1311 |       1308 |     0 |            3 |     99 % |  2023-08-12 |
+| Lithuanian           |  1311 |       1266 |     0 |           45 |     96 % |  2023-09-11 |
+| Norwegian            |  1311 |        730 |     0 |          581 |     55 % |             |
+| Persian              |  1311 |        641 |     0 |          670 |     48 % |  2013-08-15 |
+| Polish               |  1311 |       1301 |     0 |           10 |     99 % |  2023-05-24 |
+| Portuguese           |  1311 |       1309 |     0 |            2 |     99 % |  2023-09-03 |
+| Romanian             |  1311 |        561 |    44 |          706 |     46 % |             |
+| Russian              |  1311 |       1284 |     0 |           27 |     97 % |  2023-04-27 |
+| Serbian              |  1311 |        632 |     0 |          679 |     48 % |             |
+| Sinhala              |  1311 |        563 |    58 |          690 |     47 % |  2010-12-12 |
+| Slovak               |  1311 |       1189 |     0 |          122 |     90 % |  2022-02-17 |
+| Slovenian            |  1311 |       1308 |     0 |            3 |     99 % |  2023-08-11 |
+| Spanish              |  1311 |       1284 |     0 |           27 |     97 % |  2023-05-02 |
+| Swedish              |  1311 |       1237 |     2 |           72 |     94 % |  2023-02-08 |
+| Tamil                |  1311 |       1223 |     0 |           88 |     93 % |  2023-07-24 |
+| Turkish              |  1311 |       1298 |     0 |           13 |     99 % |  2023-07-06 |
+| Ukrainian            |  1311 |        708 |     0 |          603 |     54 % |  2009-06-13 |
 
 ## ShellExtension
 
index 37c5396..3133ba0 100644 (file)
@@ -973,6 +973,12 @@ msgstr "قائمة البرنامج الوسيطي (الغلاف) في الجز
 msgid "Right Shell menu"
 msgstr "قائمة البرنامج الوسيطي (الغلاف) في الجزء الأيمن"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "نسخ"
 
@@ -1521,8 +1527,8 @@ msgstr "&تفعيل كشف المجموعات التي نقلها"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "خوارزمية المقارنة (تجريبي):"
+msgid "Diff &algorithm:"
+msgstr "خوارزمية المقارنة:"
 
 msgid "Enable indent &heuristic"
 msgstr "تفعيل الم&سافة البادئة الإرشادية"
index a86f0be..b9361c2 100644 (file)
@@ -1177,6 +1177,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Eskuineko Shell menua"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1860,7 +1866,7 @@ msgstr "Gaitu bloke &mugitu atzematea"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index e88be2b..890848e 100644 (file)
@@ -12,7 +12,7 @@ msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
 "POT-Creation-Date: 2023-03-13 09:30-0300\n"
-"PO-Revision-Date: 2023-07-25 22:20-0300\n"
+"PO-Revision-Date: 2023-09-10 18:30-0300\n"
 "Last-Translator: Marcello <marcello.mco@gmail.com>\n"
 "Language-Team: Felipe\n"
 "Language: pt_BR\n"
@@ -972,6 +972,12 @@ msgstr "Menu do Shell do Meio"
 msgid "Right Shell menu"
 msgstr "Menu do Shell Direito"
 
+msgid "Both Shell menu"
+msgstr "Ambos Menus Shell"
+
+msgid "All Shell menu"
+msgstr "Todos Menus Shell"
+
 msgid "Copy"
 msgstr "Copiar"
 
@@ -1518,8 +1524,8 @@ msgstr "A&tivar a detecção dos blocos movidos"
 msgid "Align &similar lines"
 msgstr "Alinhar linhas &semelhantes"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Algoritmo da &diferenciação (Experimental):"
+msgid "Diff &algorithm:"
+msgstr "Algoritmo da &diferenciação:"
 
 msgid "Enable indent &heuristic"
 msgstr "Ativar heurística de &recuo"
@@ -2658,7 +2664,7 @@ msgid "You are about to close the window that is comparing folders. Are you sure
 msgstr "Você está pra fechar a janela que está comparando as pastas. Você tem certeza que você quer fechar a janela?"
 
 msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgstr "Você está prestes a fechar a janela de comparação de pastas que demorou um tempo considerável para ser montada. Tem certea que deseja fechar a janela?"
 
 msgid "The file or folder name is invalid."
 msgstr "Nome de arquivo ou pasta inválido."
index df71738..89b185a 100644 (file)
@@ -969,6 +969,12 @@ msgstr "Меню на обкръжението на средния"
 msgid "Right Shell menu"
 msgstr "Меню на обкръжението на десния"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Копиране"
 
@@ -1517,8 +1523,8 @@ msgstr "Разпознаване на преместени па&раграфи"
 msgid "Align &similar lines"
 msgstr "Подра&вняване на подобни редове"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Алгоритъм за различия (експериментално):"
+msgid "Diff &algorithm:"
+msgstr "&Алгоритъм за различия:"
 
 msgid "Enable indent &heuristic"
 msgstr "П&редполагане на отстъпа"
index c3c6e08..ac777bd 100644 (file)
@@ -1174,6 +1174,12 @@ msgstr "Menú de sistema del mig"
 msgid "Right Shell menu"
 msgstr "Menú de sistema de la dreta"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr "Copia"
@@ -1858,8 +1864,8 @@ msgstr "&Habilita detecció de blocs desplaçats"
 msgid "Align &similar lines"
 msgstr "Em&parella les línies similars"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Algoritme de diferenciació (Experimental):"
+msgid "Diff &algorithm:"
+msgstr "Algoritme de diferenciació:"
 
 msgid "Enable indent &heuristic"
 msgstr "Habilita la heurística de sagnat"
index 4938c70..1817517 100644 (file)
@@ -13,7 +13,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
-"POT-Creation-Date: 2023-04-15 08:40+0000\n"
+"POT-Creation-Date: 2023-08-27 15:32+0000\n"
 "PO-Revision-Date: \n"
 "Last-Translator: Yin Gang <zenith.yin@gmail.com>\n"
 "Language-Team: ChineseSimplified <winmerge-translate@lists.sourceforge.net>\n"
@@ -120,7 +120,7 @@ msgid "Open &Parent Folder..."
 msgstr "打开上层文件夹(&P)..."
 
 msgid "S&hell Menu"
-msgstr "外壳菜单(&S)"
+msgstr "系统外壳菜单(&S)"
 
 msgid "Use First Line as Headers"
 msgstr "将第一行做为标题行"
@@ -975,6 +975,12 @@ msgstr "中间系统外壳菜单"
 msgid "Right Shell menu"
 msgstr "右侧系统外壳菜单"
 
+msgid "Both Shell menu"
+msgstr "所有系统外壳菜单"
+
+msgid "All Shell menu"
+msgstr "所有系统外壳菜单"
+
 msgid "Copy"
 msgstr "复制"
 
@@ -1273,8 +1279,8 @@ msgid "Substitution Filters"
 msgstr "置换过滤器"
 
 msgid ""
-"The changes that appear on the panels as the listed pairs below will be ignored or marked as insignificant. Patches "
-"are unaffected."
+"The changes that appear on the panels as the listed pairs below will be "
+"ignored or marked as insignificant. Patches are unaffected."
 msgstr "面板中出现的下列变更组合将被忽略或视作无关紧要。补丁不受影响。"
 
 msgid "Enable"
@@ -1523,8 +1529,8 @@ msgstr "启用块移动检测(&N)"
 msgid "Align &similar lines"
 msgstr "对齐相似的行(&S)"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "比较算法 (实验性) (&A):"
+msgid "Diff &algorithm:"
+msgstr "比较算法(&A):"
 
 msgid "Enable indent &heuristic"
 msgstr "启用启发式缩进(&H)"
@@ -1575,8 +1581,10 @@ msgid "&Rendering Mode:"
 msgstr "渲染模式(&R)"
 
 msgid ""
-"WinMerge allows hiding some common message boxes. Press the Reset button to make all message boxes visible again."
-msgstr "WinMerge 允许隐藏一些常见的提示框。点“重置”按钮可以恢复显示隐藏的消息框。"
+"WinMerge allows hiding some common message boxes. Press the Reset button to "
+"make all message boxes visible again."
+msgstr ""
+"WinMerge 允许隐藏一些常见的提示框。点“重置”按钮可以恢复显示隐藏的消息框。"
 
 msgid "Reset"
 msgstr "重置"
@@ -1944,7 +1952,7 @@ msgid "Enable &automatic unpacking/prediffing for the plugin"
 msgstr "启用自动解包或预比较插件(&A)"
 
 msgid "Shell Integration"
-msgstr "系统集成"
+msgstr "系统外壳集成"
 
 msgid "Explorer"
 msgstr "资源管理器"
@@ -1959,22 +1967,22 @@ msgid "Enable &Compare As menu"
 msgstr "启用比较方式菜单(&C)"
 
 msgid "&Register shell extension"
-msgstr "注册系统扩展(&R)"
+msgstr "注册系统外壳扩展(&R)"
 
 msgid "&Unregister shell extension"
-msgstr "注销系统扩展(&U)"
+msgstr "注销系统外壳扩展(&U)"
 
 msgid "Register shell extension for current user &only"
-msgstr "为当前用户注册系统扩展(&O)"
+msgstr "为当前用户注册系统外壳扩展(&O)"
 
 msgid "Unregister shell extension for current user on&ly"
-msgstr "为当前用户注销系统扩展(&L)"
+msgstr "为当前用户注销系统外壳扩展(&L)"
 
 msgid "Register shell extension for &Windows 11 or later"
-msgstr "注册系统扩展(Windows 11 或更新的系统)(&W)"
+msgstr "注册系统外壳扩展(Windows 11 或更新的系统)(&W)"
 
 msgid "Unregister shell extension for W&indows 11 or later"
-msgstr "注销系统扩展(Windows 11 或更新的系统)(&I)"
+msgstr "注销系统外壳扩展(Windows 11 或更新的系统)(&I)"
 
 msgid "Jump List"
 msgstr "跳转列表"
@@ -2162,11 +2170,12 @@ msgstr ""
 "WinMerge 文件夹比较"
 
 msgid ""
-"WinMerge comes with ABSOLUTELY NO WARRANTY. This is free software and you are welcome to redistribute it under "
-"certain circumstances; see the GNU General Public License in the Help menu for details."
+"WinMerge comes with ABSOLUTELY NO WARRANTY. This is free software and you "
+"are welcome to redistribute it under certain circumstances; see the GNU "
+"General Public License in the Help menu for details."
 msgstr ""
-"WinMerge 不提供保证和损害赔偿。这是一款自由软件,并在特定条件下欢迎您重新分发本软件。详细信息见“帮助”菜单中的“GUN 通"
-"用公共许可证”。"
+"WinMerge 不提供保证和损害赔偿。这是一款自由软件,并在特定条件下欢迎您重新分发"
+"本软件。详细信息见“帮助”菜单中的“GUN 通用公共许可证”。"
 
 msgid "&Abort"
 msgstr "中止(&A)"
@@ -2205,7 +2214,8 @@ msgid "Don't display this &message again."
 msgstr "不再显示此消息(&M)"
 
 msgid ""
-"To make this message box visible again, press the Reset button on the Message Boxes page of the Options dialog."
+"To make this message box visible again, press the Reset button on the "
+"Message Boxes page of the Options dialog."
 msgstr "要使此消息框再次可见,请点击“选项”对话框,“消息框”页面上的“重置”按钮。"
 
 msgid "Syntax"
@@ -2286,8 +2296,12 @@ msgstr "WinMerge 工程文件 (*.WinMerge)|*.WinMerge||"
 msgid "Options files (*.ini)|*.ini|All Files (*.*)|*.*||"
 msgstr "配置文件 (*.ini)|*.ini|所有文件 (*.*)|*.*||"
 
-msgid "Text Files (*.csv;*.asc;*.rpt;*.txt)|*.csv;*.asc;*.rpt;*.txt|All Files (*.*)|*.*||"
-msgstr "文本文件 (*.csv;*.asc;*.rpt;*.txt)|*.csv;*.asc;*.rpt;*.txt|所有文件 (*.*)|*.*||"
+msgid ""
+"Text Files (*.csv;*.asc;*.rpt;*.txt)|*.csv;*.asc;*.rpt;*.txt|All Files (*.*)|"
+"*.*||"
+msgstr ""
+"文本文件 (*.csv;*.asc;*.rpt;*.txt)|*.csv;*.asc;*.rpt;*.txt|所有文件 (*.*)|*."
+"*||"
 
 msgid "HTML Files (*.htm,*.html)|*.htm;*.html|All Files (*.*)|*.*||"
 msgstr "HTML 文件 (*.htm,*.html)|*.htm;*.html|所有文件 (*.*)|*.*||"
@@ -2317,7 +2331,7 @@ msgid "Message"
 msgstr "消息"
 
 msgid "Answer"
-msgstr "的选择"
+msgstr "的选择"
 
 msgid "Item"
 msgstr "条目"
@@ -2423,7 +2437,8 @@ msgstr "正则表达式"
 msgid ""
 "Filters were updated. Do you want to refresh all open folder compares?\n"
 "\n"
-"If you do not want to refresh all compares now you can select 'No' and refresh compares later."
+"If you do not want to refresh all compares now you can select 'No' and "
+"refresh compares later."
 msgstr ""
 "过滤器已经更新。是否刷新已打开的文件夹比较?\n"
 "\n"
@@ -2583,7 +2598,8 @@ msgstr ""
 msgid ""
 "You are about to compare very large files.\n"
 "Showing the contents of the files requires a very large amount of memory.\n"
-"Do you want to show only the comparison results, not the contents of the files?\n"
+"Do you want to show only the comparison results, not the contents of the "
+"files?\n"
 "\n"
 msgstr ""
 "您即将比较超大文件。\n"
@@ -2599,7 +2615,9 @@ msgid "Save changes to %1?"
 msgstr "保存更改到 %1?"
 
 #, c-format
-msgid "%1 is marked read-only. Would you like to override the read-only file? (No to save as new filename.)"
+msgid ""
+"%1 is marked read-only. Would you like to override the read-only file? (No "
+"to save as new filename.)"
 msgstr "%1 标记为只读。您希望覆盖只读文件吗?(选“否”使用新文件名保存)"
 
 msgid "Error backing up file"
@@ -2896,11 +2914,15 @@ msgstr "您确定要移动 %d 个项目?"
 msgid "Confirm Move"
 msgstr "确认移动"
 
-msgid "You are about to close the window that is comparing folders. Are you sure you want to close the window?"
-msgstr "您即将关闭比较文件夹的窗口。确定关闭该窗口?"
+msgid ""
+"You are about to close the window that is comparing folders. Are you sure "
+"you want to close the window?"
+msgstr "您即将关闭文件夹比较窗口。确定要关闭该窗口吗?"
 
-msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgid ""
+"You are about to close the folder comparison window that took a significant "
+"amount of time. Are you sure you want to close the window?"
+msgstr "您即将关闭已花费大量时间的文件夹比较窗口。确定要关闭该窗口吗?"
 
 msgid "The file or folder name is invalid."
 msgstr "文件或文件夹的名称不合法。"
@@ -3291,10 +3313,14 @@ msgstr "右侧文件的字符编码。"
 msgid "Middle side encoding."
 msgstr "中间文件的字符编码。"
 
-msgid "Number of ignored differences in file. These differences are ignored by WinMerge and cannot be merged."
+msgid ""
+"Number of ignored differences in file. These differences are ignored by "
+"WinMerge and cannot be merged."
 msgstr "文件中已忽略的差异数。这些差异已被 WinMerge 忽略,无法合并它们。"
 
-msgid "Number of differences in file. This number does not include ignored differences."
+msgid ""
+"Number of differences in file. This number does not include ignored "
+"differences."
 msgstr "文件中的差异数。不包括忽略的差异。"
 
 msgid "Shows an asterisk (*) if the file is binary."
@@ -3352,23 +3378,27 @@ msgstr "选中的文件完全相同。"
 msgid "An error occurred while comparing the files."
 msgstr "比较文件时发生错误。"
 
-msgid "Temporary files could not be created. Check your temporary path settings."
+msgid ""
+"Temporary files could not be created. Check your temporary path settings."
 msgstr "无法创建临时文件。请检查您的临时路径设置。"
 
 msgid ""
 "These files use different carriage return types.\n"
 "\n"
-"Do you want to treat all carriage return types as equivalent for this comparison?\n"
+"Do you want to treat all carriage return types as equivalent for this "
+"comparison?\n"
 "\n"
-"Note: If you always want to treat all carriage return types as equivalent, set the option 'Ignore carriage return "
-"differences (Windows/Unix/Mac)' in the Compare tab of the options dialog (available under Edit/Options)."
+"Note: If you always want to treat all carriage return types as equivalent, "
+"set the option 'Ignore carriage return differences (Windows/Unix/Mac)' in "
+"the Compare tab of the options dialog (available under Edit/Options)."
 msgstr ""
 "这些文件使用了不同类型的换行符。\n"
 "\n"
 "是否在本次比较中将所有类型的换行符视作相等?\n"
 "\n"
-"小提示:如果您希望始终将所有类型的换行符视为相等,点击“编辑”菜单的“选项”子菜单,在选项对话框中的“比较”一栏中设置“忽"
-"略换行符差异(Windows/Unix/Mac)”选项。"
+"小提示:如果您希望始终将所有类型的换行符视为相等,点击“编辑”菜单的“选项”子菜"
+"单,在选项对话框中的“比较”一栏中设置“忽略换行符差异(Windows/Unix/Mac)”选"
+"项。"
 
 msgid "The selected folder is invalid."
 msgstr "所选的文件夹无效。"
@@ -3391,7 +3421,7 @@ msgstr ""
 "并且打开这两个文件夹?"
 
 msgid "Are you sure you want to copy all differences to the other file?"
-msgstr "确定要把所有的差异复制到另一个文件吗?"
+msgstr "确定要把所有的差异复制到另一个文件吗?"
 
 msgid "Do you want to move to the next file?"
 msgstr "您是否要跳转到下一个文件?"
@@ -3414,8 +3444,10 @@ msgstr "您是否要跳转到最后一个文件?"
 #, c-format
 msgid ""
 "Different codepages found in left (cp%d) and right (cp%d) files.\n"
-"Displaying each file in its codepage will give a better display but merging/copying will be dangerous.\n"
-"Would you like to treat both files as being in the default Windows codepage (recommended)?"
+"Displaying each file in its codepage will give a better display but merging/"
+"copying will be dangerous.\n"
+"Would you like to treat both files as being in the default Windows codepage "
+"(recommended)?"
 msgstr ""
 "左右两侧为不同代码页的文件 (左侧为 cp%d,右侧为 cp%d)。\n"
 "分别以不同代码页显示将会有较好的效果,但是合并/复制会有风险。\n"
@@ -3447,7 +3479,9 @@ msgstr "已替换 %1 个字符串。"
 msgid "Cannot find string \"%s\"."
 msgstr "找不到字符串“%s”。"
 
-msgid "You are now entering Merge Mode. If you want to turn off Merge Mode, press F9 key."
+msgid ""
+"You are now entering Merge Mode. If you want to turn off Merge Mode, press "
+"F9 key."
 msgstr "您正在进入合并模式。如果您想关闭合并模式,请按 F9 键。"
 
 #, c-format
@@ -3529,7 +3563,8 @@ msgstr "文件夹不存在。"
 
 msgid ""
 "Archive support is not enabled.\n"
-"All needed components (7-Zip and/or Merge7z*.dll) for archive support cannot be found.\n"
+"All needed components (7-Zip and/or Merge7z*.dll) for archive support cannot "
+"be found.\n"
 "See manual for more info about archive support and how to enable it."
 msgstr ""
 "没有启用压缩包支持。\n"
@@ -3732,7 +3767,9 @@ msgstr ""
 "\n"
 "上一个文件 (Ctrl+F7)"
 
-msgid "The adapted unpacker is applied to both files (one file only needs the extension)."
+msgid ""
+"The adapted unpacker is applied to both files (one file only needs the "
+"extension)."
 msgstr "在两个文件上应用适当的解包程序 (文件只需要有适当的扩展名)。"
 
 msgid "No prediffer (normal)"
@@ -4052,8 +4089,11 @@ msgid "'%1' is not prediffer plugin"
 msgstr "'%1' 不是预比较插件"
 
 #, c-format
-msgid "An error occurred while prediffing the file '%1' with the plugin '%2'. The prediffing is not applied any more."
-msgstr "在用插件 '%2' 对文件 '%1' 进行预比较时发生了一个错误,将不再使用该预比较。"
+msgid ""
+"An error occurred while prediffing the file '%1' with the plugin '%2'. The "
+"prediffing is not applied any more."
+msgstr ""
+"在用插件 '%2' 对文件 '%1' 进行预比较时发生了一个错误,将不再使用该预比较。"
 
 msgid "Filter applied"
 msgstr "过滤器已应用"
@@ -4064,7 +4104,8 @@ msgstr "剪贴板位于 %s"
 
 msgid ""
 "Clipboard history is disabled.\r\n"
-"To enable clipboard history, press Windows logo key + V and then click the Turn on button."
+"To enable clipboard history, press Windows logo key + V and then click the "
+"Turn on button."
 msgstr ""
 "剪贴板历史记录被禁用了。\r\n"
 "要启用剪贴板历史记录, 请按 Windows 徽标键 + V,然后单击“打开”按钮。"
@@ -4076,7 +4117,7 @@ msgid "The 32-bit version of WinMerge does not support Clipboard Compare"
 msgstr "32 位的 WinMerge 不支持剪贴板比较"
 
 msgid "WebView2 runtime is not installed. Do you want to download it?"
-msgstr "未安装 WebView2 运行库。想下载吗?"
+msgstr "未安装 WebView2 运行库。想下载吗?"
 
 msgid "New Text Compare"
 msgstr "新的文本比较"
@@ -4274,7 +4315,8 @@ msgstr ""
 msgid ""
 "Apply filter command. \r\n"
 "Usage: ExecFilterCommand COMMAND\r\n"
-"  COMMAND - command to execute. %1 in the command is replaced with the filename."
+"  COMMAND - command to execute. %1 in the command is replaced with the "
+"filename."
 msgstr ""
 "应用过滤器命令。\r\n"
 "用法: ExecFilterCommand COMMAND\r\n"
@@ -4459,16 +4501,26 @@ msgstr "显示 MS Visio 文件的文本内容"
 msgid "Display the text content of MS Word files"
 msgstr "显示 MS Word 文件的文本内容"
 
-msgid "Ignore some columns - ignored columns list from the plugin name or the plugin argument"
+msgid ""
+"Ignore some columns - ignored columns list from the plugin name or the "
+"plugin argument"
 msgstr "忽略一些列 - 忽略名称为插件名称或参数的列"
 
-msgid "The plugin ignores comments (//... and /* ... */) in C, C++, PHP and JavaScript files."
-msgstr "这个插件忽略在 C, C++, PHP 和 JavaScript 文件中的 (//... and /* ... */) 注释行。"
+msgid ""
+"The plugin ignores comments (//... and /* ... */) in C, C++, PHP and "
+"JavaScript files."
+msgstr ""
+"这个插件忽略在 C, C++, PHP 和 JavaScript 文件中的 (//... and /* ... */) 注释"
+"行。"
 
-msgid "Ignore some fields - ignored fields list from the plugin name or the plugin argument"
+msgid ""
+"Ignore some fields - ignored fields list from the plugin name or the plugin "
+"argument"
 msgstr "忽略一些字段 - 忽略名称为插件名称或参数的字段"
 
-msgid "This plugin ignores the leading line numbers in text files (e.g. NC and BASIC files)."
+msgid ""
+"This plugin ignores the leading line numbers in text files (e.g. NC and "
+"BASIC files)."
 msgstr "这个插件忽略在文本文件中行首的行号(比如 NC 和 BASIC 的文件)。"
 
 msgid "Prediff Line Filter"
@@ -4529,9 +4581,10 @@ msgstr "比较页眉和页脚"
 
 msgid ""
 "Cannot get Macros.\r\n"
-"   To allow WinMerge to compare macros, use MS Office to alter the settings in the Macro Security for the current "
-"application.\r\n"
-"   The Trust access to Visual Basic Project feature should be turned on to use this feature in WinMerge.\r\n"
+"   To allow WinMerge to compare macros, use MS Office to alter the settings "
+"in the Macro Security for the current application.\r\n"
+"   The Trust access to Visual Basic Project feature should be turned on to "
+"use this feature in WinMerge.\r\n"
 msgstr "无法获取宏。\n"
 
 msgid "Compare VBA macros"
@@ -4623,5 +4676,7 @@ msgstr "输入想要应用补丁 '%1' 的文件夹名称"
 msgid "Folder '%1' does not exist"
 msgstr "文件夹 '%1' 不存在"
 
-msgid "Do not specify the '-p0' command line option for the patch file which includes absolute paths"
+msgid ""
+"Do not specify the '-p0' command line option for the patch file which "
+"includes absolute paths"
 msgstr "不需要为包含了绝对路径的 补丁文件指定 '-p0' 命令行选项"
index d524d39..d5d1e9f 100644 (file)
@@ -1181,6 +1181,12 @@ msgstr "中間介面選單"
 msgid "Right Shell menu"
 msgstr "右側介面選單"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr "複製"
@@ -1868,8 +1874,8 @@ msgstr "偵測移位的區塊 (&N)"
 msgid "Align &similar lines"
 msgstr "相似行對齊 (&S)"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "實é©\97æ\80§å·®ç\95°æ¼\94ç®\97æ³\95 (&A)ï¼\9a"
+msgid "Diff &algorithm:"
+msgstr "差異演算法 (&A):"
 
 msgid "Enable indent &heuristic"
 msgstr "啟用縮排啟發式演算法 (&H)"
index 4b813fc..76ddb70 100644 (file)
@@ -10,8 +10,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: WinMerge in Corsican\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
-"POT-Creation-Date: 2023-06-12 00:06+0000\n"
-"PO-Revision-Date: 2023-07-06 17:40+0200\n"
+"POT-Creation-Date: 2023-09-08 20:55+0000\n"
+"PO-Revision-Date: 2023-09-10 17:36+0200\n"
 "Last-Translator: Patriccollu di Santa Maria è Sichè <https://github.com/Patriccollu/Lingua_Corsa-Infurmatica/#readme>\n"
 "Language-Team: Patriccollu di Santa Maria è Sichè\n"
 "Language: co\n"
@@ -481,16 +481,16 @@ msgid "Tree &Mode"
 msgstr "&Modu in arburu"
 
 msgid "E&xpand Subfolders"
-msgstr ""
+msgstr "&Allargà i sottucartulari"
 
 msgid "&All Subfolders"
-msgstr ""
+msgstr "&Tutti i sottucartulari"
 
 msgid "&Different Subfolders"
-msgstr ""
+msgstr "I sottucartulari &sfarenti"
 
 msgid "&Identical Subfolders"
-msgstr ""
+msgstr "I sottucartulari &uguali"
 
 msgid "&Collapse All Subfolders"
 msgstr "&Ripiegà tutti i sottucartulari"
@@ -974,6 +974,12 @@ msgstr "Listinu cuntestuale à u centru"
 msgid "Right Shell menu"
 msgstr "Listinu cuntestuale à diritta"
 
+msgid "Both Shell menu"
+msgstr "I dui listini cuntestuali"
+
+msgid "All Shell menu"
+msgstr "Tutti i listini cuntestuali"
+
 msgid "Copy"
 msgstr "Cupià"
 
@@ -1522,8 +1528,8 @@ msgstr "Attivà l’avventata di i blocchi &dispiazzati"
 msgid "Align &similar lines"
 msgstr "&Alineà e linee simile"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Cudificazione di sfarenza (esperimentale) :"
+msgid "Diff &algorithm:"
+msgstr "Cudificazione di sfarenza :"
 
 msgid "Enable indent &heuristic"
 msgstr "Attivà l’indentazione &euristica"
@@ -1991,7 +1997,7 @@ msgid "Ign&ore time differences less than 3 seconds"
 msgstr "Ignurà e sfarenze di tempu di &menu di 3 seconde"
 
 msgid "&Automatically expand subfolders after comparison:"
-msgstr ""
+msgstr "&Allargà autumaticamente i sottucartulari dopu à u paragone :"
 
 msgid "Include &unique subfolders contents"
 msgstr "Include u cuntenutu &unicu di i sottucartulari"
@@ -2294,16 +2300,16 @@ msgid "XML Files (*.xml)|*.xml|All Files (*.*)|*.*||"
 msgstr "Schedarii XML (*.xml)|*.xml|Tutti i schedarii (*.*)|*.*||"
 
 msgid "Do not expand"
-msgstr ""
+msgstr "Ùn allargà micca"
 
 msgid "Expand all subfolders"
-msgstr ""
+msgstr "Allargà tutti i sottucartulari"
 
 msgid "Expand different subfolders"
-msgstr ""
+msgstr "Allargà i sottucartulari sfarenti"
 
 msgid "Expand identical subfolders"
-msgstr ""
+msgstr "Allargà i sottucartulari uguali"
 
 msgid "File Type"
 msgstr "Tipu di schedariu"
@@ -2502,7 +2508,7 @@ msgstr "Paragone di l’elementi…"
 
 #, c-format
 msgid "%.1f[items/sec]"
-msgstr ""
+msgstr "%.1f[elementi/sec]"
 
 msgid "Select two existing folders or files to compare."
 msgstr "Selezziunà dui cartulari o schedarii esistente à paragunà."
@@ -2899,7 +2905,7 @@ msgid "You are about to close the window that is comparing folders. Are you sure
 msgstr "State per chjode a finestra chì paraguneghja i cartulari. Da veru vulete chjode a finestra ?"
 
 msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgstr "State per chjode a finestra di paragone di cartulare chì hà pigliatu un bellu pezzu. Da veru vulete chjode a finestra ?"
 
 msgid "The file or folder name is invalid."
 msgstr "U nome di u schedariu o di u cartulare hè inaccettevule."
@@ -4513,7 +4519,7 @@ msgid "Compare worksheets as image (very slow)"
 msgstr "Paragunà i foglii di calculu tale fiure (pianu pianu)"
 
 msgid " - Image split size: "
-msgstr " - Dimensione di spartera di a fiura :"
+msgstr " - Dimensione di spartera di a fiura : "
 
 msgid "Compare worksheets as HTML"
 msgstr "Paragunà i foglii di calculu tale HTML"
@@ -4595,7 +4601,7 @@ msgid "Find what"
 msgstr "Cosa circà"
 
 msgid "Replace with"
-msgstr "Rimpiazzà cù "
+msgstr "Rimpiazzà cù"
 
 msgid "Settings"
 msgstr "Preferenze"
index 11727e3..f46a199 100644 (file)
@@ -1174,6 +1174,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Desni Shell izbornik"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1858,7 +1864,7 @@ msgstr "Omogući &razlikovanje premještenih blokova"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 6afa635..1bfb9fd 100644 (file)
@@ -1174,6 +1174,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Pravá systémová nabídka"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1858,7 +1864,7 @@ msgstr "Povolit zjišťování přesunutých &bloků"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 2c01e28..dfb8a2d 100644 (file)
@@ -1175,6 +1175,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Højre Shell menu"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1859,7 +1865,7 @@ msgstr "&Aktiver detektion af flyttede blokke"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 71fd00d..e47bce0 100644 (file)
@@ -972,6 +972,12 @@ msgstr "Middelste shellmenu"
 msgid "Right Shell menu"
 msgstr "Rechter shellmenu"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopiëren"
 
@@ -1518,8 +1524,8 @@ msgstr "Detectie verplaatste blokken inschakelen"
 msgid "Align &similar lines"
 msgstr "Gelijkaardige regels uitlijnen"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Vergelijkingsalgoritme (experimenteel):"
+msgid "Diff &algorithm:"
+msgstr "Vergelijkingsalgoritme:"
 
 msgid "Enable indent &heuristic"
 msgstr "Inspringing-heuristiek inschakelen"
index 9ddbf02..4bec3f4 100644 (file)
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
-"POT-Creation-Date: 2023-08-27 15:32+0000\n"
+"POT-Creation-Date: 2023-09-08 20:55+0000\n"
 "PO-Revision-Date: \n"
 "Last-Translator: \n"
 "Language-Team: English <winmerge-translate@lists.sourceforge.net>\n"
@@ -966,6 +966,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr ""
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr ""
 
@@ -1512,7 +1518,7 @@ msgstr ""
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 4392698..9dbd459 100644 (file)
@@ -972,6 +972,12 @@ msgstr "Keskimmäinen liittymävalikko"
 msgid "Right Shell menu"
 msgstr "Oikea Shell-valikko"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopioi"
 
@@ -1523,8 +1529,8 @@ msgstr "Ota siirretyn lohkon tunnistus käyttöön"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Ero&algoritmi (kokeellinen):"
+msgid "Diff &algorithm:"
+msgstr "Ero&algoritmi:"
 
 msgid "Enable indent &heuristic"
 msgstr "Ota käyttöön &heuristinen sisennys"
index db2739f..afb2168 100644 (file)
@@ -1182,6 +1182,12 @@ msgstr "Menu explorateur du Milieu"
 msgid "Right Shell menu"
 msgstr "Menu explorateur Droite"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr "Copier"
@@ -1866,8 +1872,8 @@ msgstr "&Activer la détection des blocs déplacés"
 msgid "Align &similar lines"
 msgstr "Aligner les lignes &similaires"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Algorithme Différentiel (expérimental) :"
+msgid "Diff &algorithm:"
+msgstr "&Algorithme Différentiel:"
 
 msgid "Enable indent &heuristic"
 msgstr "Activer l'indentation &heuristique"
index a40a803..d2b3ee8 100644 (file)
@@ -973,6 +973,12 @@ msgstr "Menú contextual central"
 msgid "Right Shell menu"
 msgstr "Menú contextual dereito"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Copiar"
 
@@ -1519,8 +1525,8 @@ msgstr "Habilitar detecció&n de bloques desprazados"
 msgid "Align &similar lines"
 msgstr "Aliñar liñas &similares"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Algoritmo de comparación (experimental):"
+msgid "Diff &algorithm:"
+msgstr "&Algoritmo de comparación:"
 
 msgid "Enable indent &heuristic"
 msgstr "Habilitar a &heurística do sangrado"
index eed4276..e208c9d 100644 (file)
@@ -1177,6 +1177,12 @@ msgstr "Mittleres Shell-Menü"
 msgid "Right Shell menu"
 msgstr "Rechtes Shell-Menü"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr "Kopieren"
@@ -1862,8 +1868,8 @@ msgstr "Verschobene &Blöcke erkennen"
 msgid "Align &similar lines"
 msgstr "&Ähnliche Zeilen ausrichten"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Diff-Algorithmus (experimentell):"
+msgid "Diff &algorithm:"
+msgstr "&Diff-Algorithmus:"
 
 msgid "Enable indent &heuristic"
 msgstr "&Heuristischen Einzug aktivieren"
index 0682002..bc4ae70 100644 (file)
@@ -1173,6 +1173,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr ""
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1857,7 +1863,7 @@ msgstr "Ενεργοποίηση ανι&χνεύσεως μετακινηθέν
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 4a955b0..d0a079c 100644 (file)
@@ -1176,6 +1176,12 @@ msgstr "Középső intéző menü"
 msgid "Right Shell menu"
 msgstr "Jobb intéző menü"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr "Másolás"
@@ -1860,8 +1866,8 @@ msgstr "Mozgatott &blokk észlelés bekapcsolása"
 msgid "Align &similar lines"
 msgstr "Hasonló sorok igazítása"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Különbségkereső algoritmus (kísérleti):"
+msgid "Diff &algorithm:"
+msgstr "Különbségkereső algoritmus:"
 
 msgid "Enable indent &heuristic"
 msgstr "Heurisztika engedélyezése"
@@ -3448,7 +3454,7 @@ msgid "You are about to close the window that is comparing folders. Are you sure
 msgstr "Bezárni készülsz a mappákat összehasonlító ablakot. Biztosan bezárod az ablakot?"
 
 msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgstr "Bezárni készülsz a mappa összehasonlító ablakot, ami meglehetősen sok időt vett igénybe. Biztosan bezárod az ablakot?"
 
 msgid "The file or folder name is invalid."
 msgstr "A fájl- vagy a mappanév érvénytelen"
index e9b69eb..7b86d67 100644 (file)
@@ -970,6 +970,12 @@ msgstr "Menu shell centrale"
 msgid "Right Shell menu"
 msgstr "Menu shell destra"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Copia"
 
@@ -1516,8 +1522,8 @@ msgstr "Attiva rilevamento blocc&hi spostati"
 msgid "Align &similar lines"
 msgstr "Allinea le righe &simili"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Algoritmo differenze (sperimentale):"
+msgid "Diff &algorithm:"
+msgstr "&Algoritmo differenze:"
 
 msgid "Enable indent &heuristic"
 msgstr "Abilita rientro &euristico"
index 2859266..cff0ffc 100644 (file)
@@ -10,7 +10,7 @@ msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
 "POT-Creation-Date: 2020-12-05 22:07+0000\n"
-"PO-Revision-Date: 2023-08-05 10:36+0900\n"
+"PO-Revision-Date: 2023-09-15 09:18+0900\n"
 "Last-Translator: Takashi Sawanaka <sawanaka@d1.dion.ne.jp>\n"
 "Language-Team: Japanese <winmerge-translate@lists.sourceforge.net>\n"
 "Language: ja\n"
@@ -484,7 +484,7 @@ msgid "&All Subfolders"
 msgstr "すべてのサブフォルダー(&A)"
 
 msgid "&Different Subfolders"
-msgstr "差異があるサブフォルダー(&A)"
+msgstr "差異があるサブフォルダー(&D)"
 
 msgid "&Identical Subfolders"
 msgstr "同一のサブフォルダー(&I)"
@@ -971,6 +971,12 @@ msgstr "中央シェル メニュー"
 msgid "Right Shell menu"
 msgstr "右側シェル メニュー"
 
+msgid "Both Shell menu"
+msgstr "両側シェル メニュー"
+
+msgid "All Shell menu"
+msgstr "全てのシェル メニュー"
+
 msgid "Copy"
 msgstr "コピー"
 
@@ -1521,8 +1527,8 @@ msgstr "移動ブロック検出を有効にする(&N)"
 msgid "Align &similar lines"
 msgstr "類似行をマッチさせる(&S)"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Diff アルゴリズム (実験的機能)(&A):"
+msgid "Diff &algorithm:"
+msgstr "Diff アルゴリズム(&A):"
 
 msgid "Enable indent &heuristic"
 msgstr "Indent heuristic を有効にする(&H)"
index 8e77e36..ec79811 100644 (file)
@@ -1183,6 +1183,12 @@ msgstr "가운데 셸 메뉴"
 msgid "Right Shell menu"
 msgstr "오른쪽 셸 메뉴"
 
+msgid "Both Shell menu"
+msgstr "두 셀 메뉴"
+
+msgid "All Shell menu"
+msgstr "모든 쉘 메뉴"
+
 #, c-format
 msgid "Copy"
 msgstr "복사"
@@ -1867,8 +1873,8 @@ msgstr "이동된 블럭 감지 활성화(&N)"
 msgid "Align &similar lines"
 msgstr "유사한 줄 정렬(&S)"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "비교 알고리즘 (실험 기능)(&A)"
+msgid "Diff &algorithm:"
+msgstr "비교 알고리즘(&A)"
 
 msgid "Enable indent &heuristic"
 msgstr "들여쓰기 휴리스틱 활성화(&H)"
index 18b983e..319484f 100644 (file)
@@ -8,8 +8,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
-"POT-Creation-Date: 2023-08-05 10:45+0000\n"
-"PO-Revision-Date: 2023-08-08 08:08+0200\n"
+"POT-Creation-Date: 2023-09-08 20:55+0000\n"
+"PO-Revision-Date: 2023-09-11 11:11+0200\n"
 "Last-Translator: Tichij <tichij@mail.com>\n"
 "Language-Team: Lithuanian <winmerge-translate@lists.sourceforge.net>\n"
 "Language: lt\n"
@@ -20,7 +20,7 @@ msgstr ""
 "X-Poedit-Language: Lithuanian\n"
 "X-Poedit-SourceCharset: UTF-8\n"
 "X-Poedit-Basepath: ../../Src/\n"
-"X-Generator: Poedit 3.3.1\n"
+"X-Generator: Poedit 3.3.2\n"
 
 #. LANGUAGE, SUBLANGUAGE
 msgid "LANG_ENGLISH, SUBLANG_ENGLISH_US"
@@ -972,6 +972,12 @@ msgstr "Vidurinis sistemos meniu"
 msgid "Right Shell menu"
 msgstr "Dešinysis sistemos meniu"
 
+msgid "Both Shell menu"
+msgstr "Abu sistemos meniu"
+
+msgid "All Shell menu"
+msgstr "Visi sistemos meniu"
+
 msgid "Copy"
 msgstr "Kopijuoti"
 
@@ -1518,8 +1524,8 @@ msgstr "Įju&ngti perkeltų blokų aptikimą"
 msgid "Align &similar lines"
 msgstr "&Sutapdinti panašias eilutes"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Lyginimo &algoritmas (Bandymai):"
+msgid "Diff &algorithm:"
+msgstr "Lyginimo &algoritmas:"
 
 msgid "Enable indent &heuristic"
 msgstr "Įgalinti &heuristinę įtrauką"
@@ -2658,7 +2664,7 @@ msgid "You are about to close the window that is comparing folders. Are you sure
 msgstr "Jūs ketinate užverti langą, kuriame lyginami katalogai. Ar tikrai norite užverti langą?"
 
 msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgstr "Jūs ketinate užverti katalogų palyginimo langą, kurio suformavimas užtruko nemažai laiko. Ar tikrai norite užverti langą?"
 
 msgid "The file or folder name is invalid."
 msgstr "Netinkamas failo ar katalogo pavadinimas."
index db714ea..8f9cb24 100644 (file)
@@ -972,6 +972,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Høyre skallmeny"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr ""
 
@@ -1520,7 +1526,7 @@ msgstr "&Aktiver flyttet blokk-oppdagelse"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index c597d91..b36fc75 100644 (file)
@@ -1175,6 +1175,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr " گزينگان / فهرست پوسته راست "
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1861,7 +1867,7 @@ msgstr "&n فعال کردن تشخيص قطعه جابجا شده "
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 5ea68a3..aa33fa1 100644 (file)
@@ -973,6 +973,12 @@ msgstr "Środkowe menu powłoki"
 msgid "Right Shell menu"
 msgstr "Prawe menu powłoki"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopiuj"
 
@@ -1519,8 +1525,8 @@ msgstr "Włącz wykrywanie przeniesionych bloków"
 msgid "Align &similar lines"
 msgstr "Wyrównaj podobne wiersze"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Algorytm porównywania (eksperymentalny):"
+msgid "Diff &algorithm:"
+msgstr "Algorytm porównywania:"
 
 msgid "Enable indent &heuristic"
 msgstr "Włącz heurystykę wcięcia"
index 23576f5..dc1d6a7 100644 (file)
@@ -11,7 +11,7 @@ msgstr ""
 "Project-Id-Version: WinMerge\n"
 "Report-Msgid-Bugs-To: https://bugs.winmerge.org/\n"
 "POT-Creation-Date: 2022-10-16 00:15+0000\n"
-"PO-Revision-Date: 2023-08-07 12:43+0100\n"
+"PO-Revision-Date: 2023-09-03 16:25+0100\n"
 "Last-Translator: Hugo Carvalho <hugokarvalho@hotmail.com>\n"
 "Language-Team: Portuguese <winmerge-translate@lists.sourceforge.net>\n"
 "Language: pt\n"
@@ -973,6 +973,12 @@ msgstr "Menu de contexto do meio"
 msgid "Right Shell menu"
 msgstr "Menu de contexto da direita"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Copiar"
 
@@ -1270,12 +1276,10 @@ msgstr "Remover"
 msgid "Substitution Filters"
 msgstr "Filtros de substituição"
 
-msgid ""
-"The changes that appear on the panels as the listed pairs below will be ignored or marked as insignificant. Patches "
-"are unaffected."
+msgid "The changes that appear on the panels as the listed pairs below will be ignored or marked as insignificant. Patches are unaffected."
 msgstr ""
-"As alterações que aparecem nos painéis como os pares listados abaixo serão ignoradas ou marcadas como "
-"insignificantes. As correções não são afetadas."
+"As alterações que aparecem nos painéis como os pares listados abaixo serão ignoradas ou marcadas como insignificantes. As correções não são "
+"afetadas."
 
 msgid "Enable"
 msgstr "Ativar"
@@ -1523,8 +1527,8 @@ msgstr "Ativar deteção de bloco movido"
 msgid "Align &similar lines"
 msgstr "Alinhar linhas &semelhantes"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Diff &algoritmo (Experimental):"
+msgid "Diff &algorithm:"
+msgstr "Diff &algoritmo:"
 
 msgid "Enable indent &heuristic"
 msgstr "Ativar travessão &heurístico"
@@ -1574,10 +1578,8 @@ msgstr "Caracteres da palavra:"
 msgid "&Rendering Mode:"
 msgstr "Modo de &renderização:"
 
-msgid ""
-"WinMerge allows hiding some common message boxes. Press the Reset button to make all message boxes visible again."
-msgstr ""
-"O WinMerge permite ocultar mensagens predefinidas. Prima o botão Repor para visualizar novamente todas as mensagens."
+msgid "WinMerge allows hiding some common message boxes. Press the Reset button to make all message boxes visible again."
+msgstr "O WinMerge permite ocultar mensagens predefinidas. Prima o botão Repor para visualizar novamente todas as mensagens."
 
 msgid "Reset"
 msgstr "Repor"
@@ -2163,11 +2165,11 @@ msgstr ""
 "Comparação de pastas WinMerge"
 
 msgid ""
-"WinMerge comes with ABSOLUTELY NO WARRANTY. This is free software and you are welcome to redistribute it under "
-"certain circumstances; see the GNU General Public License in the Help menu for details."
+"WinMerge comes with ABSOLUTELY NO WARRANTY. This is free software and you are welcome to redistribute it under certain circumstances; see "
+"the GNU General Public License in the Help menu for details."
 msgstr ""
-"O WinMerge vem SEM QUALQUER GARANTIA. Este é um software livre e pode ser redistribuído sobre determinadas "
-"circunstâncias; Consulte a licença pública geral GNU ou vá ao menu de Ajuda para mais informação."
+"O WinMerge vem SEM QUALQUER GARANTIA. Este é um software livre e pode ser redistribuído sobre determinadas circunstâncias; Consulte a "
+"licença pública geral GNU ou vá ao menu de Ajuda para mais informação."
 
 msgid "&Abort"
 msgstr "&Abortar"
@@ -2205,11 +2207,8 @@ msgstr "Ignorar tudo"
 msgid "Don't display this &message again."
 msgstr "Não voltar a mostrar esta mensagem."
 
-msgid ""
-"To make this message box visible again, press the Reset button on the Message Boxes page of the Options dialog."
-msgstr ""
-"Para tornar esta caixa de mensagens visível novamente, prima o botão Repor na página Caixas de mensagens da janela "
-"de opções."
+msgid "To make this message box visible again, press the Reset button on the Message Boxes page of the Options dialog."
+msgstr "Para tornar esta caixa de mensagens visível novamente, prima o botão Repor na página Caixas de mensagens da janela de opções."
 
 msgid "Syntax"
 msgstr "Sintaxe"
@@ -2900,10 +2899,10 @@ msgid "Confirm Move"
 msgstr "Confirmar"
 
 msgid "You are about to close the window that is comparing folders. Are you sure you want to close the window?"
-msgstr "Está prestes a fechar a janela que está a comparar as pastas. Tem a certeza que deseja fechar a janela?"
+msgstr "Está prestes a fechar a janela que está a comparar as pastas. Tem a certeza de que pretende fechar a janela?"
 
 msgid "You are about to close the folder comparison window that took a significant amount of time. Are you sure you want to close the window?"
-msgstr ""
+msgstr "Está prestes a fechar a janela de comparação de pastas que demorou bastante tempo. Tem a certeza de que pretende fechar a janela?"
 
 msgid "The file or folder name is invalid."
 msgstr "O nome do ficheiro ou pasta é inválido."
@@ -3296,8 +3295,7 @@ msgid "Middle side encoding."
 msgstr "Codificação do meio."
 
 msgid "Number of ignored differences in file. These differences are ignored by WinMerge and cannot be merged."
-msgstr ""
-"Número de diferenças ignoradas no ficheiro. Estas diferenças são ignoradas pelo WinMerge e não podem ser fundidas."
+msgstr "Número de diferenças ignoradas no ficheiro. Estas diferenças são ignoradas pelo WinMerge e não podem ser fundidas."
 
 msgid "Number of differences in file. This number does not include ignored differences."
 msgstr "Número de diferenças no ficheiro. Este número não inclui diferenças ignoradas."
@@ -3365,15 +3363,15 @@ msgid ""
 "\n"
 "Do you want to treat all carriage return types as equivalent for this comparison?\n"
 "\n"
-"Note: If you always want to treat all carriage return types as equivalent, set the option 'Ignore carriage return "
-"differences (Windows/Unix/Mac)' in the Compare tab of the options dialog (available under Edit/Options)."
+"Note: If you always want to treat all carriage return types as equivalent, set the option 'Ignore carriage return differences (Windows/Unix/"
+"Mac)' in the Compare tab of the options dialog (available under Edit/Options)."
 msgstr ""
 "Estes ficheiros utilizam diferentes tipos de procedimento.\n"
 "\n"
 "Deseja tratar todos os tipos de procedimentos por igual para comparação?\n"
 "\n"
-"Nota: Se deseja tratar todos os tipos de procedimentos por igual, defina a opção 'Ignorar diferentes tipos de "
-"ficheiros (Windows/Unix/Mac)' no separador de comparação no diálogo opções (disponível em Editar/Definições)."
+"Nota: Se deseja tratar todos os tipos de procedimentos por igual, defina a opção 'Ignorar diferentes tipos de ficheiros (Windows/Unix/Mac)' "
+"no separador de comparação no diálogo opções (disponível em Editar/Definições)."
 
 msgid "The selected folder is invalid."
 msgstr "A pasta selecionada é inválida."
@@ -3423,8 +3421,8 @@ msgid ""
 "Would you like to treat both files as being in the default Windows codepage (recommended)?"
 msgstr ""
 "Encontradas páginas de código diferentes nos ficheiros da esquerda (cp%d) e direita (cp%d).\n"
-"Apresentar cada ficheiro na sua página de código terá melhor visualização, mas combinar/copiar poderá ser arriscado."
-"\\Deseja tratar os dois ficheiros como tendo as páginas de código predefinidas para as janelas?"
+"Apresentar cada ficheiro na sua página de código terá melhor visualização, mas combinar/copiar poderá ser arriscado.\\Deseja tratar os dois "
+"ficheiros como tendo as páginas de código predefinidas para as janelas?"
 
 msgid "Information lost due to encoding errors: both files"
 msgstr "Informações perdidas devido a erros de codificação: ambos os ficheiros"
@@ -4059,9 +4057,7 @@ msgstr "'%1' não é um plugin de pré-diferenciação"
 
 #, c-format
 msgid "An error occurred while prediffing the file '%1' with the plugin '%2'. The prediffing is not applied any more."
-msgstr ""
-"Ocorreu um erro durante a pré-diferenciação do ficheiro '%1' com o plugin '%2'. A pré-diferenciação já não é "
-"aplicada."
+msgstr "Ocorreu um erro durante a pré-diferenciação do ficheiro '%1' com o plugin '%2'. A pré-diferenciação já não é aplicada."
 
 msgid "Filter applied"
 msgstr "Filtro aplicado"
@@ -4537,13 +4533,11 @@ msgstr "Comparar cabeçalhos e rodapés"
 
 msgid ""
 "Cannot get Macros.\r\n"
-"   To allow WinMerge to compare macros, use MS Office to alter the settings in the Macro Security for the current "
-"application.\r\n"
+"   To allow WinMerge to compare macros, use MS Office to alter the settings in the Macro Security for the current application.\r\n"
 "   The Trust access to Visual Basic Project feature should be turned on to use this feature in WinMerge.\r\n"
 msgstr ""
 "Não é possível obter Macros.\r\n"
-"   Para possibilitar a comparação de macros, use o MS Office para alterar as definições na Segurança de Macro para "
-"a aplicação atual.\r\n"
+"   Para possibilitar a comparação de macros, use o MS Office para alterar as definições na Segurança de Macro para a aplicação atual.\r\n"
 "   O acesso de Confiança do projeto do Visual Basic deve estar ativado para usar este recurso no WinMerge.\r\n"
 
 msgid "Compare VBA macros"
index ed33783..a2265a9 100644 (file)
@@ -1174,6 +1174,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr ""
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1858,7 +1864,7 @@ msgstr "Activea&ză detecţie blocuri mutate"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 4a06d34..c8e366d 100644 (file)
@@ -974,6 +974,12 @@ msgstr "Меню оболочки в центре"
 msgid "Right Shell menu"
 msgstr "Меню оболочки справа"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Копировать"
 
@@ -1520,8 +1526,8 @@ msgstr "Обнаружение переме&щенных блоков"
 msgid "Align &similar lines"
 msgstr "Выровнять по&хожие строки"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Алгоритм сравнения (эксперимент.):"
+msgid "Diff &algorithm:"
+msgstr "Алгоритм сравнения:"
 
 msgid "Enable indent &heuristic"
 msgstr "Включать эвристику отступов"
index b79855e..1abad2c 100644 (file)
@@ -1171,6 +1171,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Десни изборник /љуске/"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1841,7 +1847,7 @@ msgstr "Омогући откривање премештених група"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index b54308b..bc665b3 100644 (file)
@@ -1174,6 +1174,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Right Shell menu"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1858,7 +1864,7 @@ msgstr "E&nable moved block detection"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 30c74e6..9e23105 100644 (file)
@@ -972,6 +972,12 @@ msgstr "Vzhľad strednej ponuky"
 msgid "Right Shell menu"
 msgstr "Vzhľad pravej ponuky"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopírovať"
 
@@ -1518,8 +1524,8 @@ msgstr "Povoliť &zisťovanie presunu bloku"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Algoritmus rozdielov (experimentálne):"
+msgid "Diff &algorithm:"
+msgstr "&Algoritmus rozdielov:"
 
 msgid "Enable indent &heuristic"
 msgstr "Povoliť &heuristické odsadenie"
index d1d6ad5..b9a688a 100644 (file)
@@ -972,6 +972,12 @@ msgstr "Srednji meni lupine"
 msgid "Right Shell menu"
 msgstr "Meni lupine desne"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopiraj"
 
@@ -1518,8 +1524,8 @@ msgstr "Omogoči zazna&vanje premaknjenih blokov"
 msgid "Align &similar lines"
 msgstr "Poravnaj po&dobne črte"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Al&goritem razlik (poskusno):"
+msgid "Diff &algorithm:"
+msgstr "Al&goritem razlik:"
 
 msgid "Enable indent &heuristic"
 msgstr "Omogoči &hevristični zamik"
index 1f6add5..8ad7f53 100644 (file)
@@ -975,6 +975,12 @@ msgstr "Menú contextual central"
 msgid "Right Shell menu"
 msgstr "Menú contextual derecho"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Copiar"
 
@@ -1521,8 +1527,8 @@ msgstr "Habilitar detecció&n de bloques desplazados"
 msgid "Align &similar lines"
 msgstr "Alinear líneas &simliares"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Algoritmo de comparación (experimental):"
+msgid "Diff &algorithm:"
+msgstr "&Algoritmo de comparación:"
 
 msgid "Enable indent &heuristic"
 msgstr "Habilitar la &heurística de indentación"
index 1b9beb7..5eeb916 100644 (file)
@@ -976,6 +976,12 @@ msgstr "Gränssnittsmeny mitten"
 msgid "Right Shell menu"
 msgstr "Gränssnittsmeny höger"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopiera"
 
@@ -1527,8 +1533,8 @@ msgstr "Aktivera detektering av flyttade block"
 msgid "Align &similar lines"
 msgstr "Injustera likartade rader"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "Jämförelsealgoritm (experimentell):"
+msgid "Diff &algorithm:"
+msgstr "Jämförelsealgoritm:"
 
 msgid "Enable indent &heuristic"
 msgstr "Aktivera indragsstöd"
index c121a22..de988ac 100644 (file)
@@ -967,6 +967,12 @@ msgstr "மத்திய ஷெல் மெனு"
 msgid "Right Shell menu"
 msgstr "வலது ஷெல் மெனு"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "நகல்"
 
@@ -1513,8 +1519,8 @@ msgstr "நகர்த்தப்பட்ட தொகுதி கண்ட
 msgid "Align &similar lines"
 msgstr "ஒத்த வரிகளை சீரமைக்கவும்"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "வேறுபாடு &அல்காரிதம் (பரிசோதனை):"
+msgid "Diff &algorithm:"
+msgstr "வேறுபாடு &அல்காரிதம்:"
 
 msgid "Enable indent &heuristic"
 msgstr "இன்டென்ட் &யூரிஸ்டிக் இயக்கு"
index d4064b1..993fc8f 100644 (file)
@@ -972,6 +972,12 @@ msgstr "Orta pano sağ tık menüsü"
 msgid "Right Shell menu"
 msgstr "Sağ pano sağ tık menüsü"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 msgid "Copy"
 msgstr "Kopyala"
 
@@ -1523,8 +1529,8 @@ msgstr "Taşı&nmış blok algılaması kullanılsın"
 msgid "Align &similar lines"
 msgstr "&Benzer satırlar hizalansın"
 
-msgid "Diff &algorithm (Experimental):"
-msgstr "&Fark algortiması (Deneysel):"
+msgid "Diff &algorithm:"
+msgstr "&Fark algortiması:"
 
 msgid "Enable indent &heuristic"
 msgstr "&Sezgisel girinti kullanılsın"
index f893374..49238d0 100644 (file)
@@ -1158,6 +1158,12 @@ msgstr ""
 msgid "Right Shell menu"
 msgstr "Праве меню оболонки"
 
+msgid "Both Shell menu"
+msgstr ""
+
+msgid "All Shell menu"
+msgstr ""
+
 #, c-format
 msgid "Copy"
 msgstr ""
@@ -1842,7 +1848,7 @@ msgstr "Виявлення перемі&щених блоків"
 msgid "Align &similar lines"
 msgstr ""
 
-msgid "Diff &algorithm (Experimental):"
+msgid "Diff &algorithm:"
 msgstr ""
 
 msgid "Enable indent &heuristic"
index 73eec39..e9c002c 100644 (file)
--- a/Version.h
+++ b/Version.h
@@ -1,5 +1,5 @@
-#define FILEVER        2,16,32,2\r
-#define PRODUCTVER     2,16,32,2\r
-#define STRFILEVER     "2.16.32.2"\r
-#define STRPRODUCTVER  "2.16.32.2"\r
-#define STRPRIVATEBUILD "jp-2"\r
+#define FILEVER        2,16,32,3\r
+#define PRODUCTVER     2,16,32,3\r
+#define STRFILEVER     "2.16.32.3"\r
+#define STRPRODUCTVER  "2.16.32.3"\r
+#define STRPRIVATEBUILD "jp-3"\r