OSDN Git Service

Improve plugin system (#797)
authorTakashi Sawanaka <sdottaka@users.sourceforge.net>
Sun, 20 Jun 2021 08:12:00 +0000 (17:12 +0900)
committerGitHub <noreply@github.com>
Sun, 20 Jun 2021 08:12:00 +0000 (17:12 +0900)
- Add categorized Unpacker plugin menu items to various menus
  - Select Files or Folders window
  ![image](https://user-images.githubusercontent.com/98126/122665970-85f3de80-d1e5-11eb-8ffb-5182652326c3.png)
  - Folder Compare window
  ![image](https://user-images.githubusercontent.com/98126/122665994-b471b980-d1e5-11eb-87e8-4b91a15bd8a7.png)
  - File Compare window
  ![image](https://user-images.githubusercontent.com/98126/122664730-23e3ab00-d1de-11eb-99c7-285596efaf9d.png)
  ![image](https://user-images.githubusercontent.com/98126/122666029-ee42c000-d1e5-11eb-922e-b047d74c43fb.png)
- Make it possible to specify multiple Unpacker/Prediffer plugins by concatenating them with `|` and to specify arguments.
   e.g. `ExecFilterCommand sort | MakeUpper`
![image](https://user-images.githubusercontent.com/98126/122665171-aa998780-d1e0-11eb-9f88-deae7da2c6e5.png)
- Allow Unpacker/Prediffer plugins to be specified for multiple files at once in Folder Compare window. The specified plugin will be visible in the Unpacker and Prediffer columns
   ![image](https://user-images.githubusercontent.com/98126/122666428-116e6f00-d1e8-11eb-9cc5-554285c8460e.png)
   ![image](https://user-images.githubusercontent.com/98126/122664824-ad937880-d1de-11eb-9699-18132231d11e.png)
- Add "(U)" to the tab title when using the Unpacker plugin. Also, add "(P)" to the tab title when using the Prediffer plugin
  ![image](https://user-images.githubusercontent.com/98126/122665422-12040700-d1e2-11eb-9b31-746eb8a79cf9.png)
- Allow the plugin settings dialog to specify default arguments that will be used when no plugin arguments are specified
- Allow plugins used by Automatic Unpacking/Prediffing to be excluded in the plugin settings dialog
  ![image](https://user-images.githubusercontent.com/98126/122665573-f816f400-d1e2-11eb-964e-accbd09734ba.png)
- New unpacker plugins
   - ApacheTika (Apache Tika)
   - PrettifyJSON (jq)
   - PrettifyXML (tidy-html5)
   - QueryCSV (q)
   - QueryTSV (q)
   - QueryJSON (jq)
   - MakeUpper (auto-generated unpacker plugin from editor script plugin)
   - MakeLower (auto-generated unpacker plugin from editor script plugin)
   - RemoveDuplicates (auto-generated unpacker plugin from editor script plugin)
   - CountDuplicates (auto-generated unpacker plugin from editor script plugin)
   - SortAscending (auto-generated unpacker plugin from editor script plugin)
   - ExecFilterCommand (auto-generated unpacker plugin from editor script plugin)
   - Tokenize (auto-generated unpacker plugin from editor script plugin)
   - Trim (auto-generated unpacker plugin from editor script plugin)
   - VisualizeGraphviz (graphviz)
- New editor script plugins
   - RemoveDuplicates
   - CountDuplicates
   - Tokenize
   - Trim
   - ApacheTika  (auto-generated editor script plugin from unpacker plugin)
   - PrettifyJSON  (auto-generated editor script plugin from unpacker plugin)
   - PrettifyXML  (auto-generated editor script plugin from unpacker plugin)
 - Internals
   - Allow command-based plugins to be defined in XML file
   - Make the menu items of the Unpacker / Prediffer / Editor Script plugin translatable
   - Create Editor Script plugins from the Unpacker plugins

211 files changed:
.gitmodules
ALL.vs2017.sln
ALL.vs2019.sln
BuildArc.cmd
Docs/Manual/EN/Plugins.xml
Docs/Manual/JP/Plugins.xml
DownloadDeps.cmd
Installer/InnoSetup/WinMerge.iss
Installer/InnoSetup/WinMergeARM64.is6.iss
Installer/InnoSetup/WinMergeX64.is6.iss
Installer/InnoSetup/WinMergeX64.iss
Installer/InnoSetup/WinMergeX64NonAdmin.iss
Plugins/Commands/Apache-Tika/tika.bat [new file with mode: 0644]
Plugins/Commands/q/q.bat [new file with mode: 0644]
Plugins/CopyDlls.bat [new file with mode: 0644]
Plugins/Plugins.xml [new file with mode: 0644]
Plugins/dlls/ARM64/IgnoreColumns.dll
Plugins/dlls/ARM64/IgnoreCommentsC.dll
Plugins/dlls/ARM64/IgnoreFieldsComma.dll
Plugins/dlls/ARM64/IgnoreFieldsTab.dll
Plugins/dlls/ApplyPatch.sct
Plugins/dlls/CompareMSExcelFiles.sct
Plugins/dlls/CompareMSPowerPointFiles.sct
Plugins/dlls/CompareMSVisioFiles.sct
Plugins/dlls/CompareMSWordFiles.sct
Plugins/dlls/IgnoreColumns.dll
Plugins/dlls/IgnoreCommentsC.dll
Plugins/dlls/IgnoreFieldsComma.dll
Plugins/dlls/IgnoreFieldsTab.dll
Plugins/dlls/PrediffLineFilter.sct
Plugins/dlls/X64/IgnoreColumns.dll
Plugins/dlls/X64/IgnoreCommentsC.dll
Plugins/dlls/X64/IgnoreFieldsComma.dll
Plugins/dlls/X64/IgnoreFieldsTab.dll
Plugins/dlls/editor addin.sct
Plugins/dlls/insert datetime.sct
Plugins/src_VCPP/IgnoreColumns/IgnoreColumns.idl
Plugins/src_VCPP/IgnoreColumns/IgnoreColumns.rc
Plugins/src_VCPP/IgnoreColumns/WinMergeScript.cpp
Plugins/src_VCPP/IgnoreColumns/WinMergeScript.h
Plugins/src_VCPP/IgnoreCommentsC/IgnoreCommentsC.idl
Plugins/src_VCPP/IgnoreCommentsC/IgnoreCommentsC.rc
Plugins/src_VCPP/IgnoreCommentsC/WinMergeScript.cpp
Plugins/src_VCPP/IgnoreCommentsC/WinMergeScript.h
Plugins/src_VCPP/IgnoreFieldsComma/IgnoreFieldsComma.idl
Plugins/src_VCPP/IgnoreFieldsComma/IgnoreFieldsComma.rc
Plugins/src_VCPP/IgnoreFieldsComma/WinMergeScript.cpp
Plugins/src_VCPP/IgnoreFieldsComma/WinMergeScript.h
Plugins/src_VCPP/IgnoreFieldsTab/IgnoreFieldsTab.idl
Plugins/src_VCPP/IgnoreFieldsTab/IgnoreFieldsTab.rc
Plugins/src_VCPP/IgnoreFieldsTab/WinMergeScript.cpp
Plugins/src_VCPP/IgnoreFieldsTab/WinMergeScript.h
Src/Common/UniFile.h
Src/Common/UnicodeString.cpp
Src/Common/UnicodeString.h
Src/Common/unicoder.cpp
Src/Common/unicoder.h
Src/DiffContext.cpp
Src/DiffContext.h
Src/DiffFileData.cpp
Src/DiffFileData.h
Src/DiffTextBuffer.cpp
Src/DiffTextBuffer.h
Src/DiffWrapper.cpp
Src/DirActions.h
Src/DirDoc.cpp
Src/DirView.cpp
Src/DirView.h
Src/DirViewColItems.cpp
Src/EncodingErrorBar.cpp
Src/EncodingErrorBar.h
Src/FileTransform.cpp
Src/FileTransform.h
Src/FolderCmp.cpp
Src/HexMergeDoc.cpp
Src/HexMergeDoc.h
Src/HexMergeFrm.cpp
Src/HexMergeFrm.h
Src/HexMergeView.cpp
Src/HexMergeView.h
Src/IMergeDoc.h
Src/ImgMergeFrm.cpp
Src/ImgMergeFrm.h
Src/InternalPlugins.cpp [new file with mode: 0644]
Src/MainFrm.cpp
Src/MainFrm.h
Src/Merge.cpp
Src/Merge.h
Src/Merge.rc
Src/Merge.vcxproj
Src/Merge.vcxproj.filters
Src/Merge7zFormatMergePluginImpl.cpp
Src/MergeDoc.cpp
Src/MergeDoc.h
Src/MergeEditFrm.cpp
Src/MergeEditFrm.h
Src/MergeEditView.cpp
Src/MergeEditView.h
Src/MergeFrameCommon.cpp
Src/MergeFrameCommon.h
Src/OpenDoc.cpp
Src/OpenDoc.h
Src/OpenView.cpp
Src/OpenView.h
Src/OptionsDef.h
Src/OptionsInit.cpp
Src/PluginManager.cpp
Src/PluginManager.h
Src/Plugins.cpp
Src/Plugins.h
Src/PluginsListDlg.cpp
Src/ProjectFile.cpp
Src/ProjectFile.h
Src/SelectPluginDlg.cpp [new file with mode: 0644]
Src/SelectPluginDlg.h [moved from Src/SelectUnpackerDlg.h with 61% similarity]
Src/SelectUnpackerDlg.cpp [deleted file]
Src/TempFile.h
Src/UniMarkdownFile.cpp [deleted file]
Src/UniMarkdownFile.h [deleted file]
Src/WinMergePluginBase.h
Src/paths.cpp
Src/paths.h
Src/resource.h
Testing/Data/Office/excel.xls
Testing/FolderCompare/FolderCompare.vcxproj
Testing/FolderCompare/FolderCompare.vcxproj.filters
Testing/GoogleTest/Plugins/Plugins_test.cpp
Testing/GoogleTest/ProjectFile/ProjectFile_test_LeftAndRight.cpp
Testing/GoogleTest/ProjectFile/ProjectFile_test_LeftAndRightNonRecursive.cpp
Testing/GoogleTest/ProjectFile/ProjectFile_test_PathsAndFilter.cpp
Testing/GoogleTest/ProjectFile/ProjectFile_test_SimpleLeft.cpp
Testing/GoogleTest/ProjectFile/ProjectFile_test_SimpleRight.cpp
Testing/GoogleTest/TestData/PathsAndFilter.WinMerge
Testing/GoogleTest/UnitTests/UnitTests.vcxproj
Testing/GoogleTest/UnitTests/UnitTests.vcxproj.filters
Testing/GoogleTest/UnitTests/misc.cpp
Translations/InnoSetup/Arabic.isl
Translations/InnoSetup/Basque.isl
Translations/InnoSetup/Brazilian.isl
Translations/InnoSetup/Bulgarian.isl
Translations/InnoSetup/Catalan.isl
Translations/InnoSetup/Chinese_Simplified.isl
Translations/InnoSetup/Chinese_Traditional.isl
Translations/InnoSetup/Croatian.isl
Translations/InnoSetup/Czech.isl
Translations/InnoSetup/Danish.isl
Translations/InnoSetup/Dutch.isl
Translations/InnoSetup/English.isl
Translations/InnoSetup/Finnish.isl
Translations/InnoSetup/French.isl
Translations/InnoSetup/Galician.isl
Translations/InnoSetup/German.isl
Translations/InnoSetup/Greek.isl
Translations/InnoSetup/Hungarian.isl
Translations/InnoSetup/Italian.isl
Translations/InnoSetup/Japanese.isl
Translations/InnoSetup/Korean.isl
Translations/InnoSetup/Lithuanian.isl
Translations/InnoSetup/Norwegian.isl
Translations/InnoSetup/Persian.isl
Translations/InnoSetup/Polish.isl
Translations/InnoSetup/Portuguese.isl
Translations/InnoSetup/Romanian.isl
Translations/InnoSetup/Russian.isl
Translations/InnoSetup/Serbian.isl
Translations/InnoSetup/Sinhala.islu
Translations/InnoSetup/Slovak.isl
Translations/InnoSetup/Slovenian.isl
Translations/InnoSetup/Spanish.isl
Translations/InnoSetup/Swedish.isl
Translations/InnoSetup/Turkish.isl
Translations/InnoSetup/Ukrainian.isl
Translations/TranslationsStatus.html
Translations/TranslationsStatus.md
Translations/TranslationsStatus.xml
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/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/Turkish.po
Translations/WinMerge/Ukrainian.po

index 4dc0680..a33cf17 100644 (file)
@@ -13,3 +13,9 @@
 [submodule "Externals/freeimage"]
        path = Externals/freeimage
        url = https://github.com/WinMerge/freeimage.git
+[submodule "Externals/tidy-html5"]
+       path = Externals/tidy-html5
+       url = https://github.com/htacg/tidy-html5.git
+[submodule "Externals/jq"]
+       path = Externals/jq
+       url = https://github.com/stedolan/jq.git
index 52ecedb..62a52f8 100644 (file)
@@ -49,6 +49,9 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GUITests", "Testing\GoogleTest\GUITests\GUITests.vcxproj", "{0A3727B1-51E7-4702-AD0C-8AEE317EA510}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Plugins.xml = Plugins\Plugins.xml
+       EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DisplayBinaryFiles", "Plugins\src_VCPP\DisplayBinaryFiles\DisplayBinaryFiles.vcxproj", "{6877DE2D-4ABA-49B0-858D-7D9A9F92945C}"
 EndProject
@@ -319,6 +322,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "diffutils", "Src\diffutils\
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "Externals\gtest\gtest.vcxitems", "{9EE35458-B145-444F-92B7-27FF72112C42}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commands", "Commands", "{BB290B2D-F5B9-4552-AE32-9319C03E41C0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apache-Tika", "Apache-Tika", "{5DADCF29-6A44-4AD1-8E42-DCB162A1907D}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Commands\Apache-Tika\tika.bat = Plugins\Commands\Apache-Tika\tika.bat
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "q", "q", "{E4EF583F-653D-4445-A649-555C8AD730E7}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Commands\q\q.bat = Plugins\Commands\q\q.bat
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\gtest\gtest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
@@ -1024,6 +1039,9 @@ Global
                {E11617CA-2D87-4571-B22A-48C922D9A0F9} = {2313487A-3891-4F6E-A4F4-13E8DE53D7AC}
                {68F1D3A1-9DCA-4B3D-B245-F4ACA5F16563} = {CE514278-A13F-4F6A-93EB-5653410AC214}
                {9EE35458-B145-444F-92B7-27FF72112C42} = {CE514278-A13F-4F6A-93EB-5653410AC214}
+               {BB290B2D-F5B9-4552-AE32-9319C03E41C0} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
+               {5DADCF29-6A44-4AD1-8E42-DCB162A1907D} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
+               {E4EF583F-653D-4445-A649-555C8AD730E7} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
index 4215c02..d1a49c0 100644 (file)
@@ -49,6 +49,9 @@ EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GUITests", "Testing\GoogleTest\GUITests\GUITests.vcxproj", "{0A3727B1-51E7-4702-AD0C-8AEE317EA510}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Plugins.xml = Plugins\Plugins.xml
+       EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DisplayBinaryFiles", "Plugins\src_VCPP\DisplayBinaryFiles\DisplayBinaryFiles.vcxproj", "{6877DE2D-4ABA-49B0-858D-7D9A9F92945C}"
 EndProject
@@ -319,6 +322,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "diffutils", "Src\diffutils\
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "Externals\gtest\gtest.vcxitems", "{9EE35458-B145-444F-92B7-27FF72112C42}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commands", "Commands", "{BB290B2D-F5B9-4552-AE32-9319C03E41C0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Apache-Tika", "Apache-Tika", "{5DADCF29-6A44-4AD1-8E42-DCB162A1907D}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Commands\Apache-Tika\tika.bat = Plugins\Commands\Apache-Tika\tika.bat
+       EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "q", "q", "{E4EF583F-653D-4445-A649-555C8AD730E7}"
+       ProjectSection(SolutionItems) = preProject
+               Plugins\Commands\q\q.bat = Plugins\Commands\q\q.bat
+       EndProjectSection
+EndProject
 Global
        GlobalSection(SharedMSBuildProjectFiles) = preSolution
                Externals\gtest\gtest.vcxitems*{0a3727b1-51e7-4702-ad0c-8aee317ea510}*SharedItemsImports = 4
@@ -1024,6 +1039,9 @@ Global
                {E11617CA-2D87-4571-B22A-48C922D9A0F9} = {2313487A-3891-4F6E-A4F4-13E8DE53D7AC}
                {68F1D3A1-9DCA-4B3D-B245-F4ACA5F16563} = {CE514278-A13F-4F6A-93EB-5653410AC214}
                {9EE35458-B145-444F-92B7-27FF72112C42} = {CE514278-A13F-4F6A-93EB-5653410AC214}
+               {BB290B2D-F5B9-4552-AE32-9319C03E41C0} = {AA9C3A4D-4CD6-46BE-A266-A5FE7BE52F65}
+               {5DADCF29-6A44-4AD1-8E42-DCB162A1907D} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
+               {E4EF583F-653D-4445-A649-555C8AD730E7} = {BB290B2D-F5B9-4552-AE32-9319C03E41C0}
        EndGlobalSection
        GlobalSection(ExtensibilityGlobals) = postSolution
                SolutionGuid = {CC2E4F75-FADC-4F44-BD62-47A321828081}
index 89acf04..8fb5ff0 100644 (file)
@@ -68,7 +68,7 @@ if not "%1" == "" (
 )
 
 rem Create folder structure
-for %%i in (ColorSchemes Languages Filters MergePlugins Docs Frhed\Docs Frhed\Languages WinIMerge Merge7z\Lang GnuWin32) do (
+for %%i in (ColorSchemes Languages Filters MergePlugins Docs Frhed\Docs Frhed\Languages WinIMerge Merge7z\Lang Commands\Apache-Tika Commands\tidy-html5 Commands\jq Commands\q Commands\GnuWin32) do (
   mkdir "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\%%i" 2> NUL
 )
 
@@ -154,9 +154,26 @@ if "%1" == "" (
   copy Build\WinIMerge\bin64\vcomp*.dll "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\" > NUL
 )
 
+rem Commands
+echo Copy Commands...
+xcopy /s/y Plugins\Commands "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands"
+
 rem Patch
 echo Copy Patch...
-xcopy /s/y Build\GnuWin32 "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\GnuWin32\" > NUL
+xcopy /s/y Build\GnuWin32 "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\GnuWin32\" > NUL
+
+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.4\COPYING "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\jq\" > NUL
+
+rem Copy tidy-html5...
+echo Copy tidy-html5...
+copy Build\tidy-html5\bin\tidy.* "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\tidy-html5\" > NUL
+copy Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\Commands\tidy-html5\" > NUL
+
+rem Plugin.xml
+copy Plugins\Plugins.xml "%DISTDIR%\%PLATFORMH%zip-version\WinMerge\MergePlugins\" > NUL
 
 echo.
 echo ------------------------------------------------------------
index f227840..babd607 100644 (file)
 
       <itemizedlist>
         <listitem>
-          <para><function>MakeUpper</function></para>
+          <para><function>Make Uppercase</function></para>
         </listitem>
 
         <listitem>
-          <para><function>MakeLower</function></para>
+          <para><function>Make Lowercase</function></para>
         </listitem>
 
         <listitem>
-          <para><function>SortAscending</function></para>
+          <para><function>Sort Lines Ascending</function></para>
         </listitem>
 
         <listitem>
-          <para><function>SortDescending</function></para>
+          <para><function>Sort Lines Descending</function></para>
         </listitem>
 
         <listitem>
-          <para><function>ExecFilterCommand</function></para>
+          <para><function>Apply Filter Command...</function></para>
         </listitem>
 
         <listitem>
-          <para><function>InsertDate</function></para>
+          <para><function>Insert Date</function></para>
         </listitem>
 
         <listitem>
-          <para><function>InsertTime</function></para>
+          <para><function>Insert Time</function></para>
         </listitem>
       </itemizedlist>
 
       </indexterm></title>
 
     <section id="CompareMSExcelFiles">
-      <title><filename>CompareMSExcelFiles.sct<indexterm>
-          <primary>CompareMSExcelFiles.sct plugin file</primary>
+      <title><filename>CompareMSExcelFiles<indexterm>
+          <primary>CompareMSExcelFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para>Displays the text contents of a <trademark
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Packing</segtitle>
 
           <segtitle>Settings dialog support</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_powerpnt">
-      <title><filename>CompareMSPowerPointFiles.sct<indexterm>
-          <primary>CompareMSPowerPointFiles.sct plugin file</primary>
+      <title><filename>CompareMSPowerPointFiles<indexterm>
+          <primary>CompareMSPowerPointFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para>Displays the text content of a <trademark
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Packing</segtitle>
 
           <segtitle>Settings dialog support</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_visio">
-      <title><filename>CompareMSVisioFiles.sct<indexterm>
-          <primary>CompareMSVisioFiles.sct plugin file</primary>
+      <title><filename>CompareMSVisioFiles<indexterm>
+          <primary>CompareMSVisioFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para>Displays the text content of a <trademark
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Packing</segtitle>
 
           <segtitle>Settings dialog support</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_msword">
-      <title><filename>CompareMSWordFiles.sct<indexterm>
-          <primary>CompareMSWordFiles.sct plugin file</primary>
+      <title><filename>CompareMSWordFiles<indexterm>
+          <primary>CompareMSWordFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para>Displays the text content of a <trademark
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Packing</segtitle>
 
           <segtitle>Settings dialog support</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="IgnoreColumns">
-      <title><filename>IgnoreColumns.dll<indexterm>
-          <primary>IgnoreColumns.dll plugin file</primary>
+      <title><filename>IgnoreColumns<indexterm>
+          <primary>IgnoreColumns plugin file</primary>
         </indexterm></filename></title>
 
       <para>This plugin ignores characters at specified columns. The first
       </itemizedlist>
 
       <example>
-        <title><filename>IgnoreColumns.dll</filename> examples</title>
+        <title><filename>IgnoreColumns</filename> examples</title>
 
         <variablelist>
           <varlistentry>
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
     </section>
 
     <section>
-      <title><filename>IgnoreCommentsC.dll<indexterm>
-          <primary>IgnoreCommentsC.dll plugin file</primary>
+      <title><filename>IgnoreCommentsC<indexterm>
+          <primary>IgnoreCommentsC plugin file</primary>
         </indexterm></filename></title>
 
       <para>The plugin ignores comments within<constant> //</constant>... and
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
             class="extension">*.ts</filename></seg>
 
             <seg>No</seg>
+
+            <seg>No</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreFieldsComma.dll<indexterm>
-          <primary>IgnoreFieldsComma.dll plugin file</primary>
+      <title><filename>IgnoreFieldsComma<indexterm>
+          <primary>IgnoreFieldsComma plugin file</primary>
         </indexterm></filename></title>
 
       <para>This plugin is for files with fields and commas as delimiters (CSV
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
             <seg><filename class="extension">*.csv</filename></seg>
 
             <seg>Yes</seg>
+
+            <seg>Yes</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreFieldsTab.dll<indexterm>
-          <primary>IgnoreFieldsTab.dll plugin file</primary>
+      <title><filename>IgnoreFieldsTab<indexterm>
+          <primary>IgnoreFieldsTab plugin file</primary>
         </indexterm></filename></title>
 
       <para>This plugin is for files that use fields and tabs as delimiters
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
             <seg><filename class="extension">*.txt</filename></seg>
 
             <seg>Yes</seg>
+
+            <seg>Yes</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreLeadingLineNumbers.dll<indexterm>
-          <primary>IgnoreLeadingLineNumbers.dll plugin file</primary>
+      <title><filename>IgnoreLeadingLineNumbers<indexterm>
+          <primary>IgnoreLeadingLineNumbers plugin file</primary>
         </indexterm></filename></title>
 
       <para>This plugin ignores the leading line numbers in text files (for
 
           <segtitle>File filter</segtitle>
 
+          <segtitle>Plugin argument</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <segtitle>Requirement</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg><xref linkend="MSVBVM60" /></seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section id="EditorAddin">
-      <title><filename>editor addin.sct<indexterm>
-          <primary>editor addin.sct plugin file</primary>
+      <title><filename>editor addin<indexterm>
+          <primary>editor addin plugin file</primary>
         </indexterm></filename></title>
 
       <para>Adds five functions to the <menuchoice>
 
       <itemizedlist>
         <listitem>
-          <simpara><guimenuitem>MakeUpper</guimenuitem> convert the selection to
+          <simpara><guimenuitem>Make Uppercase</guimenuitem> convert the selection to
           UPPER CASE.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>MakeLower</guimenuitem> convert the selection to
+          <simpara><guimenuitem>Make Lowercase</guimenuitem> convert the selection to
           lower case.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>SortAscending</guimenuitem> sort the selection 
+          <simpara><guimenuitem>Sort Lines Ascending</guimenuitem> sort the selection 
           in ascending order.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>SortDescending</guimenuitem> sort the selection 
+          <simpara><guimenuitem>Sort Lines Descending</guimenuitem> sort the selection 
           in descending order.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>ExecFilterCommand</guimenuitem> replace the selection 
-          with the output of the specified filter command.</simpara>
+          <simpara><guimenuitem>Apply Filter Command...</guimenuitem> replace the selection 
+          with the output of the specified filter command.
+          Specifying %1 in the argument of the filter command replaces it with the filename of the active pane.</simpara>
         </listitem>
       </itemizedlist>
 
       <para><segmentedlist>
           <segtitle>Category</segtitle>
+          <segtitle>File filter</segtitle>
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
             <seg>Editor complement</seg>
+            <seg>*</seg>
             <seg>No</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section id="Plugins_datetime">
-      <title><filename>insert datetime.sct<indexterm>
-          <primary>insert datetime.sct plugin file</primary>
+      <title><filename>insert datetime<indexterm>
+          <primary>insert datetime plugin file</primary>
         </indexterm></filename></title>
 
       <para>Adds two functions to the <menuchoice>
 
       <itemizedlist>
         <listitem>
-          <simpara><guimenuitem>InsertDate</guimenuitem> insert date in the
+          <simpara><guimenuitem>Insert Date</guimenuitem> insert date in the
           current locale format.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>InsertTime</guimenuitem> insert time in the
+          <simpara><guimenuitem>Insert Time</guimenuitem> insert time in the
           current locale format.</simpara>
         </listitem>
       </itemizedlist>
       <para><segmentedlist>
           <segtitle>Category</segtitle>
 
+          <segtitle>File filter</segtitle>
+
           <segtitle>Settings dialog support</segtitle>
 
           <seglistitem>
             <seg>Editor complement</seg>
 
+            <seg>*</seg>
+
             <seg>No</seg>
           </seglistitem>
         </segmentedlist></para>
index 017bd10..7a2161f 100644 (file)
@@ -20,7 +20,7 @@
 
     <listitem>
       <para><filename class="directory">MergePlugins</filename>
-      ã\82µã\83\96ã\83\95ã\82©ã\83«ã\83\80ã\81«ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\95ã\82\8cã\81¾ã\81\99ã\80\82WinMergeã\81§ã\81¯ã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®ã\83\97ã\83©ã\82°ã\82¤ã\83³ã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dます。</para>
+      ã\82µã\83\96ã\83\95ã\82©ã\83«ã\83\80ã\81«ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\95ã\82\8cã\81¾ã\81\99ã\80\82WinMergeã\81¯ã\80\81ã\81\84ã\81\8fã\81¤ã\81\8bã\81®ã\83\97ã\83©ã\82°ã\82¤ã\83³ã\82\92ã\82¤ã\83³ã\82¹ã\83\88ã\83¼ã\83«ã\81\97ます。</para>
     </listitem>
 
     <listitem>
         </listitem>
 
         <listitem>
-          <para><function>InsertDate</function></para>
+          <para><function>Insert Date</function></para>
         </listitem>
 
         <listitem>
-          <para><function>InsertTime</function></para>
+          <para><function>Insert Time</function></para>
         </listitem>
       </itemizedlist>
 
       </indexterm></title>
 
     <section id="CompareMSExcelFiles">
-      <title><filename>CompareMSExcelFiles.sct<indexterm>
-          <primary>CompareMSExcelFiles.sct plugin file</primary>
+      <title><filename>CompareMSExcelFiles<indexterm>
+          <primary>CompareMSExcelFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para><trademark
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>書き戻し</segtitle>
 
           <segtitle>設定ダイアログサポート</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_powerpnt">
-      <title><filename>CompareMSPowerPointFiles.sct<indexterm>
-          <primary>CompareMSPowerPointFiles.sct plugin file</primary>
+      <title><filename>CompareMSPowerPointFiles<indexterm>
+          <primary>CompareMSPowerPointFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para><trademark
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>書き戻し</segtitle>
 
           <segtitle>設定ダイアログサポート</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_visio">
-      <title><filename>CompareMSVisioFiles.sct<indexterm>
-          <primary>CompareMSVisioFiles.sct plugin file</primary>
+      <title><filename>CompareMSVisioFiles<indexterm>
+          <primary>CompareMSVisioFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para><trademark
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>書き戻し</segtitle>
 
           <segtitle>設定ダイアログサポート</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="Plugins_msword">
-      <title><filename>CompareMSWordFiles.sct<indexterm>
-          <primary>CompareMSWordFiles.sct plugin file</primary>
+      <title><filename>CompareMSWordFiles<indexterm>
+          <primary>CompareMSWordFiles plugin file</primary>
         </indexterm></filename></title>
 
       <para><trademark
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>書き戻し</segtitle>
 
           <segtitle>設定ダイアログサポート</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg>Yes</seg>
 
             <seg><trademark class="registered">Microsoft</trademark>
     </section>
 
     <section id="EditorAddin">
-      <title><filename>editor addin.sct<indexterm>
-          <primary>editor addin.sct plugin file</primary>
+      <title><filename>editor addin<indexterm>
+          <primary>editor addin plugin file</primary>
         </indexterm></filename></title>
 
       <para>5つの機能を<menuchoice>
     </section>
 
     <section id="IgnoreColumns">
-      <title><filename>IgnoreColumns.dll<indexterm>
-          <primary>IgnoreColumns.dll plugin file</primary>
+      <title><filename>IgnoreColumns<indexterm>
+          <primary>IgnoreColumns plugin file</primary>
         </indexterm></filename></title>
 
       <para>このプラグインは、指定された列の文字を無視します。 最初の列の番号は1です。</para>
       </itemizedlist>
 
       <example>
-        <title><filename>IgnoreColumns.dll</filename> examples</title>
+        <title><filename>IgnoreColumns</filename> examples</title>
 
         <variablelist>
           <varlistentry>
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <seglistitem>
     </section>
 
     <section>
-      <title><filename>IgnoreCommentsC.dll<indexterm>
-          <primary>IgnoreCommentsC.dll plugin file</primary>
+      <title><filename>IgnoreCommentsC<indexterm>
+          <primary>IgnoreCommentsC plugin file</primary>
         </indexterm></filename></title>
 
       <para>このプラグインはC言語, C++, PHP, JavaScript ファイルの<constant> //</constant>... と
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <seglistitem>
             class="extension">*.ts</filename></seg>
 
             <seg>No</seg>
+
+            <seg>No</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreFieldsComma.dll<indexterm>
-          <primary>IgnoreFieldsComma.dll plugin file</primary>
+      <title><filename>IgnoreFieldsComma<indexterm>
+          <primary>IgnoreFieldsComma plugin file</primary>
         </indexterm></filename></title>
 
       <para>このプラグインは、フィールドとコンマを区切り文字として使用するファイル用です
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <seglistitem>
             <seg><filename class="extension">*.csv</filename></seg>
 
             <seg>Yes</seg>
+
+            <seg>Yes</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreFieldsTab.dll<indexterm>
-          <primary>IgnoreFieldsTab.dll plugin file</primary>
+      <title><filename>IgnoreFieldsTab<indexterm>
+          <primary>IgnoreFieldsTab plugin file</primary>
         </indexterm></filename></title>
 
       <para>このプラグインは、フィールドとタブを区切り記号として使用するファイル用です
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <seglistitem>
             <seg><filename class="extension">*.txt</filename></seg>
 
             <seg>Yes</seg>
+
+            <seg>Yes</seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
     <section>
-      <title><filename>IgnoreLeadingLineNumbers.dll<indexterm>
-          <primary>IgnoreLeadingLineNumbers.dll plugin file</primary>
+      <title><filename>IgnoreLeadingLineNumbers<indexterm>
+          <primary>IgnoreLeadingLineNumbers plugin file</primary>
         </indexterm></filename></title>
 
       <para>このプラグインは、テキストファイル
 
           <segtitle>ファイルフィルタ</segtitle>
 
+          <segtitle>プラグイン引数</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <segtitle>必要なもの</segtitle>
 
             <seg>No</seg>
 
+            <seg>No</seg>
+
             <seg><xref linkend="MSVBVM60" /></seg>
           </seglistitem>
         </segmentedlist></para>
     </section>
 
+    <section id="EditorAddin">
+      <title><filename>editor addin<indexterm>
+          <primary>editor addin plugin file</primary>
+        </indexterm></filename></title>
+
+      <para>Adds five functions to the <menuchoice>
+          <guimenu>プラグイン</guimenu>
+
+          <guisubmenu>スクリプト</guisubmenu>
+        </menuchoice> メニュー:</para>
+
+      <itemizedlist>
+        <listitem>
+          <simpara><guimenuitem>大文字に変換</guimenuitem> convert the selection to
+          UPPER CASE.</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><guimenuitem>小文字に変換</guimenuitem> convert the selection to
+          lower case.</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><guimenuitem>昇順にソート</guimenuitem> sort the selection 
+          in ascending order.</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><guimenuitem>降順にソート</guimenuitem> sort the selection 
+          in descending order.</simpara>
+        </listitem>
+
+        <listitem>
+          <simpara><guimenuitem>フィルタコマンドを適用...</guimenuitem> replace the selection 
+          with the output of the specified filter command.
+          Specifying %1 in the argument of the filter command replaces it with the filename of the active pane.</simpara>
+        </listitem>
+      </itemizedlist>
+
+      <para><segmentedlist>
+          <segtitle>分類</segtitle>
+          <segtitle>ファイルフィルタ</segtitle>
+          <segtitle>設定ダイアログサポート</segtitle>
+
+          <seglistitem>
+            <seg>エディタ補完</seg>
+            <seg>*</seg>
+            <seg>No</seg>
+          </seglistitem>
+        </segmentedlist></para>
+    </section>
+
     <section id="Plugins_datetime">
-      <title><filename>insert datetime.sct<indexterm>
-          <primary>insert datetime.sct plugin file</primary>
+      <title><filename>insert datetime<indexterm>
+          <primary>insert datetime plugin file</primary>
         </indexterm></filename></title>
 
       <para><menuchoice>
 
       <itemizedlist>
         <listitem>
-          <simpara><guimenuitem>InsertDate</guimenuitem> insert date in the
+          <simpara><guimenuitem>日付を挿入</guimenuitem> insert date in the
           current locale format.</simpara>
         </listitem>
 
         <listitem>
-          <simpara><guimenuitem>InsertTime</guimenuitem> insert time in the
+          <simpara><guimenuitem>時刻を挿入</guimenuitem> insert time in the
           current locale format.</simpara>
         </listitem>
       </itemizedlist>
       <para><segmentedlist>
           <segtitle>分類</segtitle>
 
+          <segtitle>ファイルフィルタ</segtitle>
+
           <segtitle>設定ダイアログサポート</segtitle>
 
           <seglistitem>
-            <seg>Editor complement</seg>
+            <seg>エディタ補完</seg>
+
+            <seg>*</seg>
 
             <seg>No</seg>
           </seglistitem>
index 792cef4..5cdf93b 100644 (file)
@@ -12,6 +12,10 @@ https://github.com/WinMerge/frhed/releases/download/0.10904.2017/frhed-0.10904.2
 https://github.com/WinMerge/frhed/releases/download/0.10904.2017/frhed-0.10904.2017.7-ARM64.zip!Build\ARM64 ^
 https://github.com/WinMerge/winimerge/releases/download/v1.0.29/winimerge-1.0.29.0-exe.zip!Build ^
 https://github.com/WinMerge/patch/releases/download/v2.5.9-7/patch-2.5.9-7-bin.zip!Build\GnuWin32 ^
+https://github.com/htacg/tidy-html5/releases/download/5.4.0/tidy-5.4.0-win32.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.4/jq-win32.exe!Build\jq ^
+https://github.com/stedolan/jq/archive/refs/tags/jq-1.4.zip!Build\jq ^
 http://www.magicnotes.com/steelbytes/SBAppLocale_ENG.zip!Docs\Manual\Tools
 
 pushd "%~dp0"
@@ -22,7 +26,12 @@ for %%p in (%urls_destdirs%) do (
     if not exist %downloadsdir%\%%~nxu (
       powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest %%u -Outfile %downloadsdir%\%%~nxu"
     )
-    7z x %downloadsdir%\%%~nxu -aoa -o%%v
+    if "%%~xu" == ".zip" (
+      7z x %downloadsdir%\%%~nxu -aoa -o%%v
+    ) else (
+      mkdir %%v > NUL
+      copy %downloadsdir%\%%~nxu %%v
+    )
   )
 )
 
@@ -34,11 +43,21 @@ for %%i in (Build Build\X64 Build\ARM64) do (
     mkdir %%i\%%j\Filters 2> NUL
     mkdir %%i\%%j\ColorSchemes 2> NUL
     mkdir %%i\%%j\MergePlugins 2> NUL
+    mkdir %%i\%%j\Commands\jq 2> NUL
+    mkdir %%i\%%j\Commands\tidy-html5 2> NUL
+    mkdir %%i\%%j\Commands\GnuWin32 2> NUL
     xcopy /s/y %%i\Merge7z %%i\%%j\Merge7z\
     xcopy /s/y %%i\Frhed %%i\%%j\Frhed\
+    xcopy /s/y Build\GnuWin32 %%i\%%j\Commands\GnuWin32\
+    copy Build\jq\jq-win32.exe %%i\%%j\Commands\jq\jq.exe
+    copy Build\jq\jq-jq-1.4\COPYING %%i\%%j\Commands\jq\
+    copy Build\tidy-html5\bin\tidy.* %%i\%%j\Commands\tidy-html5\
+    copy Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md %%i\%%j\Commands\tidy-html5\
+    xcopy /s/y Plugins\Commands %%i\%%j\Commands
     xcopy /s/y Filters %%i\%%j\Filters\
     xcopy /s/y ColorSchemes %%i\%%j\ColorSchemes\
     xcopy /s/y Plugins\dlls\*.sct %%i\%%j\MergePlugins\
+    xcopy /s/y Plugins\Plugins.xml %%i\%%j\MergePlugins\
     if "%%i" == "Build" (
       copy Build\WinIMerge\bin\WinIMergeLib.dll %%i\%%j\WinIMerge\
       copy Plugins\dlls\*.dll %%i\%%j\MergePlugins\
index 30a8dd6..836737e 100755 (executable)
@@ -178,7 +178,7 @@ Name: Plugins; Description: {cm:Plugins}; Flags: disablenouninstallwarning; Type
 Name: Frhed; Description: {cm:Frhed}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: WinIMerge; Description: {cm:WinIMerge}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: ArchiveSupport; Description: {cm:ArchiveSupport}; Flags: disablenouninstallwarning; Types: full typical\r
-Name: Patch; Description: {cm:Patch}; Flags: disablenouninstallwarning; Types: full typical\r
+Name: Commands; Description: {cm:Commands}; Flags: disablenouninstallwarning; Types: full typical\r
 \r
 ;Language components\r
 Name: Languages; Description: {cm:Languages}; Flags: disablenouninstallwarning\r
@@ -520,6 +520,7 @@ Source: ..\..\Docs\users\GPL.rtf; DestDir: {app}\Docs\; Flags: comparetimestamp
 \r
 ;Plugins\r
 ;Please note IgnoreVersion and CompareTimeStamp are to instruct the installer to not not check for version info and go straight to comparing modification dates\r
+Source: ..\..\Plugins\Plugins.xml; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
@@ -558,7 +559,17 @@ Source: ..\..\Build\WinIMerge\bin\WinIMergeLib.dll; DestDir: {app}\WinIMerge; Fl
 Source: ..\..\Build\WinIMerge\bin\vcomp140.dll; DestDir: {app}; Components: WinIMerge\r
 \r
 ;GnuWin32 Patch for Windows\r
-Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\GnuWin32; Flags: recursesubdirs; Components: Patch\r
+Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\Commands\GnuWin32; Flags: recursesubdirs; Components: Commands\r
+; HTML Tidy\r
+Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+; jq\r
+Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\jq\jq-jq-1.4\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Commands\r
+; Apache Tika\r
+Source: ..\..\Plugins\Commands\Apache-Tika\*.bat; DestDir: {app}\Commands\Apache-Tika; Flags: recursesubdirs; Components: Commands\r
+; q\r
+Source: ..\..\Plugins\Commands\q\*.bat; DestDir: {app}\Commands\q; Flags: recursesubdirs; Components: Commands\r
 \r
 [Dirs]\r
 Name: "{app}\MergePlugins"\r
index 75436cb..f624197 100644 (file)
@@ -185,7 +185,7 @@ Name: Plugins; Description: {cm:Plugins}; Flags: disablenouninstallwarning; Type
 Name: Frhed; Description: {cm:Frhed}; Flags: disablenouninstallwarning; Types: full typical
 Name: WinIMerge; Description: {cm:WinIMerge}; Flags: disablenouninstallwarning; Types: full typical
 Name: ArchiveSupport; Description: {cm:ArchiveSupport}; Flags: disablenouninstallwarning; Types: full typical
-Name: Patch; Description: {cm:Patch}; Flags: disablenouninstallwarning; Types: full typical
+Name: Commands; Description: {cm:Commands}; Flags: disablenouninstallwarning; Types: full typical
 
 ;Language components
 Name: Languages; Description: {cm:Languages}; Flags: disablenouninstallwarning
@@ -508,6 +508,7 @@ Source: ..\..\Docs\users\GPL.rtf; DestDir: {app}\Docs\; Flags: comparetimestamp
 
 ;Plugins
 ;Please note IgnoreVersion and CompareTimeStamp are to instruct the installer to not not check for version info and go straight to comparing modification dates
+Source: ..\..\Plugins\Plugins.xml; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
@@ -545,7 +546,17 @@ Source: ..\..\Build\WinIMerge\binARM64\WinIMergeLib.dll; DestDir: {app}\WinIMerg
 ;Source: ..\..\Build\WinIMerge\binARM64\vcomp140.dll; DestDir: {app}; Components: WinIMerge
 
 ;GnuWin32 Patch for Windows
-Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\GnuWin32; Flags: recursesubdirs; Components: Patch
+Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\Commands\GnuWin32; Flags: recursesubdirs; Components: Commands
+; HTML Tidy
+Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands
+Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands
+; jq
+Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Commands
+Source: ..\..\Build\jq\jq-jq-1.4\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Commands
+; Apache Tika
+Source: ..\..\Plugins\Commands\Apache-Tika\*.bat; DestDir: {app}\Commands\Apache-Tika; Flags: recursesubdirs; Components: Commands
+; q
+Source: ..\..\Plugins\Commands\q\*.bat; DestDir: {app}\Commands\q; Flags: recursesubdirs; Components: Commands
 
 [Dirs]
 Name: "{app}\MergePlugins"
index 72a997b..f7292bf 100644 (file)
@@ -184,7 +184,7 @@ Name: Plugins; Description: {cm:Plugins}; Flags: disablenouninstallwarning; Type
 Name: Frhed; Description: {cm:Frhed}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: WinIMerge; Description: {cm:WinIMerge}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: ArchiveSupport; Description: {cm:ArchiveSupport}; Flags: disablenouninstallwarning; Types: full typical\r
-Name: Patch; Description: {cm:Patch}; Flags: disablenouninstallwarning; Types: full typical\r
+Name: Commands; Description: {cm:Commands}; Flags: disablenouninstallwarning; Types: full typical\r
 \r
 ;Language components\r
 Name: Languages; Description: {cm:Languages}; Flags: disablenouninstallwarning\r
@@ -507,6 +507,7 @@ Source: ..\..\Docs\users\GPL.rtf; DestDir: {app}\Docs\; Flags: comparetimestamp
 \r
 ;Plugins\r
 ;Please note IgnoreVersion and CompareTimeStamp are to instruct the installer to not not check for version info and go straight to comparing modification dates\r
+Source: ..\..\Plugins\Plugins.xml; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
@@ -544,7 +545,17 @@ Source: ..\..\Build\WinIMerge\bin64\WinIMergeLib.dll; DestDir: {app}\WinIMerge;
 Source: ..\..\Build\WinIMerge\bin64\vcomp140.dll; DestDir: {app}; Components: WinIMerge\r
 \r
 ;GnuWin32 Patch for Windows\r
-Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\GnuWin32; Flags: recursesubdirs; Components: Patch\r
+Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\Commands\GnuWin32; Flags: recursesubdirs; Components: Commands\r
+; HTML Tidy\r
+Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+; jq\r
+Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\jq\jq-jq-1.4\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Commands\r
+; Apache Tika\r
+Source: ..\..\Plugins\Commands\Apache-Tika\*.bat; DestDir: {app}\Commands\Apache-Tika; Flags: recursesubdirs; Components: Commands\r
+; q\r
+Source: ..\..\Plugins\Commands\q\*.bat; DestDir: {app}\Commands\q; Flags: recursesubdirs; Components: Commands\r
 \r
 [Dirs]\r
 Name: "{app}\MergePlugins"\r
index 5f18768..55ec5df 100644 (file)
@@ -181,7 +181,7 @@ Name: Plugins; Description: {cm:Plugins}; Flags: disablenouninstallwarning; Type
 Name: Frhed; Description: {cm:Frhed}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: WinIMerge; Description: {cm:WinIMerge}; Flags: disablenouninstallwarning; Types: full typical\r
 Name: ArchiveSupport; Description: {cm:ArchiveSupport}; Flags: disablenouninstallwarning; Types: full typical\r
-Name: Patch; Description: {cm:Patch}; Flags: disablenouninstallwarning; Types: full typical\r
+Name: Commands; Description: {cm:Commands}; Flags: disablenouninstallwarning; Types: full typical\r
 \r
 ;Language components\r
 Name: Languages; Description: {cm:Languages}; Flags: disablenouninstallwarning\r
@@ -499,6 +499,7 @@ Source: ..\..\Docs\users\GPL.rtf; DestDir: {app}\Docs\; Flags: comparetimestamp
 \r
 ;Plugins\r
 ;Please note IgnoreVersion and CompareTimeStamp are to instruct the installer to not not check for version info and go straight to comparing modification dates\r
+Source: ..\..\Plugins\Plugins.xml; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins\r
@@ -536,7 +537,17 @@ Source: ..\..\Build\WinIMerge\bin64\WinIMergeLib.dll; DestDir: {app}\WinIMerge;
 Source: ..\..\Build\WinIMerge\bin64\vcomp140.dll; DestDir: {app}; Components: WinIMerge\r
 \r
 ;GnuWin32 Patch for Windows\r
-Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\GnuWin32; Flags: recursesubdirs; Components: Patch\r
+Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\Commands\GnuWin32; Flags: recursesubdirs; Components: Commands\r
+; HTML Tidy\r
+Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands\r
+; jq\r
+Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Commands\r
+Source: ..\..\Build\jq\jq-jq-1.4\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Commands\r
+; Apache Tika\r
+Source: ..\..\Plugins\Commands\Apache-Tika\*.bat; DestDir: {app}\Commands\Apache-Tika; Flags: recursesubdirs; Components: Commands\r
+; q\r
+Source: ..\..\Plugins\Commands\q\*.bat; DestDir: {app}\Commands\q; Flags: recursesubdirs; Components: Commands\r
 \r
 [Dirs]\r
 Name: "{app}\MergePlugins"\r
index 3ade493..ca4b63a 100644 (file)
@@ -180,7 +180,7 @@ Name: Plugins; Description: {cm:Plugins}; Flags: disablenouninstallwarning; Type
 Name: Frhed; Description: {cm:Frhed}; Flags: disablenouninstallwarning; Types: full typical
 Name: WinIMerge; Description: {cm:WinIMerge}; Flags: disablenouninstallwarning; Types: full typical
 Name: ArchiveSupport; Description: {cm:ArchiveSupport}; Flags: disablenouninstallwarning; Types: full typical
-Name: Patch; Description: {cm:Patch}; Flags: disablenouninstallwarning; Types: full typical
+Name: Commands; Description: {cm:Commands}; Flags: disablenouninstallwarning; Types: full typical
 
 ;Language components
 Name: Languages; Description: {cm:Languages}; Flags: disablenouninstallwarning
@@ -498,6 +498,7 @@ Source: ..\..\Docs\users\GPL.rtf; DestDir: {app}\Docs\; Flags: comparetimestamp
 
 ;Plugins
 ;Please note IgnoreVersion and CompareTimeStamp are to instruct the installer to not not check for version info and go straight to comparing modification dates
+Source: ..\..\Plugins\Plugins.xml; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\editor addin.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\insert datetime.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
 Source: ..\..\Plugins\dlls\CompareMSExcelFiles.sct; DestDir: {app}\MergePlugins; Flags: IgnoreVersion CompareTimeStamp; Components: Plugins
@@ -535,7 +536,15 @@ Source: ..\..\Build\WinIMerge\bin64\WinIMergeLib.dll; DestDir: {app}\WinIMerge;
 Source: ..\..\Build\WinIMerge\bin64\vcomp140.dll; DestDir: {app}; Components: WinIMerge
 
 ;GnuWin32 Patch for Windows
-Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\GnuWin32; Flags: recursesubdirs; Components: Patch
+Source: ..\..\Build\GnuWin32\*.*; DestDir: {app}\Commands\GnuWin32; Flags: recursesubdirs; Components: Commands
+; HTML Tidy
+Source: ..\..\Build\tidy-html5\bin\*.*; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands
+Source: ..\..\Build\tidy-html5\tidy-html5-5.4.0\README\LICENSE.md; DestDir: {app}\Commands\tidy-html5; Flags: recursesubdirs; Components: Commands
+; jq
+Source: ..\..\Build\jq\jq-win32.exe; DestDir: {app}\Commands\jq; DestName: jq.exe; Flags: recursesubdirs; Components: Commands
+Source: ..\..\Build\jq\jq-jq-1.4\COPYING; DestDir: {app}\Commands\jq; Flags: recursesubdirs; Components: Commands
+; Apache Tika
+Source: ..\..\Plugins\Commands\Apache-Tika\*.bat; DestDir: {app}\Commands\Apache-Tika; Flags: recursesubdirs; Components: Commands
 
 [Dirs]
 Name: "{app}\MergePlugins"
diff --git a/Plugins/Commands/Apache-Tika/tika.bat b/Plugins/Commands/Apache-Tika/tika.bat
new file mode 100644 (file)
index 0000000..7f8ffc0
--- /dev/null
@@ -0,0 +1,26 @@
+@echo off
+setlocal EnableDelayedExpansion
+set /a "ii=%RANDOM%*4/32678"
+set DOWNLOAD_URL0=https://ftp.jaist.ac.jp/pub/apache/tika/2.0.0-BETA/tika-app-2.0.0-BETA.jar
+set DOWNLOAD_URL1=https://ftp.riken.jp/net/apache/tika/2.0.0-BETA/tika-app-2.0.0-BETA.jar
+set DOWNLOAD_URL2=https://ftp.tsukuba.wide.ad.jp/software/apache/tika/2.0.0-BETA/tika-app-2.0.0-BETA.jar
+set DOWNLOAD_URL3=https://ftp.yz.yamagata-u.ac.jp/pub/network/apache/tika/2.0.0-BETA/tika-app-2.0.0-BETA.jar
+set DOWNLOAD_URL=!DOWNLOAD_URL%ii%!
+set DOWNLOAD_URL_JPEG2000=https://github.com/jai-imageio/jai-imageio-jpeg2000/releases/download/jai-imageio-jpeg2000-1.4.0/jai-imageio-jpeg2000-1.4.0.jar
+set TIKA_PATH=WinMerge\Commands\Apache-Tika\tika-app-2.0.0-BETA.jar
+set JAI_IMAGEIO_JPEG2000_PATH=WinMerge\Commands\Apache-Tika\jai-imageio-jpeg2000-1.4.0.jar
+set MESSAGE='Apache Tika is not installed. Do you want to download it and its dependences from %DOWNLOAD_URL% and %DOWNLOAD_URL_JPEG2000%?'
+set TITLE='Apache Tika Plugin'
+
+cd "%APPDATA%"
+if not exist %TIKA_PATH% (
+  for %%i in (%TIKA_PATH%) do mkdir %%~pi 2> NUL
+  powershell "if ((New-Object -com WScript.Shell).Popup(%MESSAGE%,0,%TITLE%,1) -ne 1) { throw }" > NUL
+  if errorlevel 1 (
+    echo "download is canceled" 1>&2
+  ) else (
+    start "Downloading..." /WAIT powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest %DOWNLOAD_URL% -Outfile %TIKA_PATH%"
+    start "Downloading..." /WAIT powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest %DOWNLOAD_URL_JPEG2000% -Outfile %JAI_IMAGEIO_JPEG2000_PATH%"
+  )
+)
+java -Xbootclasspath/a:%JAI_IMAGEIO_JPEG2000_PATH% -jar %TIKA_PATH% %3 %4 %5 %6 %7 %8 %9 "%~1" > "%~2"
diff --git a/Plugins/Commands/q/q.bat b/Plugins/Commands/q/q.bat
new file mode 100644 (file)
index 0000000..590d6f8
--- /dev/null
@@ -0,0 +1,17 @@
+@echo off
+set DOWNLOAD_URL=https://github.com/harelba/q/releases/download/2.0.19/q-AMD64-Windows.exe
+set Q_PATH=WinMerge\Commands\q\q-AMD64-Windows.exe
+set MESSAGE='q command is not installed. Do you want to download it from %DOWNLOAD_URL%?'
+set TITLE='CSV/TSV Data Querier Plugin'
+
+cd "%APPDATA%"
+if not exist %Q_PATH% (
+  for %%i in (%Q_PATH%) do mkdir %%~pi 2> NUL
+  powershell "if ((New-Object -com WScript.Shell).Popup(%MESSAGE%,0,%TITLE%,1) -ne 1) { throw }" > NUL
+  if errorlevel 1 (
+    echo "download is canceled" 1>&2
+  ) else (
+    start "Downloading..." /WAIT powershell -command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest %DOWNLOAD_URL% -Outfile %Q_PATH%"
+  )
+)
+%Q_PATH% %*
diff --git a/Plugins/CopyDlls.bat b/Plugins/CopyDlls.bat
new file mode 100644 (file)
index 0000000..686446b
--- /dev/null
@@ -0,0 +1,7 @@
+for /d %%d in (src_VCPP\*) do (
+  copy %%d\Release\*.dll dlls\ 
+  copy %%d\X64\Release\*.dll dlls\X64\
+  copy %%d\ARM64\Release\*.dll dlls\ARM64\
+)
+
+pause
\ No newline at end of file
diff --git a/Plugins/Plugins.xml b/Plugins/Plugins.xml
new file mode 100644 (file)
index 0000000..b35af89
--- /dev/null
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<plugins>
+  <plugin name="PrettifyXML">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="XML Prettier with tidy-html5. &#xD;&#xA;Arguments: Command line arugments passed to the tidy command." />
+    <file-filters value="\.xml$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".xml" />
+    <extended-properties value="ProcessType=Prettification;MenuCaption=Prettify XML;GenerateEditorScript" />
+    <arguments value="-xml -indent --indent-attributes yes --tab-size 4 --indent-spaces 4 -wrap 0 --sort-attributes alpha" />
+    <unpack-file>
+    <command>"${WINMERGE_HOME}\Commands\tidy-html5\tidy.exe" ${*} -o "${DST_FILE}" "${SRC_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="PrettifyJSON">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="JSON Prettier with jq command. &#xD;&#xA;Arguments: Filter or command line options passed to the jq command." />
+    <file-filters value="\.json$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".json" />
+    <extended-properties value="ProcessType=Prettification;MenuCaption=Prettify JSON;GenerateEditorScript" />
+    <arguments value="&quot;.&quot;" />
+    <unpack-file>
+    <command>cmd /c type "${SRC_FILE}" | "${WINMERGE_HOME}\Commands\jq\jq.exe" ${*} &gt; "${DST_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="QueryCSV">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="CSV Querier with q command. &#xD;&#xA;Arguments: SQL statement or command line options passed to the q command." />
+    <file-filters value="\.csv$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".csv" />
+    <extended-properties value="ProcessType=Data Query;MenuCaption=Query CSV Data...;ArgumentsRequired" />
+    <arguments value="&quot;SELECT * FROM -&quot;" />
+    <unpack-file>
+      <command>cmd /c type "${SRC_FILE}" | "${WINMERGE_HOME}\Commands\q\q.bat" ${*} &gt; "${DST_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="QueryTSV">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="TSV Querier with q command. &#xD;&#xA;Arguments: SQL statement or command line options passed to the q command." />
+    <file-filters value="\.tsv$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".tsv" />
+    <extended-properties value="ProcessType=Data Query;MenuCaption=Query TSV Data...;ArgumentsRequired" />
+    <arguments value="&quot;SELECT * FROM -&quot;" />
+    <unpack-file>
+      <command>cmd /c type "${SRC_FILE}" | "${WINMERGE_HOME}\Commands\q\q.bat" -t ${*} &gt; "${DST_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="QueryJSON">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="JSON Querier with jq command. &#xD;&#xA;Arguments: Filter or command line options passed to the jq command." />
+    <file-filters value="\.json$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".json" />
+    <extended-properties value="ProcessType=Data Query;MenuCaption=Query JSON Data...;ArgumentsRequired" />
+    <arguments value="&quot;.&quot;" />
+    <unpack-file>
+      <command>cmd /c type "${SRC_FILE}" | "${WINMERGE_HOME}\Commands\jq\jq.exe" ${*} &gt; "${DST_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="VisualizeGraphviz">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="Graphviz Visualizer. &#xD;&#xA;Arguments: Command line options passed to the dot command." />
+    <file-filters value="\.gv;$\.dot$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".png" />
+    <extended-properties value="ProcessType=Visualization;MenuCaption=Visualize Graphviz" />
+    <arguments value="-Tpng" />
+    <unpack-file>
+      <command>dot.exe ${*} -o"${DST_FILE}" "${SRC_FILE}"</command>
+    </unpack-file>
+  </plugin>
+  <plugin name="ApacheTika">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="General content extractor with Apache Tika. &#xD;&#xA;Arguments: Command line options passed to the tika-app.jar." />
+    <file-filters value="\.*$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".txt" />
+    <extended-properties value="ProcessType=Content Extraction;MenuCaption=Apache Tika;GenerateEditorScript" />
+    <arguments value="-eUTF-8 -t" />
+    <unpack-file>
+      <command>"${WINMERGE_HOME}\Commands\apache-tika\tika.bat" "${SRC_FILE}" "${DST_FILE}" "${*}"</command>
+    </unpack-file>
+  </plugin>
+  <!--
+  <plugin name="VBScript-test">
+    <event value="FILE_PACK_UNPACK" />
+    <description value="VBScript test" />
+    <file-filters value="\.nomatch$" />
+    <is-automatic value="false" />
+    <unpacked-file-extension value=".txt" />
+    <unpack-file>
+      <command>cmd /c cscript //nologo "${SCRIPT_FILE}" "${SRC_FILE}" > "${DST_FILE}"</command>
+      <script fileExtension=".vbs">
+WScript.StdOut.WriteLine "Hello World!"
+WScript.StdOut.WriteLine WScript.Arguments(0)
+      </script>
+    </unpack-file>
+  </plugin>
+  -->
+</plugins>
index e687704..a317aa3 100644 (file)
Binary files a/Plugins/dlls/ARM64/IgnoreColumns.dll and b/Plugins/dlls/ARM64/IgnoreColumns.dll differ
index 32b1455..15a3721 100644 (file)
Binary files a/Plugins/dlls/ARM64/IgnoreCommentsC.dll and b/Plugins/dlls/ARM64/IgnoreCommentsC.dll differ
index 0f41ad1..0351790 100644 (file)
Binary files a/Plugins/dlls/ARM64/IgnoreFieldsComma.dll and b/Plugins/dlls/ARM64/IgnoreFieldsComma.dll differ
index 789db22..c337401 100644 (file)
Binary files a/Plugins/dlls/ARM64/IgnoreFieldsTab.dll and b/Plugins/dlls/ARM64/IgnoreFieldsTab.dll differ
index 2768a89..d9fd0d3 100644 (file)
@@ -1,23 +1,26 @@
 <scriptlet>
 <implements type="Automation" id="dispatcher">
-    <property name="PluginEvent">
-        <get/>
-    </property>
-    <property name="PluginDescription">
-        <get/>
-    </property>
-    <property name="PluginFileFilters">
-        <get/>
-    </property>
-    <property name="PluginIsAutomatic">
-        <get/>
-    </property>
-    <method name="UnpackFile"/>
-    <method name="PackFile"/>
-    <method name="IsFolder"/>
-    <method name="UnpackFolder"/>
-    <method name="PackFolder"/>
-    <method name="ShowSettingsDialog"/>
+       <property name="PluginEvent">
+               <get/>
+       </property>
+       <property name="PluginDescription">
+               <get/>
+       </property>
+       <property name="PluginFileFilters">
+               <get/>
+       </property>
+       <property name="PluginIsAutomatic">
+               <get/>
+       </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
+       <method name="UnpackFile"/>
+       <method name="PackFile"/>
+       <method name="IsFolder"/>
+       <method name="UnpackFolder"/>
+       <method name="PackFolder"/>
+       <method name="ShowSettingsDialog"/>
 </implements>
 
 <script language="VBS">
@@ -49,6 +52,7 @@ Const PLUGIN_NAME = "ApplyPatch.sct WinMerge Plugin"
 
 Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
 Dim wsh: Set wsh = CreateObject("WScript.Shell")
+Dim PrevFileName: PrevFileName = ""
 
 Function get_PluginEvent()
     get_PluginEvent = "FILE_FOLDER_PACK_UNPACK"
@@ -63,7 +67,11 @@ Function get_PluginFileFilters()
 End Function
 
 Function get_PluginIsAutomatic()
-    get_PluginIsAutomatic = True
+    get_PluginIsAutomatic = False
+End Function
+
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "MenuCaption=Apply Patch..."
 End Function
 
 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
@@ -73,6 +81,7 @@ Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
 
     If Not IsPatchFile(fileSrc) Then
         ' FIXME:
+        PrevFileName = fileSrc
         fso.CopyFile fileSrc, fileDst
         pbChanged = True
         pSubcode = 1
@@ -80,7 +89,11 @@ Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
         Exit Function
     End If
 
-    filePatched = wsh.RegRead(REGKEY_PATH & "\Files\Left\Item_0")
+    If PrevFileName <> "" Then
+        filePatched = PrevFileName
+    Else
+        filePatched = wsh.RegRead(REGKEY_PATH & "\Files\Left\Item_0")
+    End If
     If IsPatchFile(filePatched) Then
         filePatched = wsh.RegRead(REGKEY_PATH & "\Files\Right\Item_0")
     End If
@@ -232,7 +245,7 @@ Function GetPatchExeFolder()
     On Error Resume Next
     winMergeExePath = "C:\Program Files\WinMerge\WinMergeU.exe"
     winMergeExePath = wsh.RegRead(REGKEY_PATH & "\Executable")
-    GetPatchExeFolder = fso.BuildPath(fso.GetParentFolderName(winMergeExePath), "GnuWin32\bin")
+    GetPatchExeFolder = fso.BuildPath(fso.GetParentFolderName(winMergeExePath), "Commands\GnuWin32\bin")
 End Function
 
 Function SafeUBound(ary)
index f7b29c1..197c81a 100644 (file)
@@ -15,6 +15,9 @@
        <property name="PluginUnpackedFileExtension">
                <get/>
        </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
        <method name="UnpackFile"/>
        <method name="PackFile"/>
        <method name="IsFolder"/>
@@ -390,6 +393,10 @@ Function get_PluginUnpackedFileExtension()
        get_PluginUnpackedFileExtension = ".tsv"
 End Function
 
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "ProcessType=Content Extraction;FileType=MS-Excel;MenuCaption=MS-Excel"
+End Function
+
 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
        Dim fo
        Dim xl
index 1f7c5b4..096550f 100644 (file)
@@ -12,6 +12,9 @@
        <property name="PluginIsAutomatic">
                <get/>
        </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
        <method name="UnpackFile"/>
        <method name="PackFile"/>
        <method name="IsFolder"/>
@@ -139,6 +142,10 @@ Function get_PluginIsAutomatic()
        get_PluginIsAutomatic = True
 End Function
 
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "ProcessType=Content Extraction;FileType=MS-PowerPoint;MenuCaption=MS-PowerPoint"
+End Function
+
 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
        Dim fo
        Dim pp
index 1486f12..56c822d 100644 (file)
@@ -12,6 +12,9 @@
        <property name="PluginIsAutomatic">
                <get/>
        </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
        <method name="UnpackFile"/>
        <method name="PackFile"/>
        <method name="IsFolder"/>
@@ -117,6 +120,9 @@ Function get_PluginIsAutomatic()
        get_PluginIsAutomatic = True
 End Function
 
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "ProcessType=Content Extraction;FileType=MS-Visio;MenuCaption=MS-Visio"
+End Function
 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
        Dim fo
        Dim vs
index 4ff6af5..c78a6f7 100644 (file)
@@ -12,6 +12,9 @@
        <property name="PluginIsAutomatic">
                <get/>
        </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
        <method name="UnpackFile"/>
        <method name="PackFile"/>
        <method name="IsFolder"/>
@@ -129,6 +132,10 @@ Function get_PluginIsAutomatic()
        get_PluginIsAutomatic = True
 End Function
 
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "ProcessType=Content Extraction;FileType=MS-Word;MenuCaption=MS-Word"
+End Function
+
 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
        Dim fo
        Dim wd 
index 8b3bc7e..e1a5831 100644 (file)
Binary files a/Plugins/dlls/IgnoreColumns.dll and b/Plugins/dlls/IgnoreColumns.dll differ
index 07f7f29..ce1304f 100644 (file)
Binary files a/Plugins/dlls/IgnoreCommentsC.dll and b/Plugins/dlls/IgnoreCommentsC.dll differ
index 2d5d007..75af8a8 100644 (file)
Binary files a/Plugins/dlls/IgnoreFieldsComma.dll and b/Plugins/dlls/IgnoreFieldsComma.dll differ
index 9926a36..f28833a 100644 (file)
Binary files a/Plugins/dlls/IgnoreFieldsTab.dll and b/Plugins/dlls/IgnoreFieldsTab.dll differ
index ecb9d10..1bb419e 100644 (file)
@@ -12,6 +12,9 @@
   <property name="PluginIsAutomatic">\r
     <get/>\r
   </property>\r
+  <property name="PluginExtendedProperties">\r
+    <get/>\r
+  </property>\r
   <method name="PrediffBufferW"/>\r
   <method name="ShowSettingsDialog"/>\r
 </implements>\r
@@ -66,6 +69,10 @@ Function get_PluginIsAutomatic()
   get_PluginIsAutomatic = True\r
 End Function\r
 \r
+Function get_PluginExtendedProperties()\r
+  get_PluginExtendedProperties = "MenuCaption=Apply Prediff Substitution Filters"\r
+End Function\r
+\r
 Function SafeUBound(ary)\r
   On Error Resume Next\r
   SafeUBound = -1\r
index 7e907a4..ca98676 100644 (file)
Binary files a/Plugins/dlls/X64/IgnoreColumns.dll and b/Plugins/dlls/X64/IgnoreColumns.dll differ
index bd1e448..dbb0138 100644 (file)
Binary files a/Plugins/dlls/X64/IgnoreCommentsC.dll and b/Plugins/dlls/X64/IgnoreCommentsC.dll differ
index 97d2ad0..2102905 100644 (file)
Binary files a/Plugins/dlls/X64/IgnoreFieldsComma.dll and b/Plugins/dlls/X64/IgnoreFieldsComma.dll differ
index 3477d92..1335a6e 100644 (file)
Binary files a/Plugins/dlls/X64/IgnoreFieldsTab.dll and b/Plugins/dlls/X64/IgnoreFieldsTab.dll differ
index c014d2b..a42ef77 100644 (file)
@@ -2,16 +2,34 @@
 
 <implements type="Automation" id="dispatcher">
        <property name="PluginEvent">
-                 <get/>
-        </property>
+               <get/>
+       </property>
        <property name="PluginDescription">
-                 <get/>
-        </property>
-       <method name="MakeUpper"/>
+               <get/>
+       </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
+       <property name="PluginFileFilters">
+               <get/>
+       </property>
+       <property name="PluginArguments">
+               <get/>
+               <put/>
+       </property>
+       <property name="PluginVariables">
+               <get/>
+               <put/>
+       </property>
+       <method name="MakeUpper"/>
        <method name="MakeLower"/>
+       <method name="RemoveDuplicates"/>
+       <method name="CountDuplicates"/>
        <method name="SortAscending"/>
        <method name="SortDescending"/>
        <method name="ExecFilterCommand"/>
+       <method name="Tokenize"/>
+       <method name="Trim"/>
 </implements>
 
 <script language="VBS">
@@ -21,15 +39,62 @@ Const WinMergeRegKeyPath = "HKCU\Software\Thingamahoochie\WinMerge\"
 Const PluginRegKeyPath = "HKCU\Software\Thingamahoochie\WinMerge\Plugins\editor addin.sct\"
 
 Dim wsh: Set wsh = CreateObject("WScript.Shell")
+Dim arguments: arguments = ""
+Dim variables: variables = Array()
 
 Function get_PluginEvent()
-         get_PluginEvent = "EDITOR_SCRIPT"
+       get_PluginEvent = "EDITOR_SCRIPT"
 End Function
 
 Function get_PluginDescription()
-         get_PluginDescription = "Basic text functions for the context menu"
+       get_PluginDescription = "Basic text functions for the context menu"
 End Function
 
+Function get_PluginFileFilters()
+       get_PluginFileFilters= ".*"
+End Function
+
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = _
+       "GenerateUnpacker;" & _
+       "MakeUpper.MenuCaption=Make Uppercase;" & _
+       "MakeUpper.Description=Make selection uppercase;" & _
+       "MakeLower.MenuCaption=Make Lowercase;" & _
+       "MakeLower.Description=Make selection lowercase;" & _
+       "RemoveDuplicates.MenuCaption=Remove Duplicate Lines;" & _
+       "RemoveDuplicates.Description=Remove duplicate lines;" & _
+       "CountDuplicates.MenuCaption=Count Duplicate Lines;" & _
+       "CountDuplicates.Description=Count duplicate lines;" & _
+       "SortAscending.MenuCaption=Sort Lines Ascending;" & _
+       "SortAscending.Description=Sort lines Ascending;" & _
+       "SortDescending.MenuCaption=Sort Lines Descending;" & _
+       "SortDescending.Description=Sort lines descending;" & _
+       "ExecFilterCommand.MenuCaption=Apply Filter Command...;" & _
+       "ExecFilterCommand.Description=Apply filter command. " & vbCrLf & "Arguments: filter command. %1 is replaced with the file name.;" & _
+       "ExecFilterCommand.ArgumentsRequired;" & _
+       "Tokenize.MenuCaption=Tokenize...;" & _
+       "Tokenize.Description=Tokenize selection. " & vbCrLf & "Arguments: a regular expression for tokenizing. (e.g. [^\w]+);" & _
+       "Tokenize.ArgumentsRequired;" & _
+       "Trim.MenuCaption=Trim Spaces;" & _
+       "Trim.Description=Trim spaces;"
+End Function
+
+Function get_PluginArguments()
+       get_PluginArguments = arguments
+End Function
+
+Sub put_PluginArguments(NewValue)
+       arguments = NewValue
+End Sub
+
+Function get_PluginVariables()
+       get_PluginVariables = Join(ariables, Chr(0))
+End Function
+
+Sub put_PluginVariables(NewValue)
+       variables = Split(NewValue, Chr(0))
+End Sub
+
 Function regRead(Key, DefaultValue)
        regRead = DefaultValue
        On Error Resume Next
@@ -52,13 +117,56 @@ Function MakeLower(Text)
        MakeLower = LCase(Text)
 End Function
 
+Function ReplaceVariables(ByVal str)
+       Dim newstr
+       Dim pos
+       Dim foundpos
+       Dim ch
+       pos = 1
+       Do While True
+               foundpos = InStr(pos, str, "%")
+               If foundpos > 0 Then
+                       ch = Mid(str, foundpos + 1, 1)
+                       If ch = "%" Then
+                               newstr = newstr & "%"
+                               pos = foundpos + 2
+                       ElseIf IsNumeric(ch) Then
+                               newstr = newstr & Mid(str, pos, foundpos - pos)
+                               If CLng(ch) <= UBound(variables) Then
+                                       newstr = newstr & variables(CLng(ch))
+                               End If
+                               pos = foundpos + 2
+                       Else
+                               newstr = newstr & Mid(str, pos, foundpos - pos + 1)
+                               pos = foundpos + 1
+                       End If
+               Else
+                       newstr = newstr & Mid(str, pos)
+                       Exit Do
+               End If
+       Loop
+       ReplaceVariables = newstr
+End Function
+
+Function IsFirstArgumentEmpty()
+       IsFirstArgumentEmpty = (Trim(arguments) = "")
+End Function
+
 Function ExecFilterCommand(Text)
        Dim cmd
-       cmd = regRead(PluginRegKeyPath & "ExecFilterCommand", "")
-       If IsLangJapanese() Then
-               cmd = InputBox("\83t\83B\83\8b\83^\83R\83}\83\93\83h\82ð\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢", "ExecFilterCommand", cmd)
+       If IsFirstArgumentEmpty() Then
+               cmd = regRead(PluginRegKeyPath & "ExecFilterCommand", "")
+               If IsLangJapanese() Then
+                       cmd = InputBox("\83t\83B\83\8b\83^\83R\83}\83\93\83h\82ð\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢", "ExecFilterCommand", cmd)
+               Else
+                       cmd = InputBox("Enter filter command", "ExecFilterCommand", cmd)
+               End If
+               If cmd <> "" Then
+                       wsh.RegWrite PluginRegKeyPath & "ExecFilterCommand", cmd
+               End If
+               cmd = ReplaceVariables(cmd)
        Else
-               cmd = InputBox("Enter filter command", "ExecFilterCommand", cmd)
+               cmd = arguments
        End If
        If cmd = "" Then
                If IsLangJapanese() Then
@@ -103,15 +211,97 @@ Function ExecFilterCommand(Text)
 
        fso.DeleteFile path
 
-       wsh.RegWrite PluginRegKeyPath & "ExecFilterCommand", cmd
-
 End Function
 
+' port from WinMerge2011
+Function Tokenize(Text)
+       Dim pattern
+       If IsFirstArgumentEmpty() Then
+               pattern = regRead(PluginRegKeyPath & "Tokenize", "")
+               If IsLangJapanese() Then
+                       pattern = InputBox("\83g\81[\83N\83\93\95ª\8a\84\82·\82é\8bæ\90Ø\82è\82ð\90³\8bK\95\\8c»\82Å\93ü\97Í\82µ\82Ä\82­\82¾\82³\82¢ (\97á: [^\w]+):", "Tokenize", pattern)
+               Else
+                       pattern = InputBox("Enter regex to tokenize (e.g. [^\w]+):", "Tokenize", pattern)
+               End If
+               If pattern <> "" Then
+                       wsh.RegWrite PluginRegKeyPath & "Tokenize", pattern
+               End If
+       Else
+               pattern = arguments
+       End If
+       If pattern = "" Then
+               If IsLangJapanese() Then
+                       Err.Raise 30001, , "\83L\83\83\83\93\83Z\83\8b\82³\82ê\82Ü\82µ\82½"
+               Else
+                       Err.Raise 30001, , "Canceled"
+               End If
+               Exit Function
+       End If
+       Dim re
+       Set re = New RegExp
+       re.Global = True
+       re.IgnoreCase = True
+       re.Pattern = pattern
+       Tokenize = re.Replace(Text, vbCrLf)
+End Function
 
 </script>
 
 <script language="JScript">
 
+function RemoveDuplicates(Text) {
+       var eol = Text.match(/\r\n|\n|\r/);
+       var lines = Text.split(eol);
+       var newlines = new Array();
+       var dic = {};
+       var lasteol = false;
+
+       if (!lines[lines.length - 1]) {
+               lines.pop();
+               lasteol = true;
+       }
+       for (var i = 0, j = 0; i < lines.length; i++) {
+               var line = lines[i];
+               if (typeof dic[line] === 'undefined') {
+                       dic[line] = 1;
+                       newlines[j] = line;
+                       j++;
+               }
+       }
+       if (lasteol)
+               newlines[j] = "";
+       return newlines.join(eol);
+}
+
+function CountDuplicates(Text) {
+       var eol = Text.match(/\r\n|\n|\r/);
+       var lines = Text.split(eol);
+       var newlines = new Array();
+       var dic = {};
+
+       if (!lines[lines.length - 1]) {
+               lines.pop();
+       }
+       
+       for (var i = 0; i < lines.length; i++) {
+               var line = lines[i];
+               if (typeof dic[line] === 'undefined') {
+                       dic[line] = 1;
+                       newlines[j] = line;
+                       j++;
+               } else {
+                       dic[line]++;
+               }
+       }
+       var j = 0;
+       for (var line in dic) {
+               newlines[j] = line + '\t' + dic[line];
+               j++;
+       }
+       newlines[j] = "";
+       return newlines.join(eol);
+}
+
 function SortAscending(Text) {
        var eol = Text.match(/\r\n|\n|\r/);
        var lines = Text.split(eol);
@@ -141,6 +331,15 @@ function SortDescending(Text) {
        }
 }
 
+function Trim(Text) {
+       var eol = Text.match(/\r\n|\n|\r/);
+       var lines = Text.split(eol);
+       for (var i = 0; i < lines.length; i++) {
+               lines[i] = lines[i].replace(/^\s+|\s+$/g, "");
+       }
+       return lines.join(eol);
+}
+
 </script>
 
 </scriptlet>
index f0ac286..7307d40 100644 (file)
@@ -2,12 +2,15 @@
 
 <implements type="Automation" id="dispatcher">
        <property name="PluginEvent">
-                 <get/>
-        </property>
+               <get/>
+       </property>
        <property name="PluginDescription">
-                 <get/>
-        </property>
-       <method name="InsertDate"/>
+               <get/>
+       </property>
+       <property name="PluginExtendedProperties">
+               <get/>
+       </property>
+       <method name="InsertDate"/>
        <method name="InsertTime"/>
 </implements>
 
 Option Explicit
 
 Function get_PluginEvent()
-         get_PluginEvent = "EDITOR_SCRIPT"
+       get_PluginEvent = "EDITOR_SCRIPT"
 End Function
 
 Function get_PluginDescription()
-         get_PluginDescription = "Basic text functions for the context menu"
+       get_PluginDescription = "Basic text functions for the context menu"
 End Function
 
+Function get_PluginExtendedProperties()
+       get_PluginExtendedProperties = "InsertDate.MenuCaption=Insert Date;InsertTime.MenuCaption=Insert Time"
+End Function
 
 ' transformation functions
 Function InsertDate(Text)
index 4703d08..d1b506d 100644 (file)
@@ -19,8 +19,11 @@ import "ocidl.idl";
                [propget, id(2), helpstring("property PluginDescription")] HRESULT PluginDescription([out, retval] BSTR *pVal);
                [propget, id(3), helpstring("property PluginFileFilters")] HRESULT PluginFileFilters([out, retval] BSTR *pVal);
                [propget, id(4), helpstring("property PluginIsAutomatic")] HRESULT PluginIsAutomatic([out, retval] VARIANT_BOOL *pVal);
-               [id(5), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
-               [id(6), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
+               [propget, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([out, retval] BSTR *pVal);
+               [propput, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([in] BSTR val);
+               [propget, id(6), helpstring("property PluginExtendedProperties")] HRESULT PluginExtendedProperties([out, retval] BSTR *pVal);
+               [id(7), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
+               [id(8), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
        };
 
 [
index 4285159..77c5327 100644 (file)
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,1,3
- PRODUCTVERSION 1,0,1,3
+ FILEVERSION 1,0,1,5
+ PRODUCTVERSION 1,0,1,5
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -124,12 +124,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "IgnoreColumns Module"
-            VALUE "FileVersion", "1.0.1.3"
+            VALUE "FileVersion", "1.0.1.5"
             VALUE "InternalName", "IgnoreColumns"
-            VALUE "LegalCopyright", "Copyright 2003-2015"
+            VALUE "LegalCopyright", "Copyright 2003-2021"
             VALUE "OriginalFilename", "IgnoreColumns.DLL"
             VALUE "ProductName", "IgnoreColumns Module"
-            VALUE "ProductVersion", "1.0.1.3"
+            VALUE "ProductVersion", "1.0.1.5"
         END
     END
     BLOCK "VarFileInfo"
index b4d8ad2..0c5279b 100644 (file)
@@ -160,31 +160,51 @@ STDMETHODIMP CWinMergeScript::get_PluginEvent(BSTR *pVal)
 
 STDMETHODIMP CWinMergeScript::get_PluginDescription(BSTR *pVal)
 {
-       *pVal = SysAllocString(L"Ignore some columns - ignored columns list from the plugin name");
+       *pVal = SysAllocString(L"Ignore some columns - ignored columns list from the plugin name or the plugin argument");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginFileFilters(BSTR *pVal)
 {
        *pVal = SysAllocString(L"\\.txt$");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL *pVal)
 {
        *pVal = VARIANT_TRUE;
        return S_OK;
 }
 
+STDMETHODIMP CWinMergeScript::get_PluginArguments(BSTR *pVal)
+{
+       *pVal = m_bstrArguments.Copy();
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::put_PluginArguments(BSTR val)
+{
+       m_bstrArguments = val;
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::get_PluginExtendedProperties(BSTR *pVal)
+{
+       *pVal = SysAllocString(L"MenuCaption=Ignore Columns");
+       return S_OK;
+}
+
 STDMETHODIMP CWinMergeScript::PrediffBufferW(BSTR *pText, INT *pSize, VARIANT_BOOL *pbChanged, VARIANT_BOOL *pbHandled)
 {
        WCHAR * pBeginText = *pText;
        long nSize = *pSize;
        WCHAR * pEndText = pBeginText + nSize;
 
-       CString rangestr = GetColumnRangeString();
+       int argc = 0;
+       wchar_t **argv = CommandLineToArgvW(m_bstrArguments.m_str, &argc);
+       CString rangestr = (argc > 0) ? argv[0] : GetColumnRangeString();
+       if (argv)
+               LocalFree(argv);
 
        int nExcludedRanges = CreateArrayFromRangeString(rangestr, NULL);
        int (* aExcludedRanges)[2] = new int[nExcludedRanges][2];
index bd9ec6b..17cbcf3 100644 (file)
@@ -22,7 +22,7 @@ class ATL_NO_VTABLE CWinMergeScript :
        public IDispatchImpl<IWinMergeScript, &IID_IWinMergeScript, &LIBID_IgnoreColumnsLib, 1, 0, CComTypeInfoHolderFileOnly>
 {
 public:
-       CWinMergeScript()
+       CWinMergeScript() : m_bstrArguments(L"")
        {
        }
 
@@ -39,10 +39,16 @@ END_COM_MAP()
 public:
        STDMETHOD(PrediffBufferW)(/*[in]*/ BSTR * pText, /*[in]*/ INT * pSize, /*[in]*/ VARIANT_BOOL * pbChanged, /*[out, retval]*/ VARIANT_BOOL * pbHandled);
        STDMETHOD(ShowSettingsDialog)(/*[out, retval]*/ VARIANT_BOOL * pbHandled);
+       STDMETHOD(get_PluginExtendedProperties)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(get_PluginArguments)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(put_PluginArguments)(/*[in]*/ BSTR val);
        STDMETHOD(get_PluginIsAutomatic)(/*[out, retval]*/ VARIANT_BOOL *pVal);
        STDMETHOD(get_PluginFileFilters)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginDescription)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginEvent)(/*[out, retval]*/ BSTR *pVal);
+
+protected:
+       CComBSTR m_bstrArguments;
 };
 
 #endif //__WINMERGESCRIPT_H_
index 6dada5f..24dbc68 100644 (file)
@@ -19,8 +19,9 @@ import "ocidl.idl";
                [propget, id(2), helpstring("property PluginDescription")] HRESULT PluginDescription([out, retval] BSTR *pVal);
                [propget, id(3), helpstring("property PluginFileFilters")] HRESULT PluginFileFilters([out, retval] BSTR *pVal);
                [propget, id(4), helpstring("property PluginIsAutomatic")] HRESULT PluginIsAutomatic([out, retval] VARIANT_BOOL *pVal);
-               [id(5), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
-               [id(6), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
+               [propget, id(5), helpstring("property PluginExtendedProperties")] HRESULT PluginExtendedProperties([out, retval] BSTR *pVal);
+               [id(6), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
+               [id(7), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
        };
 
 [
index 06e70ed..c52a149 100644 (file)
@@ -28,8 +28,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,1,4
- PRODUCTVERSION 1,0,1,4
+ FILEVERSION 1,0,1,5
+ PRODUCTVERSION 1,0,1,5
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -47,15 +47,15 @@ BEGIN
             VALUE "Comments", "\0"
             VALUE "CompanyName", "\0"
             VALUE "FileDescription", "IgnoreCommentsC Module\0"
-            VALUE "FileVersion", "1, 0, 1, 4\0"
+            VALUE "FileVersion", "1, 0, 1, 5\0"
             VALUE "InternalName", "IgnoreCommentsC\0"
-            VALUE "LegalCopyright", "Copyright 2005-2018\0"
+            VALUE "LegalCopyright", "Copyright 2005-2021\0"
             VALUE "LegalTrademarks", "\0"
             VALUE "OLESelfRegister", "\0"
             VALUE "OriginalFilename", "IgnoreCommentsC.DLL\0"
             VALUE "PrivateBuild", "\0"
             VALUE "ProductName", "IgnoreCommentsC Module\0"
-            VALUE "ProductVersion", "1, 0, 1, 4\0"
+            VALUE "ProductVersion", "1, 0, 1, 5\0"
             VALUE "SpecialBuild", "\0"
         END
     END
index 60037ac..6594b47 100644 (file)
@@ -32,6 +32,11 @@ STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL *pVal)
   return S_OK;
 }
 
+STDMETHODIMP CWinMergeScript::get_PluginExtendedProperties(BSTR *pVal)
+{
+       *pVal = SysAllocString(L"MenuCaption=Ignore Comments (C-Family Languages)");
+       return S_OK;
+}
 
 STDMETHODIMP CWinMergeScript::UnpackBufferA(SAFEARRAY **pBuffer, INT *pSize, VARIANT_BOOL *pbChanged, INT *pSubcode, VARIANT_BOOL *pbSuccess)
 {
index 6012656..659459a 100644 (file)
@@ -43,6 +43,7 @@ public:
        STDMETHOD(UnpackBufferA)(/*[in]*/ SAFEARRAY ** pBuffer, /*[in]*/ INT * pSize, /*[in]*/ VARIANT_BOOL * pbChanged, /*[in]*/ INT * pSubcode, /*[out, retval]*/ VARIANT_BOOL * pbSuccess);
        STDMETHOD(PrediffBufferW)(BSTR *pText, INT *pSize, VARIANT_BOOL *pbChanged, VARIANT_BOOL *pbHandled);
        STDMETHOD(ShowSettingsDialog)(/*[out, retval]*/ VARIANT_BOOL * pbHandled);
+       STDMETHOD(get_PluginExtendedProperties)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginIsAutomatic)(/*[out, retval]*/ VARIANT_BOOL *pVal);
        STDMETHOD(get_PluginFileFilters)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginDescription)(/*[out, retval]*/ BSTR *pVal);
index 0deef90..b28c48f 100644 (file)
@@ -19,8 +19,11 @@ import "ocidl.idl";
                [propget, id(2), helpstring("property PluginDescription")] HRESULT PluginDescription([out, retval] BSTR *pVal);
                [propget, id(3), helpstring("property PluginFileFilters")] HRESULT PluginFileFilters([out, retval] BSTR *pVal);
                [propget, id(4), helpstring("property PluginIsAutomatic")] HRESULT PluginIsAutomatic([out, retval] VARIANT_BOOL *pVal);
-               [id(5), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
-               [id(6), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
+               [propget, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([out, retval] BSTR *pVal);
+               [propput, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([in] BSTR val);
+               [propget, id(6), helpstring("property PluginExtendedProperties")] HRESULT PluginExtendedProperties([out, retval] BSTR *pVal);
+               [id(7), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
+               [id(8), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
        };
 
 [
index cbe896e..b30fd7c 100644 (file)
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,1,4
- PRODUCTVERSION 1,0,1,4
+ FILEVERSION 1,0,1,5
+ PRODUCTVERSION 1,0,1,5
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -124,12 +124,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "IgnoreFieldsComma Module"
-            VALUE "FileVersion", "1.0.1.4"
+            VALUE "FileVersion", "1.0.1.5"
             VALUE "InternalName", "IgnoreFieldsComma"
-            VALUE "LegalCopyright", "Copyright 2003-2020"
+            VALUE "LegalCopyright", "Copyright 2003-2021"
             VALUE "OriginalFilename", "IgnoreFieldsComma.DLL"
             VALUE "ProductName", "IgnoreFieldsComma Module"
-            VALUE "ProductVersion", "1.0.1.4"
+            VALUE "ProductVersion", "1.0.1.5"
         END
     END
     BLOCK "VarFileInfo"
index b802415..914e1f7 100644 (file)
@@ -160,31 +160,51 @@ STDMETHODIMP CWinMergeScript::get_PluginEvent(BSTR *pVal)
 
 STDMETHODIMP CWinMergeScript::get_PluginDescription(BSTR *pVal)
 {
-       *pVal = SysAllocString(L"Ignore some fields - ignored fields list from the plugin name");
+       *pVal = SysAllocString(L"Ignore some fields - ignored fields list from the plugin name or the plugin argument");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginFileFilters(BSTR *pVal)
 {
        *pVal = SysAllocString(L"\\.csv$");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL *pVal)
 {
        *pVal = VARIANT_TRUE;
        return S_OK;
 }
 
+STDMETHODIMP CWinMergeScript::get_PluginArguments(BSTR *pVal)
+{
+       *pVal = m_bstrArguments.Copy();
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::put_PluginArguments(BSTR val)
+{
+       m_bstrArguments = val;
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::get_PluginExtendedProperties(BSTR *pVal)
+{
+       *pVal = SysAllocString(L"MenuCaption=Ignore CSV Fields");
+       return S_OK;
+}
+
 STDMETHODIMP CWinMergeScript::PrediffBufferW(BSTR *pText, INT *pSize, VARIANT_BOOL *pbChanged, VARIANT_BOOL *pbHandled)
 {
        WCHAR * pBeginText = *pText;
        long nSize = *pSize;
        WCHAR * pEndText = pBeginText + nSize;
 
-       CString rangestr = GetColumnRangeString();
+       int argc = 0;
+       wchar_t** argv = CommandLineToArgvW(m_bstrArguments.m_str, &argc);
+       CString rangestr = (argc > 0) ? argv[0] : GetColumnRangeString();
+       if (argv)
+               LocalFree(argv);
 
        int nExcludedRanges = CreateArrayFromRangeString(rangestr, NULL);
        int (* aExcludedRanges)[2] = new int[nExcludedRanges][2];
index af3930b..595dd87 100644 (file)
@@ -22,7 +22,7 @@ class ATL_NO_VTABLE CWinMergeScript :
        public IDispatchImpl<IWinMergeScript, &IID_IWinMergeScript, &LIBID_IgnoreFieldsCommaLib, 1, 0, CComTypeInfoHolderFileOnly>
 {
 public:
-       CWinMergeScript()
+       CWinMergeScript() : m_bstrArguments(L"")
        {
        }
 
@@ -39,10 +39,16 @@ END_COM_MAP()
 public:
        STDMETHOD(PrediffBufferW)(/*[in]*/ BSTR * pText, /*[in]*/ INT * pSize, /*[in]*/ VARIANT_BOOL * pbChanged, /*[out, retval]*/ VARIANT_BOOL * pbHandled);
        STDMETHOD(ShowSettingsDialog)(/*[out, retval]*/ VARIANT_BOOL * pbHandled);
+       STDMETHOD(get_PluginExtendedProperties)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(get_PluginArguments)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(put_PluginArguments)(/*[in]*/ BSTR val);
        STDMETHOD(get_PluginIsAutomatic)(/*[out, retval]*/ VARIANT_BOOL *pVal);
        STDMETHOD(get_PluginFileFilters)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginDescription)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginEvent)(/*[out, retval]*/ BSTR *pVal);
+
+protected:
+       CComBSTR m_bstrArguments;
 };
 
 #endif //__WINMERGESCRIPT_H_
index 627cb64..59b049e 100644 (file)
@@ -19,8 +19,11 @@ import "ocidl.idl";
                [propget, id(2), helpstring("property PluginDescription")] HRESULT PluginDescription([out, retval] BSTR *pVal);
                [propget, id(3), helpstring("property PluginFileFilters")] HRESULT PluginFileFilters([out, retval] BSTR *pVal);
                [propget, id(4), helpstring("property PluginIsAutomatic")] HRESULT PluginIsAutomatic([out, retval] VARIANT_BOOL *pVal);
-               [id(5), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
-               [id(6), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
+               [propget, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([out, retval] BSTR *pVal);
+               [propput, id(5), helpstring("property PluginArguments")] HRESULT PluginArguments([in] BSTR val);
+               [propget, id(6), helpstring("property PluginExtendedProperties")] HRESULT PluginExtendedProperties([out, retval] BSTR *pVal);
+               [id(7), helpstring("method PrediffBufferW")] HRESULT PrediffBufferW([in] BSTR * pText, [in] INT * pSize, [in] VARIANT_BOOL * pbChanged, [out, retval] VARIANT_BOOL * pbHandled);
+               [id(8), helpstring("method ShowSettingsDialog")] HRESULT ShowSettingsDialog([out, retval] VARIANT_BOOL * pbHandled);
        };
 
 [
index ac7657a..5c7a0a3 100644 (file)
@@ -107,8 +107,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,1,4
- PRODUCTVERSION 1,0,1,4
+ FILEVERSION 1,0,1,5
+ PRODUCTVERSION 1,0,1,5
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -124,12 +124,12 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "FileDescription", "IgnoreFieldsTab Module"
-            VALUE "FileVersion", "1.0.1.4"
+            VALUE "FileVersion", "1.0.1.5"
             VALUE "InternalName", "IgnoreFieldsTab"
-            VALUE "LegalCopyright", "Copyright 2003-2020"
+            VALUE "LegalCopyright", "Copyright 2003-2021"
             VALUE "OriginalFilename", "IgnoreFieldsTab.DLL"
             VALUE "ProductName", "IgnoreFieldsTab Module"
-            VALUE "ProductVersion", "1.0.1.4"
+            VALUE "ProductVersion", "1.0.1.5"
         END
     END
     BLOCK "VarFileInfo"
index 6867868..5701b57 100644 (file)
@@ -160,31 +160,51 @@ STDMETHODIMP CWinMergeScript::get_PluginEvent(BSTR *pVal)
 
 STDMETHODIMP CWinMergeScript::get_PluginDescription(BSTR *pVal)
 {
-       *pVal = SysAllocString(L"Ignore some fields - ignored fields list from the plugin name");
+       *pVal = SysAllocString(L"Ignore some fields - ignored fields list from the plugin name or the plugin argument");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginFileFilters(BSTR *pVal)
 {
        *pVal = SysAllocString(L"\\.tsv$");
        return S_OK;
 }
 
-// not used yet
 STDMETHODIMP CWinMergeScript::get_PluginIsAutomatic(VARIANT_BOOL *pVal)
 {
        *pVal = VARIANT_TRUE;
        return S_OK;
 }
 
+STDMETHODIMP CWinMergeScript::get_PluginArguments(BSTR *pVal)
+{
+       *pVal = m_bstrArguments.Copy();
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::put_PluginArguments(BSTR val)
+{
+       m_bstrArguments = val;
+       return S_OK;
+}
+
+STDMETHODIMP CWinMergeScript::get_PluginExtendedProperties(BSTR *pVal)
+{
+       *pVal = SysAllocString(L"MenuCaption=Ignore TSV Fields");
+       return S_OK;
+}
+
 STDMETHODIMP CWinMergeScript::PrediffBufferW(BSTR *pText, INT *pSize, VARIANT_BOOL *pbChanged, VARIANT_BOOL *pbHandled)
 {
        WCHAR * pBeginText = *pText;
        long nSize = *pSize;
        WCHAR * pEndText = pBeginText + nSize;
 
-       CString rangestr = GetColumnRangeString();
+       int argc = 0;
+       wchar_t** argv = CommandLineToArgvW(m_bstrArguments.m_str, &argc);
+       CString rangestr = (argc > 0) ? argv[0] : GetColumnRangeString();
+       if (argv)
+               LocalFree(argv);
 
        int nExcludedRanges = CreateArrayFromRangeString(rangestr, NULL);
        int (* aExcludedRanges)[2] = new int[nExcludedRanges][2];
index 358177c..da74617 100644 (file)
@@ -22,7 +22,7 @@ class ATL_NO_VTABLE CWinMergeScript :
        public IDispatchImpl<IWinMergeScript, &IID_IWinMergeScript, &LIBID_IgnoreFieldsTabLib, 1, 0, CComTypeInfoHolderFileOnly>
 {
 public:
-       CWinMergeScript()
+       CWinMergeScript() : m_bstrArguments(L"")
        {
        }
 
@@ -39,10 +39,16 @@ END_COM_MAP()
 public:
        STDMETHOD(PrediffBufferW)(/*[in]*/ BSTR * pText, /*[in]*/ INT * pSize, /*[in]*/ VARIANT_BOOL * pbChanged, /*[out, retval]*/ VARIANT_BOOL * pbHandled);
        STDMETHOD(ShowSettingsDialog)(/*[out, retval]*/ VARIANT_BOOL * pbHandled);
+       STDMETHOD(get_PluginExtendedProperties)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(get_PluginArguments)(/*[out, retval]*/ BSTR *pVal);
+       STDMETHOD(put_PluginArguments)(/*[in]*/ BSTR val);
        STDMETHOD(get_PluginIsAutomatic)(/*[out, retval]*/ VARIANT_BOOL *pVal);
        STDMETHOD(get_PluginFileFilters)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginDescription)(/*[out, retval]*/ BSTR *pVal);
        STDMETHOD(get_PluginEvent)(/*[out, retval]*/ BSTR *pVal);
+
+protected:
+       CComBSTR m_bstrArguments;
 };
 
 #endif //__WINMERGESCRIPT_H_
index f37a165..e325c70 100644 (file)
@@ -168,7 +168,6 @@ protected:
  */
 class UniMemFile : public UniLocalFile
 {
-       friend class UniMarkdownFile;
 public:
        enum AccessMode
        {
index 7d918ac..f6aeff8 100644 (file)
@@ -218,4 +218,20 @@ String format_string2(const String& fmt, const String& arg1, const String& arg2)
        return format_strings(fmt, args, 2);
 }
 
+std::vector<StringView> split(StringView str, TCHAR delim)
+{
+       std::vector<StringView> result;
+       size_t start = 0;
+       for (size_t i = 0; i < str.size(); i++)
+       {
+               if (str[i] == delim)
+               {
+                       result.emplace_back(str.data() + start, i - start);
+                       start = i + 1;
+               }
+       }
+       result.emplace_back(str.data() + start, str.size() - start);
+       return result;
+}
+
 }
index b5e5fe2..b9b1fb5 100644 (file)
@@ -8,6 +8,7 @@
 #pragma once
 
 #include <string>
+#include <string_view>
 #include <tchar.h>
 
 #ifdef _UNICODE
@@ -17,6 +18,7 @@
 #endif // _UNICODE
 
 typedef std_tchar(string) String;
+typedef std_tchar(string_view) StringView;
 
 namespace strutils
 {
@@ -87,6 +89,8 @@ String join(const InputIterator& begin, const InputIterator& end, const String&
        return result;
 }
 
+std::vector<StringView> split(StringView str, TCHAR delim);
+
 inline String to_str(int val) { return strutils::format(_T("%d"), val); }
 inline String to_str(unsigned val) { return strutils::format(_T("%u"), val); }
 inline String to_str(long val) { return strutils::format(_T("%ld"), val); }
index 932ff37..06d995e 100644 (file)
@@ -876,13 +876,6 @@ String toTString(const std::string& str)
 #endif
 }
 
-std::wstring toUTF16(const String& tstr)
-{
-       std::wstring wstr;
-       toUTF16(tstr, wstr);
-       return wstr;
-}
-
 void toUTF16(const String& tstr, std::wstring& wstr)
 {
 #ifdef UNICODE
index ed45651..ea06b23 100644 (file)
@@ -93,7 +93,17 @@ void dealloc(void *ptr);
 String toTString(const std::wstring& str);
 String toTString(const std::string& str);
 void toUTF16(const String& tstr, std::wstring& wstr);
-std::wstring toUTF16(const String& tstr);
+inline std::wstring toUTF16(const String& tstr)
+{
+#ifdef UNICODE
+       return tstr;
+#else
+       std::wstring wstr;
+       toUTF16(tstr, wstr);
+       return wstr;
+#endif
+}
+
 void toUTF8(const String& tstr, std::string& u8str);
 std::string toUTF8(const String& tstr);
 std::string toSystemCP(const std::string& str);
index a3218fb..acf817c 100644 (file)
@@ -235,7 +235,8 @@ CompareOptions * CDiffContext::GetCompareOptions(int compareMethod)
 void CDiffContext::FetchPluginInfos(const String& filteredFilenames,
                PackingInfo ** infoUnpacker, PrediffingInfo ** infoPrediffer)
 {
-       assert(m_piPluginInfos != nullptr);
+       if (!m_piPluginInfos)
+               return;
        m_piPluginInfos->FetchPluginInfos(filteredFilenames, infoUnpacker, infoPrediffer);
 }
 
@@ -247,3 +248,39 @@ bool CDiffContext::ShouldAbort() const
 {
        return m_piAbortable!=nullptr && m_piAbortable->ShouldAbort();
 }
+
+/**
+ * @brief Get actual compared paths from DIFFITEM.
+ * @param [in] pCtx Pointer to compare context.
+ * @param [in] di DiffItem from which the paths are created.
+ * @param [out] left Gets the left compare path.
+ * @param [out] right Gets the right compare path.
+ * @note If item is unique, same path is returned for both.
+ */
+void CDiffContext::GetComparePaths(const DIFFITEM &di, PathContext & tFiles) const
+{
+       int nDirs = GetCompareDirs();
+
+       tFiles.SetSize(nDirs);
+
+       for (int nIndex = 0; nIndex < nDirs; nIndex++)
+       {
+               if (di.diffcode.exists(nIndex))
+               {
+                       tFiles.SetPath(nIndex,
+                               paths::ConcatPath(GetPath(nIndex), di.diffFileInfo[nIndex].GetFile()), false);
+               }
+               else
+               {
+                       tFiles.SetPath(nIndex, _T("NUL"), false);
+               }
+       }
+}
+
+String CDiffContext::GetFilteredFilenames(const DIFFITEM& di) const
+{
+       PathContext paths;
+       GetComparePaths(di, paths);
+       return GetFilteredFilenames(paths);
+}
+
index 4f9af4a..9176df5 100644 (file)
@@ -151,6 +151,10 @@ public:
 
        const DIFFOPTIONS *GetOptions() const { return m_pOptions.get(); }
 
+       void GetComparePaths(const DIFFITEM& di, PathContext& tFiles) const;
+       String GetFilteredFilenames(const DIFFITEM& di) const;
+       static String GetFilteredFilenames(const PathContext& paths) { return strutils::join(paths.begin(), paths.end(), _T("|")); }
+
        IDiffFilter * m_piFilterGlobal; /**< Interface for file filtering. */
        IDiffFilter * m_pImgfileFilter; /**< Interface for image file filtering */
        IPluginInfos * m_piPluginInfos;
index 6af31e8..d211fad 100644 (file)
@@ -135,7 +135,7 @@ void DiffFileData::Reset()
  */
 bool DiffFileData::Filepath_Transform(bool bForceUTF8,
        const FileTextEncoding & encoding, const String & filepath, String & filepathTransformed,
-       const String& filteredFilenames, PrediffingInfo * infoPrediffer)
+       const String& filteredFilenames, PrediffingInfo& infoPrediffer)
 {
        // third step : prediff (plugins)
        bool bMayOverwrite =  // temp variable set each time it is used
@@ -145,7 +145,7 @@ bool DiffFileData::Filepath_Transform(bool bForceUTF8,
        // if a prediffer fails, we consider it is not the good one, that's all
        // FileTransform_Prediffing returns `false` only if the prediffer works, 
        // but the data can not be saved to disk (no more place ??)
-       if (!FileTransform::Prediffing(infoPrediffer, filepathTransformed, filteredFilenames, bMayOverwrite))
+       if (!infoPrediffer.Prediffing(filepathTransformed, filteredFilenames, bMayOverwrite, { filepath }))
                return false;
 
        if ((encoding.m_unicoding && encoding.m_unicoding != ucr::UTF8) || bForceUTF8)
index 43716e6..daebd10 100644 (file)
@@ -34,7 +34,7 @@ struct DiffFileData
        void SetDisplayFilepaths(const String& szTrueFilepath1, const String& szTrueFilepath2);
 
        bool Filepath_Transform(bool bForceUTF8, const FileTextEncoding & encoding, const String & filepath, String & filepathTransformed,
-               const String& filteredFilenames, PrediffingInfo * infoPrediffer);
+               const String& filteredFilenames, PrediffingInfo& infoPrediffer);
 
 // Data (public)
        file_data * m_inf;
index 019b950..caa70dd 100644 (file)
@@ -82,7 +82,6 @@ static CRLFSTYLE GetTextFileStyle(const UniMemFile::txtstats & stats)
 CDiffTextBuffer::CDiffTextBuffer(CMergeDoc * pDoc, int pane)
 : m_pOwnerDoc(pDoc)
 , m_nThisPane(pane)
-, m_unpackerSubcode(0)
 , m_bMixedEOL(false)
 {
 }
@@ -222,7 +221,7 @@ OnNotifyLineHasBeenEdited(int nLine)
  * @note If this method fails, it calls InitNew so the CDiffTextBuffer is in a valid state
  */
 int CDiffTextBuffer::LoadFromFile(LPCTSTR pszFileNameInit,
-               PackingInfo * infoUnpacker, LPCTSTR sToFindUnpacker, bool & readOnly,
+               PackingInfo& infoUnpacker, LPCTSTR sToFindUnpacker, bool & readOnly,
                CRLFSTYLE nCrlfStyle, const FileTextEncoding & encoding, CString &sError)
 {
        ASSERT(!m_bInit);
@@ -230,14 +229,12 @@ int CDiffTextBuffer::LoadFromFile(LPCTSTR pszFileNameInit,
 
        // Unpacking the file here, save the result in a temporary file
        m_strTempFileName = pszFileNameInit;
-       if (!FileTransform::Unpacking(infoUnpacker, &m_unpackerSubcode, m_strTempFileName, sToFindUnpacker))
+       if (!infoUnpacker.Unpacking(&m_unpackerSubcodes, m_strTempFileName, sToFindUnpacker, { m_strTempFileName }))
        {
                InitNew(); // leave crystal editor in valid, empty state
                return FileLoadResult::FRESULT_ERROR_UNPACK;
        }
 
-       // we use the same unpacker for both files, so it must be defined after first file
-       ASSERT(infoUnpacker->m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_AUTO);
        // we will load the transformed file
        LPCTSTR pszFileName = m_strTempFileName.c_str();
 
@@ -251,9 +248,7 @@ int CDiffTextBuffer::LoadFromFile(LPCTSTR pszFileNameInit,
        if (def && def->encoding != -1)
                m_nSourceEncoding = def->encoding;
        
-       UniFile *pufile = infoUnpacker->m_pufile;
-       if (pufile == nullptr)
-               pufile = new UniMemFile;
+       UniFile *pufile = new UniMemFile;
 
        // Now we only use the UniFile interface
        // which is something we could implement for HTTP and/or FTP files
@@ -270,7 +265,7 @@ int CDiffTextBuffer::LoadFromFile(LPCTSTR pszFileNameInit,
        }
        else
        {
-               if (infoUnpacker->m_PluginName.length() > 0)
+               if (!infoUnpacker.GetPluginPipeline().empty())
                {
                        // re-detect codepage
                        int iGuessEncodingType = GetOptionsMgr()->GetInt(OPT_CP_DETECT);
@@ -411,7 +406,7 @@ int CDiffTextBuffer::LoadFromFile(LPCTSTR pszFileNameInit,
  * @return SAVE_DONE or an error code (list in MergeDoc.h)
  */
 int CDiffTextBuffer::SaveToFile (const String& pszFileName,
-               bool bTempFile, String & sError, PackingInfo * infoUnpacker /*= nullptr*/,
+               bool bTempFile, String & sError, PackingInfo& infoUnpacker /*= nullptr*/,
                CRLFSTYLE nCrlfStyle /*= CRLFSTYLE::AUTOMATIC*/,
                bool bClearModifiedFlag /*= true*/,
                int nStartLine /*= 0*/, int nLines /*= -1*/)
@@ -427,8 +422,7 @@ int CDiffTextBuffer::SaveToFile (const String& pszFileName,
                return SAVE_FAILED;     // No filename, cannot save...
 
        if (nCrlfStyle == CRLFSTYLE::AUTOMATIC &&
-               !GetOptionsMgr()->GetBool(OPT_ALLOW_MIXED_EOL) ||
-               infoUnpacker!=nullptr && infoUnpacker->m_bDisallowMixedEOL)
+               !GetOptionsMgr()->GetBool(OPT_ALLOW_MIXED_EOL))
        {
                        // get the default nCrlfStyle of the CDiffTextBuffer
                nCrlfStyle = GetCRLFMode();
@@ -544,9 +538,8 @@ int CDiffTextBuffer::SaveToFile (const String& pszFileName,
        {
                // If we are saving user files
                // we need an unpacker/packer, at least a "do nothing" one
-               ASSERT(infoUnpacker != nullptr);
                // repack the file here, overwrite the temporary file we did save in
-               bSaveSuccess = FileTransform::Packing(sIntermediateFilename, pszFileName, *infoUnpacker, m_unpackerSubcode);
+               bSaveSuccess = infoUnpacker.Packing(sIntermediateFilename, pszFileName, m_unpackerSubcodes, { pszFileName });
                try
                {
                        TFile(sIntermediateFilename).remove();
index bfe7e9a..eb8283b 100644 (file)
@@ -23,7 +23,7 @@ private :
        int m_nThisPane; /**< Left/Right side */
        String m_strTempPath; /**< Temporary files folder. */
        String m_strTempFileName; /**< Temporary file name. */
-       int m_unpackerSubcode; /**< Plugin information. */
+       std::vector<int> m_unpackerSubcodes; /**< Plugin information. */
        bool m_bMixedEOL; /**< EOL style of this buffer is mixed? */
 
        /** 
@@ -51,11 +51,11 @@ public :
        bool curUndoGroup();
        void ReplaceFullLines(CDiffTextBuffer& dbuf, CDiffTextBuffer& sbuf, CCrystalTextView * pSource, int nLineBegin, int nLineEnd, int nAction =CE_ACTION_UNKNOWN);
 
-       int LoadFromFile(LPCTSTR pszFileName, PackingInfo * infoUnpacker,
+       int LoadFromFile(LPCTSTR pszFileName, PackingInfo& infoUnpacker,
                LPCTSTR filteredFilenames, bool & readOnly, CRLFSTYLE nCrlfStyle,
                const FileTextEncoding & encoding, CString &sError);
        int SaveToFile (const String& pszFileName, bool bTempFile, String & sError,
-               PackingInfo * infoUnpacker = nullptr, CRLFSTYLE nCrlfStyle = CRLFSTYLE::AUTOMATIC,
+               PackingInfo& infoUnpacker, CRLFSTYLE nCrlfStyle = CRLFSTYLE::AUTOMATIC,
                bool bClearModifiedFlag = true, int nStartLine = 0, int nLines = -1);
        ucr::UNICODESET getUnicoding() const { return m_encoding.m_unicoding; }
        void setUnicoding(ucr::UNICODESET value) { m_encoding.m_unicoding = value; }
index 300bdbf..8efdf6d 100644 (file)
@@ -430,22 +430,17 @@ bool CDiffWrapper::RunFileDiff()
 
                        // this can only fail if the data can not be saved back (no more
                        // place on disk ???) What to do then ??
-                       if (!FileTransform::Prediffing(m_infoPrediffer.get(), strFileTemp[file], m_sToFindPrediffer, m_bPathsAreTemp))
+                       if (m_infoPrediffer && !m_infoPrediffer->Prediffing(strFileTemp[file], m_sToFindPrediffer, m_bPathsAreTemp, { strFileTemp[file] }))
                        {
                                // display a message box
                                String sError = strutils::format(
                                        _T("An error occurred while prediffing the file '%s' with the plugin '%s'. The prediffing is not applied any more."),
                                        strFileTemp[file].c_str(),
-                                       m_infoPrediffer->m_PluginName.c_str());
+                                       m_infoPrediffer->GetPluginPipeline().c_str());
                                AppErrorMessageBox(sError);
                                // don't use any more this prediffer
-                               m_infoPrediffer->m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
-                               m_infoPrediffer->m_PluginName.erase();
+                               m_infoPrediffer->ClearPluginPipeline();
                        }
-
-                       // We use the same plugin for both files, so it must be defined before
-                       // second file
-                       assert(m_infoPrediffer->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_MANUAL);
                }
        }
 
index 3f0cbf2..f540736 100644 (file)
@@ -657,7 +657,7 @@ void ApplyFolderNameAndFileName(const InputIterator& begin, const InputIterator&
  * @brief Apply specified setting for prediffing to all selected items
  */
 template<class InputIterator>
-void ApplyPluginPrediffSetting(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, PLUGIN_MODE newsetting)
+void ApplyPluginPipeline(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, bool unpacker, const String& pluginPipeline)
 {
        // Unlike other group actions, here we don't build an action list
        // to execute; we just apply this change directly
@@ -668,19 +668,14 @@ void ApplyPluginPrediffSetting(const InputIterator& begin, const InputIterator&
                const DIFFITEM& di = *it;
                if (!di.diffcode.isDirectory())
                {
-                       String filteredFilenames;
-                       for (int i = 0; i < ctxt.GetCompareDirs(); ++i)
-                       {
-                               if (di.diffcode.exists(i))
-                               {
-                                       if (!filteredFilenames.empty()) filteredFilenames += _T("|");
-                                       filteredFilenames += ::GetItemFileName(ctxt, di, i);
-                               }
-                       }
                        PackingInfo * infoUnpacker = nullptr;
                        PrediffingInfo * infoPrediffer = nullptr;
+                       String filteredFilenames = ctxt.GetFilteredFilenames(di);
                        const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
-                       infoPrediffer->Initialize(newsetting);
+                       if (unpacker)
+                               infoUnpacker->SetPluginPipeline(pluginPipeline);
+                       else
+                               infoPrediffer->SetPluginPipeline(pluginPipeline);
                }
        }
 }
@@ -689,12 +684,13 @@ void ApplyPluginPrediffSetting(const InputIterator& begin, const InputIterator&
  * @brief Updates just before displaying plugin context view in list
  */
 template<class InputIterator>
-std::pair<int, int> CountPredifferYesNo(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt)
+std::tuple<int, int, int> CountPluginNoneAutoOthers(const InputIterator& begin, const InputIterator& end, const CDiffContext& ctxt, bool unpacker)
 {
-       int nPredifferYes = 0;
-       int nPredifferNo = 0;
+       int nNone = 0;
+       int nAuto = 0;
+       int nOthers = 0;
        if( !ctxt.m_bPluginsEnabled || ctxt.m_piPluginInfos == nullptr ) 
-               return std::make_pair(nPredifferYes, nPredifferNo);
+               return std::make_tuple(nNone, nAuto, nOthers);
 
        for (InputIterator it = begin; it != end; ++it)
        {
@@ -706,18 +702,20 @@ std::pair<int, int> CountPredifferYesNo(const InputIterator& begin, const InputI
                if (!di.diffcode.isDirectory() && !di.diffcode.isBin() && IsItemExistAll(ctxt, di)
                        && !di.diffcode.isResultFiltered())
                {
-                       PathContext tFiles = GetItemFileNames(ctxt, di);
-                       String filteredFilenames = strutils::join(tFiles.begin(), tFiles.end(), _T("|"));
-                       PackingInfo * unpacker;
-                       PrediffingInfo * prediffer;
-                       const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &unpacker, &prediffer);
-                       if (prediffer->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_AUTO || !prediffer->m_PluginName.empty())
-                               nPredifferYes ++;
+                       PackingInfo * infoUnpacker;
+                       PrediffingInfo * infoPrediffer;
+                       String filteredFilenames = ctxt.GetFilteredFilenames(di);
+                       const_cast<CDiffContext&>(ctxt).FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
+                       String pluginPipeline = unpacker ? infoUnpacker->GetPluginPipeline() : infoPrediffer->GetPluginPipeline();
+                       if (pluginPipeline.empty())
+                               nNone++;
+                       else if (pluginPipeline == _T("<Automatic>"))
+                               nAuto++;
                        else
-                               nPredifferNo ++;
+                               nOthers++;
                }
        }
-       return std::make_pair(nPredifferYes, nPredifferNo);
+       return std::make_tuple(nNone, nAuto, nOthers);
 }
 
 template<class InputIterator>
index 5092f40..70cd193 100644 (file)
@@ -254,9 +254,6 @@ void CDirDoc::InitDiffContext(CDiffContext *pCtxt)
        theApp.m_pGlobalFileFilter->ReloadUpdatedFilters();
        pCtxt->m_piFilterGlobal = theApp.m_pGlobalFileFilter.get();
        
-       //Reset the cache for the Automatic/Manual Unpacking/Prediffer settings to take effect
-       m_pluginman.Reset();
-
        // All plugin management is done by our plugin manager
        pCtxt->m_piPluginInfos = GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED) ? &m_pluginman : nullptr;
 }
index f067156..e8456b1 100644 (file)
@@ -24,7 +24,7 @@
 #include "MainFrm.h"
 #include "resource.h"
 #include "FileTransform.h"
-#include "SelectUnpackerDlg.h"
+#include "SelectPluginDlg.h"
 #include "paths.h"
 #include "7zCommon.h"
 #include "OptionsDef.h"
@@ -165,8 +165,8 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_UPDATE_COMMAND_UI(ID_DIR_OPEN_RIGHT_WITH, OnUpdateCtxtDirOpenWith<SIDE_RIGHT>)
        ON_COMMAND(ID_DIR_OPEN_RIGHT_PARENT_FOLDER, OnCtxtDirOpenParentFolder<SIDE_RIGHT>)
        ON_UPDATE_COMMAND_UI(ID_DIR_OPEN_RIGHT_PARENT_FOLDER, OnUpdateCtxtDirOpenParentFolder<SIDE_RIGHT>)
-       ON_COMMAND(ID_POPUP_OPEN_WITH_UNPACKER, OnCtxtOpenWithUnpacker)
-       ON_UPDATE_COMMAND_UI(ID_POPUP_OPEN_WITH_UNPACKER, OnUpdateCtxtOpenWithUnpacker)
+       ON_COMMAND(ID_OPEN_WITH_UNPACKER, OnOpenWithUnpacker)
+       ON_UPDATE_COMMAND_UI(ID_OPEN_WITH_UNPACKER, OnUpdateCtxtOpenWithUnpacker)
        ON_COMMAND(ID_DIR_OPEN_LEFT_WITHEDITOR, OnCtxtDirOpenWithEditor<SIDE_LEFT>)
        ON_UPDATE_COMMAND_UI(ID_DIR_OPEN_LEFT_WITHEDITOR, OnUpdateCtxtDirOpenWithEditor<SIDE_LEFT>)
        ON_COMMAND(ID_DIR_OPEN_MIDDLE_WITHEDITOR, OnCtxtDirOpenWithEditor<SIDE_MIDDLE>)
@@ -227,8 +227,10 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_COMMAND(ID_DIR_SHELL_CONTEXT_MENU_RIGHT, OnCtxtDirShellContextMenu<SIDE_RIGHT>)
        ON_COMMAND(ID_EDIT_SELECT_ALL, OnSelectAll)
        ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdateSelectAll)
-       ON_COMMAND_RANGE(ID_PREDIFF_MANUAL, ID_PREDIFF_AUTO, OnPluginPredifferMode)
-       ON_UPDATE_COMMAND_UI_RANGE(ID_PREDIFF_MANUAL, ID_PREDIFF_AUTO, OnUpdatePluginPredifferMode)
+       ON_COMMAND_RANGE(ID_PREDIFFER_SETTINGS_NONE, ID_PREDIFFER_SETTINGS_SELECT, OnPluginSettings)
+       ON_COMMAND_RANGE(ID_UNPACKER_SETTINGS_NONE, ID_UNPACKER_SETTINGS_SELECT, OnPluginSettings)
+       ON_UPDATE_COMMAND_UI_RANGE(ID_PREDIFFER_SETTINGS_NONE, ID_PREDIFFER_SETTINGS_SELECT, OnUpdatePluginMode)
+       ON_UPDATE_COMMAND_UI_RANGE(ID_UNPACKER_SETTINGS_NONE, ID_UNPACKER_SETTINGS_SELECT, OnUpdatePluginMode)
        ON_COMMAND(ID_DIR_COPY_PATHNAMES_LEFT, OnCopyPathnames<SIDE_LEFT>)
        ON_COMMAND(ID_DIR_COPY_PATHNAMES_MIDDLE, OnCopyPathnames<SIDE_MIDDLE>)
        ON_COMMAND(ID_DIR_COPY_PATHNAMES_RIGHT, OnCopyPathnames<SIDE_RIGHT>)
@@ -279,10 +281,10 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_COMMAND(ID_MERGE_COMPARE_LEFT2_RIGHT1, OnMergeCompare2<SELECTIONTYPE_LEFT2RIGHT1>)
        ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_LEFT2_RIGHT1, OnUpdateMergeCompare2<SELECTIONTYPE_LEFT2RIGHT1>)
        ON_COMMAND(ID_MERGE_COMPARE_NONHORIZONTALLY, OnMergeCompareNonHorizontally)
-       ON_COMMAND(ID_MERGE_COMPARE_XML, OnMergeCompareXML)
-       ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_XML, OnUpdateMergeCompare)
        ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnMergeCompareAs)
+       ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnMergeCompareAs)
        ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateMergeCompare)
+       ON_UPDATE_COMMAND_UI(ID_NO_UNPACKER, OnUpdateNoUnpacker)
        ON_COMMAND(ID_VIEW_TREEMODE, OnViewTreeMode)
        ON_UPDATE_COMMAND_UI(ID_VIEW_TREEMODE, OnUpdateViewTreeMode)
        ON_COMMAND(ID_VIEW_EXPAND_ALLSUBDIRS, OnViewExpandAllSubdirs)
@@ -329,7 +331,6 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
        ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
        ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
-       //}}AFX_MSG_MAP
        ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnClick)
        ON_NOTIFY_REFLECT(LVN_ITEMCHANGED, OnItemChanged)
        ON_NOTIFY_REFLECT(LVN_BEGINLABELEDIT, OnBeginLabelEdit)
@@ -340,6 +341,7 @@ BEGIN_MESSAGE_MAP(CDirView, CListView)
        ON_BN_CLICKED(IDC_COMPARISON_STOP, OnBnClickedComparisonStop)
        ON_BN_CLICKED(IDC_COMPARISON_PAUSE, OnBnClickedComparisonPause)
        ON_BN_CLICKED(IDC_COMPARISON_CONTINUE, OnBnClickedComparisonContinue)
+       //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
 /////////////////////////////////////////////////////////////////////////////
@@ -1348,7 +1350,7 @@ void CDirView::Open(const PathContext& paths, DWORD dwFlags[3], FileTextEncoding
        else if (HasZipSupport() && std::count_if(paths.begin(), paths.end(), ArchiveGuessFormat) == paths.GetSize())
        {
                // Open archives, not adding paths to MRU
-               GetMainFrame()->DoFileOpen(&paths, dwFlags, nullptr, _T(""), GetDiffContext().m_bRecursive, nullptr, _T(""), infoUnpacker);
+               GetMainFrame()->DoFileOpen(&paths, dwFlags, nullptr, _T(""), GetDiffContext().m_bRecursive, nullptr, infoUnpacker, nullptr);
        }
        else
        {
@@ -1360,20 +1362,32 @@ void CDirView::Open(const PathContext& paths, DWORD dwFlags[3], FileTextEncoding
                // then it was set in a previous diff after unpacking, so we trust it
 
                // Open identical and different files
+               PathContext filteredPaths;
                FileLocation fileloc[3];
                String strDesc[3];
                const String sUntitled[] = { _("Untitled left"), paths.GetSize() < 3 ? _("Untitled right") : _("Untitled middle"), _("Untitled right") };
                for (int i = 0; i < paths.GetSize(); ++i)
                {
                        if (paths::DoesPathExist(paths[i]) == paths::DOES_NOT_EXIST)
+                       {
                                strDesc[i] = sUntitled[i];
+                               filteredPaths.SetPath(i, _T("NUL"), false);
+                       }
                        else
                        {
                                fileloc[i].setPath(paths[i]);
                                fileloc[i].encoding = encoding[i];
+                               filteredPaths.SetPath(i, paths[i], false);
                        }
                }
 
+               if (!infoUnpacker)
+               {
+                       PrediffingInfo* infoPrediffer = nullptr;
+                       String filteredFilenames = CDiffContext::GetFilteredFilenames(filteredPaths);
+                       GetDiffContext().FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
+               }
+
                GetMainFrame()->ShowAutoMergeDoc(pDoc, paths.GetSize(), fileloc,
                        dwFlags, strDesc, _T(""), infoUnpacker);
        }
@@ -1526,19 +1540,36 @@ void CDirView::OpenSelectionAs(UINT id)
        const String sUntitled[] = { _("Untitled left"), paths.GetSize() < 3 ? _("Untitled right") : _("Untitled middle"), _("Untitled right") };
        DWORD dwFlags[3] = { 0 };
        String strDesc[3];
+       PathContext filteredPaths;
        FileLocation fileloc[3];
        for (int pane = 0; pane < paths.GetSize(); pane++)
        {
                if (paths::DoesPathExist(paths[pane]) == paths::DOES_NOT_EXIST)
+               {
                        strDesc[pane] = sUntitled[pane];
+                       filteredPaths.SetPath(pane, _T("NUL"), false);
+               }
                else
                {
                        fileloc[pane].setPath(paths[pane]);
                        fileloc[pane].encoding = encoding[pane];
+                       filteredPaths.SetPath(pane, paths[pane]);
                }
                dwFlags[pane] |= FFILEOPEN_NOMRU | (pDoc->GetReadOnly(nPane[pane]) ? FFILEOPEN_READONLY : 0);
        }
-       GetMainFrame()->ShowMergeDoc(id, pDoc, paths.GetSize(), fileloc, dwFlags, strDesc);
+       if (ID_UNPACKERS_FIRST <= id && id <= ID_UNPACKERS_LAST)
+       {
+               PackingInfo infoUnpacker(
+                               CMainFrame::GetPluginPipelineByMenuId(id, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+               GetMainFrame()->ShowAutoMergeDoc(pDoc, paths.GetSize(), fileloc, dwFlags, strDesc, _T(""), &infoUnpacker);
+       }
+       else
+       {
+               PackingInfo* infoUnpacker = nullptr;
+               PrediffingInfo* infoPrediffer = nullptr;
+               GetDiffContext().FetchPluginInfos(CDiffContext::GetFilteredFilenames(filteredPaths), &infoUnpacker, &infoPrediffer);
+               GetMainFrame()->ShowMergeDoc(id, pDoc, paths.GetSize(), fileloc, dwFlags, strDesc, _T(""), infoUnpacker);
+       }
 }
 
 /// User chose (context menu) delete left
@@ -2684,22 +2715,23 @@ void CDirView::OnCustomizeColumns()
        GetOptionsMgr()->SaveOption(keyname, m_pColItems->SaveColumnOrders());
 }
 
-void CDirView::OnCtxtOpenWithUnpacker()
+void CDirView::OnOpenWithUnpacker()
 {
        int sel = -1;
        sel = m_pList->GetNextItem(sel, LVNI_SELECTED);
        if (sel != -1)
        {
+               PackingInfo* infoUnpacker = nullptr;
+               PrediffingInfo* infoPrediffer = nullptr;
+               CDiffContext& ctxt = GetDiffContext();
+               String filteredFilenames = ctxt.GetFilteredFilenames(GetDiffItem(sel));
+               ctxt.FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
                // let the user choose a handler
-               CSelectUnpackerDlg dlg(GetDiffItem(sel).diffFileInfo[0].filename, this);
-               // create now a new infoUnpacker to initialize the manual/automatic flag
-               PackingInfo infoUnpacker(PLUGIN_MODE::PLUGIN_AUTO);
-               dlg.SetInitialInfoHandler(&infoUnpacker);
-
+               CSelectPluginDlg dlg(infoUnpacker->GetPluginPipeline(), filteredFilenames, true, false, this);
                if (dlg.DoModal() == IDOK)
                {
-                       infoUnpacker = dlg.GetInfoHandler();
-                       OpenSelection(SELECTIONTYPE_NORMAL, &infoUnpacker, false);
+                       PackingInfo infoUnpackerNew(dlg.GetPluginPipeline());
+                       OpenSelection(SELECTIONTYPE_NORMAL, &infoUnpackerNew, false);
                }
        }
 
@@ -3032,16 +3064,43 @@ void CDirView::OnUpdateSelectAll(CCmdUI* pCmdUI)
 /**
  * @brief Handle clicks in plugin context view in list
  */
-void CDirView::OnPluginPredifferMode(UINT nID)
+void CDirView::OnPluginSettings(UINT nID)
 {
-       ApplyPluginPrediffSetting(SelBegin(), SelEnd(), GetDiffContext(), 
-               (nID == ID_PREDIFF_AUTO) ? PLUGIN_MODE::PLUGIN_AUTO : PLUGIN_MODE::PLUGIN_MANUAL);
+       bool unpacker = (ID_UNPACKER_SETTINGS_NONE <= nID && nID <= ID_UNPACKER_SETTINGS_SELECT);
+       String pluginPipeline;
+       switch (nID)
+       {
+       case ID_PREDIFFER_SETTINGS_NONE:
+       case ID_UNPACKER_SETTINGS_NONE:
+               pluginPipeline = _T("");
+               break;
+       case ID_PREDIFFER_SETTINGS_AUTO:
+       case ID_UNPACKER_SETTINGS_AUTO:
+               pluginPipeline = _T("<Automatic>");
+               break;
+       case ID_PREDIFFER_SETTINGS_SELECT:
+       case ID_UNPACKER_SETTINGS_SELECT:
+               int sel = m_pList->GetNextItem(-1, LVNI_SELECTED);
+               PackingInfo* infoUnpacker = nullptr;
+               PrediffingInfo* infoPrediffer = nullptr;
+               CDiffContext& ctxt = GetDiffContext();
+               String filteredFilenames = ctxt.GetFilteredFilenames(GetDiffItem(sel));
+               ctxt.FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
+               GetDiffContext().FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
+               CSelectPluginDlg dlg(infoUnpacker->GetPluginPipeline(), filteredFilenames, unpacker, false, this);
+               if (dlg.DoModal() != IDOK)
+                       return;
+               pluginPipeline = dlg.GetPluginPipeline();
+               break;
+       }
+       ApplyPluginPipeline(SelBegin(), SelEnd(), GetDiffContext(), unpacker, pluginPipeline);
+       Invalidate();
 }
 
 /**
  * @brief Updates just before displaying plugin context view in list
  */
-void CDirView::OnUpdatePluginPredifferMode(CCmdUI* pCmdUI)
+void CDirView::OnUpdatePluginMode(CCmdUI* pCmdUI)
 {
        // 2004-04-03, Perry
        // CMainFrame::OnUpdatePluginUnpackMode handles this for global unpacking
@@ -3056,10 +3115,12 @@ void CDirView::OnUpdatePluginPredifferMode(CCmdUI* pCmdUI)
        if (pPopup == nullptr)
                return;
 
-       std::pair<int, int> counts = CountPredifferYesNo(SelBegin(), SelEnd(), GetDiffContext());
+       bool unpacker = (ID_UNPACKER_SETTINGS_NONE <= pCmdUI->m_nID && pCmdUI->m_nID <= ID_UNPACKER_SETTINGS_SELECT);
+       auto counts = CountPluginNoneAutoOthers(SelBegin(), SelEnd(), GetDiffContext(), unpacker);
 
-       CheckContextMenu(pPopup, ID_PREDIFF_AUTO, (counts.first > 0));
-       CheckContextMenu(pPopup, ID_PREDIFF_MANUAL, (counts.second > 0));
+       CheckContextMenu(pPopup, unpacker ? ID_UNPACKER_SETTINGS_NONE   : ID_PREDIFFER_SETTINGS_NONE,   (std::get<0>(counts) > 0));
+       CheckContextMenu(pPopup, unpacker ? ID_UNPACKER_SETTINGS_AUTO   : ID_PREDIFFER_SETTINGS_AUTO,   (std::get<1>(counts) > 0));
+       CheckContextMenu(pPopup, unpacker ? ID_UNPACKER_SETTINGS_SELECT : ID_PREDIFFER_SETTINGS_SELECT, (std::get<2>(counts) > 0));
 }
 
 /**
@@ -3709,13 +3770,6 @@ void CDirView::OnMergeCompareNonHorizontally()
        }
 }
 
-void CDirView::OnMergeCompareXML()
-{
-       CWaitCursor waitstatus;
-       PackingInfo packingInfo(PLUGIN_MODE::PLUGIN_BUILTIN_XML);
-       OpenSelection(SELECTIONTYPE_NORMAL, &packingInfo, false);
-}
-
 void CDirView::OnMergeCompareAs(UINT nID)
 {
        CWaitCursor waitstatus;
@@ -3724,8 +3778,8 @@ void CDirView::OnMergeCompareAs(UINT nID)
 
 void CDirView::OnUpdateMergeCompare(CCmdUI *pCmdUI)
 {
-       bool openableForDir = !(pCmdUI->m_nID >= ID_MERGE_COMPARE_TEXT &&
-                                                   pCmdUI->m_nID <= ID_MERGE_COMPARE_XML);
+       bool openableForDir = !((pCmdUI->m_nID >= ID_MERGE_COMPARE_TEXT && pCmdUI->m_nID <= ID_MERGE_COMPARE_IMAGE) ||
+               (pCmdUI->m_nID >= ID_UNPACKERS_FIRST && pCmdUI->m_nID <= ID_UNPACKERS_LAST));
 
        DoUpdateOpen(SELECTIONTYPE_NORMAL, pCmdUI, openableForDir);
 }
@@ -3736,6 +3790,20 @@ void CDirView::OnUpdateMergeCompare2(CCmdUI *pCmdUI)
        DoUpdateOpen(seltype, pCmdUI);
 }
 
+void CDirView::OnUpdateNoUnpacker(CCmdUI *pCmdUI)
+{
+       pCmdUI->Enable();
+       pCmdUI->m_pMenu->DeleteMenu(pCmdUI->m_nID, MF_BYCOMMAND);
+
+       int sel = GetSingleSelectedItem();
+       if (sel == -1 || GetItemKey(sel) == reinterpret_cast<DIFFITEM *>(SPECIAL_ITEM_POS))
+               return;
+
+       String filteredFilenames = GetDiffContext().GetFilteredFilenames(*GetItemKey(sel));
+       CMainFrame::AppendPluginMenus(pCmdUI->m_pMenu, filteredFilenames,
+               FileTransform::UnpackerEventNames, true, ID_UNPACKERS_FIRST);
+}
+
 void CDirView::OnViewCompareStatistics()
 {
        CompareStatisticsDlg dlg(GetDocument()->GetCompareStats());
index 3132cb8..e3ee7cf 100644 (file)
@@ -289,7 +289,7 @@ protected:
        afx_msg void OnUpdateStatusMiddleRO(CCmdUI* pCmdUI);
        afx_msg void OnUpdateStatusRightRO(CCmdUI* pCmdUI);
        afx_msg void OnCustomizeColumns();
-       afx_msg void OnCtxtOpenWithUnpacker();
+       afx_msg void OnOpenWithUnpacker();
        afx_msg void OnUpdateCtxtOpenWithUnpacker(CCmdUI* pCmdUI);
        afx_msg void OnToolsGenerateReport();
        afx_msg LRESULT OnGenerateFileCmpReport(WPARAM wParam, LPARAM lParam);
@@ -300,8 +300,8 @@ protected:
        afx_msg void OnCtxtDirShellContextMenu();
        afx_msg void OnSelectAll();
        afx_msg void OnUpdateSelectAll(CCmdUI* pCmdUI);
-       afx_msg void OnPluginPredifferMode(UINT nID);
-       afx_msg void OnUpdatePluginPredifferMode(CCmdUI* pCmdUI);
+       afx_msg void OnPluginSettings(UINT nID);
+       afx_msg void OnUpdatePluginMode(CCmdUI* pCmdUI);
        template<SIDE_TYPE side>
        afx_msg void OnCopyPathnames();
        afx_msg void OnCopyBothPathnames();
@@ -365,11 +365,11 @@ protected:
        template<SELECTIONTYPE seltype>
        afx_msg void OnMergeCompare2();
        afx_msg void OnMergeCompareNonHorizontally();
-       afx_msg void OnMergeCompareXML();
        afx_msg void OnMergeCompareAs(UINT nID);
        afx_msg void OnUpdateMergeCompare(CCmdUI *pCmdUI);
        template<SELECTIONTYPE seltype>
        afx_msg void OnUpdateMergeCompare2(CCmdUI *pCmdUI);
+       afx_msg void OnUpdateNoUnpacker(CCmdUI* pCmdUI);
        afx_msg void OnViewCompareStatistics();
        afx_msg void OnFileEncoding();
        afx_msg void OnHelp();
index a82d6b9..d10bc1c 100644 (file)
@@ -16,6 +16,7 @@
 #include "locality.h"
 #include "paths.h"
 #include "MergeApp.h"
+#include "FileTransform.h"
 #include "DebugNew.h"
 
 using Poco::Timestamp;
@@ -57,6 +58,8 @@ const char *COLHDR_MENCODING    = N_("Middle Encoding");
 const char *COLHDR_NIDIFFS      = N_("Ignored Diff");
 const char *COLHDR_NSDIFFS      = N_("Differences");
 const char *COLHDR_BINARY       = NC_("DirView|ColumnHeader", "Binary");
+const char *COLHDR_UNPACKER     = N_("Unpacker");
+const char *COLHDR_PREDIFFER    = N_("Prediffer");
 
 const char *COLDESC_FILENAME    = N_("Filename or folder name.");
 const char *COLDESC_DIR         = N_("Subfolder name when subfolders are included.");
@@ -91,6 +94,8 @@ const char *COLDESC_MENCODING   = N_("Middle side encoding.");
 const char *COLDESC_NIDIFFS     = N_("Number of ignored differences in file. These differences are ignored by WinMerge and cannot be merged.");
 const char *COLDESC_NSDIFFS     = N_("Number of differences in file. This number does not include ignored differences.");
 const char *COLDESC_BINARY      = N_("Shows an asterisk (*) if the file is binary.");
+const char *COLDESC_UNPACKER    = N_("Unpacker plugin name or pipeline.");
+const char *COLDESC_PREDIFFER   = N_("Prediffer plugin name or pipeline.");
 }
 
 /**
@@ -721,6 +726,30 @@ static String ColREOLTypeGet(const CDiffContext * pCtxt, const void *p)
        return GetEOLType(pCtxt, &di, pCtxt->GetCompareDirs() < 3 ? 1 : 2);
 }
 
+static String GetPluginPipeline(const CDiffContext* pCtxt, const DIFFITEM& di, bool unpacker)
+{
+       if (di.diffcode.isDirectory())
+               return _T("");
+       PackingInfo* pInfoUnpacker = nullptr;
+       PrediffingInfo * pInfoPrediffer = nullptr;
+       String filteredFilenames = pCtxt->GetFilteredFilenames(di);
+       const_cast<CDiffContext *>(pCtxt)->FetchPluginInfos(filteredFilenames, &pInfoUnpacker, &pInfoPrediffer);
+       if (unpacker)
+               return pInfoUnpacker ? pInfoUnpacker->GetPluginPipeline() : _T("");
+       else
+               return pInfoPrediffer ? pInfoPrediffer->GetPluginPipeline() : _T("");
+}
+
+static String ColUnpackerGet(const CDiffContext * pCtxt, const void *p)
+{
+       return GetPluginPipeline(pCtxt, *static_cast<const DIFFITEM *>(p), true);
+}
+
+static String ColPredifferGet(const CDiffContext * pCtxt, const void *p)
+{
+       return GetPluginPipeline(pCtxt, *static_cast<const DIFFITEM *>(p), false);
+}
+
 /**
  * @}
  */
@@ -985,6 +1014,8 @@ static DirColInfo f_cols[] =
        { _T("Snidiffs"), nullptr, COLHDR_NIDIFFS, COLDESC_NIDIFFS, ColDiffsGet, ColDiffsSort, FIELD_OFFSET(DIFFITEM, nidiffs), -1, false, DirColInfo::ALIGN_RIGHT },
        { _T("Leoltype"), nullptr, COLHDR_LEOL_TYPE, COLDESC_LEOL_TYPE, &ColLEOLTypeGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
        { _T("Reoltype"), nullptr, COLHDR_REOL_TYPE, COLDESC_REOL_TYPE, &ColREOLTypeGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
+       { _T("Unpacker"), nullptr, COLHDR_UNPACKER, COLDESC_UNPACKER, &ColUnpackerGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
+       { _T("Prediffer"), nullptr, COLHDR_PREDIFFER, COLDESC_PREDIFFER, &ColPredifferGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
 };
 static DirColInfo f_cols3[] =
 {
@@ -1021,6 +1052,8 @@ static DirColInfo f_cols3[] =
        { _T("Leoltype"), nullptr, COLHDR_LEOL_TYPE, COLDESC_LEOL_TYPE, &ColLEOLTypeGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
        { _T("Meoltype"), nullptr, COLHDR_MEOL_TYPE, COLDESC_MEOL_TYPE, &ColMEOLTypeGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
        { _T("Reoltype"), nullptr, COLHDR_REOL_TYPE, COLDESC_REOL_TYPE, &ColREOLTypeGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
+       { _T("Unpacker"), nullptr, COLHDR_UNPACKER, COLDESC_UNPACKER, &ColUnpackerGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
+       { _T("Prediffer"), nullptr, COLHDR_PREDIFFER, COLDESC_PREDIFFER, &ColPredifferGet, 0, 0, -1, true, DirColInfo::ALIGN_LEFT },
 };
 
 /**
index dee8022..750dae3 100644 (file)
@@ -3,6 +3,9 @@
 
 #include "stdafx.h"
 #include "EncodingErrorBar.h"
+#include "OptionsMgr.h"
+#include "OptionsDef.h"
+#include "MergeApp.h"
 
 #ifdef _DEBUG
 #define new DEBUG_NEW
@@ -31,6 +34,7 @@ void CEncodingErrorBar::DoDataExchange(CDataExchange* pDX)
 
 BEGIN_MESSAGE_MAP(CEncodingErrorBar, CTrDialogBar)
        //{{AFX_MSG_MAP(CEncodingErrorBar)
+       ON_UPDATE_COMMAND_UI(IDC_PLUGIN, OnUpdateBnClickedPlugin)
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -47,6 +51,11 @@ BOOL CEncodingErrorBar::Create(CWnd *pParentWnd)
                      // EXCEPTION: OCX Property Pages should return FALSE
 }
 
+void CEncodingErrorBar::OnUpdateBnClickedPlugin(CCmdUI* pCmdUI)
+{
+       pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
+}
+
 void CEncodingErrorBar::SetText(const String& sText)
 {
        SetDlgItemText((unsigned)IDC_STATIC, sText);
index 3917ea6..fcf5226 100644 (file)
@@ -36,6 +36,7 @@ protected:
 
        // Generated message map functions
        //{{AFX_MSG(CEncodingErrorBar)
+       afx_msg void OnUpdateBnClickedPlugin(CCmdUI* pCmdUI);
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 
index 3ab9562..ddd54c0 100644 (file)
 #include "FileTransform.h"
 #include <vector>
 #include <Poco/Exception.h>
+#include <Poco/Mutex.h>
 #include "Plugins.h"
 #include "multiformatText.h"
-#include "UniMarkdownFile.h"
 #include "Environment.h"
 #include "TFile.h"
+#include "paths.h"
+#include "MergeApp.h"
 
 using Poco::Exception;
 
-namespace FileTransform
-{
-
-PLUGIN_MODE g_UnpackerMode = PLUGIN_MODE::PLUGIN_MANUAL;
-PLUGIN_MODE g_PredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
+static Poco::FastMutex g_mutex;
 
+////////////////////////////////////////////////////////////////////////////////
+// transformations : packing unpacking
 
 
+std::vector<PluginForFile::PipelineItem> PluginForFile::ParsePluginPipeline(String& errorMessage) const
+{
+       return ParsePluginPipeline(m_PluginPipeline, errorMessage);
+}
 
+std::vector<PluginForFile::PipelineItem> PluginForFile::ParsePluginPipeline(const String& pluginPipeline, String& errorMessage)
+{
+       std::vector<PluginForFile::PipelineItem> result;
+       bool inQuotes = false;
+       TCHAR quoteChar = 0;
+       std::vector<String> args;
+       String token, name;
+       errorMessage.clear();
+       const TCHAR* p = pluginPipeline.c_str();
+       while (_istspace(*p)) p++;
+       while (*p)
+       {
+               TCHAR sep = 0;
+               while (*p)
+               {
+                       if (!inQuotes)
+                       {
+                               if (*p == '"' || *p == '\'')
+                               {
+                                       inQuotes = true;
+                                       quoteChar = *p;
+                               }
+                               else if (_istspace(*p))
+                               {
+                                       sep = *p;
+                                       break;
+                               }
+                               else if (*p == '|')
+                               {
+                                       sep = *p;
+                                       break;
+                               }
+                               else
+                                       token += *p;
+                       }
+                       else
+                       {
+                               if (*p == quoteChar)
+                               {
+                                       if (*(p + 1) == quoteChar)
+                                       {
+                                               token += *p;
+                                               ++p;
+                                       }
+                                       else
+                                       {
+                                               inQuotes = false;
+                                       }
+                               }
+                               else
+                               {
+                                       token += *p;
+                               }
+                       }
+                       ++p;
+               }
+               if (name.empty())
+               {
+                       name = token;
+               }
+               else
+               {
+                       args.push_back(token);
+               }
+               while (_istspace(*p)) p++;
+               if (*p == '|')
+                       sep = *p;
+               if (sep == '|')
+                       p++;
+               token.clear();
+               if (sep == '|' || !*p)
+               {
+                       if (name.empty() || (sep == '|' && !*p))
+                       {
+                               errorMessage = strutils::format_string1(_("Missing plugin name in plugin pipeline: %1"), pluginPipeline);
+                               break;
+                       }
+                       result.push_back({ name, args, quoteChar });
+                       name.clear();
+                       args.clear();
+                       quoteChar = 0;
+               }
+       };
+       if (inQuotes)
+               errorMessage = strutils::format_string1(_("Missing quotation mark in plugin pipeline: %1"), pluginPipeline);
+       return result;
+}
 
-////////////////////////////////////////////////////////////////////////////////
-// transformations : packing unpacking
+String PluginForFile::MakePluginPipeline(const std::vector<PluginForFile::PipelineItem>& list)
+{
+       int i = 0;
+       String pipeline;
+       for (const auto& [name, args, quoteChar] : list)
+       {
+               if (quoteChar && name.find_first_of(_T(" '\"")) != String::npos)
+               {
+                       String nameQuoted = name;
+                       strutils::replace(nameQuoted, String(1, quoteChar), String(2, quoteChar));
+                       pipeline += strutils::format(_T("%c%s%c"), quoteChar, nameQuoted, quoteChar);
+               }
+               else
+               {
+                       pipeline += name;
+               }
+               if (!args.empty())
+               {
+                       for (const auto& arg : args)
+                       {
+                               if (quoteChar)
+                               {
+                                       String argQuoted = arg;
+                                       strutils::replace(argQuoted, String(1, quoteChar), String(2, quoteChar));
+                                       pipeline += strutils::format(_T(" %c%s%c"), quoteChar, argQuoted, quoteChar);
+                               }
+                               else
+                               {
+                                       pipeline += _T(" ") + arg;
+                               }
+                       }
+               }
+               if (i < list.size() - 1)
+                       pipeline += _T("|");
+               i++;
+       }
+       return pipeline;
+}
 
-bool getPackUnpackPlugin(const String& pluginName, PluginInfo*& plugin, bool& bWithFile)
+String PluginForFile::MakeArguments(const std::vector<String>& args, const std::vector<StringView>& variables)
 {
-       bWithFile = true;
-       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_PACK_UNPACK", pluginName);
-       if (plugin == nullptr)
+       String newstr;
+       int i = 0;
+       for (const auto& arg : args)
        {
-               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_FOLDER_PACK_UNPACK", pluginName);
-               if (plugin == nullptr)
+               String newarg;
+               for (const TCHAR* p = arg.c_str(); *p; ++p)
                {
-                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"BUFFER_PACK_UNPACK", pluginName);
-                       if (plugin == nullptr)
+                       if (*p == '%' && *(p + 1) != 0)
                        {
-                               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, pluginName);
-                               if (plugin == nullptr)
+                               ++p;
+                               TCHAR c = *p;
+                               if (c == '%')
                                {
-                                       AppErrorMessageBox(strutils::format_string1(_("Plugin not found or invalid: %1"), pluginName));
+                                       newarg += '%';
+                               }
+                               else if (c >= '1' && c <= '9')
+                               {
+                                       if ((c - '1') < variables.size())
+                                               newarg += String{ variables[(c - '1')].data(), variables[(c - '1')].length() };
                                }
                                else
                                {
-                                       plugin = nullptr;
-                                       AppErrorMessageBox(strutils::format(_T("'%s' is not PACK_UNPACK plugin"), pluginName));
+                                       newarg += *(p - 1);
+                                       newarg += c;
                                }
-                               return false;
                        }
-                       bWithFile = false;
+                       else
+                       {
+                               newarg += *p;
+                       }
+               }
+               if (newarg.find_first_of(_T(" \"")) != String::npos)
+               {
+                       strutils::replace(newarg, _T("\""), _T("\"\""));
+                       newstr += _T("\"") + newarg + _T("\"");
+               }
+               else
+               {
+                       newstr += newarg;
+               }
+               if (i < args.size() - 1)
+                       newstr += ' ';
+               i++;
+       }
+       return newstr;
+}
+
+bool PackingInfo::GetPackUnpackPlugin(const String& filteredFilenames, bool bReverse,
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>>& plugins,
+       String *pPluginPipelineResolved, String& errorMessage) const
+{
+       auto result = ParsePluginPipeline(errorMessage);
+       if (!errorMessage.empty())
+               return false;
+       std::vector<PluginForFile::PipelineItem> pipelineResolved;
+       for (auto& [pluginName, args, quoteChar] : result)
+       {
+               PluginInfo* plugin = nullptr;
+               bool bWithFile = true;
+               if (pluginName == _T("<None>") || pluginName == _("<None>"))
+                       ;
+               else if (pluginName == _T("<Automatic>") || pluginName == _("<Automatic>"))
+               {
+                       plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_PACK_UNPACK", filteredFilenames);
+                       if (plugin == nullptr)
+                               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_FOLDER_PACK_UNPACK", filteredFilenames);
+                       if (plugin == nullptr)
+                       {
+                               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"BUFFER_PACK_UNPACK", filteredFilenames);
+                               bWithFile = false;
+                       }
+               }
+               else
+               {
+                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_PACK_UNPACK", pluginName);
+                       if (plugin == nullptr)
+                       {
+                               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_FOLDER_PACK_UNPACK", pluginName);
+                               if (plugin == nullptr)
+                               {
+                                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"BUFFER_PACK_UNPACK", pluginName);
+                                       if (plugin == nullptr)
+                                       {
+                                               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, pluginName);
+                                               if (plugin == nullptr)
+                                               {
+                                                       errorMessage = strutils::format_string1(_("Plugin not found or invalid: %1"), pluginName);
+                                               }
+                                               else
+                                               {
+                                                       plugin = nullptr;
+                                                       errorMessage = strutils::format(_T("'%s' is not PACK_UNPACK plugin"), pluginName);
+                                               }
+                                               return false;
+                                       }
+                                       bWithFile = false;
+                               }
+                       }
+               }
+               if (plugin)
+               {
+                       pipelineResolved.push_back({plugin->m_name, args, quoteChar });
+                       if (bReverse)
+                               plugins.insert(plugins.begin(), { plugin, args, bWithFile });
+                       else
+                               plugins.push_back({ plugin, args, bWithFile });
                }
        }
+       if (pPluginPipelineResolved)
+               *pPluginPipelineResolved = MakePluginPipeline(pipelineResolved);
        return true;
 }
 
 // known handler
-bool Packing(String & filepath, const PackingInfo& handler, int handlerSubcode)
+bool PackingInfo::Packing(String & filepath, const std::vector<int>& handlerSubcodes, const std::vector<StringView>& variables) const
 {
        // no handler : return true
-       if (handler.m_PluginName.empty())
+       if (m_PluginPipeline.empty())
                return true;
 
-       storageForPlugins bufferData;
-       bufferData.SetDataFileAnsi(filepath);
-
        // control value
-       bool bHandled = false;
-       bool bWithFile = true;
-       PluginInfo* plugin = nullptr;
-       if (!getPackUnpackPlugin(handler.m_PluginName, plugin, bWithFile))
-               return false;
-
-       LPDISPATCH piScript = plugin->m_lpDispatch;
-       if (bWithFile)
+       String errorMessage;
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>> plugins;
+       if (!GetPackUnpackPlugin(_T(""), true, plugins, nullptr, errorMessage))
        {
-               // use a temporary dest name
-               String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
-               String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
-               bHandled = plugin::InvokePackFile(srcFileName,
-                       dstFileName,
-                       bufferData.GetNChanged(),
-                       piScript, handlerSubcode);
-               if (bHandled)
-                       bufferData.ValidateNewFile();
+               AppErrorMessageBox(errorMessage);
+               return false;
        }
-       else
+
+       auto itSubcode = handlerSubcodes.rbegin();
+       for (auto& [plugin, args, bWithFile] : plugins)
        {
-               bHandled = plugin::InvokePackBuffer(*bufferData.GetDataBufferAnsi(),
-                       bufferData.GetNChanged(),
-                       piScript, handlerSubcode);
-               if (bHandled)
-                       bufferData.ValidateNewBuffer();
-       }
+               bool bHandled = false;
+               storageForPlugins bufferData;
+               bufferData.SetDataFileAnsi(filepath);
 
-       // if this packer does not work, that is an error
-       if (!bHandled)
-               return false;
+               LPDISPATCH piScript = plugin->m_lpDispatch;
+               Poco::FastMutex::ScopedLock lock(g_mutex);
 
-       // if the buffer changed, write it before leaving
-       bool bSuccess = true;
-       if (bufferData.GetNChangedValid() > 0)
-       {
-               bSuccess = bufferData.SaveAsFile(filepath);
-       }
+               if (plugin->m_hasVariablesProperty)
+               {
+                       if (!plugin::InvokePutPluginVariables(String(variables[0].data(), variables[0].length()), piScript))
+                               return false;
+               }
+               if (plugin->m_hasArgumentsProperty)
+               {
+                       if (!plugin::InvokePutPluginArguments(args.empty() ? plugin->m_arguments : MakeArguments(args, variables), piScript))
+                               return false;
+               }
 
-       return bSuccess;
+               if (bWithFile)
+               {
+                       // use a temporary dest name
+                       String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
+                       String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
+                       bHandled = plugin::InvokePackFile(srcFileName,
+                               dstFileName,
+                               bufferData.GetNChanged(),
+                               piScript, *itSubcode);
+                       if (bHandled)
+                               bufferData.ValidateNewFile();
+               }
+               else
+               {
+                       bHandled = plugin::InvokePackBuffer(*bufferData.GetDataBufferAnsi(),
+                               bufferData.GetNChanged(),
+                               piScript, *itSubcode);
+                       if (bHandled)
+                               bufferData.ValidateNewBuffer();
+               }
+
+               // if this packer does not work, that is an error
+               if (!bHandled)
+                       return false;
+
+               // if the buffer changed, write it before leaving
+               if (bufferData.GetNChangedValid() > 0)
+               {
+                       bool bSuccess = bufferData.SaveAsFile(filepath);
+                       if (!bSuccess)
+                               return false;
+               }
+               ++itSubcode;
+       }
+       return true;
 }
 
-bool Packing(const String& srcFilepath, const String& dstFilepath, const PackingInfo& handler, int handlerSubcode)
+bool PackingInfo::Packing(const String& srcFilepath, const String& dstFilepath, const std::vector<int>& handlerSubcodes, const std::vector<StringView>& variables) const
 {
        String csTempFileName = srcFilepath;
-       if (!Packing(csTempFileName, handler, handlerSubcode))
+       if (!Packing(csTempFileName, handlerSubcodes, variables))
                return false;
        try
        {
@@ -138,317 +371,253 @@ bool Packing(const String& srcFilepath, const String& dstFilepath, const Packing
        }
 }
 
-// known handler
-bool Unpacking(String & filepath, const PackingInfo * handler, int * handlerSubcode)
+bool PackingInfo::Unpacking(std::vector<int> * handlerSubcodes, String & filepath, const String& filteredText, const std::vector<StringView>& variables)
 {
        // no handler : return true
-       if (handler == nullptr || handler->m_PluginName.empty())
+       if (m_PluginPipeline.empty())
                return true;
 
-       storageForPlugins bufferData;
-       bufferData.SetDataFileAnsi(filepath);
-
-       // temporary subcode 
-       int subcode;
-
        // control value
-       bool bHandled = false;
-       bool bWithFile = true;
-       PluginInfo* plugin = nullptr;
-       if (!getPackUnpackPlugin(handler->m_PluginName, plugin, bWithFile))
-               return false;
-
-       LPDISPATCH piScript = plugin->m_lpDispatch;
-       if (bWithFile)
+       String errorMessage;
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>> plugins;
+       if (!GetPackUnpackPlugin(filteredText, false, plugins, &m_PluginPipeline, errorMessage))
        {
-               // use a temporary dest name
-               bufferData.SetDestFileExtension(plugin->m_ext);
-               String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
-               String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
-               bHandled = plugin::InvokeUnpackFile(srcFileName,
-                       dstFileName,
-                       bufferData.GetNChanged(),
-                       piScript, subcode);
-               if (bHandled)
-                       bufferData.ValidateNewFile();
-       }
-       else
-       {
-               bHandled = plugin::InvokeUnpackBuffer(*bufferData.GetDataBufferAnsi(),
-                       bufferData.GetNChanged(),
-                       piScript, subcode);
-               if (bHandled)
-                       bufferData.ValidateNewBuffer();
-       }
-
-       // if this unpacker does not work, that is an error
-       if (!bHandled)
+               AppErrorMessageBox(errorMessage);
                return false;
+       }
 
-       // valid the subcode
-       if (handlerSubcode)
-               *handlerSubcode = subcode;
-
-       // if the buffer changed, write it before leaving
-       bool bSuccess = true;
-       if (bufferData.GetNChangedValid() > 0)
+       for (auto& [plugin, args, bWithFile] : plugins)
        {
-               bSuccess = bufferData.SaveAsFile(filepath);
-       }
+               if (plugin->m_argumentsRequired && args.empty())
+               {
 
-       return bSuccess;
-}
+               }
+       }
 
+       if (handlerSubcodes)
+               handlerSubcodes->clear();
 
-// scan plugins for the first handler
-bool Unpacking(String & filepath, const String& filteredText, PackingInfo * handler, int * handlerSubcode)
-{
-       // PLUGIN_MODE::PLUGIN_BUILTIN_XML : read source file through custom UniFile
-       if (handler->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_BUILTIN_XML)
+       for (auto& [plugin, args, bWithFile] : plugins)
        {
-               handler->m_pufile = new UniMarkdownFile;
-               handler->m_textType = _T("xml");
-               handler->m_bDisallowMixedEOL = true;
-               handler->m_PluginName.erase(); // Make FileTransform_Packing() a NOP
-               // Leave eToBeScanned alone so above lines will continue to execute on
-               // subsequent calls to this function
-               return true;
-       }
+               bool bHandled = false;
+               storageForPlugins bufferData;
+               bufferData.SetDataFileAnsi(filepath);
 
-       storageForPlugins bufferData;
-       bufferData.SetDataFileAnsi(filepath);
+               // temporary subcode 
+               int subcode = 0;
 
-       // temporary subcode 
-       int subcode = 0;
-       // control value
-       bool bHandled = false;
-
-       PluginInfo * plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_PACK_UNPACK", filteredText);
-       if (plugin == nullptr)
-               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_FOLDER_PACK_UNPACK", filteredText);
-       if (plugin != nullptr)
-       {
-               handler->m_PluginName = plugin->m_name;
-               // use a temporary dest name
-               bufferData.SetDestFileExtension(plugin->m_ext);
-               String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
-               String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
-               bHandled = plugin::InvokeUnpackFile(srcFileName,
-                       dstFileName,
-                       bufferData.GetNChanged(),
-                       plugin->m_lpDispatch, subcode);
-               if (bHandled)
-                       bufferData.ValidateNewFile();
-       }
+               LPDISPATCH piScript = plugin->m_lpDispatch;
+               Poco::FastMutex::ScopedLock lock(g_mutex);
 
-       // We can not assume that the file is text, so use a safearray and not a BSTR
-       // TODO : delete this event ?   Is anyone going to use this ?
+               if (plugin->m_hasVariablesProperty)
+               {
+                       if (!plugin::InvokePutPluginVariables(String(variables[0].data(), variables[0].length()), piScript))
+                               return false;
+               }
+               if (plugin->m_hasArgumentsProperty)
+               {
+                       if (!plugin::InvokePutPluginArguments(args.empty() ? plugin->m_arguments : MakeArguments(args, variables), piScript))
+                               return false;
+               }
 
-       if (!bHandled)
-       {
-               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"BUFFER_PACK_UNPACK", filteredText);
-               if (plugin != nullptr)
+               if (bWithFile)
+               {
+                       // use a temporary dest name
+                       bufferData.SetDestFileExtension(!plugin->m_ext.empty() ? plugin->m_ext : paths::FindExtension(filepath));
+                       String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
+                       String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
+                       bHandled = plugin::InvokeUnpackFile(srcFileName,
+                               dstFileName,
+                               bufferData.GetNChanged(),
+                               piScript, subcode);
+                       if (bHandled)
+                               bufferData.ValidateNewFile();
+               }
+               else
                {
-                       handler->m_PluginName = plugin->m_name;
                        bHandled = plugin::InvokeUnpackBuffer(*bufferData.GetDataBufferAnsi(),
                                bufferData.GetNChanged(),
-                               plugin->m_lpDispatch, subcode);
+                               piScript, subcode);
                        if (bHandled)
                                bufferData.ValidateNewBuffer();
                }
-       }
-
-       if (!bHandled)
-       {
-               // we didn't find any unpacker, just hope it is normal Ansi/Unicode
-               handler->m_PluginName = _T("");
-               subcode = 0;
-               bHandled = true;
-       }
 
-       // the handler is now defined
-       handler->m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
+               // if this unpacker does not work, that is an error
+               if (!bHandled)
+                       return false;
 
-       // assign the sucode
-       if (handlerSubcode)
-               *handlerSubcode = subcode;
+               // valid the subcode
+               if (handlerSubcodes)
+                       handlerSubcodes->push_back(subcode);
 
-       // if the buffer changed, write it before leaving
-       bool bSuccess = true;
-       if (bufferData.GetNChangedValid() > 0)
-       {
-               bSuccess = bufferData.SaveAsFile(filepath);
+               // if the buffer changed, write it before leaving
+               if (bufferData.GetNChangedValid() > 0)
+               {
+                       bool bSuccess = bufferData.SaveAsFile(filepath);
+                       if (!bSuccess)
+                               return false;
+               }
        }
-
-       return bSuccess;
+       return true;
 }
 
-bool Unpacking(PackingInfo *handler, int * handlerSubcode, String& filepath, const String& filteredText)
+String PackingInfo::GetUnpackedFileExtension(const String& filteredFilenames) const
 {
-       if (handler->m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
-               return Unpacking(filepath, filteredText, handler, handlerSubcode);
-       else
-               return Unpacking(filepath, handler, handlerSubcode);
+       String ext;
+       String errorMessage;
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>> plugins;
+       if (GetPackUnpackPlugin(filteredFilenames, false, plugins, nullptr, errorMessage))
+       {
+               for (auto& [plugin, args, bWithFile] : plugins)
+                       ext += plugin->m_ext;
+       }
+       return ext;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // transformation prediffing
 
-bool getPrediffPlugin(const String& pluginName, PluginInfo*& plugin, bool& bWithFile)
+bool PrediffingInfo::GetPrediffPlugin(const String& filteredFilenames, bool bReverse,
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>>& plugins,
+       String *pPluginPipelineResolved, String& errorMessage) const
 {
-       bWithFile = true;
-       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_PREDIFF", pluginName);
-       if (plugin == nullptr)
+       auto result = ParsePluginPipeline(errorMessage);
+       if (!errorMessage.empty())
+               return false;
+       std::vector<PluginForFile::PipelineItem> pipelineResolved;
+       for (auto& [pluginName, args, quoteChar] : result)
        {
-               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"BUFFER_PREDIFF", pluginName);
-               if (plugin == nullptr)
+               PluginInfo* plugin = nullptr;
+               bool bWithFile = true;
+               if (pluginName == _T("<None>") || pluginName == _("<None>"))
+                       ;
+               else if (pluginName == _T("<Automatic>") || pluginName == _("<Automatic>"))
                {
-                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, pluginName);
+                       plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_PREDIFF", filteredFilenames);
                        if (plugin == nullptr)
                        {
-                               AppErrorMessageBox(strutils::format_string1(_("Plugin not found or invalid: %1"), pluginName));
+                               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"BUFFER_PREDIFF", filteredFilenames);
+                               if (plugin)
+                                       bWithFile = false;
                        }
-                       else
+               }
+               else
+               {
+                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_PREDIFF", pluginName);
+                       if (plugin == nullptr)
                        {
-                               plugin = nullptr;
-                               AppErrorMessageBox(strutils::format(_T("'%s' is not PREDIFF plugin"), pluginName));
+                               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"BUFFER_PREDIFF", pluginName);
+                               if (plugin == nullptr)
+                               {
+                                       plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, pluginName);
+                                       if (plugin == nullptr)
+                                       {
+                                               errorMessage = strutils::format_string1(_("Plugin not found or invalid: %1"), pluginName);
+                                       }
+                                       else
+                                       {
+                                               errorMessage = strutils::format(_T("'%s' is not PREDIFF plugin"), pluginName);
+                                       }
+                                       return false;
+                               }
+                               bWithFile = false;
                        }
-                       return false;
                }
-               bWithFile = false;
+               if (plugin)
+               {
+                       pipelineResolved.push_back({ plugin->m_name, args, quoteChar });
+                       if (bReverse)
+                               plugins.insert(plugins.begin(), { plugin, args, bWithFile });
+                       else
+                               plugins.push_back({ plugin, args, bWithFile });
+               }
        }
+       if (pPluginPipelineResolved)
+               *pPluginPipelineResolved = MakePluginPipeline(pipelineResolved);
        return true;
 }
 
-// known handler
-bool Prediffing(String & filepath, PrediffingInfo handler, bool bMayOverwrite)
+bool PrediffingInfo::Prediffing(String & filepath, const String& filteredText, bool bMayOverwrite, const std::vector<StringView>& variables)
 {
        // no handler : return true
-       if (handler.m_PluginName.empty())
+       if (m_PluginPipeline.empty())
                return true;
 
-       storageForPlugins bufferData;
-       // detect Ansi or Unicode file
-       bufferData.SetDataFileUnknown(filepath, bMayOverwrite);
-       // TODO : set the codepage
-       // bufferData.SetCodepage();
-
        // control value
        bool bHandled = false;
-       bool bWithFile = true;
-       PluginInfo* plugin = nullptr;
-       if (!getPrediffPlugin(handler.m_PluginName, plugin, bWithFile))
-               return false;
-
-       LPDISPATCH piScript = plugin->m_lpDispatch;
-       if (bWithFile)
-       {
-               // use a temporary dest name
-               String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
-               String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
-               bHandled = plugin::InvokePrediffFile(srcFileName,
-                       dstFileName,
-                       bufferData.GetNChanged(),
-                       piScript);
-               if (bHandled)
-                       bufferData.ValidateNewFile();
-       }
-       else
+       String errorMessage;
+       std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>> plugins;
+       if (!GetPrediffPlugin(filteredText, false, plugins, &m_PluginPipeline, errorMessage))
        {
-               // probably it is for VB/VBscript so use a BSTR as argument
-               bHandled = plugin::InvokePrediffBuffer(*bufferData.GetDataBufferUnicode(),
-                       bufferData.GetNChanged(),
-                       piScript);
-               if (bHandled)
-                       bufferData.ValidateNewBuffer();
-       }
-
-       // if this unpacker does not work, that is an error
-       if (!bHandled)
+               AppErrorMessageBox(errorMessage);
                return false;
-
-       // if the buffer changed, write it before leaving
-       bool bSuccess = true;
-       if (bufferData.GetNChangedValid() > 0)
-       {
-               // bufferData changes filepath here to temp filepath
-               bSuccess = bufferData.SaveAsFile(filepath);
        }
 
-       return bSuccess;
-}
-
-
-// scan plugins for the first handler
-bool Prediffing(String & filepath, const String& filteredText, PrediffingInfo * handler, bool bMayOverwrite)
-{
-       storageForPlugins bufferData;
-       // detect Ansi or Unicode file
-       bufferData.SetDataFileUnknown(filepath, bMayOverwrite);
-       // TODO : set the codepage
-       // bufferData.SetCodepage();
+       for (const auto& [plugin, args, bWithFile] : plugins)
+       {
+               storageForPlugins bufferData;
+               // detect Ansi or Unicode file
+               bufferData.SetDataFileUnknown(filepath, bMayOverwrite);
+               // TODO : set the codepage
+               // bufferData.SetCodepage();
 
-       // control value
-       bool bHandled = false;
+               LPDISPATCH piScript = plugin->m_lpDispatch;
+               Poco::FastMutex::ScopedLock lock(g_mutex);
 
-       PluginInfo * plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_PREDIFF", filteredText);
-       if (plugin != nullptr)
-       {
-               handler->m_PluginName = plugin->m_name;
-               // use a temporary dest name
-               String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
-               String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
-               bHandled = plugin::InvokePrediffFile(srcFileName,
-                       dstFileName,
-                       bufferData.GetNChanged(),
-                       plugin->m_lpDispatch);
-               if (bHandled)
-                       bufferData.ValidateNewFile();
-       }
+               if (plugin->m_hasVariablesProperty)
+               {
+                       if (!plugin::InvokePutPluginVariables(String(variables[0].data(), variables[0].length()), piScript))
+                               return false;
+               }
+               if (plugin->m_hasArgumentsProperty)
+               {
+                       if (!plugin::InvokePutPluginArguments(args.empty() ? plugin->m_arguments : MakeArguments(args, variables), piScript))
+                               return false;
+               }
 
-       if (!bHandled)
-       {
-               plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"BUFFER_PREDIFF", filteredText);
-               if (plugin != nullptr)
+               if (bWithFile)
+               {
+                       // use a temporary dest name
+                       String srcFileName = bufferData.GetDataFileAnsi(); // <-Call order is important
+                       String dstFileName = bufferData.GetDestFileName(); // <-Call order is important
+                       bHandled = plugin::InvokePrediffFile(srcFileName,
+                               dstFileName,
+                               bufferData.GetNChanged(),
+                               piScript);
+                       if (bHandled)
+                               bufferData.ValidateNewFile();
+               }
+               else
                {
-                       handler->m_PluginName = plugin->m_name;
                        // probably it is for VB/VBscript so use a BSTR as argument
                        bHandled = plugin::InvokePrediffBuffer(*bufferData.GetDataBufferUnicode(),
                                bufferData.GetNChanged(),
-                               plugin->m_lpDispatch);
+                               piScript);
                        if (bHandled)
                                bufferData.ValidateNewBuffer();
                }
-       }
 
-       if (!bHandled)
-       {
-               // we didn't find any prediffer, that is OK anyway
-               handler->m_PluginName = _T("");
-               bHandled = true;
-       }
-
-       // the handler is now defined
-       handler->m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
+               // if this unpacker does not work, that is an error
+               if (!bHandled)
+                       return false;
 
-       // if the buffer changed, write it before leaving
-       bool bSuccess = true;
-       if (bufferData.GetNChangedValid() > 0)
-       {
-               bSuccess = bufferData.SaveAsFile(filepath);
+               // if the buffer changed, write it before leaving
+               if (bufferData.GetNChangedValid() > 0)
+               {
+                       // bufferData changes filepath here to temp filepath
+                       bool bSuccess = bufferData.SaveAsFile(filepath);
+                       if (!bSuccess)
+                               return false;
+               }
        }
-
-       return bSuccess;
+       return true;
 }
 
-bool Prediffing(PrediffingInfo * handler, String & filepath, const String& filteredText, bool bMayOverwrite)
+namespace FileTransform
 {
-       if (handler->m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
-               return Prediffing(filepath, filteredText, handler, bMayOverwrite);
-       else
-               return Prediffing(filepath, *handler, bMayOverwrite);
-}
 
+bool AutoUnpacking = false;
+bool AutoPrediffing = false;
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -530,7 +699,7 @@ std::vector<String> GetFreeFunctionsInScripts(const wchar_t *TransformationEvent
        return sNamesArray;
 }
 
-bool Interactive(String & text, const wchar_t *TransformationEvent, int iFncChosen)
+bool Interactive(String & text, const std::vector<String>& args, const wchar_t *TransformationEvent, int iFncChosen, const std::vector<StringView>& variables)
 {
        if (iFncChosen < 0)
                return false;
@@ -551,25 +720,115 @@ bool Interactive(String & text, const wchar_t *TransformationEvent, int iFncChos
        if (iScript >= piScriptArray->size())
                return false;
 
+       PluginInfo* plugin = piScriptArray->at(iScript).get();
+
        // iFncChosen is the index of the function in the script file
        // we must convert it to the function ID
-       int fncID = plugin::GetMethodIDInScript(piScriptArray->at(iScript)->m_lpDispatch, iFncChosen);
+       int fncID = plugin::GetMethodIDInScript(plugin->m_lpDispatch, iFncChosen);
+
+       if (plugin->m_hasVariablesProperty)
+       {
+               if (!plugin::InvokePutPluginVariables(String(variables[0].data(), variables[0].length()), plugin->m_lpDispatch))
+                       return false;
+       }
+       if (plugin->m_hasArgumentsProperty)
+       {
+               if (!plugin::InvokePutPluginArguments(args.empty() ? plugin->m_arguments : PluginForFile::MakeArguments(args, variables), plugin->m_lpDispatch))
+                       return false;
+       }
 
        // execute the transform operation
        int nChanged = 0;
-       plugin::InvokeTransformText(text, nChanged, piScriptArray->at(iScript)->m_lpDispatch, fncID);
+       plugin::InvokeTransformText(text, nChanged, plugin->m_lpDispatch, fncID);
 
        return (nChanged != 0);
 }
 
-String GetUnpackedFileExtension(const String& filteredFilenames, const PackingInfo* handler)
+std::pair<
+       std::vector<std::tuple<String, String, unsigned, PluginInfo *>>,
+       std::map<String, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>>
+>
+CreatePluginMenuInfos(const String& filteredFilenames, const std::vector<std::wstring>& events, unsigned baseId)
 {
-       PluginInfo* plugin = nullptr;
-       if (handler->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_MANUAL && !handler->m_PluginName.empty())
-               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, handler->m_PluginName.c_str());
-       else
-               plugin = CAllThreadsScripts::GetActiveSet()->GetUnpackerPluginByFilter(filteredFilenames);
-       return plugin ? plugin->m_ext : _T("");
+       std::vector<std::tuple<String, String, unsigned, PluginInfo *>> suggestedPlugins;
+       std::map<String, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>> allPlugins;
+       std::map<String, int> captions;
+       unsigned id = baseId;
+       bool addedNoneAutomatic = false;
+       for (const auto& event: events)
+       {
+               auto pScriptArray =
+                       CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(event.c_str());
+               for (auto& plugin : *pScriptArray)
+               {
+                       if (!plugin->m_disabled)
+                       {
+                               if (event != L"EDITOR_SCRIPT")
+                               {
+                                       if (!addedNoneAutomatic)
+                                       {
+                                               String process = _T("");
+                                               allPlugins.insert_or_assign(process, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>());
+                                               allPlugins[process].emplace_back(_("<None>"), _T(""), id++, plugin.get());
+                                               allPlugins[process].emplace_back(_("<Automatic>"), _T("<Automatic>"), id++, plugin.get());
+                                               addedNoneAutomatic = true;
+                                       }
+                                       const auto menuCaption = plugin->GetExtendedPropertyValue(_T("MenuCaption"));
+                                       const auto processType = plugin->GetExtendedPropertyValue(_T("ProcessType"));
+                                       const String caption = tr(ucr::toUTF8(menuCaption.has_value() ?
+                                               String{ menuCaption->data(), menuCaption->size() } : plugin->m_name));
+                                       const String process = tr(ucr::toUTF8(processType.has_value() ?
+                                               String{ processType->data(), processType->size() } : _T("&Others")));
+
+                                       if (plugin->TestAgainstRegList(filteredFilenames))
+                                               suggestedPlugins.emplace_back(caption, plugin->m_name, id, plugin.get());
+
+                                       if (allPlugins.find(process) == allPlugins.end())
+                                               allPlugins.insert_or_assign(process, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>());
+                                       allPlugins[process].emplace_back(caption, plugin->m_name, id, plugin.get());
+                                       captions[caption]++;
+                                       id++;
+                               }
+                               else
+                               {
+                                       LPDISPATCH piScript = plugin->m_lpDispatch;
+                                       std::vector<String> scriptNamesArray;
+                                       std::vector<int> scriptIdsArray;
+                                       int nScriptFnc = plugin::GetMethodsFromScript(piScript, scriptNamesArray, scriptIdsArray);
+                                       bool matched = plugin->TestAgainstRegList(filteredFilenames);
+                                       for (int i = 0; i < nScriptFnc; ++i, ++id)
+                                       {
+                                               const auto menuCaption = plugin->GetExtendedPropertyValue(scriptNamesArray[i] + _T(".MenuCaption"));
+                                               auto processType = plugin->GetExtendedPropertyValue(scriptNamesArray[i] + _T(".ProcessType"));
+                                               if (!processType.has_value())
+                                                       processType = plugin->GetExtendedPropertyValue(_T("ProcessType"));
+                                               const String caption = tr(ucr::toUTF8(menuCaption.has_value() ?
+                                                       String{ menuCaption->data(), menuCaption->size() } : scriptNamesArray[i]));
+                                               const String process = tr(ucr::toUTF8(processType.has_value() ?
+                                                       String{ processType->data(), processType->size() } : _T("&Others")));
+                                               if (matched)
+                                                       suggestedPlugins.emplace_back(caption, plugin->m_name, id, plugin.get());
+                                               if (allPlugins.find(process) == allPlugins.end())
+                                                       allPlugins.insert_or_assign(process, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>());
+                                               allPlugins[process].emplace_back(caption, plugin->m_name, id, plugin.get());
+                                       }
+                               }
+                       }
+               }
+       }
+       auto ResolveConflictMenuCaptions = [&captions](auto& plugins)
+       {
+               for (auto& plugin : plugins)
+               {
+                       const String& caption = std::get<0>(plugin);
+                       if (captions[caption] > 1)
+                               std::get<0>(plugin) = caption + _T("(") + std::get<1>(plugin) + _T(")");
+               }
+       };
+       ResolveConflictMenuCaptions(suggestedPlugins);
+       for (auto& [processType, plugins] : allPlugins)
+               ResolveConflictMenuCaptions(plugins);
+       return { suggestedPlugins, allPlugins };
 }
 
 }
index b42c2a9..1e13256 100644 (file)
 
 #include <vector>
 #include "UnicodeString.h"
-#include "MergeApp.h"
 
-/**
- * @brief Modes for plugin (Modes for prediffing included)
- */
-enum class PLUGIN_MODE
-{
-       // Modes for "unpacking"
-       PLUGIN_MANUAL,
-       PLUGIN_AUTO,
-       PLUGIN_BUILTIN_XML,
-
-       // Modes for "prediffing"
-       PREDIFF_MANUAL = PLUGIN_MANUAL,
-       PREDIFF_AUTO = PLUGIN_AUTO,
-};
+class PluginInfo;
 
 namespace FileTransform
 {
-extern PLUGIN_MODE g_UnpackerMode;
-extern PLUGIN_MODE g_PredifferMode;
+extern bool AutoUnpacking;
+extern bool AutoPrediffing;
 }
 
-class UniFile;
-
 /**
  * @brief Plugin information for a given file
  *
@@ -46,29 +30,41 @@ class UniFile;
 class PluginForFile
 {
 public:
-       void Initialize(PLUGIN_MODE Mode)
+       struct PipelineItem
        {
-               // and init Plugin/Prediffer mode and Plugin name accordingly
-               m_PluginOrPredifferMode = Mode;
-               if (Mode != PLUGIN_MODE::PLUGIN_AUTO)
-               {
-                       m_PluginName.erase();
-               }
-               else
-               {
-                       m_PluginName = _("<Automatic>");
-               }
+               String name;
+               std::vector<String> args;
+               TCHAR quoteChar;
        };
-       explicit PluginForFile(PLUGIN_MODE Mode) 
+
+       void Initialize(bool automatic)
        {
-               Initialize(Mode);
-       };
-public:
-       /// PLUGIN_AUTO if the plugin will be defined during the first use (via scan of all available plugins)
-       PLUGIN_MODE     m_PluginOrPredifferMode;
+               // and init Plugin/Prediffer mode and Plugin name accordingly
+               m_PluginPipeline = automatic ? _T("<Automatic>") : _T("");
+       }
+
+       explicit PluginForFile(bool automatic) 
+       {
+               Initialize(automatic);
+       }
+
+       explicit PluginForFile(const String& pluginPipeline)
+       : m_PluginPipeline(pluginPipeline)
+       {
+       }
+
+       const String& GetPluginPipeline() const { return m_PluginPipeline; }
+       void SetPluginPipeline(const String& pluginPipeline) { m_PluginPipeline = pluginPipeline; }
+       void ClearPluginPipeline() { m_PluginPipeline.clear(); }
+
+       std::vector<PipelineItem> ParsePluginPipeline(String& errorMessage) const;
+       static std::vector<PipelineItem> ParsePluginPipeline(const String& pluginPipeline, String& errorMessage);
+       static String MakePluginPipeline(const std::vector<PipelineItem>& list);
+       static String MakeArguments(const std::vector<String>& args, const std::vector<StringView>& variables);
 
+protected:
        /// plugin name when it is defined
-       String          m_PluginName;
+       String m_PluginPipeline;
 };
 
 /**
@@ -81,18 +77,53 @@ public:
 class PackingInfo : public PluginForFile
 {
 public:
-       explicit PackingInfo(PLUGIN_MODE Mode = FileTransform::g_UnpackerMode)
-       : PluginForFile(Mode)
-       , m_pufile(nullptr)
-       , m_bDisallowMixedEOL(false)
+       explicit PackingInfo(bool automatic = FileTransform::AutoUnpacking)
+       : PluginForFile(automatic)
        {
        }
-public:
-       /// text type to override syntax highlighting
-       String          m_textType;
-       /// custom UniFile
-       UniFile*        m_pufile;
-       bool            m_bDisallowMixedEOL;
+
+       explicit PackingInfo(const String& pluginPipeline)
+       : PluginForFile(pluginPipeline)
+       {
+       }
+
+       bool GetPackUnpackPlugin(const String& filteredFilenames, bool bReverse,
+               std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>>& plugins,
+               String *pPluginPipelineResolved, String& errorMessage) const;
+
+       // Events handler
+       // WinMerge uses one of these entry points to call a plugin
+
+       // bMayOverwrite : tells if we can overwrite the source file
+       // if we don't, don't forget do delete the temp file after use
+
+       /**
+        * @brief Prepare one file for loading, scan all available plugins (events+filename filtering) 
+        *
+        * @param filepath : [in, out] Most plugins change this filename
+        *
+        * @return Tells if WinMerge handles this file
+        *
+        * @note Event FILE_UNPACK
+        * Apply only the first correct handler
+        */
+       bool Unpacking(std::vector<int> * handlerSubcodes, String & filepath, const String& filteredText, const std::vector<StringView>& variables);
+
+       /**
+        * @brief Prepare one file for saving, known handler
+        *
+        * @return Tells if we can save the file (really hope we can)
+        *
+        * @param filepath : [in, out] Most plugins change this filename
+        *
+        * @note Event FILE_PACK
+        * Never do Unicode conversion, it was done in SaveFromFile
+        */
+       bool Packing(String & filepath, const std::vector<int>& handlerSubcodes, const std::vector<StringView>& variables) const;
+
+       bool Packing(const String& srcFilepath, const String& dstFilepath, const std::vector<int>& handlerSubcodes, const std::vector<StringView>& variables) const;
+
+       String GetUnpackedFileExtension(const String& filteredFilenames) const;
 };
 
 /**
@@ -103,77 +134,36 @@ public:
 class PrediffingInfo : public PluginForFile
 {
 public:
-       explicit PrediffingInfo(PLUGIN_MODE Mode = FileTransform::g_PredifferMode)
-       : PluginForFile(Mode)
+       explicit PrediffingInfo(bool automatic = FileTransform::AutoPrediffing)
+       : PluginForFile(automatic)
+       {
+       }
+
+       explicit PrediffingInfo(const String& pluginPipeline)
+       : PluginForFile(pluginPipeline)
        {
        }
+
+       bool GetPrediffPlugin(const String& filteredFilenames, bool bReverse,
+               std::vector<std::tuple<PluginInfo*, std::vector<String>, bool>>& plugins,
+               String* pPluginPipelineResolved, String& errorMessage) const;
+
+       /**
+        * @brief Prepare one file for diffing, scan all available plugins (events+filename filtering) 
+        *
+        * @param filepath : [in, out] Most plugins change this filename
+        * @param handler : unpacking handler, to keep to pack again
+        *
+        * @return Tells if WinMerge handles this file
+        *
+        * @note Event FILE_PREDIFF BUFFER_PREDIFF
+        * Apply only the first correct handler
+        */
+       bool Prediffing(String & filepath, const String& filteredText, bool bMayOverwrite, const std::vector<StringView>& variables);
 };
 
 namespace FileTransform
 {
-
-// Events handler
-// WinMerge uses one of these entry points to call a plugin
-
-// bMayOverwrite : tells if we can overwrite the source file
-// if we don't, don't forget do delete the temp file after use
-
-/**
- * @brief Prepare one file for loading, scan all available plugins (events+filename filtering) 
- *
- * @param filepath : [in, out] Most plugins change this filename
- * @param handler : unpacking handler, to keep to pack again
- *
- * @return Tells if WinMerge handles this file
- *
- * @note Event FILE_UNPACK
- * Apply only the first correct handler
- */
-bool Unpacking(String & filepath, const String& filteredText, PackingInfo * handler, int * handlerSubcode);
-/**
- * @brief Prepare one file for loading, known handler
- *
- * @param filepath : [in, out] Most plugins change this filename
- */
-bool Unpacking(String & filepath, const PackingInfo * handler, int * handlerSubcode);
-
-bool Unpacking(PackingInfo * handler, int * handlerSubcode, String & filepath, const String& filteredText);
-
-/**
- * @brief Prepare one file for saving, known handler
- *
- * @return Tells if we can save the file (really hope we can)
- *
- * @param filepath : [in, out] Most plugins change this filename
- *
- * @note Event FILE_PACK
- * Never do Unicode conversion, it was done in SaveFromFile
- */
-bool Packing(String & filepath, const PackingInfo& handler, int handlerSubcode);
-
-bool Packing(const String& srcFilepath, const String& dstFilepath, const PackingInfo& handler, int handlerSubcode);
-
-/**
- * @brief Prepare one file for diffing, scan all available plugins (events+filename filtering) 
- *
- * @param filepath : [in, out] Most plugins change this filename
- * @param handler : unpacking handler, to keep to pack again
- *
- * @return Tells if WinMerge handles this file
- *
- * @note Event FILE_PREDIFF BUFFER_PREDIFF
- * Apply only the first correct handler
- */
-bool Prediffing(String & filepath, const String& filteredText, PrediffingInfo * handler, bool bMayOverwrite);
-/**
- * @brief Prepare one file for diffing, known handler
- *
- * @param filepath : [in, out] Most plugins change this filename
- */
-bool Prediffing(String & filepath, PrediffingInfo handler, bool bMayOverwrite);
-
-bool Prediffing(PrediffingInfo * handler, String & filepath, const String& filteredText, bool bMayOverwrite);
-
 /**
  * @brief Transform all files to UTF8 aslong possible
  *
@@ -217,8 +207,15 @@ std::vector<String> GetFreeFunctionsInScripts(const wchar_t* TransformationEvent
  *
  * @note Event EDITOR_SCRIPT, ?
  */
-bool Interactive(String & text, const wchar_t *TransformationEvent, int iFncChosen);
+bool Interactive(String & text, const std::vector<String>& params, const wchar_t *TransformationEvent, int iFncChosen, const std::vector<StringView>& variables);
+
+std::pair<
+       std::vector<std::tuple<String, String, unsigned, PluginInfo *>>,
+       std::map<String, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>>
+>
+CreatePluginMenuInfos(const String& filteredFilenames, const std::vector<std::wstring>& events, unsigned baseId);
 
-String GetUnpackedFileExtension(const String& filteredFilenames, const PackingInfo* handler);
+inline const std::vector<String> UnpackerEventNames = { L"BUFFER_PACK_UNPACK", L"FILE_PACK_UNPACK", L"FILE_FOLDER_PACK_UNPACK" };
+inline const std::vector<String> PredifferEventNames = { L"BUFFER_PREDIFF", L"FILE_PREDIFF" };
 
 }
index f41f58c..48c8f79 100644 (file)
@@ -21,6 +21,7 @@
 #include "TimeSizeCompare.h"
 #include "TFile.h"
 #include "FileFilterHelper.h"
+#include "MergeApp.h"
 #include "DebugNew.h"
 
 using CompareEngines::ByteCompare;
@@ -28,8 +29,6 @@ using CompareEngines::BinaryCompare;
 using CompareEngines::TimeSizeCompare;
 using CompareEngines::ImageCompare;
 
-static void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, PathContext & files);
-
 FolderCmp::FolderCmp(CDiffContext *pCtxt)
 : m_pCtxt(pCtxt)
 , m_pDiffUtilsEngine(nullptr)
@@ -97,7 +96,7 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        m_diffFileData.m_textStats[nIndex].clear();
 
                PathContext tFiles;
-               GetComparePaths(m_pCtxt, di, tFiles);
+               m_pCtxt->GetComparePaths(di, tFiles);
                struct change *script10 = nullptr;
                struct change *script12 = nullptr;
                struct change *script02 = nullptr;
@@ -112,7 +111,7 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
 
                // Transformation happens here
                // text used for automatic mode : plugin filter must match it
-               String filteredFilenames = strutils::join(tFiles.begin(), tFiles.end(), _T("|"));
+               String filteredFilenames = CDiffContext::GetFilteredFilenames(tFiles);
 
                PackingInfo * infoUnpacker = nullptr;
                PrediffingInfo * infoPrediffer = nullptr;
@@ -134,11 +133,8 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                        // Invoke unpacking plugins
                        if (infoUnpacker && strutils::compare_nocase(filepathUnpacked[nIndex], _T("NUL")) != 0)
                        {
-                               if (!FileTransform::Unpacking(infoUnpacker, nullptr, filepathUnpacked[nIndex], filteredFilenames))
+                               if (!infoUnpacker->Unpacking(nullptr, filepathUnpacked[nIndex], filteredFilenames, { tFiles[nIndex] }))
                                        goto exitPrepAndCompare;
-
-                               // we use the same plugins for both files, so they must be defined before second file
-                               assert(infoUnpacker->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_MANUAL);
                        }
 
                        // As we keep handles open on unpacked files, Transform() may not delete them.
@@ -155,7 +151,7 @@ int FolderCmp::prepAndCompareFiles(DIFFITEM &di)
                for (nIndex = 0; nIndex < nDirs; nIndex++)
                {
                // Invoke prediff'ing plugins
-                       if (infoPrediffer && !m_diffFileData.Filepath_Transform(bForceUTF8, encoding[nIndex], filepathUnpacked[nIndex], filepathTransformed[nIndex], filteredFilenames, infoPrediffer))
+                       if (!m_diffFileData.Filepath_Transform(bForceUTF8, encoding[nIndex], filepathUnpacked[nIndex], filepathTransformed[nIndex], filteredFilenames, *infoPrediffer))
                                goto exitPrepAndCompare;
                }
 
@@ -417,17 +413,17 @@ exitPrepAndCompare:
                diffdata02.Reset();
                
                // delete the temp files after comparison
-               if (filepathTransformed[0] != filepathUnpacked[0])
+               if (filepathTransformed[0] != filepathUnpacked[0] && !filepathTransformed[0].empty())
                        try { TFile(filepathTransformed[0]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathTransformed[0])); }
-               if (filepathTransformed[1] != filepathUnpacked[1])
+               if (filepathTransformed[1] != filepathUnpacked[1] && !filepathTransformed[1].empty())
                        try { TFile(filepathTransformed[1]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathTransformed[1])); }
-               if (nDirs > 2 && filepathTransformed[2] != filepathUnpacked[2])
+               if (nDirs > 2 && filepathTransformed[2] != filepathUnpacked[2] && !filepathTransformed[2].empty())
                        try { TFile(filepathTransformed[2]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathTransformed[2])); }
-               if (filepathUnpacked[0] != tFiles[0])
+               if (filepathUnpacked[0] != tFiles[0] && !filepathUnpacked[0].empty())
                        try { TFile(filepathUnpacked[0]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathUnpacked[0])); }
-               if (filepathUnpacked[1] != tFiles[1])
+               if (filepathUnpacked[1] != tFiles[1] && !filepathUnpacked[1].empty())
                        try { TFile(filepathUnpacked[1]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathUnpacked[1])); }
-               if (nDirs > 2 && filepathUnpacked[2] != tFiles[2])
+               if (nDirs > 2 && filepathUnpacked[2] != tFiles[2] && !filepathUnpacked[2].empty())
                        try { TFile(filepathUnpacked[2]).remove(); } catch (...) { LogErrorString(strutils::format(_T("DeleteFile(%s) failed"), filepathUnpacked[2])); }
 
                // When comparing empty file and nonexistent file, `DIFFCODE::SAME` flag is set to the variable `code`, so change the flag to `DIFFCODE::DIFF`
@@ -441,7 +437,7 @@ exitPrepAndCompare:
                        m_pBinaryCompare.reset(new BinaryCompare());
                m_pBinaryCompare->SetAbortable(m_pCtxt->GetAbortable());
                PathContext tFiles;
-               GetComparePaths(m_pCtxt, di, tFiles);
+               m_pCtxt->GetComparePaths(di, tFiles);
                code = m_pBinaryCompare->CompareFiles(tFiles, di);
        }
        else if (nCompMethod == CMP_DATE || nCompMethod == CMP_DATE_SIZE || nCompMethod == CMP_SIZE)
@@ -461,7 +457,7 @@ exitPrepAndCompare:
                }
 
                PathContext tFiles;
-               GetComparePaths(m_pCtxt, di, tFiles);
+               m_pCtxt->GetComparePaths(di, tFiles);
                code = DIFFCODE::IMAGE | m_pImageCompare->CompareFiles(tFiles, di);
        }
        else
@@ -473,30 +469,3 @@ exitPrepAndCompare:
        return code;
 }
 
-/**
- * @brief Get actual compared paths from DIFFITEM.
- * @param [in] pCtx Pointer to compare context.
- * @param [in] di DiffItem from which the paths are created.
- * @param [out] left Gets the left compare path.
- * @param [out] right Gets the right compare path.
- * @note If item is unique, same path is returned for both.
- */
-void GetComparePaths(CDiffContext * pCtxt, const DIFFITEM &di, PathContext & tFiles)
-{
-       int nDirs = pCtxt->GetCompareDirs();
-
-       tFiles.SetSize(nDirs);
-
-       for (int nIndex = 0; nIndex < nDirs; nIndex++)
-       {
-               if (di.diffcode.exists(nIndex))
-               {
-                       tFiles.SetPath(nIndex,
-                               paths::ConcatPath(pCtxt->GetPath(nIndex), di.diffFileInfo[nIndex].GetFile()), false);
-               }
-               else
-               {
-                       tFiles.SetPath(nIndex, _T("NUL"), false);
-               }
-       }
-}
index 824a81e..829ea4b 100644 (file)
@@ -25,6 +25,7 @@
 #include "OptionsDef.h"
 #include "DiffFileInfo.h"
 #include "SaveClosingDlg.h"
+#include "SelectPluginDlg.h"
 #include "DiffList.h"
 #include "paths.h"
 #include "OptionsMgr.h"
@@ -99,7 +100,9 @@ BEGIN_MESSAGE_MAP(CHexMergeDoc, CDocument)
        ON_COMMAND(ID_VIEW_ZOOMNORMAL, OnViewZoomNormal)
        ON_COMMAND(ID_REFRESH, OnRefresh)
        ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnFileRecompareAs)
+       ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnFileRecompareAs)
        ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateFileRecompareAs)
+       ON_COMMAND(ID_OPEN_WITH_UNPACKER, OnOpenWithUnpacker)
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
@@ -420,6 +423,11 @@ void CHexMergeDoc::SetDirDoc(CDirDoc * pDirDoc)
        m_pDirDoc = pDirDoc;
 }
 
+bool CHexMergeDoc::GetReadOnly(int nBuffer) const
+{
+       return m_pView[nBuffer]->GetReadOnly();
+}
+
 /**
  * @brief Return pointer to parent frame
  */
@@ -446,7 +454,7 @@ bool CHexMergeDoc::CloseNow()
        if (!PromptAndSaveIfNeeded(true))
                return false;
 
-       GetParentFrame()->CloseNow();
+       GetParentFrame()->DestroyWindow();
        return true;
 }
 
@@ -637,7 +645,7 @@ void CHexMergeDoc::RefreshOptions()
  */
 void CHexMergeDoc::SetTitle(LPCTSTR lpszTitle)
 {
-       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc);
+       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc, &m_infoUnpacker, nullptr);
        CDocument::SetTitle(sTitle.c_str());
 }
 
@@ -814,18 +822,41 @@ void CHexMergeDoc::OnFileRecompareAs(UINT nID)
        int nBuffers = m_nBuffers;
        CDirDoc *pDirDoc = m_pDirDoc->GetMainView() ? m_pDirDoc : 
                static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
+       PackingInfo infoUnpacker(m_infoUnpacker.GetPluginPipeline());
+
        for (int nBuffer = 0; nBuffer < nBuffers; ++nBuffer)
        {
                fileloc[nBuffer].setPath(m_filePaths[nBuffer]);
                dwFlags[nBuffer] = m_pView[nBuffer]->GetReadOnly() ? FFILEOPEN_READONLY : 0;
                strDesc[nBuffer] = m_strDesc[nBuffer];
        }
+       if (ID_UNPACKERS_FIRST <= nID && nID <= ID_UNPACKERS_LAST)
+       {
+               infoUnpacker.SetPluginPipeline(CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+               nID = ID_MERGE_COMPARE_HEX;
+       }
+
        CloseNow();
-       GetMainFrame()->ShowMergeDoc(nID, pDirDoc, nBuffers, fileloc, dwFlags, strDesc);
+       GetMainFrame()->ShowMergeDoc(nID, pDirDoc, nBuffers, fileloc, dwFlags, strDesc, _T(""), &infoUnpacker);
+}
+
+void CHexMergeDoc::OnOpenWithUnpacker()
+{
+       CSelectPluginDlg dlg(m_infoUnpacker.GetPluginPipeline(),
+               strutils::join(m_filePaths.begin(), m_filePaths.end(), _T("|")), false, true);
+       if (dlg.DoModal() == IDOK)
+       {
+               PackingInfo infoUnpacker(dlg.GetPluginPipeline());
+               PathContext paths = m_filePaths;
+               DWORD dwFlags[3] = { FFILEOPEN_NOMRU, FFILEOPEN_NOMRU, FFILEOPEN_NOMRU };
+               String strDesc[3] = { m_strDesc[0], m_strDesc[1], m_strDesc[2] };
+               CloseNow();
+               GetMainFrame()->DoFileOpen(ID_MERGE_COMPARE_HEX, &paths, dwFlags, strDesc, _T(""), &infoUnpacker);
+       }
 }
 
 void CHexMergeDoc::OnUpdateFileRecompareAs(CCmdUI* pCmdUI)
 {
-       pCmdUI->Enable(pCmdUI->m_nID != ID_MERGE_COMPARE_XML);
+       pCmdUI->Enable(pCmdUI->m_nID != ID_MERGE_COMPARE_HEX);
 }
 
index 503c015..0ba0138 100644 (file)
@@ -69,9 +69,13 @@ public:
        void DirDocClosing(CDirDoc * pDirDoc) override;
        bool CloseNow() override;
        bool GenerateReport(const String& sFileName) const override { return true; }
-       const PackingInfo* GetUnpacker() const { return &m_infoUnpacker; };
+       const PackingInfo* GetUnpacker() const override { return &m_infoUnpacker; };
        PackingInfo* GetUnpacker() { return &m_infoUnpacker; };
        void SetUnpacker(const PackingInfo* infoUnpacker) override { if (infoUnpacker) m_infoUnpacker = *infoUnpacker;  };
+       const PrediffingInfo* GetPrediffer() const override { return nullptr; };
+       int GetFileCount() const override { return m_filePaths.GetSize(); }
+       String GetPath(int pane) const override { return m_filePaths[pane]; }
+       bool GetReadOnly(int pane) const override;
        CHexMergeFrame * GetParentFrame() const;
        void UpdateHeaderPath(int pane);
        void RefreshOptions();
@@ -121,6 +125,7 @@ protected:
        afx_msg void OnRefresh();
        afx_msg void OnFileRecompareAs(UINT nID);
        afx_msg void OnUpdateFileRecompareAs(CCmdUI* pCmdUI);
+       afx_msg void OnOpenWithUnpacker();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 };
index fdc8b96..e9347ce 100644 (file)
@@ -188,7 +188,11 @@ BOOL CHexMergeFrame::DestroyWindow()
        SavePosition();
        SaveActivePane();
        SaveWindowState();
-       return CMDIChildWnd::DestroyWindow();
+       CFrameWnd* pParentFrame = GetParentFrame();
+       BOOL result = CMergeFrameCommon::DestroyWindow();
+       if (pParentFrame)
+               pParentFrame->OnUpdateFrameTitle(FALSE);
+       return result;
 }
 
 /**
@@ -382,15 +386,6 @@ void CHexMergeFrame::OnIdleUpdateCmdUI()
        CMDIChildWnd::OnIdleUpdateCmdUI();
 }
 
-/// Document commanding us to close
-void CHexMergeFrame::CloseNow()
-{
-       SavePosition(); // Save settings before closing!
-       SaveActivePane();
-       MDIActivate();
-       MDIDestroy();
-}
-
 /**
  * @brief Update any resources necessary after a GUI language change
  */
index d884485..d7dcc81 100644 (file)
@@ -32,7 +32,6 @@ public:
 // Operations
 public:
        void UpdateResources();
-       void CloseNow();
        IHeaderBar * GetHeaderInterface();
        CHexMergeDoc * GetMergeDoc() { return m_pMergeDoc; }
 
index 2f501dc..692cd50 100644 (file)
@@ -97,7 +97,6 @@ END_MESSAGE_MAP()
 CHexMergeView::CHexMergeView()
 : m_pif(nullptr)
 , m_nThisPane(0)
-, m_unpackerSubcode(0)
 {
 }
 
@@ -271,7 +270,7 @@ HRESULT CHexMergeView::LoadFile(LPCTSTR path)
 {
        CHexMergeDoc *pDoc = static_cast<CHexMergeDoc *>(GetDocument());
        String strTempFileName = path;
-       if (!FileTransform::Unpacking(pDoc->GetUnpacker(), &m_unpackerSubcode, strTempFileName, path))
+       if (!pDoc->GetUnpacker()->Unpacking(&m_unpackerSubcodes, strTempFileName, path, { strTempFileName }))
                return E_FAIL;
        HANDLE h = CreateFile(strTempFileName.c_str(), GENERIC_READ,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -345,11 +344,11 @@ HRESULT CHexMergeView::SaveFile(LPCTSTR path, bool packing)
                return hr;
 
        CHexMergeDoc* pDoc = static_cast<CHexMergeDoc*>(GetDocument());
-       if (packing && !pDoc->GetUnpacker()->m_PluginName.empty())
+       if (packing && !pDoc->GetUnpacker()->GetPluginPipeline().empty())
        {
-               if (!FileTransform::Packing(sIntermediateFilename, path, *pDoc->GetUnpacker(), m_unpackerSubcode))
+               if (!pDoc->GetUnpacker()->Packing(sIntermediateFilename, path, m_unpackerSubcodes, { path }))
                {
-                       String str = CMergeApp::GetPackingErrorMessage(m_nThisPane, pDoc->m_nBuffers, path, pDoc->GetUnpacker()->m_PluginName);
+                       String str = CMergeApp::GetPackingErrorMessage(m_nThisPane, pDoc->m_nBuffers, path, *pDoc->GetUnpacker());
                        int answer = AfxMessageBox(str.c_str(), MB_OKCANCEL | MB_ICONWARNING);
                        if (answer == IDOK)
                        {
index ad53b8f..322b6bc 100644 (file)
@@ -30,7 +30,7 @@ public:
 protected: // create from serialization only
        CHexMergeView();
        DECLARE_DYNCREATE(CHexMergeView)
-       int m_unpackerSubcode;
+       std::vector<int> m_unpackerSubcodes;
 public:
        HRESULT LoadFile(LPCTSTR);
        HRESULT SaveFile(LPCTSTR, bool packing = true);
index 0b202a7..c8104d7 100644 (file)
@@ -4,6 +4,7 @@
 \r
 class CDirDoc;\r
 class PackingInfo;\r
+class PrediffingInfo;\r
 \r
 struct IMergeDoc\r
 {\r
@@ -20,6 +21,11 @@ struct IMergeDoc
        virtual bool GenerateReport(const String &path) const = 0;\r
        virtual void DirDocClosing(CDirDoc * pDirDoc) = 0;\r
        virtual void CheckFileChanged() = 0;\r
+       virtual const PackingInfo *GetUnpacker() const = 0;\r
        virtual void SetUnpacker(const PackingInfo *infoUnpacker) = 0;\r
+       virtual const PrediffingInfo *GetPrediffer() const = 0;\r
+       virtual int GetFileCount() const = 0;\r
+       virtual String GetPath(int pane) const = 0;\r
+       virtual bool GetReadOnly(int pane) const = 0;\r
 };\r
 \r
index 3c24d0f..a34c362 100644 (file)
@@ -27,6 +27,7 @@
 #include "FileOrFolderSelect.h"
 #include "UniFile.h"
 #include "SaveClosingDlg.h"
+#include "SelectPluginDlg.h"
 #include "FileLocation.h"
 #include "Constants.h"
 #include "DropHandler.h"
@@ -73,7 +74,9 @@ BEGIN_MESSAGE_MAP(CImgMergeFrame, CMergeFrameCommon)
        ON_UPDATE_COMMAND_UI(ID_FILE_RIGHT_READONLY, OnUpdateRightReadOnly)
        ON_COMMAND(ID_RESCAN, OnFileReload)
        ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnFileRecompareAs)
+       ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnFileRecompareAs)
        ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateFileRecompareAs)
+       ON_COMMAND(ID_OPEN_WITH_UNPACKER, OnOpenWithUnpacker)
        ON_COMMAND(ID_WINDOW_CHANGE_PANE, OnWindowChangePane)
        ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
        ON_MESSAGE(MSG_STORE_PANESIZES, OnStorePaneSizes)
@@ -168,7 +171,6 @@ CImgMergeFrame::CImgMergeFrame()
 , m_nBufferType{BUFFERTYPE::NORMAL, BUFFERTYPE::NORMAL, BUFFERTYPE::NORMAL}
 , m_bRO{}
 , m_nActivePane(-1)
-, m_unpackerSubcode{}
 {
 }
 
@@ -576,7 +578,11 @@ BOOL CImgMergeFrame::DestroyWindow()
        SaveActivePane();
        SaveOptions();
        SaveWindowState();
-       return CMergeFrameCommon::DestroyWindow();
+       CFrameWnd* pParentFrame = GetParentFrame();
+       BOOL result = CMergeFrameCommon::DestroyWindow();
+       if (pParentFrame)
+               pParentFrame->OnUpdateFrameTitle(FALSE);
+       return result;
 }
 
 void CImgMergeFrame::LoadOptions()
@@ -692,12 +698,12 @@ bool CImgMergeFrame::DoFileSave(int pane)
                        }
                        if (filename != m_filePaths[pane])
                        {
-                               if (!FileTransform::Packing(filename, m_filePaths[pane], m_infoUnpacker, m_unpackerSubcode[pane]))
+                               if (!m_infoUnpacker.Packing(filename, m_filePaths[pane], m_unpackerSubcodes[pane], { m_filePaths[pane] }))
                                {
                                        // Restore save point
                                        m_pImgMergeWindow->SetSavePoint(pane, savepoint);
 
-                                       String str = CMergeApp::GetPackingErrorMessage(pane, m_pImgMergeWindow->GetPaneCount(), m_filePaths[pane], m_infoUnpacker.m_PluginName);
+                                       String str = CMergeApp::GetPackingErrorMessage(pane, m_pImgMergeWindow->GetPaneCount(), m_filePaths[pane], m_infoUnpacker);
                                        int answer = AfxMessageBox(str.c_str(), MB_OKCANCEL | MB_ICONWARNING);
                                        if (answer == IDOK)
                                                return DoFileSaveAs(pane, false);
@@ -726,7 +732,7 @@ RETRY:
        if (SelectFile(AfxGetMainWnd()->GetSafeHwnd(), strPath, false, path.c_str(), title))
        {
                std::wstring filename = ucr::toUTF16(strPath);
-               if (packing && !m_infoUnpacker.m_PluginName.empty())
+               if (packing && !m_infoUnpacker.GetPluginPipeline().empty())
                {
                        String tempPath = env::GetTemporaryPath();
                        filename = ucr::toUTF16(env::GetTemporaryFileName(tempPath, _T("MRG_"), 0)
@@ -743,12 +749,12 @@ RETRY:
                }
                if (filename != strPath)
                {
-                       if (!FileTransform::Packing(filename, strPath, m_infoUnpacker, m_unpackerSubcode[pane]))
+                       if (!m_infoUnpacker.Packing(filename, strPath, m_unpackerSubcodes[pane], { strPath }))
                        {
                                // Restore save point
                                m_pImgMergeWindow->SetSavePoint(pane, savepoint);
 
-                               String str = CMergeApp::GetPackingErrorMessage(pane, m_pImgMergeWindow->GetPaneCount(), strPath, m_infoUnpacker.m_PluginName);
+                               String str = CMergeApp::GetPackingErrorMessage(pane, m_pImgMergeWindow->GetPaneCount(), strPath, m_infoUnpacker);
                                int answer = AfxMessageBox(str.c_str(), MB_OKCANCEL | MB_ICONWARNING);
                                if (answer == IDOK)
                                        return DoFileSaveAs(pane, false);
@@ -933,7 +939,7 @@ void CImgMergeFrame::OnUpdateRightReadOnly(CCmdUI* pCmdUI)
        pCmdUI->SetCheck(m_pImgMergeWindow->GetReadOnly(m_pImgMergeWindow->GetPaneCount() - 1));
 }
 
-void CImgMergeFrame::OnFileRecompareAs(UINT nId)
+void CImgMergeFrame::OnFileRecompareAs(UINT nID)
 {
        FileLocation fileloc[3];
        DWORD dwFlags[3];
@@ -941,19 +947,42 @@ void CImgMergeFrame::OnFileRecompareAs(UINT nId)
        int nBuffers = m_filePaths.GetSize();
        CDirDoc *pDirDoc = m_pDirDoc->GetMainView() ? m_pDirDoc :
                static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
+       PackingInfo infoUnpacker(m_infoUnpacker.GetPluginPipeline());
+
        for (int nBuffer = 0; nBuffer < nBuffers; ++nBuffer)
        {
                fileloc[nBuffer].setPath(m_filePaths[nBuffer]);
                dwFlags[nBuffer] = m_bRO[nBuffer] ? FFILEOPEN_READONLY : 0;
                strDesc[nBuffer] = m_strDesc[nBuffer];
        }
+       if (ID_UNPACKERS_FIRST <= nID && nID <= ID_UNPACKERS_LAST)
+       {
+               infoUnpacker.SetPluginPipeline(CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+               nID = ID_MERGE_COMPARE_IMAGE;
+       }
+
        CloseNow();
-       GetMainFrame()->ShowMergeDoc(nId, pDirDoc, nBuffers, fileloc, dwFlags, strDesc);
+       GetMainFrame()->ShowMergeDoc(nID, pDirDoc, nBuffers, fileloc, dwFlags, strDesc, _T(""), &infoUnpacker);
 }
 
 void CImgMergeFrame::OnUpdateFileRecompareAs(CCmdUI* pCmdUI)
 {
-       pCmdUI->Enable(pCmdUI->m_nID != ID_MERGE_COMPARE_XML);
+       pCmdUI->Enable(pCmdUI->m_nID != ID_MERGE_COMPARE_IMAGE);
+}
+
+void CImgMergeFrame::OnOpenWithUnpacker()
+{
+       CSelectPluginDlg dlg(m_infoUnpacker.GetPluginPipeline(),
+               strutils::join(m_filePaths.begin(), m_filePaths.end(), _T("|")), true, false);
+       if (dlg.DoModal() == IDOK)
+       {
+               PackingInfo infoUnpacker(dlg.GetPluginPipeline());
+               PathContext paths = m_filePaths;
+               DWORD dwFlags[3] = { FFILEOPEN_NOMRU, FFILEOPEN_NOMRU, FFILEOPEN_NOMRU };
+               String strDesc[3] = { m_strDesc[0], m_strDesc[1], m_strDesc[2] };
+               CloseNow();
+               GetMainFrame()->DoFileOpen(ID_MERGE_COMPARE_IMAGE, &paths, dwFlags, strDesc, _T(""), &infoUnpacker);
+       }
 }
 
 void  CImgMergeFrame::OnWindowChangePane() 
@@ -1039,7 +1068,7 @@ void CImgMergeFrame::UpdateHeaderSizes()
  */
 void CImgMergeFrame::SetTitle(LPCTSTR lpszTitle)
 {
-       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc);
+       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc, &m_infoUnpacker, nullptr);
        CMergeFrameCommon::SetTitle(sTitle.c_str());
        if (m_hWnd != nullptr)
                SetWindowText(sTitle.c_str());
@@ -1066,8 +1095,10 @@ bool CImgMergeFrame::OpenImages()
        for (int pane = 0; pane < m_filePaths.GetSize(); ++pane)
        {
                strTempFileName[pane] = m_filePaths[pane];
-               if (!FileTransform::Unpacking(&m_infoUnpacker, &m_unpackerSubcode[pane], strTempFileName[pane], filteredFilenames))
-                       return false;
+               if (!m_infoUnpacker.Unpacking(&m_unpackerSubcodes[pane], strTempFileName[pane], filteredFilenames, { strTempFileName[pane] }))
+               {
+                       //return false;
+               }
        }
        if (m_filePaths.GetSize() == 2)
                bResult = m_pImgMergeWindow->OpenImages(ucr::toUTF16(strTempFileName[0]).c_str(), ucr::toUTF16(strTempFileName[1]).c_str());
@@ -1221,11 +1252,7 @@ bool CImgMergeFrame::CloseNow()
        if (!PromptAndSaveIfNeeded(true))
                return false;
 
-       SavePosition(); // Save settings before closing!
-       SaveActivePane();
-       SaveOptions();
-       MDIActivate();
-       MDIDestroy();
+       DestroyWindow();
        return true;
 }
 
index 7487dc0..fa718fa 100644 (file)
@@ -58,7 +58,12 @@ public:
        void UpdateAutoPaneResize();
        void UpdateSplitter();
        bool GenerateReport(const String& sFileName) const override;
+       const PackingInfo* GetUnpacker() const override { return &m_infoUnpacker; };
        void SetUnpacker(const PackingInfo* infoUnpacker) override { if (infoUnpacker) m_infoUnpacker = *infoUnpacker; };
+       const PrediffingInfo* GetPrediffer() const override { return nullptr; };
+       int GetFileCount() const override { return m_filePaths.GetSize(); }
+       String GetPath(int pane) const override { return m_filePaths[pane]; }
+       bool GetReadOnly(int pane) const override { return m_bRO[pane]; }
        void DoAutoMerge(int dstPane);
        bool IsModified() const;
        IMergeDoc::FileChange IsFileChangedOnDisk(int pane) const;
@@ -118,7 +123,7 @@ private:
        CDirDoc *m_pDirDoc;
        int m_nActivePane;
        PackingInfo m_infoUnpacker;
-       int m_unpackerSubcode[3];
+       std::vector<int> m_unpackerSubcodes[3];
 
        //{{AFX_MSG(CImgMergeFrame)
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
@@ -143,8 +148,9 @@ private:
        afx_msg void OnUpdateRightReadOnly(CCmdUI* pCmdUI);
        afx_msg void OnFileReload();
        afx_msg void OnFileClose();
-       afx_msg void OnFileRecompareAs(UINT nId);
+       afx_msg void OnFileRecompareAs(UINT nID);
        afx_msg void OnUpdateFileRecompareAs(CCmdUI* pCmdUI);
+       afx_msg void OnOpenWithUnpacker();
        afx_msg void OnWindowChangePane();
        afx_msg void OnSize(UINT nType, int cx, int cy);
        afx_msg void OnIdleUpdateCmdUI();
diff --git a/Src/InternalPlugins.cpp b/Src/InternalPlugins.cpp
new file mode 100644 (file)
index 0000000..1024b56
--- /dev/null
@@ -0,0 +1,623 @@
+#include "pch.h"
+#include "Plugins.h"
+#define POCO_NO_UNWINDOWS 1
+#include <Poco/FileStream.h>
+#include <Poco/SAX/SAXParser.h>
+#include <Poco/SAX/SAXException.h>
+#include <Poco/SAX/ContentHandler.h>
+#include <Poco/SAX/Attributes.h>
+#include <Poco/Exception.h>
+#include <vector>
+#include <list>
+#include <unordered_set>
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <windows.h>
+#include "MergeApp.h"
+#include "paths.h"
+#include "Environment.h"
+#include "OptionsMgr.h"
+#include "OptionsDef.h"
+#include "codepage_detect.h"
+#include "UniFile.h"
+#include "WinMergePluginBase.h"
+#include "TempFile.h"
+
+using Poco::XML::SAXParser;
+using Poco::XML::ContentHandler;
+using Poco::XML::Locator;
+using Poco::XML::XMLChar;
+using Poco::XML::XMLString;
+using Poco::XML::Attributes;
+using namespace std::literals::string_literals;
+
+namespace
+{
+       HRESULT ReadFile(const String& path, String& text)
+       {
+               UniMemFile file;
+               if (!file.OpenReadOnly(path))
+                       return HRESULT_FROM_WIN32(GetLastError());
+               file.ReadBom();
+               if (!file.HasBom())
+               {
+                       int iGuessEncodingType = GetOptionsMgr()->GetInt(OPT_CP_DETECT);
+                       int64_t fileSize = file.GetFileSize();
+                       FileTextEncoding encoding = codepage_detect::Guess(
+                               paths::FindExtension(path), file.GetBase(), static_cast<size_t>(
+                                       fileSize < static_cast<int64_t>(codepage_detect::BufSize) ?
+                                       fileSize : static_cast<int64_t>(codepage_detect::BufSize)),
+                               iGuessEncodingType);
+                       file.SetCodepage(encoding.m_codepage);
+               }
+               file.ReadStringAll(text);
+               file.Close();
+               return S_OK;
+       }
+
+       HRESULT WriteFile(const String& path, const String& text, bool bom = true)
+       {
+               UniStdioFile fileOut;
+               if (!fileOut.Open(path, _T("wb")))
+                       return HRESULT_FROM_WIN32(GetLastError());
+               fileOut.SetUnicoding(ucr::UNICODESET::UTF8);
+               fileOut.WriteString(text);
+               fileOut.Close();
+               return S_OK;
+       }
+}
+
+namespace internal_plugin
+{
+
+struct Script
+{
+       String m_body;
+       String m_fileExtension;
+};
+
+struct Method
+{
+       String m_command;
+       std::unique_ptr<Script> m_script;
+};
+
+struct Info
+{
+       Info(const String& name) : m_name(name) {}
+       Info(Info&& info) = default;
+       String m_name;
+       String m_event;
+       String m_description;
+       String m_fileFilters;
+       bool m_isAutomatic = false;
+       String m_unpackedFileExtension;
+       String m_extendedProperties;
+       String m_arguments;
+       std::unique_ptr<Method> m_prediffFile;
+       std::unique_ptr<Method> m_unpackFile;
+       std::unique_ptr<Method> m_packFile;
+       std::unique_ptr<Method> m_unpackFolder;
+       std::unique_ptr<Method> m_packFolder;
+       std::map<String, Method> m_editorScripts;
+};
+
+class XMLHandler : public Poco::XML::ContentHandler
+{
+public:
+       inline static const std::string Empty = "";
+       inline static const std::string PluginsElement = "plugins";
+       inline static const std::string PluginElement = "plugin";
+       inline static const std::string EventElement = "event";
+       inline static const std::string DescriptionElement = "description";
+       inline static const std::string FileFiltersElement = "file-filters";
+       inline static const std::string IsAutomaticElement = "is-automatic";
+       inline static const std::string UnpackedFileExtensionElement = "unpacked-file-extension";
+       inline static const std::string ExtendedPropertiesElement = "extended-properties";
+       inline static const std::string ArgumentsElement = "arguments";
+       inline static const std::string PrediffFileElement = "prediff-file";
+       inline static const std::string UnpackFileElement = "unpack-file";
+       inline static const std::string PackFileElement = "pack-file";
+       inline static const std::string UnpackFolderElement = "unpack-folder";
+       inline static const std::string PackFolderElement = "pack-folder";
+       inline static const std::string CommandElement = "command";
+       inline static const std::string ScriptElement = "script";
+       inline static const std::string NameAttribute = "name";
+       inline static const std::string ValueAttribute = "value";
+       inline static const std::string FileExtensionAttribute = "fileExtension";
+
+       explicit XMLHandler(std::list<Info>* pPlugins) : m_pPlugins(pPlugins) {}
+
+       void setDocumentLocator(const Locator* loc) {}
+       void startDocument() {}
+       void endDocument() {}
+       void startElement(const XMLString& uri, const XMLString& localName, const XMLString& qname, const Attributes& attributes)
+       {
+               if (!m_stack.empty())
+               {
+                       if (m_stack.top() == PluginsElement)
+                       {
+                               if (localName == PluginElement)
+                               {
+                                       String name;
+                                       int index = attributes.getIndex(Empty, NameAttribute);
+                                       if (index >= 0)
+                                               name = ucr::toTString(attributes.getValue(index));
+                                       m_pPlugins->emplace_back(name);
+                                       m_pMethod = nullptr;
+                               }
+                       }
+                       else if (m_stack.top() == PluginElement)
+                       {
+                               Info& plugin = m_pPlugins->back();
+                               String value;
+                               int index = attributes.getIndex(Empty, ValueAttribute);
+                               if (index >= 0)
+                               {
+                                       value = ucr::toTString(attributes.getValue(index));
+                                       if (localName == EventElement)
+                                               plugin.m_event = value;
+                                       else if (localName == DescriptionElement)
+                                               plugin.m_description = value;
+                                       else if (localName == FileFiltersElement)
+                                               plugin.m_fileFilters = value;
+                                       else if (localName == IsAutomaticElement)
+                                       {
+                                               TCHAR ch = value.c_str()[0];
+                                               plugin.m_isAutomatic = (ch == 't' || ch == 'T');
+                                       }
+                                       else if (localName == UnpackedFileExtensionElement)
+                                               plugin.m_unpackedFileExtension = value;
+                                       else if (localName == ExtendedPropertiesElement)
+                                               plugin.m_extendedProperties = value;
+                                       else if (localName == ArgumentsElement)
+                                               plugin.m_arguments = value;
+                               }
+                               else if (localName == PrediffFileElement)
+                               {
+                                       plugin.m_prediffFile.reset(new Method());
+                                       m_pMethod = plugin.m_prediffFile.get();
+                               }
+                               else if (localName == UnpackFileElement)
+                               {
+                                       plugin.m_unpackFile.reset(new Method());
+                                       m_pMethod = plugin.m_unpackFile.get();
+                               }
+                               else if (localName == PackFileElement)
+                               {
+                                       plugin.m_packFile.reset(new Method());
+                                       m_pMethod = plugin.m_packFile.get();
+                               }
+                               else if (localName == UnpackFolderElement)
+                               {
+                                       plugin.m_unpackFolder.reset(new Method());
+                                       m_pMethod = plugin.m_unpackFolder.get();
+                               }
+                               else if (localName == PackFolderElement)
+                               {
+                                       plugin.m_packFolder.reset(new Method());
+                                       m_pMethod = plugin.m_packFolder.get();
+                               }
+                       }
+                       else if (m_pMethod)
+                       {
+                               if (localName == ScriptElement)
+                               {
+                                       m_pMethod->m_script.reset(new Script);
+                                       int index = attributes.getIndex(Empty, FileExtensionAttribute);
+                                       if (index >= 0)
+                                               m_pMethod->m_script->m_fileExtension = ucr::toTString(attributes.getValue(index));
+                               }
+                       }
+               }
+               m_stack.push(localName);
+       }
+       void endElement(const XMLString& uri, const XMLString& localName, const XMLString& qname)
+       {
+               m_stack.pop();
+       }
+       void characters(const XMLChar ch[], int start, int length)
+       {
+               if (m_stack.empty())
+                       return;
+               if (m_stack.top() == CommandElement && m_pMethod)
+               {
+                       m_pMethod->m_command += xmlch2tstr(ch, length);
+               }
+               else if (m_stack.top() == ScriptElement && m_pMethod && m_pMethod->m_script)
+               {
+                       m_pMethod->m_script->m_body += xmlch2tstr(ch, length);
+               }
+       }
+       void ignorableWhitespace(const XMLChar ch[], int start, int length) {}
+       void processingInstruction(const XMLString& target, const XMLString& data) {}
+       void startPrefixMapping(const XMLString& prefix, const XMLString& uri) {}
+       void endPrefixMapping(const XMLString& prefix) {}
+       void skippedEntity(const XMLString& name) {}
+
+private:
+       static String xmlch2tstr(const XMLChar* ch, int length)
+       {
+               return ucr::toTString(std::string(ch, length));
+       }
+
+       std::list<Info>* m_pPlugins = nullptr;
+       std::stack<std::string> m_stack;
+       Method* m_pMethod = nullptr;
+};
+
+class UnpackerGeneratedFromEditorScript : public WinMergePluginBase
+{
+public:
+       UnpackerGeneratedFromEditorScript(const PluginInfo& plugin, const std::wstring funcname, int id)
+               : WinMergePluginBase(
+                       L"FILE_PACK_UNPACK",
+                       strutils::format_string1(_T("Unpacker to execute %1 script (automatically generated)"), funcname),
+                       L"\\.nomatch$", L"")
+               , m_pDispatch(plugin.m_lpDispatch)
+               , m_funcid(id)
+               , m_hasArgumentsProperty(plugin.m_hasArgumentsProperty)
+               , m_hasVariablesProperty(plugin.m_hasVariablesProperty)
+       {
+               auto desc = plugin.GetExtendedPropertyValue(funcname + _T(".Description"));
+               if (desc.has_value())
+                       m_sDescription = *desc;
+               m_pDispatch->AddRef();
+               auto menuCaption = plugin.GetExtendedPropertyValue(funcname + _T(".MenuCaption"));
+               String caption = menuCaption.has_value() ? String{ menuCaption->data(), menuCaption->length() } : funcname;
+               m_sExtendedProperties = ucr::toUTF16(strutils::format(_T("ProcessType=Editor script;MenuCaption=%s"), caption))
+                       + (plugin.GetExtendedPropertyValue(funcname + _T(".ArgumentsRequired")).has_value() ? L";ArgumentsRequired" : L"");
+       }
+
+       virtual ~UnpackerGeneratedFromEditorScript()
+       {
+               m_pDispatch->Release();
+       }
+
+       HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess) override
+       {
+               String text;
+               HRESULT hr = ReadFile(fileSrc, text);
+               if (FAILED(hr))
+                       return hr;
+               if (m_hasVariablesProperty && !plugin::InvokePutPluginVariables(ucr::toTString(fileSrc), m_pDispatch))
+                       return E_FAIL;
+               if (m_hasArgumentsProperty && !plugin::InvokePutPluginArguments(m_sArguments, m_pDispatch))
+                       return E_FAIL;
+               int changed = 0;
+               if (!plugin::InvokeTransformText(text, changed, m_pDispatch, m_funcid))
+                       return E_FAIL;
+               hr = WriteFile(fileDst, text);
+               if (FAILED(hr))
+                       return hr;
+               *pSubcode = 0;
+               *pbChanged = VARIANT_TRUE;
+               *pbSuccess = VARIANT_TRUE;
+               return S_OK;
+       }
+
+       HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess) override
+       {
+               *pbChanged = VARIANT_FALSE;
+               *pbSuccess = VARIANT_FALSE;
+               return S_OK;
+       }
+
+private:
+       IDispatch* m_pDispatch;
+       int m_funcid;
+       bool m_hasArgumentsProperty;
+       bool m_hasVariablesProperty;
+};
+
+class InternalPlugin : public WinMergePluginBase
+{
+public:
+       InternalPlugin(Info&& info)
+               : WinMergePluginBase(info.m_event, info.m_description, info.m_fileFilters, info.m_unpackedFileExtension, info.m_extendedProperties, info.m_arguments, info.m_isAutomatic)
+               , m_info(std::move(info))
+       {
+       }
+
+       virtual ~InternalPlugin()
+       {
+       }
+
+       HRESULT STDMETHODCALLTYPE PrediffFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, VARIANT_BOOL* pbSuccess) override
+       {
+               if (!m_info.m_prediffFile)
+               {
+                       *pbChanged = VARIANT_FALSE;
+                       *pbSuccess = VARIANT_FALSE;
+                       return S_OK;
+               }
+               TempFile scriptFile;
+               String command = replaceMacros(m_info.m_prediffFile->m_command, fileSrc, fileDst);
+               if (m_info.m_prediffFile->m_script)
+               {
+                       createScript(*m_info.m_prediffFile->m_script, scriptFile);
+                       strutils::replace(command, _T("${SCRIPT_FILE}"), scriptFile.GetPath());
+               }
+               DWORD dwExitCode;
+               HRESULT hr = launchProgram(command, SW_HIDE, dwExitCode);
+
+               *pbChanged = SUCCEEDED(hr);
+               *pbSuccess = SUCCEEDED(hr);
+               return hr;
+       }
+
+       HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess) override
+       {
+               if (!m_info.m_unpackFile)
+               {
+                       *pSubcode = 0;
+                       *pbChanged = VARIANT_FALSE;
+                       *pbSuccess = VARIANT_FALSE;
+                       return S_OK;
+               }
+               TempFile scriptFile;
+               String command = replaceMacros(m_info.m_unpackFile->m_command, fileSrc, fileDst);
+               if (m_info.m_unpackFile->m_script)
+               {
+                       createScript(*m_info.m_unpackFile->m_script, scriptFile);
+                       strutils::replace(command, _T("${SCRIPT_FILE}"), scriptFile.GetPath());
+               }
+               DWORD dwExitCode;
+               HRESULT hr = launchProgram(command, SW_HIDE, dwExitCode);
+
+               *pSubcode = 0;
+               *pbChanged = SUCCEEDED(hr);
+               *pbSuccess = SUCCEEDED(hr);
+               return hr;
+       }
+
+       HRESULT STDMETHODCALLTYPE PackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT subcode, VARIANT_BOOL* pbSuccess) override
+       {
+               if (!m_info.m_packFile)
+               {
+                       *pbChanged = VARIANT_FALSE;
+                       *pbSuccess = VARIANT_FALSE;
+                       return S_OK;
+               }
+               TempFile scriptFile;
+               String command = replaceMacros(m_info.m_packFile->m_command, fileSrc, fileDst);
+               if (m_info.m_packFile->m_script)
+               {
+                       createScript(*m_info.m_packFile->m_script, scriptFile);
+                       strutils::replace(command, _T("${SCRIPT_FILE}"), scriptFile.GetPath());
+               }
+               DWORD dwExitCode;
+               HRESULT hr = launchProgram(command, SW_HIDE, dwExitCode);
+
+               *pbChanged = SUCCEEDED(hr);
+               *pbSuccess = SUCCEEDED(hr);
+               return hr;
+       }
+
+protected:
+
+       String replaceMacros(const String& cmd, const String & fileSrc, const String& fileDst)
+       {
+               String command = cmd;
+               strutils::replace(command, _T("${SRC_FILE}"), fileSrc);
+               strutils::replace(command, _T("${DST_FILE}"), fileDst);
+               std::vector<StringView> vars = strutils::split(m_sVariables, '\0');
+               for (size_t i = 0; i < vars.size(); ++i)
+                       strutils::replace(command, strutils::format(_T("${%d}"), i), { vars[i].data(), vars[i].length() });
+               strutils::replace(command, _T("${*}"), m_sArguments);
+               return command;
+       }
+
+       static HRESULT createScript(const Script& script, TempFile& tempFile)
+       {
+               String path = tempFile.Create(_T(""), script.m_fileExtension);
+               return WriteFile(path, script.m_body, false);
+       }
+
+       static HRESULT launchProgram(const String& sCmd, WORD wShowWindow, DWORD &dwExitCode)
+       {
+               TempFile stderrFile;
+               String sOutputFile = stderrFile.Create();
+               if (_wgetenv(L"WINMERGE_HOME") == nullptr)
+                       _wputenv_s(L"WINMERGE_HOME", env::GetProgPath().c_str());
+               String command = sCmd;
+               strutils::replace(command, _T("${WINMERGE_HOME}"), env::GetProgPath());
+               STARTUPINFO stInfo = { sizeof(STARTUPINFO) };
+               stInfo.dwFlags = STARTF_USESHOWWINDOW;
+               stInfo.wShowWindow = wShowWindow;
+               SECURITY_ATTRIBUTES sa{ sizeof(sa) };
+               sa.bInheritHandle = true;
+               stInfo.hStdError = CreateFile(sOutputFile.c_str(), GENERIC_READ | GENERIC_WRITE,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
+               stInfo.hStdOutput = stInfo.hStdError;
+               stInfo.dwFlags |= STARTF_USESTDHANDLES;
+               PROCESS_INFORMATION processInfo;
+               bool retVal = !!CreateProcess(nullptr, (LPTSTR)command.c_str(),
+                       nullptr, nullptr, TRUE, CREATE_DEFAULT_ERROR_MODE, nullptr, nullptr,
+                       &stInfo, &processInfo);
+               if (!retVal)
+                       return HRESULT_FROM_WIN32(GetLastError());
+               WaitForSingleObject(processInfo.hProcess, INFINITE);
+               GetExitCodeProcess(processInfo.hProcess, &dwExitCode);
+               CloseHandle(processInfo.hThread);
+               CloseHandle(processInfo.hProcess);
+               DWORD dwStdErrorSize = 0;
+               if (stInfo.hStdError != nullptr && stInfo.hStdError != INVALID_HANDLE_VALUE)
+               {
+                       DWORD dwStdErrorSizeHigh = 0;
+                       dwStdErrorSize = GetFileSize(stInfo.hStdError, &dwStdErrorSizeHigh);
+                       CloseHandle(stInfo.hStdError);
+               }
+               if (dwExitCode != 0 && dwStdErrorSize > 0)
+               {
+                       String error;
+                       ReadFile(sOutputFile, error);
+                       ICreateErrorInfo* pCreateErrorInfo = nullptr;
+                       if (SUCCEEDED(CreateErrorInfo(&pCreateErrorInfo)))
+                       {
+                               pCreateErrorInfo->SetSource(const_cast<OLECHAR*>(command.c_str()));
+                               pCreateErrorInfo->SetDescription(const_cast<OLECHAR*>(ucr::toUTF16(error).c_str()));
+                               IErrorInfo* pErrorInfo = nullptr;
+                               pCreateErrorInfo->QueryInterface(&pErrorInfo);
+                               SetErrorInfo(0, pErrorInfo);
+                               pErrorInfo->Release();
+                               pCreateErrorInfo->Release();
+                               return DISP_E_EXCEPTION;
+                       }
+               }
+               return S_OK;
+       }
+
+private:
+       Info m_info;
+};
+
+class EditorScriptGeneratedFromUnpacker: public WinMergePluginBase
+{
+public:
+       EditorScriptGeneratedFromUnpacker(const PluginInfo& plugin, const String& funcname)
+               : WinMergePluginBase(
+                       L"EDITOR_SCRIPT",
+                       plugin.m_description,
+                       plugin.m_filtersTextDefault, L"", plugin.m_extendedProperties, plugin.m_arguments)
+               , m_pDispatch(plugin.m_lpDispatch)
+       {
+               m_pDispatch->AddRef();
+               AddFunction(ucr::toUTF16(funcname), CallUnpackFile);
+       }
+
+       virtual ~EditorScriptGeneratedFromUnpacker()
+       {
+               m_pDispatch->Release();
+       }
+
+       static HRESULT STDMETHODCALLTYPE CallUnpackFile(IDispatch *pDispatch, BSTR text, BSTR* pbstrResult)
+       {
+               TempFile src, dst;
+               String fileSrc = src.Create();
+               String fileDst = dst.Create();
+               HRESULT hr = WriteFile(fileSrc, text);
+               if (FAILED(hr))
+                       return hr;
+               int changed = 0;
+               int subcode = 0;
+               auto* thisObj = static_cast<EditorScriptGeneratedFromUnpacker*>(pDispatch);
+               auto* pInternalPlugin = dynamic_cast<InternalPlugin*>(thisObj->m_pDispatch);
+               if (pInternalPlugin)
+               {
+                       BSTR bstrFileSrc = SysAllocString(ucr::toUTF16(fileSrc).c_str());
+                       BSTR bstrFileDst= SysAllocString(ucr::toUTF16(fileDst).c_str());
+                       VARIANT_BOOL bChanged;
+                       VARIANT_BOOL bSuccess;
+                       hr = pInternalPlugin->UnpackFile(bstrFileSrc, bstrFileDst, &bChanged, &subcode, &bSuccess);
+                       SysFreeString(bstrFileSrc);
+                       SysFreeString(bstrFileDst);
+                       if (FAILED(hr))
+                               return hr;
+               }
+               else
+               {
+                       if (!plugin::InvokeUnpackFile(fileSrc, fileDst, changed, thisObj->m_pDispatch, subcode))
+                               return E_FAIL;
+               }
+               String unpackedText;
+               hr = ReadFile(fileDst, unpackedText);
+               if (FAILED(hr))
+                       return hr;
+               *pbstrResult = SysAllocStringLen(ucr::toUTF16(unpackedText).c_str(), 
+                       static_cast<unsigned>(unpackedText.length()));
+               return S_OK;
+       }
+
+private:
+       IDispatch* m_pDispatch;
+};
+
+struct Loader
+{
+       Loader()
+       {
+               CAllThreadsScripts::RegisterInternalPluginsLoader(&Load);
+       }
+
+       static bool Load(std::map<String, PluginArrayPtr>& plugins, String& errmsg)
+       {
+               if (plugins.find(L"EDITOR_SCRIPT") != plugins.end())
+               {
+                       for (auto plugin : *plugins[L"EDITOR_SCRIPT"])
+                       {
+                               if (!plugin->m_disabled && plugin->GetExtendedPropertyValue(_T("GenerateUnpacker")).has_value())
+                               {
+                                       std::vector<String> namesArray;
+                                       std::vector<int> idArray;
+                                       int validFuncs = plugin::GetMethodsFromScript(plugin->m_lpDispatch, namesArray, idArray);
+                                       for (int i = 0; i < validFuncs; ++i)
+                                       {
+                                               if (plugins.find(L"FILE_PACK_UNPACK") == plugins.end())
+                                                       plugins[L"FILE_PACK_UNPACK"].reset(new PluginArray);
+                                               PluginInfoPtr pluginNew(new PluginInfo());
+                                               IDispatch* pDispatch = new UnpackerGeneratedFromEditorScript(*plugin, namesArray[i], idArray[i]);
+                                               pDispatch->AddRef();
+                                               pluginNew->MakeInfo(namesArray[i], pDispatch);
+                                               plugins[L"FILE_PACK_UNPACK"]->push_back(pluginNew);
+                                       }
+                               }
+                       }
+               }
+
+               std::list<Info> internalPlugins;
+               XMLHandler handler(&internalPlugins);
+               SAXParser parser;
+               parser.setContentHandler(&handler);
+               try
+               {
+                       parser.parse(ucr::toUTF8(paths::ConcatPath(env::GetProgPath(), _T("MergePlugins\\Plugins.xml"))));
+               }
+               catch (Poco::XML::SAXParseException& e)
+               {
+                       errmsg = ucr::toTString(e.message());
+                       return false;
+               }
+               catch (Poco::FileNotFoundException&)
+               {
+               }
+
+               for (auto& info : internalPlugins)
+               {
+                       String event = info.m_event;
+                       String name = info.m_name;
+                       if (plugins.find(event) == plugins.end())
+                               plugins[event].reset(new PluginArray);
+                       PluginInfoPtr pluginNew(new PluginInfo());
+                       IDispatch* pDispatch = new InternalPlugin(std::move(info));
+                       pDispatch->AddRef();
+                       pluginNew->MakeInfo(name, pDispatch);
+                       plugins[event]->push_back(pluginNew);
+               }
+
+               if (plugins.find(L"FILE_PACK_UNPACK") != plugins.end())
+               {
+                       for (auto plugin : *plugins[L"FILE_PACK_UNPACK"])
+                       {
+                               if (!plugin->m_disabled && plugin->GetExtendedPropertyValue(_T("GenerateEditorScript")).has_value())
+                               {
+                                       if (plugins.find(L"EDITOR_SCRIPT") == plugins.end())
+                                               plugins[L"EDITOR_SCRIPT"].reset(new PluginArray);
+                                       PluginInfoPtr pluginNew(new PluginInfo());
+                                       auto menuCaption =  plugin->GetExtendedPropertyValue(_T("MenuCaption"));
+                                       String funcname = menuCaption.has_value() ? String{menuCaption->data(), menuCaption->length() } : plugin->m_name;
+                                       IDispatch* pDispatch = new EditorScriptGeneratedFromUnpacker(*plugin, funcname);
+                                       pDispatch->AddRef();
+                                       pluginNew->MakeInfo(plugin->m_name, pDispatch);
+                                       plugins[L"EDITOR_SCRIPT"]->push_back(pluginNew);
+                               }
+                       }
+               }
+
+               return true;
+       }
+} g_loader;
+
+}
index c97b0a9..6c0adba 100644 (file)
@@ -52,6 +52,7 @@
 #include "PreferencesDlg.h"
 #include "FileOrFolderSelect.h"
 #include "PluginsListDlg.h"
+#include "SelectPluginDlg.h"
 #include "stringdiffs.h"
 #include "MergeCmdLineInfo.h"
 #include "OptionsFont.h"
@@ -193,7 +194,9 @@ BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
        ON_UPDATE_COMMAND_UI_RANGE(ID_UNPACK_MANUAL, ID_UNPACK_AUTO, OnUpdatePluginUnpackMode)
        ON_COMMAND_RANGE(ID_PREDIFFER_MANUAL, ID_PREDIFFER_AUTO, OnPluginPrediffMode)
        ON_UPDATE_COMMAND_UI_RANGE(ID_PREDIFFER_MANUAL, ID_PREDIFFER_AUTO, OnUpdatePluginPrediffMode)
-       ON_UPDATE_COMMAND_UI(ID_RELOAD_PLUGINS, OnUpdateReloadPlugins)
+       ON_UPDATE_COMMAND_UI(ID_OPEN_WITH_UNPACKER, OnUpdatePluginRelatedMenu)
+       ON_UPDATE_COMMAND_UI(ID_APPLY_PREDIFFER, OnUpdatePluginRelatedMenu)
+       ON_UPDATE_COMMAND_UI(ID_RELOAD_PLUGINS, OnUpdatePluginRelatedMenu)
        ON_COMMAND(ID_RELOAD_PLUGINS, OnReloadPlugins)
        ON_COMMAND(ID_HELP_GETCONFIG, OnSaveConfigData)
        ON_COMMAND(ID_FILE_NEW, (OnFileNew<2, FRAME_FILE>))
@@ -413,28 +416,22 @@ void CMainFrame::OnDestroy(void)
                RevokeDragDrop(m_hWnd);
 }
 
-static HMENU GetSubmenu(HMENU menu, bool bFirstSubmenu)
+static HMENU GetSubmenu(HMENU menu, int nthSubmenu)
 {
-       if (!bFirstSubmenu)
+       for (int nth = 0, i = 0; i < ::GetMenuItemCount(menu); i++)
        {
-               // look for last submenu
-               for (int i = ::GetMenuItemCount(menu) ; i >= 0  ; i--)
-                       if (::GetSubMenu(menu, i) != nullptr)
-                               return ::GetSubMenu(menu, i);
-       }
-       else
-       {
-               // look for first submenu
-               for (int i = 0 ; i < ::GetMenuItemCount(menu) ; i++)
-                       if (::GetSubMenu(menu, i) != nullptr)
+               if (::GetSubMenu(menu, i) != nullptr)
+               {
+                       if (nth == nthSubmenu)
                                return ::GetSubMenu(menu, i);
+                       nth++;
+               }
        }
-
        // error, submenu not found
        return nullptr;
 }
 
-static HMENU GetSubmenu(HMENU mainMenu, UINT nIDFirstMenuItem, bool bFirstSubmenu)
+static HMENU GetSubmenu(HMENU mainMenu, UINT nIDFirstMenuItem, int nthSubmenu)
 {
        int i;
        for (i = 0 ; i < ::GetMenuItemCount(mainMenu) ; i++)
@@ -443,18 +440,7 @@ static HMENU GetSubmenu(HMENU mainMenu, UINT nIDFirstMenuItem, bool bFirstSubmen
        HMENU menu = ::GetSubMenu(mainMenu, i);
        if (!menu)
                return nullptr;
-       return GetSubmenu(menu, bFirstSubmenu);
-}
-
-/** 
- * @brief Find the scripts submenu from the main menu
- * As now this is the first submenu in "Edit" menu
- * We find the "Edit" menu by looking for a menu 
- *  starting with ID_EDIT_UNDO.
- */
-HMENU CMainFrame::GetScriptsSubmenu(HMENU mainMenu)
-{
-       return GetSubmenu(mainMenu, ID_PLUGINS_LIST, false);
+       return GetSubmenu(menu, nthSubmenu);
 }
 
 /**
@@ -465,7 +451,7 @@ HMENU CMainFrame::GetScriptsSubmenu(HMENU mainMenu)
  */
 HMENU CMainFrame::GetPrediffersSubmenu(HMENU mainMenu)
 {
-       return GetSubmenu(mainMenu, ID_PLUGINS_LIST, true);
+       return GetSubmenu(mainMenu, ID_PLUGINS_LIST, 1);
 }
 
 /**
@@ -622,15 +608,70 @@ LRESULT CMainFrame::OnMenuChar(UINT nChar, UINT nFlags,
  */
 void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) 
 {
-       CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
-       
        if (!bSysMenu)
        {
+               if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+               {
+                       PathContext paths;
+                       for (int i = 0; i < pMergeDoc->GetFileCount(); ++i)
+                               paths.SetPath(i, pMergeDoc->GetPath(i));
+                       String filteredFilenames = strutils::join(paths.begin(), paths.end(), _T("|"));
+                       unsigned topMenuId = pPopupMenu->GetMenuItemID(0);
+                       if (topMenuId == ID_NO_PREDIFFER)
+                       {
+                               UpdatePrediffersMenu();
+                       }
+                       else if (topMenuId == ID_MERGE_COMPARE_TEXT)
+                       {
+                               CMenu* pMenu = pPopupMenu;
+                               // empty the menu
+                               for (int i = pMenu->GetMenuItemCount() - 1; i > (ID_MERGE_COMPARE_IMAGE - ID_MERGE_COMPARE_TEXT); --i)
+                                       pMenu->DeleteMenu(i, MF_BYPOSITION);
+
+                               CMainFrame::AppendPluginMenus(pMenu, filteredFilenames, FileTransform::UnpackerEventNames, true, ID_UNPACKERS_FIRST);
+                       }
+                       else if (topMenuId == ID_NO_EDIT_SCRIPTS)
+                       {
+                               CMenu* pMenu = pPopupMenu;
+                               ASSERT(pMenu != nullptr);
+
+                               // empty the menu
+                               int i = pMenu->GetMenuItemCount();
+                               while (i--)
+                                       pMenu->DeleteMenu(0, MF_BYPOSITION);
+
+                               CMainFrame::AppendPluginMenus(pMenu, filteredFilenames, { L"EDITOR_SCRIPT" }, false, ID_SCRIPT_FIRST);
+                       }
+                       else if (topMenuId == ID_PLUGINS_LIST)
+                       {
+                               for (int j = 0; j < 2; j++)
+                               {
+                                       CMenu* pMenu = pPopupMenu->GetSubMenu((j == 0) ? 8 : (pPopupMenu->GetMenuItemCount() - 3));
+                                       ASSERT(pMenu != nullptr);
+
+                                       // empty the menu
+                                       int i = pMenu->GetMenuItemCount();
+                                       while (i--)
+                                               pMenu->DeleteMenu(0, MF_BYPOSITION);
+
+                                       if (j == 0)
+                                               CMainFrame::AppendPluginMenus(pMenu, filteredFilenames, FileTransform::UnpackerEventNames, false, ID_UNPACKERS_FIRST);
+                                       else
+                                               CMainFrame::AppendPluginMenus(pMenu, filteredFilenames, { L"EDITOR_SCRIPT" }, false, ID_SCRIPT_FIRST);
+                               }
+                       }
+               }
+
+               CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
                if (BCMenu::IsMenu(pPopupMenu))
                {
                        BCMenu::UpdateMenu(pPopupMenu);
                }
        }
+       else
+       {
+               CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);
+       }
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -669,7 +710,7 @@ bool CMainFrame::ShowAutoMergeDoc(CDirDoc * pDirDoc,
                std::transform(ifileloc, ifileloc + nFiles, filepaths.begin(),
                        [](auto& file) { return file.filepath; });
                String filteredFilenames = strutils::join(filepaths.begin(), filepaths.end(), _T("|"));
-               unpackedFileExtension = FileTransform::GetUnpackedFileExtension(filteredFilenames, infoUnpacker);
+               unpackedFileExtension = infoUnpacker->GetUnpackedFileExtension(filteredFilenames);
        }
        FileFilterHelper filterImg, filterBin;
        filterImg.UseMask(true);
@@ -871,7 +912,7 @@ bool CMainFrame::ShowImgMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocati
        pDirDoc->AddMergeDoc(pImgMergeFrame);
                
        if (!pImgMergeFrame->OpenDocs(nFiles, fileloc, GetROFromFlags(nFiles, dwFlags).data(), strDesc, this))
-               return ShowTextMergeDoc(pDirDoc, nFiles, fileloc, dwFlags, strDesc, sReportFile, infoUnpacker);
+               return false;
 
        for (int pane = 0; pane < nFiles; pane++)
        {
@@ -1017,18 +1058,19 @@ static bool AddToRecentDocs(const PathContext& paths, const unsigned flags[], bo
  * @param [in] dwRightFlags Right-side flags.
  * @param [in] bRecurse Do we run recursive (folder) compare?
  * @param [in] pDirDoc Dir compare document to use.
- * @param [in] prediffer Prediffer plugin name.
+ * @param [in] infoUnpacker Unpacker plugin name.
+ * @param [in] infoPrediffer Prediffer plugin name.
  * @return `true` if opening files and compare succeeded, `false` otherwise.
  */
 bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
        const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/, const String& sReportFile /*= T("")*/, bool bRecurse /*= false*/, CDirDoc *pDirDoc/*= nullptr*/,
-       String prediffer /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/)
+       const PackingInfo *infoUnpacker /*= nullptr*/, const PrediffingInfo *infoPrediffer /*= nullptr*/)
 {
        if (pDirDoc != nullptr && !pDirDoc->CloseMergeDocs())
                return false;
 
-       FileTransform::g_UnpackerMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_UNPACKER_MODE));
-       FileTransform::g_PredifferMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_PREDIFFER_MODE));
+       FileTransform::AutoUnpacking = GetOptionsMgr()->GetBool(OPT_PLUGINS_UNPACKER_MODE);
+       FileTransform::AutoPrediffing = GetOptionsMgr()->GetBool(OPT_PLUGINS_PREDIFFER_MODE);
 
        Merge7zFormatMergePluginScope scope(infoUnpacker);
 
@@ -1059,7 +1101,7 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
                pOpenDoc->m_files = tFiles;
                pOpenDoc->m_bRecurse = bRecurse;
                if (infoUnpacker)
-                       pOpenDoc->m_infoHandler = *infoUnpacker;
+                       pOpenDoc->m_strUnpackerPipeline = infoUnpacker->GetPluginPipeline();
                CFrameWnd *pFrame = theApp.m_pOpenTemplate->CreateNewFrame(pOpenDoc, nullptr);
                theApp.m_pOpenTemplate->InitialUpdateFrame(pFrame, pOpenDoc);
                return true;
@@ -1143,10 +1185,10 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
                for (int nPane = 0; nPane < tFiles.GetSize(); nPane++)
                        fileloc[nPane].setPath(tFiles[nPane]);
 
-               if (!prediffer.empty())
+               if (infoPrediffer && !infoPrediffer->GetPluginPipeline().empty())
                {
                        String strBothFilenames = strutils::join(tFiles.begin(), tFiles.end(), _T("|"));
-                       pDirDoc->GetPluginManager().SetPrediffer(strBothFilenames, prediffer);
+                       pDirDoc->GetPluginManager().SetPrediffer(strBothFilenames, infoPrediffer->GetPluginPipeline());
                }
 
                ShowAutoMergeDoc(pDirDoc, tFiles.GetSize(), fileloc, dwFlags, strDesc, sReportFile,
@@ -1163,14 +1205,15 @@ bool CMainFrame::DoFileOpen(const PathContext * pFiles /*= nullptr*/,
 }
 
 bool CMainFrame::DoFileOpen(UINT nID, const PathContext* pFiles /*= nullptr*/,
-       const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/)
+       const DWORD dwFlags[] /*= nullptr*/, const String strDesc[] /*= nullptr*/,
+       const String& sReportFile /*= _T("")*/, const PackingInfo *infoUnpacker /*= nullptr*/)
 {
        CDirDoc* pDirDoc = static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
        FileLocation fileloc[3];
        for (int pane = 0; pane < pFiles->GetSize(); pane++)
                fileloc[pane].setPath((*pFiles)[pane]);
        return ShowMergeDoc(nID, pDirDoc, pFiles->GetSize(), fileloc,
-               dwFlags, strDesc);
+               dwFlags, strDesc, sReportFile, infoUnpacker);
 }
 
 void CMainFrame::UpdateFont(FRAMETYPE frame)
@@ -1533,13 +1576,18 @@ void CMainFrame::OnPluginUnpackMode(UINT nID )
        switch (nID)
        {
        case ID_UNPACK_MANUAL:
-               FileTransform::g_UnpackerMode = PLUGIN_MODE::PLUGIN_MANUAL;
+               FileTransform::AutoUnpacking = false;
                break;
        case ID_UNPACK_AUTO:
-               FileTransform::g_UnpackerMode = PLUGIN_MODE::PLUGIN_AUTO;
+               FileTransform::AutoUnpacking = true;
                break;
        }
-       GetOptionsMgr()->SaveOption(OPT_PLUGINS_UNPACKER_MODE, static_cast<int>(FileTransform::g_UnpackerMode));
+       for (auto pDirDoc : GetAllDirDocs())
+       {
+               pDirDoc->GetPluginManager().SetUnpackerSettingAll(FileTransform::AutoUnpacking);
+               pDirDoc->UpdateAllViews(nullptr);
+       }
+       GetOptionsMgr()->SaveOption(OPT_PLUGINS_UNPACKER_MODE, static_cast<int>(FileTransform::AutoUnpacking));
 }
 
 void CMainFrame::OnUpdatePluginUnpackMode(CCmdUI* pCmdUI) 
@@ -1547,27 +1595,31 @@ void CMainFrame::OnUpdatePluginUnpackMode(CCmdUI* pCmdUI)
        pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
 
        if (pCmdUI->m_nID == ID_UNPACK_MANUAL)
-               pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_MANUAL == FileTransform::g_UnpackerMode);
+               pCmdUI->SetRadio(!FileTransform::AutoUnpacking);
        if (pCmdUI->m_nID == ID_UNPACK_AUTO)
-               pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_AUTO == FileTransform::g_UnpackerMode);
+               pCmdUI->SetRadio(FileTransform::AutoUnpacking);
 }
+
 void CMainFrame::OnPluginPrediffMode(UINT nID )
 {
        switch (nID)
        {
        case ID_PREDIFFER_MANUAL:
-               FileTransform::g_PredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
+               FileTransform::AutoPrediffing = false;
                break;
        case ID_PREDIFFER_AUTO:
-               FileTransform::g_PredifferMode = PLUGIN_MODE::PLUGIN_AUTO;
+               FileTransform::AutoPrediffing = true;
                break;
        }
        PrediffingInfo infoPrediffer;
        for (auto pMergeDoc : GetAllMergeDocs())
                pMergeDoc->SetPrediffer(&infoPrediffer);
        for (auto pDirDoc : GetAllDirDocs())
-               pDirDoc->GetPluginManager().SetPrediffSettingAll(FileTransform::g_PredifferMode);
-       GetOptionsMgr()->SaveOption(OPT_PLUGINS_PREDIFFER_MODE, static_cast<int>(FileTransform::g_PredifferMode));
+       {
+               pDirDoc->GetPluginManager().SetPrediffSettingAll(FileTransform::AutoPrediffing);
+               pDirDoc->UpdateAllViews(nullptr);
+       }
+       GetOptionsMgr()->SaveOption(OPT_PLUGINS_PREDIFFER_MODE, FileTransform::AutoPrediffing);
 }
 
 void CMainFrame::OnUpdatePluginPrediffMode(CCmdUI* pCmdUI) 
@@ -1575,28 +1627,20 @@ void CMainFrame::OnUpdatePluginPrediffMode(CCmdUI* pCmdUI)
        pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
 
        if (pCmdUI->m_nID == ID_PREDIFFER_MANUAL)
-               pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_MANUAL == FileTransform::g_PredifferMode);
+               pCmdUI->SetRadio(!FileTransform::AutoPrediffing);
        if (pCmdUI->m_nID == ID_PREDIFFER_AUTO)
-               pCmdUI->SetRadio(PLUGIN_MODE::PLUGIN_AUTO == FileTransform::g_PredifferMode);
+               pCmdUI->SetRadio(FileTransform::AutoPrediffing);
 }
 /**
  * @brief Called when "Reload Plugins" item is updated
  */
-void CMainFrame::OnUpdateReloadPlugins(CCmdUI* pCmdUI)
+void CMainFrame::OnUpdatePluginRelatedMenu(CCmdUI* pCmdUI)
 {
        pCmdUI->Enable(GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED));
 }
 
 void CMainFrame::OnReloadPlugins()
 {
-       // delete all script interfaces
-       // (interfaces will be created again automatically when WinMerge needs them)
-       CAllThreadsScripts::GetActiveSet()->FreeAllScripts();
-
-       // update the editor scripts submenu
-       HMENU scriptsSubmenu = GetScriptsSubmenu(m_hMenuDefault);
-       if (scriptsSubmenu != nullptr)
-               CMergeEditView::createScriptsSubmenu(scriptsSubmenu);
        UpdatePrediffersMenu();
 }
 
@@ -2053,18 +2097,24 @@ void CMainFrame::OnSaveProject()
                theApp.m_pOpenTemplate->m_hMenuShared = NewOpenViewMenu();
        COpenDoc *pOpenDoc = static_cast<COpenDoc *>(theApp.m_pOpenTemplate->CreateNewDocument());
 
-       PathContext paths;
        CFrameWnd * pFrame = GetActiveFrame();
        FRAMETYPE frame = GetFrameType(pFrame);
 
-       if (frame == FRAME_FILE)
+       if (frame == FRAME_FILE || frame == FRAME_HEXFILE || frame == FRAME_IMGFILE)
        {
-               CMergeDoc * pMergeDoc = static_cast<CMergeDoc *>(pFrame->GetActiveDocument());
-               pOpenDoc->m_files = pMergeDoc->m_filePaths;
-               for (int pane = 0; pane < pOpenDoc->m_files.GetSize(); ++pane)
-                       pOpenDoc->m_dwFlags[pane] = FFILEOPEN_PROJECT | (pMergeDoc->m_ptBuf[pane]->GetReadOnly() ? FFILEOPEN_PROJECT : 0);
-               pOpenDoc->m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
-               pOpenDoc->m_strExt = theApp.m_pGlobalFileFilter->GetFilterNameOrMask();
+               if (IMergeDoc* pMergeDoc = GetActiveIMergeDoc())
+               {
+                       PathContext paths;
+                       for (int pane = 0; pane < pMergeDoc->GetFileCount(); ++pane)
+                       {
+                               pOpenDoc->m_dwFlags[pane] = FFILEOPEN_PROJECT | (pMergeDoc->GetReadOnly(pane) ? FFILEOPEN_READONLY : 0);
+                               paths.SetPath(pane, pMergeDoc->GetPath(pane));
+                       }
+                       pOpenDoc->m_files = paths;
+                       pOpenDoc->m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
+                       pOpenDoc->m_strExt = theApp.m_pGlobalFileFilter->GetFilterNameOrMask();
+                       pOpenDoc->m_strUnpackerPipeline = pMergeDoc->GetUnpacker()->GetPluginPipeline();
+               }
        }
        else if (frame == FRAME_FOLDER)
        {
@@ -2431,7 +2481,8 @@ bool CMainFrame::DoOpenConflict(const String& conflictFile, const String strDesc
        return conflictCompared;
 }
 
-bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDesc[] /*= nullptr*/)
+bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDesc[] /*= nullptr*/,
+       const PackingInfo *infoUnpacker /*= nullptr*/)
 {
        String ext = paths::FindExtension(file);
        TempFilePtr wTemp(new TempFile());
@@ -2445,7 +2496,7 @@ bool CMainFrame::DoSelfCompare(UINT nID, const String& file, const String strDes
                (strDesc && !strDesc[1].empty()) ? strDesc[1] : _("") };
        DWORD dwFlags[2] = {FFILEOPEN_READONLY | FFILEOPEN_NOMRU, FFILEOPEN_NOMRU};
        PathContext tmpPathContext(copiedFile, file);
-       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2);
+       return DoFileOpen(nID, &tmpPathContext, dwFlags, strDesc2, _T(""), infoUnpacker);
 }
 
 /**
@@ -2661,7 +2712,19 @@ void CMainFrame::OnUpdateNoMRUs(CCmdUI* pCmdUI)
  */
 void CMainFrame::OnUpdatePluginName(CCmdUI* pCmdUI)
 {
-       pCmdUI->SetText(_T(""));
+       if (auto pMergeDoc = GetActiveIMergeDoc())
+       {
+               String pluginNames;
+               const PackingInfo* infoUnpacker = pMergeDoc->GetUnpacker();
+               if (infoUnpacker && !infoUnpacker->GetPluginPipeline().empty())
+                       pluginNames += infoUnpacker->GetPluginPipeline() + _T("&");
+               const PrediffingInfo* infoPrediffer = pMergeDoc->GetPrediffer();
+               if (infoPrediffer && !infoPrediffer->GetPluginPipeline().empty())
+                       pluginNames += infoPrediffer->GetPluginPipeline() + _T("&");
+               pCmdUI->SetText(pluginNames.substr(0, pluginNames.length() - 1).c_str());
+       }
+       else
+               pCmdUI->SetText(_T(""));
 }
 
 /**
@@ -2825,6 +2888,103 @@ void CMainFrame::ReloadMenu()
        }
 }
 
+void CMainFrame::AppendPluginMenus(CMenu *pMenu, const String& filteredFilenames,
+       const std::vector<std::wstring> events, bool addAllMenu, unsigned baseId)
+{
+       if (!GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED))
+               return;
+
+       auto [suggestedPlugins, allPlugins] = FileTransform::CreatePluginMenuInfos(filteredFilenames, events, baseId);
+
+       if (!addAllMenu)
+       {
+               pMenu->AppendMenu(MF_STRING, ID_SUGGESTED_PLUGINS, _("Suggested plugins").c_str());
+       }
+
+       for (const auto& [caption, name, id, plugin] : suggestedPlugins)
+               pMenu->AppendMenu(MF_STRING, id, caption.c_str());
+
+       CMenu* pMenu2 = pMenu;
+       CMenu popupAll;
+       if (addAllMenu)
+       {
+               popupAll.CreatePopupMenu();
+               pMenu->AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(popupAll.m_hMenu), _("Al&l").c_str());
+               pMenu2 = &popupAll;
+       }
+       else
+       {
+               pMenu->AppendMenu(MF_SEPARATOR, 0);
+               pMenu->AppendMenu(MF_STRING, ID_NOT_SUGGESTED_PLUGINS, _("Other plugins").c_str());
+       }
+
+       std::vector<String> processTypes;
+       for (const auto& [processType, pluginList] : allPlugins)
+               processTypes.push_back(processType);
+       auto it = std::find(processTypes.begin(), processTypes.end(), _("&Others"));
+       if (it != processTypes.end())
+       {
+               processTypes.erase(it);
+               processTypes.push_back(_("&Others"));
+       }
+
+       for (const auto& processType: processTypes)
+       {
+               CMenu popup;
+               popup.CreatePopupMenu();
+               if (processType.empty())
+               {
+                       for (const auto& [caption, name, id, plugin] : allPlugins[processType])
+                               pMenu2->AppendMenu(MF_STRING, id, caption.c_str());
+               }
+               else
+               {
+                       for (const auto& [caption, name, id, plugin] : allPlugins[processType])
+                               popup.AppendMenu(MF_STRING, id, caption.c_str());
+                       pMenu2->AppendMenu(MF_POPUP, reinterpret_cast<UINT_PTR>(popup.m_hMenu), processType.c_str());
+               }
+               popup.Detach();
+       }
+
+       if (addAllMenu)
+       {
+               if (baseId == ID_UNPACKERS_FIRST)
+                       pMenu2->AppendMenu(MF_STRING, ID_OPEN_WITH_UNPACKER, _("&Select...").c_str());
+               else if (baseId == ID_PREDIFFERS_FIRST)
+                       pMenu2->AppendMenu(MF_STRING, ID_APPLY_PREDIFFER, _("&Select...").c_str());
+       }
+       popupAll.Detach();
+}
+
+String CMainFrame::GetPluginPipelineByMenuId(unsigned idSearch, const std::vector<std::wstring> events, unsigned baseId)
+{
+       PluginInfo* pluginFound = nullptr;
+       auto [suggestedPlugins, allPlugins] = FileTransform::CreatePluginMenuInfos(_T(""), events, baseId);
+       for (const auto& [caption, name, id, plugin] : suggestedPlugins)
+       {
+               if (id == idSearch)
+                       pluginFound = plugin;
+       }
+       for (const auto& [processType, pluginList] : allPlugins)
+       {
+               for (const auto& [caption, name, id, plugin] : pluginList)
+               {
+                       if (id == idSearch)
+                               pluginFound = plugin;
+               }
+       }
+       if (pluginFound)
+       {
+               if (!pluginFound->m_argumentsRequired)
+                       return pluginFound->m_name;
+               CSelectPluginDlg dlg(pluginFound->m_name, _T(""), (baseId == ID_UNPACKERS_FIRST), true);
+               if (dlg.DoModal() != IDOK)
+                       return {};
+               return dlg.GetPluginPipeline();
+       }
+       return {};
+}
+
 IMergeDoc* CMainFrame::GetActiveIMergeDoc()
 {
        CFrameWnd* pFrame = GetActiveFrame();
index 7093fc0..8063201 100644 (file)
@@ -43,6 +43,7 @@ typedef CTypedPtrList<CPtrList, CDirDoc *> DirDocList;
 typedef CTypedPtrList<CPtrList, CHexMergeDoc *> HexMergeDocList;
 
 class PackingInfo;
+class PrediffingInfo;
 class CLanguageSelect;
 struct IMergeDoc;
 
@@ -85,15 +86,17 @@ public:
        HMENU NewImgMergeViewMenu();
        HMENU NewOpenViewMenu();
        HMENU NewDefaultMenu(int ID = 0);
-       HMENU GetScriptsSubmenu(HMENU mainMenu);
        HMENU GetPrediffersSubmenu(HMENU mainMenu);
        void UpdatePrediffersMenu();
 
        void FileNew(int nPanes, FRAMETYPE frameType, bool table);
        bool DoFileOpen(const PathContext *pFiles = nullptr,
-               const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr, const String& sReportFile = _T(""), bool bRecurse = false, CDirDoc *pDirDoc = nullptr, String prediffer = _T(""), const PackingInfo * infoUnpacker = nullptr);
-       bool DoFileOpen(UINT nID, const PathContext *pFiles = nullptr,
-               const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr);
+               const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr,
+               const String& sReportFile = _T(""), bool bRecurse = false, CDirDoc *pDirDoc = nullptr,
+               const PackingInfo * infoUnpacker = nullptr, const PrediffingInfo * infoPrediffer = nullptr);
+       bool DoFileOpen(UINT nID, const PathContext* pFiles = nullptr,
+               const DWORD dwFlags[] = nullptr, const String strDesc[] = nullptr,
+               const String& sReportFile = _T(""), const PackingInfo* infoUnpacker = nullptr);
        bool ShowAutoMergeDoc(CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
                const DWORD dwFlags[], const String strDesc[], const String& sReportFile = _T(""), const PackingInfo * infoUnpacker = nullptr);
        bool ShowMergeDoc(UINT nID, CDirDoc * pDirDoc, int nFiles, const FileLocation fileloc[],
@@ -118,10 +121,13 @@ public:
        void StartFlashing();
        bool AskCloseConfirmation();
        bool DoOpenConflict(const String& conflictFile, const String strDesc[] = nullptr, bool checked = false);
-       bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr);
+       bool DoSelfCompare(UINT nID, const String& file, const String strDesc[] = nullptr, const PackingInfo* infoUnpacker = nullptr);
        static FRAMETYPE GetFrameType(const CFrameWnd * pFrame);
        static void UpdateDocTitle();
        static void ReloadMenu();
+       static void AppendPluginMenus(CMenu* pMenu, const String& filteredFilenames,
+               const std::vector<std::wstring> events, bool addAllMenu, unsigned baseId);
+       static String GetPluginPipelineByMenuId(unsigned idSearch, const std::vector<std::wstring> events, unsigned baseId);
        DropHandler *GetDropHandler() const { return m_pDropHandler; }
        const CTypedPtrArray<CPtrArray, CMDIChildWnd*>* GetChildArray() const { return &m_arrChild; }
        IMergeDoc* GetActiveIMergeDoc();
@@ -256,7 +262,7 @@ protected:
        afx_msg void OnPluginUnpackMode(UINT nID);
        afx_msg void OnUpdatePluginPrediffMode(CCmdUI* pCmdUI);
        afx_msg void OnPluginPrediffMode(UINT nID);
-       afx_msg void OnUpdateReloadPlugins(CCmdUI* pCmdUI);
+       afx_msg void OnUpdatePluginRelatedMenu(CCmdUI* pCmdUI);
        afx_msg void OnReloadPlugins();
        afx_msg void OnSaveConfigData();
        template <int nFiles, FRAMETYPE frameType, bool table = false>
index 5aa61d6..2ba0d2e 100644 (file)
@@ -302,8 +302,8 @@ BOOL CMergeApp::InitInstance()
        charsets_init();
        UpdateCodepageModule();
 
-       FileTransform::g_UnpackerMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_UNPACKER_MODE));
-       FileTransform::g_PredifferMode = static_cast<PLUGIN_MODE>(GetOptionsMgr()->GetInt(OPT_PLUGINS_PREDIFFER_MODE));
+       FileTransform::AutoUnpacking = GetOptionsMgr()->GetBool(OPT_PLUGINS_UNPACKER_MODE);
+       FileTransform::AutoPrediffing = GetOptionsMgr()->GetBool(OPT_PLUGINS_PREDIFFER_MODE);
 
        NONCLIENTMETRICS ncm = { sizeof NONCLIENTMETRICS };
        if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof NONCLIENTMETRICS, &ncm, 0))
@@ -640,14 +640,15 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
        bool bCompared = false;
        String strDesc[3];
        std::unique_ptr<PackingInfo> infoUnpacker;
+       std::unique_ptr<PrediffingInfo> infoPrediffer;
 
        m_bNonInteractive = cmdInfo.m_bNonInteractive;
 
        if (!cmdInfo.m_sUnpacker.empty())
-       {
-               infoUnpacker.reset(new PackingInfo(PLUGIN_MODE::PLUGIN_MANUAL));
-               infoUnpacker->m_PluginName = cmdInfo.m_sUnpacker;
-       }
+               infoUnpacker.reset(new PackingInfo(cmdInfo.m_sUnpacker));
+
+       if (!cmdInfo.m_sPreDiffer.empty())
+               infoPrediffer.reset(new PrediffingInfo(cmdInfo.m_sPreDiffer));
 
        // Set the global file filter.
        if (!cmdInfo.m_sFileFilter.empty())
@@ -699,14 +700,14 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwMiddleFlags, cmdInfo.m_dwRightFlags};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               cmdInfo.m_sPreDiffer, infoUnpacker.get());
+                               infoUnpacker.get(), infoPrediffer.get());
                }
                else if (cmdInfo.m_Files.GetSize() > 1)
                {
                        DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                        bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                               cmdInfo.m_sPreDiffer, infoUnpacker.get());
+                               infoUnpacker.get(), infoPrediffer.get());
                }
                else if (cmdInfo.m_Files.GetSize() == 1)
                {
@@ -734,7 +735,7 @@ bool CMergeApp::ParseArgsAndDoOpen(MergeCmdLineInfo& cmdInfo, CMainFrame* pMainF
                                DWORD dwFlags[3] = {cmdInfo.m_dwLeftFlags, cmdInfo.m_dwRightFlags, FFILEOPEN_NONE};
                                bCompared = pMainFrame->DoFileOpen(&cmdInfo.m_Files,
                                        dwFlags, strDesc, cmdInfo.m_sReportFile, cmdInfo.m_bRecurse, nullptr,
-                                       cmdInfo.m_sPreDiffer, infoUnpacker.get());
+                                       infoUnpacker.get(), infoPrediffer.get());
                        }
                }
                else if (cmdInfo.m_Files.GetSize() == 0) // if there are no input args, we can check the display file dialog flag
@@ -1087,8 +1088,9 @@ int CMergeApp::HandleReadonlySave(String& strSavePath, bool bMultiFile,
        return nRetVal;
 }
 
-String CMergeApp::GetPackingErrorMessage(int pane, int paneCount, const String& path, const String& pluginName)
+String CMergeApp::GetPackingErrorMessage(int pane, int paneCount, const String& path, const PackingInfo& plugin)
 {
+       String pluginName = plugin.GetPluginPipeline();
        return strutils::format_string2(
                pane == 0 ? 
                        _("Plugin '%2' cannot pack your changes to the left file back into '%1'.\n\nThe original file will not be changed.\n\nDo you want to save the unpacked version to another file?")
@@ -1166,6 +1168,8 @@ bool CMergeApp::LoadAndOpenProjectFile(const String& sProject, const String& sRe
        bool rtn = true;
        for (auto& projItem : project.Items())
        {
+               std::unique_ptr<PrediffingInfo> pInfoPrediffer;
+               std::unique_ptr<PackingInfo> pInfoUnpacker;
                PathContext tFiles;
                bool bRecursive = false;
                projItem.GetPaths(tFiles, bRecursive);
@@ -1194,6 +1198,10 @@ bool CMergeApp::LoadAndOpenProjectFile(const String& sProject, const String& sRe
                }
                if (projItem.HasSubfolders())
                        bRecursive = projItem.GetSubfolders() > 0;
+               if (projItem.HasUnpacker())
+                       pInfoUnpacker.reset(new PackingInfo(projItem.GetUnpacker()));
+               if (projItem.HasPrediffer())
+                       pInfoPrediffer.reset(new PrediffingInfo(projItem.GetPrediffer()));
 
                DWORD dwFlags[3] = {
                        static_cast<DWORD>(tFiles.GetPath(0).empty() ? FFILEOPEN_NONE : FFILEOPEN_PROJECT),
@@ -1217,7 +1225,8 @@ bool CMergeApp::LoadAndOpenProjectFile(const String& sProject, const String& sRe
 
                GetOptionsMgr()->SaveOption(OPT_CMP_INCLUDE_SUBDIRS, bRecursive);
 
-               rtn &= GetMainFrame()->DoFileOpen(&tFiles, dwFlags, nullptr, sReportFile, bRecursive);
+               rtn &= GetMainFrame()->DoFileOpen(&tFiles, dwFlags, nullptr, sReportFile, bRecursive,
+                       nullptr, pInfoUnpacker.get(), pInfoPrediffer.get());
        }
 
        AddToRecentProjectsMRU(sProject.c_str());
index 40bd0d5..5fca640 100644 (file)
@@ -37,6 +37,7 @@ class LineFiltersList;
 class SubstitutionFiltersList;
 class SyntaxColors;
 class CCrystalTextMarkers;
+class PackingInfo;
 
 /////////////////////////////////////////////////////////////////////////////
 // CMergeApp:
@@ -90,7 +91,7 @@ public:
        static void OpenFileToExternalEditor(const String& file, int nLineNumber = 1);
        static bool CreateBackup(bool bFolder, const String& pszPath);
        static int HandleReadonlySave(String& strSavePath, bool bMultiFile, bool &bApplyToAll);
-       static String GetPackingErrorMessage(int pane, int paneCount, const String& path, const String& pluginName);
+       static String GetPackingErrorMessage(int pane, int paneCount, const String& path, const PackingInfo& plugin);
        bool GetMergingMode() const;
        void SetMergingMode(bool bMergingMode);
        static void SetupTempPath();
index 5e2740d..695b1ae 100644 (file)
@@ -76,7 +76,7 @@ BEGIN
         MENUITEM "Copy Selected Line(s) from Left", ID_COPY_LINES_FROM_LEFT\r
         MENUITEM "Copy Selected Line(s) from Right", ID_COPY_LINES_FROM_RIGHT\r
         MENUITEM SEPARATOR\r
-        MENUITEM "&Select Line Difference\tF4", ID_SELECTLINEDIFF\r
+        MENUITEM "Select Line &Difference\tF4", ID_SELECTLINEDIFF\r
         MENUITEM "Add this change to Substitution &Filters", ID_ADD_TO_IGNORED_SUBSTITUTIONS\r
         MENUITEM SEPARATOR\r
         MENUITEM "&Undo",                       ID_EDIT_UNDO\r
@@ -86,6 +86,11 @@ BEGIN
         MENUITEM "&Copy",                       ID_EDIT_COPY\r
         MENUITEM "&Paste",                      ID_EDIT_PASTE\r
         MENUITEM SEPARATOR\r
+        POPUP "&Scripts"\r
+        BEGIN\r
+            MENUITEM "< Empty >",                   ID_NO_EDIT_SCRIPTS\r
+        END\r
+        MENUITEM SEPARATOR\r
         MENUITEM "&Go to...\tCtrl+G",           ID_EDIT_WMGOTO\r
         MENUITEM "Go to Moved Line Between Left and Middle\tCtrl+Shift+G", ID_GOTO_MOVED_LINE_LM\r
         MENUITEM "Go to Moved Line Between Middle and Right\tCtrl+Alt+G",  ID_GOTO_MOVED_LINE_MR\r
@@ -404,7 +409,7 @@ BEGIN
         MENUITEM "&Manual Unpacking",           ID_UNPACK_MANUAL\r
         MENUITEM "&Automatic Unpacking",        ID_UNPACK_AUTO\r
         MENUITEM SEPARATOR\r
-        MENUITEM "&Edit with Unpacker...",      ID_POPUP_OPEN_WITH_UNPACKER\r
+        MENUITEM "&Edit with Unpacker...",      ID_OPEN_WITH_UNPACKER\r
         MENUITEM SEPARATOR\r
         MENUITEM "&Reload plugins",             ID_RELOAD_PLUGINS\r
     END\r
@@ -498,7 +503,7 @@ BEGIN
             MENUITEM "T&able",                      ID_MERGE_COMPARE_TABLE\r
             MENUITEM "&Binary",                     ID_MERGE_COMPARE_HEX\r
             MENUITEM "&Image",                      ID_MERGE_COMPARE_IMAGE\r
-            MENUITEM "&XML",                        ID_MERGE_COMPARE_XML\r
+            MENUITEM "< Empty >",                   ID_NO_UNPACKER\r
         END\r
         MENUITEM SEPARATOR\r
         POPUP "Recent F&iles Or Folders"\r
@@ -667,12 +672,17 @@ BEGIN
         MENUITEM "&Manual Unpacking",           ID_UNPACK_MANUAL\r
         MENUITEM "&Automatic Unpacking",        ID_UNPACK_AUTO\r
         MENUITEM SEPARATOR\r
-        MENUITEM "&Edit with Unpacker...",      ID_POPUP_OPEN_WITH_UNPACKER\r
+        POPUP "Unpac&ker"\r
+        BEGIN\r
+            MENUITEM "< Empty >",                   ID_NO_UNPACKER\r
+        END\r
+        MENUITEM "&Edit with Unpacker...",      ID_OPEN_WITH_UNPACKER\r
         MENUITEM SEPARATOR\r
         POPUP "&Prediffer"\r
         BEGIN\r
             MENUITEM "<PlaceHolder>",               ID_NO_PREDIFFER\r
         END\r
+        MENUITEM "Apply Pre&differ...",         ID_APPLY_PREDIFFER\r
         MENUITEM SEPARATOR\r
         POPUP "&Scripts"\r
         BEGIN\r
@@ -727,7 +737,7 @@ BEGIN
             MENUITEM "T&able",                      ID_MERGE_COMPARE_TABLE\r
             MENUITEM "&Binary",                     ID_MERGE_COMPARE_HEX\r
             MENUITEM "&Image",                      ID_MERGE_COMPARE_IMAGE\r
-            MENUITEM "&XML",                        ID_MERGE_COMPARE_XML\r
+            MENUITEM "< Empty >",                   ID_NO_UNPACKER\r
         END\r
         MENUITEM SEPARATOR\r
         POPUP "&Copy"\r
@@ -835,10 +845,17 @@ END
 \r
 IDR_POPUP_PLUGINS_SETTINGS MENU\r
 BEGIN\r
+    POPUP "Unpacker Settings"\r
+    BEGIN\r
+        MENUITEM "<None>",                      ID_UNPACKER_SETTINGS_NONE\r
+        MENUITEM "<Automatic>",                 ID_UNPACKER_SETTINGS_AUTO\r
+        MENUITEM "&Select...",                  ID_UNPACKER_SETTINGS_SELECT\r
+    END\r
     POPUP "Prediffer Settings"\r
     BEGIN\r
-        MENUITEM "&No prediffer",               ID_PREDIFF_MANUAL\r
-        MENUITEM "Auto prediffer",              ID_PREDIFF_AUTO\r
+        MENUITEM "<None>",                      ID_PREDIFFER_SETTINGS_NONE\r
+        MENUITEM "<Automatic>",                 ID_PREDIFFER_SETTINGS_AUTO\r
+        MENUITEM "&Select...",                  ID_PREDIFFER_SETTINGS_SELECT\r
     END\r
 END\r
 \r
@@ -1094,7 +1111,7 @@ BEGIN
 \r
     GROUPBOX        "",IDC_FILES_DIRS_GROUP4X,236,197,224,42\r
     LTEXT           " File: Unpacker Plugin",IDC_FILES_DIRS_GROUP4,240,198,86,11\r
-    EDITTEXT        IDC_UNPACKER_EDIT,240,209,140,14,ES_AUTOHSCROLL | ES_READONLY\r
+    CONTROL         "",IDC_UNPACKER_COMBO,"ComboBoxEx32",CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,240,209,140,140\r
     PUSHBUTTON      "Se&lect...",IDC_SELECT_UNPACKER,383,209,73,14\r
 \r
     CONTROL         "Sa&ve Project...",ID_SAVE_PROJECT,"Button",BS_SPLITBUTTON | WS_TABSTOP,10,245,100,14\r
@@ -1409,21 +1426,26 @@ BEGIN
     PUSHBUTTON      "Cancel",IDCANCEL,275,143,50,14\r
 END\r
 \r
-IDD_PLUGINS_SELECTUNPACKER DIALOGEX 0, 0, 318, 102\r
+IDD_PLUGINS_SELECTPLUGIN DIALOGEX 0, 0, 318, 138\r
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
-CAPTION "Select Unpacker"\r
+CAPTION "Select Plugin"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
-    DEFPUSHBUTTON   "OK",IDOK,168,84,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,222,84,50,14\r
-    LTEXT           "File unpacker:",IDC_STATIC,7,9,83,10\r
-    COMBOBOX        IDC_UNPACKER_NAME,92,7,220,54,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    CONTROL         "Display all unpackers, don't check the extension.",IDC_UNPACKER_ALLOW_ALL,\r
-                    "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,92,64,220,20\r
-    LTEXT           "Extensions list:",IDC_STATIC,7,26,63,10\r
-    LTEXT           "Description:",IDC_STATIC,7,43,63,10\r
-    EDITTEXT        IDC_UNPACKER_SUPPORTED_EXTENSIONS,92,24,220,12,ES_AUTOHSCROLL | ES_READONLY\r
-    EDITTEXT        IDC_UNPACKER_DESCRIPTION,92,38,220,24,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY\r
+    LTEXT           "Plugin &Name:",IDC_STATIC,7,9,83,10\r
+    COMBOBOX        IDC_PLUGIN_NAME,92,7,220,54,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Extensions list:",IDC_STATIC,7,26,83,10\r
+    EDITTEXT        IDC_PLUGIN_SUPPORTED_EXTENSIONS,92,24,220,12,ES_AUTOHSCROLL | ES_READONLY\r
+    LTEXT           "Description:",IDC_STATIC,7,43,83,10\r
+    EDITTEXT        IDC_PLUGIN_DESCRIPTION,92,38,220,36,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY\r
+    LTEXT           "Default arguments:",IDC_STATIC,7,78,83,10\r
+    EDITTEXT        IDC_PLUGIN_ARGUMENTS,92,76,220,12,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY\r
+    CONTROL         "Display all unpackers, don't check the extension.",IDC_PLUGIN_ALLOW_ALL,\r
+                    "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,92,90,220,12\r
+    LTEXT           "&Plugin Pipeline:",IDC_STATIC,7,104,83,10\r
+    CONTROL         "",IDC_PLUGIN_PIPELINE,"ComboBoxEx32",CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,92,104,220,95\r
+    PUSHBUTTON      "&Add pipe",IDC_PLUGIN_ADDPIPE,136,120,70,14\r
+    DEFPUSHBUTTON   "OK",IDOK,210,120,50,14\r
+    PUSHBUTTON      "Cancel",IDCANCEL,264,120,50,14\r
 END\r
 \r
 IDD_DIRCOMP_PROGRESS DIALOGEX 0, 0, 256, 60\r
@@ -1901,20 +1923,23 @@ BEGIN
     PUSHBUTTON      "No",IDNO,228,95,50,14\r
 END\r
 \r
-IDD_PLUGINS_LIST DIALOGEX 0, 0, 470, 231\r
+IDD_PLUGINS_LIST DIALOGEX 0, 0, 470, 257\r
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Plugins"\r
 FONT 8, "MS Shell Dlg", 0, 0, 0x1\r
 BEGIN\r
     CONTROL         "&Enable plugins",IDC_PLUGINS_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,266,10\r
     CONTROL         "",IDC_PLUGINSLIST_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,22,456,155\r
-    LTEXT           "File filters:",IDC_STATIC,7,190,70,10\r
-    COMBOBOX        IDC_PLUGIN_FILEFILTERS,80,187,305,14,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP\r
-    PUSHBUTTON      "Defaults",IDC_PLUGIN_FILEFILTERS_DEFAULTS,393,187,70,14\r
-    PUSHBUTTON      "P&lugin Settings...",IDC_PLUGIN_SETTINGS,191,210,95,14\r
-    DEFPUSHBUTTON   "OK",IDOK,293,210,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,354,210,50,14\r
-    PUSHBUTTON      "Help",ID_HELP,413,210,50,14\r
+    LTEXT           "File filters:",IDC_STATIC,7,183,70,10\r
+    COMBOBOX        IDC_PLUGIN_FILEFILTERS,80,183,305,14,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "&Plugin arguments:",IDC_STATIC,7,200,70,10\r
+    EDITTEXT        IDC_PLUGIN_ARGUMENTS,80,200,305,14,ES_AUTOHSCROLL | WS_GROUP\r
+    CONTROL         "Enable &automatic unpacking/prediffing for the plugin",IDC_PLUGIN_AUTOMATIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,218,300,10\r
+    PUSHBUTTON      "Defaults",IDC_PLUGIN_DEFAULTS,393,183,70,14\r
+    PUSHBUTTON      "P&lugin Settings...",IDC_PLUGIN_SETTINGS,191,236,95,14\r
+    DEFPUSHBUTTON   "OK",IDOK,293,236,50,14\r
+    PUSHBUTTON      "Cancel",IDCANCEL,354,236,50,14\r
+    PUSHBUTTON      "Help",ID_HELP,413,236,50,14\r
 END\r
 \r
 IDD_PROPPAGE_SHELL DIALOGEX 0, 0, 255, 242\r
@@ -3147,6 +3172,8 @@ BEGIN
     IDS_COLHDR_NIDIFFS      "Ignored Diff"\r
     IDS_COLHDR_NSDIFFS      "Differences"\r
     IDS_COLHDR_BINARY       NC_("DirView|ColumnHeader", "Binary")\r
+    IDS_COLHDR_UNPACKER     "Unpacker"\r
+    IDS_COLHDR_PREDIFFER    "Prediffer"\r
 END\r
 \r
 // DIRECTORY DIFFING : FILE COMPARISON RESULT, FULL & SHORTENED FORMS\r
@@ -3248,6 +3275,8 @@ BEGIN
     IDS_COLDESC_NIDIFFS     "Number of ignored differences in file. These differences are ignored by WinMerge and cannot be merged."\r
     IDS_COLDESC_NSDIFFS     "Number of differences in file. This number does not include ignored differences."\r
     IDS_COLDESC_BINARY      "Shows an asterisk (*) if the file is binary."\r
+    IDS_COLDESC_UNPACKER    "Unpacker plugin name or pipeline."\r
+    IDS_COLDESC_PREDIFFER   "Prediffer plugin name or pipeline."\r
 END\r
 \r
 // DIRECTORY DIFFING : GENERATE REPORT\r
@@ -3655,6 +3684,43 @@ BEGIN
     IDS_SINGLEINSTANCE_STR2 "Allow only one instance to run and wait for the instance to terminate"\r
 END\r
 \r
+STRINGTABLE\r
+BEGIN\r
+    IDS_PLUGIN_ALL           "Al&l"\r
+    IDS_PLUGIN_PROCESS_TYPE1 "Prettification"\r
+    IDS_PLUGIN_PROCESS_TYPE2 "Content Extraction"\r
+    IDS_PLUGIN_PROCESS_TYPE3 "Visualization"\r
+    IDS_PLUGIN_PROCESS_TYPE4 "Editor script"\r
+    IDS_PLUGIN_PROCESS_TYPE5 "Data Query"\r
+    IDS_PLUGIN_PROCESS_TYPE6 "&Others"\r
+    IDS_PLUGIN_MENU_CAPTION1  "Make Uppercase"\r
+    IDS_PLUGIN_MENU_CAPTION2  "Make Lowercase"\r
+    IDS_PLUGIN_MENU_CAPTION3  "Remove Duplicate Lines"\r
+    IDS_PLUGIN_MENU_CAPTION4  "Count Duplicate Lines"\r
+    IDS_PLUGIN_MENU_CAPTION5  "Sort Lines Ascending"\r
+    IDS_PLUGIN_MENU_CAPTION6  "Sort Lines Descending"\r
+    IDS_PLUGIN_MENU_CAPTION7  "Apply Filter Command..."\r
+    IDS_PLUGIN_MENU_CAPTION8  "Tokenize..."\r
+    IDS_PLUGIN_MENU_CAPTION9  "Trim Spaces"\r
+    IDS_PLUGIN_MENU_CAPTION10 "Insert Date"\r
+    IDS_PLUGIN_MENU_CAPTION11 "Insert Time"\r
+    IDS_PLUGIN_MENU_CAPTION12 "Apply Patch..."\r
+    IDS_PLUGIN_MENU_CAPTION13 "Ignore Columns"\r
+    IDS_PLUGIN_MENU_CAPTION14 "Ignore Comments (C-Family Languages)"\r
+    IDS_PLUGIN_MENU_CAPTION15 "Ignore CSV Fields"\r
+    IDS_PLUGIN_MENU_CAPTION16 "Ignore TSV Fields"\r
+    IDS_PLUGIN_MENU_CAPTION17 "Apply Prediff Substitution Filters"\r
+    IDS_PLUGIN_MENU_CAPTION18 "Prettify JSON"\r
+    IDS_PLUGIN_MENU_CAPTION19 "Prettify XML"\r
+    IDS_PLUGIN_MENU_CAPTION20 "Visualize Graphviz"\r
+    IDS_PLUGIN_MENU_CAPTION21 "Query CSV Data..."\r
+    IDS_PLUGIN_MENU_CAPTION22 "Query TSV Data..."\r
+    IDS_PLUGIN_MENU_CAPTION23 "Query JSON Data..."\r
+    IDS_PLUGIN_MISSING_PLUGIN_NAME "Missing plugin name in plugin pipeline: %1"\r
+    IDS_PLUGIN_MISSING_QUOTATION_MARK"Missing quotation mark in plugin pipeline: %1"\r
+    IDS_PLUGIN_TITLE1        "Specify plugin arguments"\r
+END\r
+\r
 #endif    // English (United States) resources\r
 /////////////////////////////////////////////////////////////////////////////\r
 \r
index 6187a37..44ee7bb 100644 (file)
       <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
     </ClCompile>\r
     <ClCompile Include="DirSelectFilesDlg.cpp" />\r
+    <ClCompile Include="InternalPlugins.cpp">\r
+      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r
+      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>\r
+    </ClCompile>\r
     <ClCompile Include="SubstitutionFiltersList.cpp">\r
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>\r
     <ClCompile Include="SaveClosingDlg.cpp" />\r
     <ClCompile Include="Common\scbarcf.cpp" />\r
     <ClCompile Include="Common\scbarg.cpp" />\r
-    <ClCompile Include="SelectUnpackerDlg.cpp" />\r
+    <ClCompile Include="SelectPluginDlg.cpp" />\r
     <ClCompile Include="SharedFilterDlg.cpp" />\r
     <ClCompile Include="Common\ShellContextMenu.cpp">\r
       <PrecompiledHeader>Use</PrecompiledHeader>\r
     </ClCompile>\r
     <ClCompile Include="TestMain.cpp" />\r
     <ClCompile Include="TrDialogs.cpp" />\r
-    <ClCompile Include="UniMarkdownFile.cpp">\r
-      <PrecompiledHeader>Use</PrecompiledHeader>\r
-      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r
-      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>\r
-    </ClCompile>\r
     <ClCompile Include="Common\varprop.cpp">\r
       <PrecompiledHeader>Use</PrecompiledHeader>\r
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\r
     <ClInclude Include="SaveClosingDlg.h" />\r
     <ClInclude Include="Common\scbarcf.h" />\r
     <ClInclude Include="Common\scbarg.h" />\r
-    <ClInclude Include="SelectUnpackerDlg.h" />\r
+    <ClInclude Include="SelectPluginDlg.h" />\r
     <ClInclude Include="SharedFilterDlg.h" />\r
     <ClInclude Include="Common\ShellContextMenu.h" />\r
     <ClInclude Include="Common\ShellFileOperations.h" />\r
     <ClInclude Include="Common\UnicodeString.h" />\r
     <ClInclude Include="Common\UniFile.h" />\r
     <ClInclude Include="TrDialogs.h" />\r
-    <ClInclude Include="UniMarkdownFile.h" />\r
     <ClInclude Include="Common\varprop.h" />\r
     <ClInclude Include="Common\VersionInfo.h" />\r
     <ClInclude Include="WildcardDropList.h" />\r
index 08e7556..22619a9 100644 (file)
     <ClCompile Include="TempFile.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="UniMarkdownFile.cpp">\r
-      <Filter>Source Files</Filter>\r
-    </ClCompile>\r
     <ClCompile Include="MergeApp.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="SaveClosingDlg.cpp">\r
       <Filter>MFCGui\Dialogs\Source Files</Filter>\r
     </ClCompile>\r
-    <ClCompile Include="SelectUnpackerDlg.cpp">\r
+    <ClCompile Include="SelectPluginDlg.cpp">\r
       <Filter>MFCGui\Dialogs\Source Files</Filter>\r
     </ClCompile>\r
     <ClCompile Include="SharedFilterDlg.cpp">\r
     <ClCompile Include="Common\IniOptionsMgr.cpp">\r
       <Filter>Common\Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="InternalPlugins.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="charsets.h">\r
     <ClInclude Include="TempFile.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="UniMarkdownFile.h">\r
-      <Filter>Header Files</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="StdAfx.h">\r
       <Filter>MFCGui\Header Files</Filter>\r
     </ClInclude>\r
     <ClInclude Include="SaveClosingDlg.h">\r
       <Filter>MFCGui\Dialogs\Header Files</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="SelectUnpackerDlg.h">\r
+    <ClInclude Include="SelectPluginDlg.h">\r
       <Filter>MFCGui\Dialogs\Header Files</Filter>\r
     </ClInclude>\r
     <ClInclude Include="SharedFilterDlg.h">\r
index 2e5200c..bae1365 100644 (file)
@@ -8,6 +8,9 @@
 #include "paths.h"
 #include "Plugins.h"
 #include "Merge7zFormatRegister.h"
+#include "OptionsMgr.h"
+#include "OptionsDef.h"
+#include "MergeApp.h"
 #include <list>
 #include <Poco/Mutex.h>
 
@@ -29,12 +32,14 @@ static Merge7zFormatMergePluginImpl *GetInstance()
 
 Merge7z::Format *Merge7zFormatMergePluginImpl::GuessFormat(const String& path)
 {
+       if (!GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED))
+               return nullptr;
        Merge7zFormatMergePluginImpl *format = GetInstance();
        PluginInfo *plugin = nullptr;
-       if (format->m_infoUnpacker.m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
+       if (format->m_infoUnpacker.GetPluginPipeline().find(_T("<Automatic>")) != String::npos)
                plugin = CAllThreadsScripts::GetActiveSet()->GetAutomaticPluginByFilter(L"FILE_FOLDER_PACK_UNPACK", path);
-       else if (!format->m_infoUnpacker.m_PluginName.empty())
-               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_FOLDER_PACK_UNPACK", format->m_infoUnpacker.m_PluginName);
+       else if (!format->m_infoUnpacker.GetPluginPipeline().empty())
+               plugin = CAllThreadsScripts::GetActiveSet()->GetPluginByName(L"FILE_FOLDER_PACK_UNPACK", format->m_infoUnpacker.GetPluginPipeline());
        if (plugin == nullptr)
                return nullptr;
        if (!plugin::InvokeIsFolder(path, plugin->m_lpDispatch))
index 4e6ffb4..5f66004 100644 (file)
@@ -42,7 +42,7 @@
 #include "SubstitutionFiltersList.h"
 #include "TempFile.h"
 #include "codepage_detect.h"
-#include "SelectUnpackerDlg.h"
+#include "SelectPluginDlg.h"
 #include "EncodingErrorBar.h"
 #include "MergeCmdLineInfo.h"
 #include "TFile.h"
@@ -80,14 +80,14 @@ BEGIN_MESSAGE_MAP(CMergeDoc, CDocument)
        ON_COMMAND(ID_FILE_SAVEAS_MIDDLE, OnFileSaveAsMiddle)
        ON_COMMAND(ID_FILE_SAVEAS_RIGHT, OnFileSaveAsRight)
        ON_UPDATE_COMMAND_UI(ID_STATUS_DIFFNUM, OnUpdateStatusNum)
-       ON_UPDATE_COMMAND_UI(ID_STATUS_PLUGIN, OnUpdatePluginName)
        ON_COMMAND(ID_TOOLS_GENERATEREPORT, OnToolsGenerateReport)
        ON_COMMAND(ID_TOOLS_GENERATEPATCH, OnToolsGeneratePatch)
        ON_COMMAND(ID_RESCAN, OnFileReload)
        ON_COMMAND(ID_FILE_ENCODING, OnFileEncoding)
        ON_COMMAND_RANGE(ID_VIEW_DIFFCONTEXT_ALL, ID_VIEW_DIFFCONTEXT_INVERT, OnDiffContext)
        ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_DIFFCONTEXT_ALL, ID_VIEW_DIFFCONTEXT_INVERT, OnUpdateDiffContext)
-       ON_COMMAND(ID_POPUP_OPEN_WITH_UNPACKER, OnCtxtOpenWithUnpacker)
+       ON_COMMAND(ID_OPEN_WITH_UNPACKER, OnOpenWithUnpacker)
+       ON_COMMAND(ID_APPLY_PREDIFFER, OnApplyPrediffer)
        ON_BN_CLICKED(IDC_FILEENCODING, OnBnClickedFileEncoding)
        ON_BN_CLICKED(IDC_PLUGIN, OnBnClickedPlugin)
        ON_BN_CLICKED(IDC_HEXVIEW, OnBnClickedHexView)
@@ -96,9 +96,8 @@ BEGIN_MESSAGE_MAP(CMergeDoc, CDocument)
        ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_TEXT, OnUpdateFileRecompareAsText)
        ON_COMMAND(ID_MERGE_COMPARE_TABLE, OnFileRecompareAsTable)
        ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_TABLE, OnUpdateFileRecompareAsTable)
-       ON_COMMAND(ID_MERGE_COMPARE_XML, OnFileRecompareAsXML)
-       ON_UPDATE_COMMAND_UI(ID_MERGE_COMPARE_XML, OnUpdateFileRecompareAsXML)
        ON_COMMAND_RANGE(ID_MERGE_COMPARE_HEX, ID_MERGE_COMPARE_IMAGE, OnFileRecompareAs)
+       ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnFileRecompareAs)
        ON_UPDATE_COMMAND_UI_RANGE(ID_SWAPPANES_SWAP23, ID_SWAPPANES_SWAP13, OnUpdateSwapContext)
        //}}AFX_MSG_MAP
 END_MESSAGE_MAP()
@@ -115,7 +114,6 @@ CMergeDoc::CMergeDoc()
 , m_CurWordDiff{ -1, static_cast<size_t>(-1), -1 }
 , m_pDirDoc(nullptr)
 , m_bMixedEol(false)
-, m_pInfoUnpacker(new PackingInfo)
 , m_pEncodingErrorBar(nullptr)
 , m_bHasSyncPoints(false)
 , m_bAutoMerged(false)
@@ -217,7 +215,7 @@ void CMergeDoc::SetUnpacker(const PackingInfo * infoNewHandler)
 {
        if (infoNewHandler != nullptr)
        {
-               *m_pInfoUnpacker = *infoNewHandler;
+               m_infoUnpacker = *infoNewHandler;
        }
 }
 
@@ -225,11 +223,19 @@ void CMergeDoc::SetPrediffer(const PrediffingInfo * infoPrediffer)
 {
        m_diffWrapper.SetPrediffer(infoPrediffer);
 }
+
 void CMergeDoc::GetPrediffer(PrediffingInfo * infoPrediffer)
 {
        m_diffWrapper.GetPrediffer(infoPrediffer);
 }
 
+const PrediffingInfo* CMergeDoc::GetPrediffer() const
+{
+       static PrediffingInfo infoPrediffer;
+       m_diffWrapper.GetPrediffer(&infoPrediffer);
+       return &infoPrediffer;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 // CMergeDoc serialization
 
@@ -255,7 +261,7 @@ void CMergeDoc::Serialize(CArchive& ar)
 static void SaveBuffForDiff(CDiffTextBuffer & buf, const String& filepath, int nStartLine, int nLines)
 {
        // and we don't repack the file
-       PackingInfo * tempPacker = nullptr;
+       PackingInfo tempPacker(false);
 
        // write buffer out to temporary file
        String sError;
@@ -511,7 +517,7 @@ int CMergeDoc::Rescan(bool &bBinary, IDENTLEVEL &identical,
                // Apply flags to lines that are trivial
                PrediffingInfo infoPrediffer;
                GetPrediffer(&infoPrediffer);
-               if (!infoPrediffer.m_PluginName.empty())
+               if (!infoPrediffer.GetPluginPipeline().empty())
                        FlagTrivialLines();
                
                // Apply flags to lines that moved, to differentiate from appeared/disappeared lines
@@ -1531,7 +1537,7 @@ bool CMergeDoc::WordListCopy(int srcPane, int dstPane, int nDiff, int firstWordD
  * @sa CMergeDoc::CDiffTextBuffer::SaveToFile()
  */
 bool CMergeDoc::TrySaveAs(String &strPath, int &nSaveResult, String & sError,
-       int nBuffer, PackingInfo * pInfoTempUnpacker)
+       int nBuffer, PackingInfo& infoTempUnpacker)
 {
        String s;
        String str;
@@ -1546,9 +1552,9 @@ bool CMergeDoc::TrySaveAs(String &strPath, int &nSaveResult, String & sError,
        // Select message based on reason function called
        if (nSaveResult == SAVE_PACK_FAILED)
        {
-               str = CMergeApp::GetPackingErrorMessage(nBuffer, m_nBuffers, strPath, pInfoTempUnpacker->m_PluginName);
+               str = CMergeApp::GetPackingErrorMessage(nBuffer, m_nBuffers, strPath, infoTempUnpacker);
                // replace the unpacker with a "do nothing" unpacker
-               pInfoTempUnpacker->Initialize(PLUGIN_MODE::PLUGIN_MANUAL);
+               infoTempUnpacker.Initialize(false);
        }
        else
        {
@@ -1575,7 +1581,7 @@ bool CMergeDoc::TrySaveAs(String &strPath, int &nSaveResult, String & sError,
                        CDiffTextBuffer *pBuffer = m_ptBuf[nBuffer].get();
                        strSavePath = s;
                        nSaveResult = pBuffer->SaveToFile(strSavePath, false, sError,
-                               pInfoTempUnpacker);
+                               infoTempUnpacker);
 
                        if (nSaveResult == SAVE_DONE)
                        {
@@ -1644,9 +1650,9 @@ bool CMergeDoc::DoSave(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer)
        }
 
        // use a temp packer
-       // first copy the m_pInfoUnpacker
+       // first copy the m_infoUnpacker
        // if an error arises during packing, change and take a "do nothing" packer
-       PackingInfo infoTempUnpacker = *m_pInfoUnpacker;
+       PackingInfo infoTempUnpacker = m_infoUnpacker;
 
        bSaveSuccess = false;
        
@@ -1693,13 +1699,13 @@ bool CMergeDoc::DoSave(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer)
        String sError;
        if (nSaveErrorCode == SAVE_DONE)
                // We have a filename, just try to save
-               nSaveErrorCode = pBuffer->SaveToFile(strSavePath, false, sError, &infoTempUnpacker);
+               nSaveErrorCode = pBuffer->SaveToFile(strSavePath, false, sError, infoTempUnpacker);
 
        if (nSaveErrorCode != SAVE_DONE)
        {
                // Saving failed, user may save to another location if wants to
                do
-                       result = TrySaveAs(strSavePath, nSaveErrorCode, sError, nBuffer, &infoTempUnpacker);
+                       result = TrySaveAs(strSavePath, nSaveErrorCode, sError, nBuffer, infoTempUnpacker);
                while (!result);
        }
 
@@ -1758,9 +1764,9 @@ bool CMergeDoc::DoSaveAs(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer)
        String strSavePath(szPath);
 
        // use a temp packer
-       // first copy the m_pInfoUnpacker
+       // first copy the m_infoUnpacker
        // if an error arises during packing, change and take a "do nothing" packer
-       PackingInfo infoTempUnpacker = *m_pInfoUnpacker;
+       PackingInfo infoTempUnpacker = m_infoUnpacker;
 
        bSaveSuccess = false;
        // false as long as the user is not satisfied
@@ -1777,7 +1783,7 @@ bool CMergeDoc::DoSaveAs(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer)
        // Loop until user succeeds saving or cancels
        String sError;
        do
-               result = TrySaveAs(strSavePath, nSaveErrorCode, sError, nBuffer, &infoTempUnpacker);
+               result = TrySaveAs(strSavePath, nSaveErrorCode, sError, nBuffer, infoTempUnpacker);
        while (!result);
 
        // Saving succeeded with given/selected filename
@@ -2106,22 +2112,6 @@ void CMergeDoc::OnUpdateStatusNum(CCmdUI* pCmdUI)
 }
 
 /**
- * @brief Update plugin name
- * @param [in] pCmdUI UI component to update.
- */
-void CMergeDoc::OnUpdatePluginName(CCmdUI* pCmdUI)
-{
-       String pluginNames;
-       if (m_pInfoUnpacker && !m_pInfoUnpacker->m_PluginName.empty())
-               pluginNames += m_pInfoUnpacker->m_PluginName + _T("&");
-       PrediffingInfo prediffer;
-       GetPrediffer(&prediffer);
-       if (!prediffer.m_PluginName.empty())
-               pluginNames += prediffer.m_PluginName + _T("&");
-       pCmdUI->SetText(pluginNames.substr(0, pluginNames.length() - 1).c_str());
-}
-
-/**
  * @brief Change number of diff context lines
  */
 void CMergeDoc::OnDiffContext(UINT nID)
@@ -2646,7 +2636,7 @@ bool CMergeDoc::CloseNow()
        if (!PromptAndSaveIfNeeded(true))
                return false;
 
-       GetParentFrame()->CloseNow();
+       GetParentFrame()->DestroyWindow();
        return true;
 }
 
@@ -2669,7 +2659,7 @@ int CMergeDoc::LoadFile(CString sFileName, int nBuffer, bool & readOnly, const F
 
        CRLFSTYLE nCrlfStyle = CRLFSTYLE::AUTOMATIC;
        CString sOpenError;
-       retVal = pBuf->LoadFromFile(sFileName, m_pInfoUnpacker.get(),
+       retVal = pBuf->LoadFromFile(sFileName, m_infoUnpacker,
                m_strBothFilenames.c_str(), readOnly, nCrlfStyle, encoding, sOpenError);
 
        // if CMergeDoc::CDiffTextBuffer::LoadFromFile failed,
@@ -2925,7 +2915,7 @@ bool CMergeDoc::OpenDocs(int nFiles, const FileLocation ifileloc[],
        { 
                if (std::count(m_nBufferType, m_nBufferType + m_nBuffers, BUFFERTYPE::UNNAMED) == m_nBuffers)
                {
-                       m_pInfoUnpacker->Initialize(PLUGIN_MODE::PLUGIN_MANUAL);
+                       m_infoUnpacker.Initialize(false);
                }
        }
 
@@ -3030,10 +3020,7 @@ bool CMergeDoc::OpenDocs(int nFiles, const FileLocation ifileloc[],
 
                for (nBuffer = 0; nBuffer < m_nBuffers; nBuffer++)
                {
-                       if (bFiltersEnabled && m_pInfoUnpacker->m_textType.length())
-                               sext[nBuffer] = m_pInfoUnpacker->m_textType;
-                       else
-                               sext[nBuffer] = GetFileExt(m_ptBuf[nBuffer]->GetTempFileName().c_str(), m_strDesc[nBuffer].c_str());
+                       sext[nBuffer] = GetFileExt(m_ptBuf[nBuffer]->GetTempFileName().c_str(), m_strDesc[nBuffer].c_str());
                        ForEachView(nBuffer, [&](auto& pView) {
                                bTyped[nBuffer] = pView->SetTextType(sext[nBuffer].c_str());
                                if (bTyped[nBuffer])
@@ -3279,7 +3266,9 @@ bool CMergeDoc::IsEditedAfterRescan(int nBuffer) const
  */
 void CMergeDoc::SetTitle(LPCTSTR lpszTitle)
 {
-       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc);
+       PrediffingInfo infoPrediffer;
+       GetPrediffer(&infoPrediffer);
+       String sTitle = (lpszTitle != nullptr) ? lpszTitle : CMergeFrameCommon::GetTitleString(m_filePaths, m_strDesc, &m_infoUnpacker, &infoPrediffer);
        CDocument::SetTitle(sTitle.c_str());
 }
 
@@ -3365,41 +3354,6 @@ void CMergeDoc::SwapFiles(int nFromIndex, int nToIndex)
 }
 
 /**
- * @brief Display unpacker dialog to user & handle user's choices
- */
-bool CMergeDoc::OpenWithUnpackerDialog()
-{
-       // let the user choose a handler
-       CSelectUnpackerDlg dlg(m_filePaths[0], nullptr);
-       // create now a new infoUnpacker to initialize the manual/automatic flag
-       PackingInfo infoUnpacker(PLUGIN_MODE::PLUGIN_AUTO);
-       dlg.SetInitialInfoHandler(&infoUnpacker);
-
-       if (dlg.DoModal() == IDOK)
-       {
-               infoUnpacker = dlg.GetInfoHandler();
-               Merge7zFormatMergePluginScope scope(&infoUnpacker);
-               if (HasZipSupport() && std::count_if(m_filePaths.begin(), m_filePaths.end(), ArchiveGuessFormat) == m_nBuffers)
-               {
-                       DWORD dwFlags[3] = {FFILEOPEN_NOMRU, FFILEOPEN_NOMRU, FFILEOPEN_NOMRU};
-                       GetMainFrame()->DoFileOpen(&m_filePaths, dwFlags, m_strDesc, _T(""), 
-                               GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS), nullptr, _T(""), &infoUnpacker);
-                       CloseNow();
-               }
-               else
-               {
-                       SetUnpacker(&infoUnpacker);
-                       OnFileReload();
-               }
-               return true;
-       }
-       else
-       {
-               return false;
-       }
-}
-
-/**
  * @brief Reloads the opened files
  */
 void CMergeDoc::OnFileReload()
@@ -3429,9 +3383,39 @@ void CMergeDoc::OnFileEncoding()
        DoFileEncodingDialog();
 }
 
-void CMergeDoc::OnCtxtOpenWithUnpacker() 
+void CMergeDoc::OnOpenWithUnpacker()
+{
+       CSelectPluginDlg dlg(m_infoUnpacker.GetPluginPipeline(),
+               strutils::join(m_filePaths.begin(), m_filePaths.end(), _T("|")), true, false);
+       if (dlg.DoModal() != IDOK)
+               return;
+
+       if (!PromptAndSaveIfNeeded(true))
+               return;
+
+       PackingInfo infoUnpacker(dlg.GetPluginPipeline());
+       PathContext paths = m_filePaths;
+       DWORD dwFlags[3] = { FFILEOPEN_NOMRU, FFILEOPEN_NOMRU, FFILEOPEN_NOMRU };
+       String strDesc[3] = { m_strDesc[0], m_strDesc[1], m_strDesc[2] };
+       int nID = m_ptBuf[0]->GetTableEditing() ? ID_MERGE_COMPARE_TABLE : ID_MERGE_COMPARE_TEXT;
+
+       if (GetMainFrame()->DoFileOpen(nID, &paths, dwFlags, strDesc, _T(""), &infoUnpacker))
+               CloseNow();
+}
+
+void CMergeDoc::OnApplyPrediffer() 
 {
-       OpenWithUnpackerDialog();
+       PrediffingInfo prediffer;
+       GetPrediffer(&prediffer);
+       // let the user choose a handler
+       CSelectPluginDlg dlg(prediffer.GetPluginPipeline(),
+               strutils::join(m_filePaths.begin(), m_filePaths.end(), _T("|")), false, false);
+       if (dlg.DoModal() != IDOK)
+               return;
+       prediffer.SetPluginPipeline(dlg.GetPluginPipeline());
+       SetPrediffer(&prediffer);
+       FlushAndRescan(true);
+       SetTitle(nullptr);
 }
 
 void CMergeDoc::OnBnClickedFileEncoding()
@@ -3447,7 +3431,7 @@ void CMergeDoc::OnBnClickedPlugin()
        if (m_pEncodingErrorBar == nullptr || m_pView[0][0] == nullptr)
                return;
        m_pView[0][0]->GetParentFrame()->ShowControlBar(m_pEncodingErrorBar.get(), FALSE, FALSE);
-       OpenWithUnpackerDialog();
+       OnOpenWithUnpacker();
 }
 
 void CMergeDoc::OnBnClickedHexView()
@@ -3465,22 +3449,17 @@ void CMergeDoc::OnOK()
 void CMergeDoc::OnFileRecompareAsText()
 {
        m_bEnableTableEditing = false;
-       PackingInfo infoUnpacker;
-       SetUnpacker(&infoUnpacker);
        OnFileReload();
 }
 
 void CMergeDoc::OnUpdateFileRecompareAsText(CCmdUI *pCmdUI)
 {
-       pCmdUI->Enable(m_pInfoUnpacker->m_PluginOrPredifferMode == PLUGIN_MODE::PLUGIN_BUILTIN_XML ||
-               m_ptBuf[0]->GetTableEditing());
+       pCmdUI->Enable(m_ptBuf[0]->GetTableEditing());
 }
 
 void CMergeDoc::OnFileRecompareAsTable()
 {
        m_bEnableTableEditing = true;
-       PackingInfo infoUnpacker;
-       SetUnpacker(&infoUnpacker);
        OnFileReload();
 }
 
@@ -3489,19 +3468,6 @@ void CMergeDoc::OnUpdateFileRecompareAsTable(CCmdUI *pCmdUI)
        pCmdUI->Enable(!m_ptBuf[0]->GetTableEditing());
 }
 
-void CMergeDoc::OnFileRecompareAsXML()
-{
-       m_bEnableTableEditing = false;
-       PackingInfo infoUnpacker(PLUGIN_MODE::PLUGIN_BUILTIN_XML);
-       SetUnpacker(&infoUnpacker);
-       OnFileReload();
-}
-
-void CMergeDoc::OnUpdateFileRecompareAsXML(CCmdUI *pCmdUI)
-{
-       pCmdUI->Enable(m_pInfoUnpacker->m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_BUILTIN_XML);
-}
-
 void CMergeDoc::OnFileRecompareAs(UINT nID)
 {
        if (!PromptAndSaveIfNeeded(true))
@@ -3509,16 +3475,26 @@ void CMergeDoc::OnFileRecompareAs(UINT nID)
        
        DWORD dwFlags[3] = { 0 };
        FileLocation fileloc[3];
+       String strDesc[3];
+       int nBuffers = m_nBuffers;
+       CDirDoc *pDirDoc = m_pDirDoc->GetMainView() ? m_pDirDoc : 
+               static_cast<CDirDoc*>(theApp.m_pDirTemplate->CreateNewDocument());
+       PackingInfo infoUnpacker(m_infoUnpacker.GetPluginPipeline());
+
        for (int pane = 0; pane < m_nBuffers; pane++)
        {
                fileloc[pane].setPath(m_filePaths[pane]);
                dwFlags[pane] |= FFILEOPEN_NOMRU | (m_ptBuf[pane]->GetReadOnly() ? FFILEOPEN_READONLY : 0);
+               strDesc[pane] = m_strDesc[pane];
        }
-       if (m_pEncodingErrorBar!=nullptr && m_pEncodingErrorBar->IsWindowVisible())
-               m_pView[0][0]->GetParentFrame()->ShowControlBar(m_pEncodingErrorBar.get(), FALSE, FALSE);
-       GetMainFrame()->ShowMergeDoc(nID, m_pDirDoc, m_nBuffers, fileloc, dwFlags, m_strDesc);
-       GetParentFrame()->ShowWindow(SW_RESTORE);
-       GetParentFrame()->DestroyWindow();
+       if (ID_UNPACKERS_FIRST <= nID && nID <= ID_UNPACKERS_LAST)
+       {
+               infoUnpacker.SetPluginPipeline(CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+               nID = m_ptBuf[0]->GetTableEditing() ? ID_MERGE_COMPARE_TABLE : ID_MERGE_COMPARE_TEXT;
+       }
+
+       if (GetMainFrame()->ShowMergeDoc(nID, pDirDoc, nBuffers, fileloc, dwFlags, strDesc, _T(""), &infoUnpacker))
+               CloseNow();
 }
 
 // Return file extension either from file name 
index 908949b..839f73a 100644 (file)
@@ -178,7 +178,7 @@ public:
        bool PartialListCopy(int srcPane, int dstPane, int nDiff, int firstLine, int lastLine = -1, bool bGroupWithPrevious = false, bool bUpdateView = true);
        bool ListCopy(int srcPane, int dstPane, int nDiff = -1, bool bGroupWithPrevious = false, bool bUpdateView = true);
        bool TrySaveAs(String& strPath, int &nLastErrorCode, String & sError,
-               int nBuffer, PackingInfo * pInfoTempUnpacker);
+               int nBuffer, PackingInfo& infoTempUnpacker);
        bool DoSave(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer);
        bool DoSaveAs(LPCTSTR szPath, bool &bSaveSuccess, int nBuffer);
        int RightLineInMovedBlock(int pane, int line);
@@ -186,9 +186,11 @@ public:
        void SetEditedAfterRescan(int nBuffer);
        bool IsEditedAfterRescan(int nBuffer = -1) const;
 
+       const PackingInfo* GetUnpacker() const override { return &m_infoUnpacker; }
        void SetUnpacker(const PackingInfo * infoUnpacker);
        void SetPrediffer(const PrediffingInfo * infoPrediffer);
        void GetPrediffer(PrediffingInfo * infoPrediffer);
+       const PrediffingInfo *GetPrediffer() const override;
        void AddMergeViews(CMergeEditView * pView[3]);
        void RemoveMergeViews(int nGroup);
        void SetLocationView(CLocationView *pLocationView) { m_pLocationView = pLocationView; }
@@ -197,6 +199,9 @@ public:
        void SetDirDoc(CDirDoc * pDirDoc) override;
        void DirDocClosing(CDirDoc * pDirDoc) override;
        bool CloseNow() override;
+       int GetFileCount() const override { return m_filePaths.GetSize(); }
+       String GetPath(int pane) const override { return m_filePaths[pane]; } 
+       bool GetReadOnly(int pane) const override { return m_ptBuf[pane]->m_bReadOnly; }
        void SwapFiles(int nFromIndex, int nToIndex);
 
        CMergeEditView * GetView(int group, int buffer) const { return m_pView[group][buffer]; }
@@ -292,7 +297,6 @@ public:
        virtual ~CMergeDoc();
        void SetDetectMovedBlocks(bool bDetectMovedBlocks);
        bool IsMixedEOL(int nBuffer) const;
-       bool OpenWithUnpackerDialog();
        bool GenerateReport(const String& sFileName) const override;
        void SetAutoMerged(bool bAutoMerged) { m_bAutoMerged = bAutoMerged; }
        bool GetAutoMerged() const { return m_bAutoMerged; };
@@ -334,7 +338,7 @@ protected:
        COleDateTime m_LastRescan; /**< Time of last rescan (for delaying) */ 
        CDiffWrapper m_diffWrapper;
        /// information about the file packer/unpacker
-       std::unique_ptr<PackingInfo> m_pInfoUnpacker;
+       PackingInfo m_infoUnpacker;
        String m_strDesc[3]; /**< Left/Middle/Right side description text */
        BUFFERTYPE m_nBufferType[3];
        bool m_bEditAfterRescan[3]; /**< Left/middle/right doc edited after rescanning */
@@ -369,24 +373,22 @@ protected:
        afx_msg void OnFileSaveAsMiddle();
        afx_msg void OnFileSaveAsRight();
        afx_msg void OnUpdateStatusNum(CCmdUI* pCmdUI);
-       afx_msg void OnUpdatePluginName(CCmdUI* pCmdUI);
        afx_msg void OnFileReload();
        afx_msg void OnFileEncoding();
        afx_msg void OnDiffContext(UINT nID);
        afx_msg void OnUpdateDiffContext(CCmdUI* pCmdUI);
        afx_msg void OnToolsGenerateReport();
        afx_msg void OnToolsGeneratePatch();
-       afx_msg void OnCtxtOpenWithUnpacker();
+       afx_msg void OnOpenWithUnpacker();
+       afx_msg void OnApplyPrediffer();
        afx_msg void OnBnClickedFileEncoding();
        afx_msg void OnBnClickedPlugin();
        afx_msg void OnBnClickedHexView();
        afx_msg void OnOK();
        afx_msg void OnFileRecompareAsText();
        afx_msg void OnFileRecompareAsTable();
-       afx_msg void OnFileRecompareAsXML();
        afx_msg void OnUpdateFileRecompareAsText(CCmdUI* pCmdUI);
        afx_msg void OnUpdateFileRecompareAsTable(CCmdUI* pCmdUI);
-       afx_msg void OnUpdateFileRecompareAsXML(CCmdUI* pCmdUI);
        afx_msg void OnFileRecompareAs(UINT nID);
        afx_msg void OnUpdateSwapContext(CCmdUI* pCmdUI);
        //}}AFX_MSG
index c34c854..183d3ab 100644 (file)
@@ -254,7 +254,11 @@ BOOL CMergeEditFrame::DestroyWindow()
        SavePosition();
        SaveActivePane();
        SaveWindowState();
-       return CMergeFrameCommon::DestroyWindow();
+       CFrameWnd* pParentFrame = GetParentFrame();
+       BOOL result = CMergeFrameCommon::DestroyWindow();
+       if (pParentFrame)
+               pParentFrame->OnUpdateFrameTitle(FALSE);
+       return result;
 }
 
 /**
@@ -409,15 +413,6 @@ void CMergeEditFrame::OnUpdateViewSplitVertically(CCmdUI* pCmdUI)
        pCmdUI->SetCheck((wndSplitter.GetColumnCount() != 1));
 }
 
-/// Document commanding us to close
-void CMergeEditFrame::CloseNow()
-{
-       SavePosition(); // Save settings before closing!
-       SaveActivePane();
-       MDIActivate();
-       MDIDestroy();
-}
-
 /**
  * @brief Update any resources necessary after a GUI language change
  */
index 85d955d..1a6b3bc 100644 (file)
@@ -33,7 +33,6 @@ public:
 // Operations
 public:
        void UpdateResources();
-       void CloseNow();
        IHeaderBar * GetHeaderInterface();
        CMergeDoc * GetMergeDoc() { return m_pMergeDoc; }
 
index f5e86e6..a12b545 100644 (file)
@@ -201,7 +201,7 @@ BEGIN_MESSAGE_MAP(CMergeEditView, CCrystalEditViewEx)
        ON_UPDATE_COMMAND_UI(ID_FILE_SHELLMENU, OnUpdateShellMenu)
        ON_COMMAND_RANGE(ID_SCRIPT_FIRST, ID_SCRIPT_LAST, OnScripts)
        ON_COMMAND(ID_NO_PREDIFFER, OnNoPrediffer)
-       ON_UPDATE_COMMAND_UI(ID_NO_PREDIFFER, OnUpdateNoPrediffer)
+       ON_UPDATE_COMMAND_UI(ID_NO_PREDIFFER, OnUpdatePrediffer)
        ON_COMMAND_RANGE(ID_PREDIFFERS_FIRST, ID_PREDIFFERS_LAST, OnPrediffer)
        ON_UPDATE_COMMAND_UI_RANGE(ID_PREDIFFERS_FIRST, ID_PREDIFFERS_LAST, OnUpdatePrediffer)
        ON_WM_VSCROLL ()
@@ -225,7 +225,6 @@ BEGIN_MESSAGE_MAP(CMergeEditView, CCrystalEditViewEx)
        ON_COMMAND(ID_SWAPPANES_SWAP12, OnViewSwapPanes12)
        ON_COMMAND(ID_SWAPPANES_SWAP23, OnViewSwapPanes23)
        ON_COMMAND(ID_SWAPPANES_SWAP13, OnViewSwapPanes13)
-       ON_UPDATE_COMMAND_UI(ID_NO_EDIT_SCRIPTS, OnUpdateNoEditScripts)
        ON_WM_SIZE()
        ON_WM_MOVE()
        ON_COMMAND(ID_HELP, OnHelp)
@@ -2894,40 +2893,6 @@ void CMergeEditView::OnUpdateStatusRO(CCmdUI* pCmdUI)
 }
 
 /**
- * @brief Create the dynamic submenu for scripts
- */
-HMENU CMergeEditView::createScriptsSubmenu(HMENU hMenu)
-{
-       // get scripts list
-       std::vector<String> functionNamesList = FileTransform::GetFreeFunctionsInScripts(L"EDITOR_SCRIPT");
-
-       // empty the menu
-       size_t i = GetMenuItemCount(hMenu);
-       while (i --)
-               DeleteMenu(hMenu, 0, MF_BYPOSITION);
-
-       if (functionNamesList.size() == 0)
-       {
-               // no script : create a <empty> entry
-               AppendMenu(hMenu, MF_STRING, ID_NO_EDIT_SCRIPTS, _("< Empty >").c_str());
-       }
-       else
-       {
-               // or fill in the submenu with the scripts names
-               int ID = ID_SCRIPT_FIRST;       // first ID in menu
-               for (i = 0 ; i < functionNamesList.size() ; i++, ID++)
-                       AppendMenu(hMenu, MF_STRING, ID, functionNamesList[i].c_str());
-
-               functionNamesList.clear();
-       }
-
-       if (!plugin::IsWindowsScriptThere())
-               AppendMenu(hMenu, MF_STRING, ID_NO_SCT_SCRIPTS, _("WSH not found - .sct scripts disabled").c_str());
-
-       return hMenu;
-}
-
-/**
  * @brief Create the dynamic submenu for prediffers
  *
  * @note The plugins are grouped in (suggested) and (not suggested)
@@ -2943,8 +2908,8 @@ HMENU CMergeEditView::createScriptsSubmenu(HMENU hMenu)
 HMENU CMergeEditView::createPrediffersSubmenu(HMENU hMenu)
 {
        // empty the menu
-       int i = GetMenuItemCount(hMenu);
-       while (i --)
+       int j = GetMenuItemCount(hMenu);
+       while (j --)
                DeleteMenu(hMenu, 0, MF_BYPOSITION);
 
        CMergeDoc *pd = GetDocument();
@@ -2952,83 +2917,43 @@ HMENU CMergeEditView::createPrediffersSubmenu(HMENU hMenu)
 
        // title
        AppendMenu(hMenu, MF_STRING, ID_NO_PREDIFFER, _("No prediffer (normal)").c_str());
+       
+       m_CurrentPredifferID = ID_NO_PREDIFFER;
+
+       if (!GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED))
+               return hMenu;
+
+       // compute the m_CurrentPredifferID (to set the radio button)
+       PrediffingInfo prediffer;
+       pd->GetPrediffer(&prediffer);
 
        // get the scriptlet files
-       PluginArray * piScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"FILE_PREDIFF");
-       PluginArray * piScriptArray2 = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"BUFFER_PREDIFF");
+       const auto& [ suggestedPlugins, allPlugins ]= FileTransform::CreatePluginMenuInfos(
+               pd->m_strBothFilenames, FileTransform::PredifferEventNames, ID_PREDIFFERS_FIRST);
 
        // build the menu : first part, suggested plugins
        // title
        AppendMenu(hMenu, MF_SEPARATOR, 0, nullptr);
        AppendMenu(hMenu, MF_STRING, ID_SUGGESTED_PLUGINS, _("Suggested plugins").c_str());
 
-       int ID = ID_PREDIFFERS_FIRST;   // first ID in menu
-       size_t iScript;
-       for (iScript = 0 ; iScript < piScriptArray->size() ; iScript++, ID ++)
-       {
-               const PluginInfoPtr & plugin = piScriptArray->at(iScript);
-               if (plugin->m_disabled || !plugin->TestAgainstRegList(pd->m_strBothFilenames))
-                       continue;
-
-               AppendMenu(hMenu, MF_STRING, ID, plugin->m_name.c_str());
-       }
-       for (iScript = 0 ; iScript < piScriptArray2->size() ; iScript++, ID ++)
-       {
-               const PluginInfoPtr & plugin = piScriptArray2->at(iScript);
-               if (plugin->m_disabled || !plugin->TestAgainstRegList(pd->m_strBothFilenames))
-                       continue;
-
-               AppendMenu(hMenu, MF_STRING, ID, plugin->m_name.c_str());
-       }
+       for (const auto& [caption, name, id, plugin ] : suggestedPlugins)
+               AppendMenu(hMenu, MF_STRING, id, caption.c_str());
 
        // build the menu : second part, others plugins
        // title
        AppendMenu(hMenu, MF_SEPARATOR, 0, nullptr);
        AppendMenu(hMenu, MF_STRING, ID_NOT_SUGGESTED_PLUGINS, _("Other plugins").c_str());
 
-       ID = ID_PREDIFFERS_FIRST;       // first ID in menu
-       for (iScript = 0 ; iScript < piScriptArray->size() ; iScript++, ID ++)
+       for (const auto& [processType, pluginAry] : allPlugins)
        {
-               const PluginInfoPtr & plugin = piScriptArray->at(iScript);
-               if (plugin->m_disabled || plugin->TestAgainstRegList(pd->m_strBothFilenames) != false)
-                       continue;
-
-               AppendMenu(hMenu, MF_STRING, ID, plugin->m_name.c_str());
-       }
-       for (iScript = 0 ; iScript < piScriptArray2->size() ; iScript++, ID ++)
-       {
-               const PluginInfoPtr & plugin = piScriptArray2->at(iScript);
-               if (plugin->m_disabled || plugin->TestAgainstRegList(pd->m_strBothFilenames) != false)
-                       continue;
-
-               AppendMenu(hMenu, MF_STRING, ID, plugin->m_name.c_str());
-       }
-
-       // compute the m_CurrentPredifferID (to set the radio button)
-       PrediffingInfo prediffer;
-       pd->GetPrediffer(&prediffer);
-
-       if (prediffer.m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
-               m_CurrentPredifferID = 0;
-       else if (prediffer.m_PluginName.empty())
-               m_CurrentPredifferID = ID_NO_PREDIFFER;
-       else
-       {
-               ID = ID_PREDIFFERS_FIRST;       // first ID in menu
-               for (iScript = 0 ; iScript < piScriptArray->size() ; iScript++, ID ++)
-               {
-                       const PluginInfoPtr & plugin = piScriptArray->at(iScript);
-                       if (prediffer.m_PluginName == plugin->m_name)
-                               m_CurrentPredifferID = ID;
-
-               }
-               for (iScript = 0 ; iScript < piScriptArray2->size() ; iScript++, ID ++)
+               for (const auto& [caption, name, id, plugin] : pluginAry)
                {
-                       const PluginInfoPtr & plugin = piScriptArray2->at(iScript);
-                       if (prediffer.m_PluginName == plugin->m_name)
-                               m_CurrentPredifferID = ID;
+                       if (!name.empty())
+                       {
+                               AppendMenu(hMenu, MF_STRING, id, caption.c_str());
+                               if (prediffer.GetPluginPipeline() == plugin->m_name)
+                                       m_CurrentPredifferID = id;
+                       }
                }
        }
 
@@ -3506,13 +3431,15 @@ void CMergeEditView::RefreshOptions()
        Options::DiffColors::Load(GetOptionsMgr(), m_cachedColors);
 }
 
-void CMergeEditView::OnScripts(UINT nID )
+void CMergeEditView::OnScripts(UINT nID)
 {
        // text is CHAR if compiled without UNICODE, WCHAR with UNICODE
-       String text = GetSelectedText();
+       CString ctext = GetSelectedText();
+       String text{ ctext, static_cast<unsigned>(ctext.GetLength()) };
 
        // transform the text with a script/ActiveX function, event=EDITOR_SCRIPT
-       bool bChanged = FileTransform::Interactive(text, L"EDITOR_SCRIPT", nID - ID_SCRIPT_FIRST);
+       bool bChanged = FileTransform::Interactive(text, {}, L"EDITOR_SCRIPT", nID - ID_SCRIPT_FIRST,
+               { GetDocument()->m_filePaths[m_nThisPane] });
        if (bChanged)
                // now replace the text
                ReplaceSelection(text.c_str(), text.length(), 0);
@@ -3521,19 +3448,6 @@ void CMergeEditView::OnScripts(UINT nID )
 /**
  * @brief Called when an editor script item is updated
  */
-void CMergeEditView::OnUpdateNoEditScripts(CCmdUI* pCmdUI)
-{
-       // append the scripts submenu
-       HMENU scriptsSubmenu = pCmdUI->m_pSubMenu ? pCmdUI->m_pSubMenu->m_hMenu : nullptr;
-       if (scriptsSubmenu != nullptr)
-               createScriptsSubmenu(scriptsSubmenu);
-
-       pCmdUI->Enable(true);
-}
-
-/**
- * @brief Called when an editor script item is updated
- */
 void CMergeEditView::OnUpdatePrediffer(CCmdUI* pCmdUI)
 {
        pCmdUI->Enable(true);
@@ -3543,29 +3457,19 @@ void CMergeEditView::OnUpdatePrediffer(CCmdUI* pCmdUI)
        PrediffingInfo prediffer;
        pd->GetPrediffer(&prediffer);
 
-       if (prediffer.m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
+       if (prediffer.GetPluginPipeline().find(_T("<Automatic>")) != String::npos)
        {
                pCmdUI->SetRadio(false);
                return;
        }
 
        // Detect when CDiffWrapper::RunFileDiff has canceled a buggy prediffer
-       if (prediffer.m_PluginName.empty())
+       if (prediffer.GetPluginPipeline().empty())
                m_CurrentPredifferID = ID_NO_PREDIFFER;
 
        pCmdUI->SetRadio(pCmdUI->m_nID == static_cast<UINT>(m_CurrentPredifferID));
 }
 
-/**
- * @brief Update "Prediffer" menuitem
- */
-void CMergeEditView::OnUpdateNoPrediffer(CCmdUI* pCmdUI)
-{
-       // recreate the sub menu (to fill the "selected prediffers")
-       GetMainFrame()->UpdatePrediffersMenu();
-       pCmdUI->Enable();
-}
-
 void CMergeEditView::OnNoPrediffer()
 {
        OnPrediffer(ID_NO_PREDIFFER);
@@ -3580,6 +3484,7 @@ void CMergeEditView::OnPrediffer(UINT nID )
 
        SetPredifferByMenu(nID);
        pd->FlushAndRescan(true);
+       pd->SetTitle(nullptr);
 }
 
 /**
@@ -3587,97 +3492,31 @@ void CMergeEditView::OnPrediffer(UINT nID )
  * Prediffer choises include ID_PREDIFF_MANUAL, ID_PREDIFF_AUTO,
  * ID_NO_PREDIFFER, & specific prediffers.
  */
-void CMergeEditView::SetPredifferByMenu(UINT nID )
+void CMergeEditView::SetPredifferByMenu(UINT nID)
 {
        CMergeDoc *pd = GetDocument();
        ASSERT(pd != nullptr);
 
+       // update data for the radio button
+       m_CurrentPredifferID = nID;
+
        if (nID == ID_NO_PREDIFFER)
        {
-               m_CurrentPredifferID = nID;
                // All flags are set correctly during the construction
-               PrediffingInfo *infoPrediffer = new PrediffingInfo;
-               infoPrediffer->m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
-               infoPrediffer->m_PluginName.clear();
-               pd->SetPrediffer(infoPrediffer);
-               pd->FlushAndRescan(true);
+               PrediffingInfo infoPrediffer(false);
+               pd->SetPrediffer(&infoPrediffer);
                return;
        }
 
-       // get the scriptlet files
-       PluginArray * piScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"FILE_PREDIFF");
-       PluginArray * piScriptArray2 = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"BUFFER_PREDIFF");
+       String pluginName = CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::PredifferEventNames, ID_PREDIFFERS_FIRST);
 
        // build a PrediffingInfo structure fom the ID
-       PrediffingInfo prediffer;
-       prediffer.m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
-
-       size_t pluginNumber = nID - ID_PREDIFFERS_FIRST;
-       if (pluginNumber < piScriptArray->size())
-       {
-               const PluginInfoPtr & plugin = piScriptArray->at(pluginNumber);
-               prediffer.m_PluginName = plugin->m_name;
-       }
-       else
-       {
-               pluginNumber -= piScriptArray->size();
-               if (pluginNumber >= piScriptArray2->size())
-                       return;
-               const PluginInfoPtr & plugin = piScriptArray2->at(pluginNumber);
-               prediffer.m_PluginName = plugin->m_name;
-       }
-
-       // update data for the radio button
-       m_CurrentPredifferID = nID;
-
+       PrediffingInfo prediffer(pluginName);
+       
        // update the prediffer and rescan
        pd->SetPrediffer(&prediffer);
 }
 
-/**
- * @brief Look through available prediffers, and return ID of requested one, if found
- */
-int CMergeEditView::FindPrediffer(LPCTSTR prediffer) const
-{
-       size_t i;
-       int ID = ID_PREDIFFERS_FIRST;
-
-       // Search file prediffers
-       PluginArray * piScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"FILE_PREDIFF");
-       for (i=0; i<piScriptArray->size(); ++i, ++ID)
-       {
-               const PluginInfoPtr & plugin = piScriptArray->at(i);
-               if (plugin->m_name == prediffer)
-                       return ID;
-       }
-
-       // Search buffer prediffers
-       PluginArray * piScriptArray2 = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"BUFFER_PREDIFF");
-       for (i=0; i<piScriptArray2->size(); ++i, ++ID)
-       {
-               const PluginInfoPtr & plugin = piScriptArray2->at(i);
-               if (plugin->m_name == prediffer)
-                       return ID;
-       }
-       return -1;
-}
-
-
-/**
- * @brief Look through available prediffers, and return ID of requested one, if found
- */
-bool CMergeEditView::SetPredifferByName(const CString & prediffer)
-{
-       int id = FindPrediffer(prediffer);
-       if (id<0) return false;
-       SetPredifferByMenu(id);
-       return true;
-}
-
 /** 
  * @brief Goto given line.
  * @param [in] nLine Destination linenumber
@@ -4752,4 +4591,3 @@ void CMergeEditView::OnStatusBarDblClick(NMHDR* pNMHDR, LRESULT* pResult)
                break;
        }
 }
-
index 1a0904d..785ff2f 100644 (file)
@@ -143,7 +143,6 @@ public:
        virtual int GetEmptySubLines( int nLineIndex ) override;
        virtual void InvalidateSubLineIndexCache( int nLineIndex ) override;
        void RepaintLocationPane();
-       bool SetPredifferByName(const CString & prediffer);
        void SetPredifferByMenu(UINT nID);
        void DocumentsLoaded();
        void UpdateLocationViewPosition(int nTopLine = -1, int nBottomLine = -1);
@@ -158,7 +157,6 @@ public:
        virtual void OnDisplayDiff(int nDiff=0);
 
        // to customize the mergeview menu
-       static HMENU createScriptsSubmenu(HMENU hMenu);
        HMENU createPrediffersSubmenu(HMENU hMenu);
 
        bool IsInitialized() const;
@@ -193,7 +191,6 @@ protected:
        virtual void OnUpdateSibling (CCrystalTextView * pUpdateSource, bool bHorz) override;
        virtual void OnUpdateCaret() override;
        bool MergeModeKeyDown(MSG* pMsg);
-       int FindPrediffer(LPCTSTR prediffer) const;
        bool IsDiffVisible(const DIFFRANGE& diff, int nLinesBelow = 0);
        void OnNext3wayDiff(int type);
        void OnUpdateNext3wayDiff(CCmdUI* pCmdUI, int type);
@@ -318,7 +315,6 @@ protected:
        afx_msg void OnShellMenu();
        afx_msg void OnUpdateShellMenu(CCmdUI* pCmdUI);
        afx_msg void OnScripts(UINT nID );
-       afx_msg void OnUpdateNoPrediffer(CCmdUI* pCmdUI);
        afx_msg void OnUpdatePrediffer(CCmdUI* pCmdUI);
        afx_msg void OnNoPrediffer();
        afx_msg void OnPrediffer(UINT nID );
@@ -343,7 +339,6 @@ protected:
        afx_msg void OnViewSwapPanes12();
        afx_msg void OnViewSwapPanes23();
        afx_msg void OnViewSwapPanes13();
-       afx_msg void OnUpdateNoEditScripts(CCmdUI* pCmdUI);
        afx_msg void OnSize(UINT nType, int cx, int cy);
        afx_msg void OnHelp();
        afx_msg void OnViewMargin();
index b8e8baa..999f0aa 100644 (file)
@@ -10,6 +10,7 @@
 #include "OptionsMgr.h"\r
 #include "paths.h"\r
 #include "Merge.h"\r
+#include "FileTransform.h"\r
 #include <../src/mfc/afximpl.h>\r
 \r
 IMPLEMENT_DYNCREATE(CMergeFrameCommon, CMDIChildWnd)\r
@@ -145,7 +146,8 @@ void CMergeFrameCommon::ShowIdenticalMessage(const PathContext& paths, bool bIde
        }\r
 }\r
 \r
-String CMergeFrameCommon::GetTitleString(const PathContext& paths, const String desc[])\r
+String CMergeFrameCommon::GetTitleString(const PathContext& paths, const String desc[],\r
+       PackingInfo *pInfoUnpacker, PrediffingInfo *pInfoPrediffer)\r
 {\r
        const int nBuffers = paths.GetSize();\r
        String sFileName[3];\r
@@ -156,7 +158,12 @@ String CMergeFrameCommon::GetTitleString(const PathContext& paths, const String
                sTitle = sFileName[0] + strutils::format(_T(" x %d"), nBuffers);\r
        else\r
                sTitle = strutils::join(&sFileName[0], &sFileName[0] + nBuffers, _T(" - "));\r
-       return sTitle;\r
+       String plugin;\r
+       if (pInfoUnpacker && !pInfoUnpacker->GetPluginPipeline().empty())\r
+               plugin += _T("U");\r
+       if (pInfoPrediffer && !pInfoPrediffer->GetPluginPipeline().empty())\r
+               plugin += _T("P");\r
+       return sTitle + (plugin.empty() ? _T("") : (_T(" (") + plugin + _T(")")));\r
 }\r
 \r
 void CMergeFrameCommon::OnGetMinMaxInfo(MINMAXINFO* lpMMI)\r
index 28825ae..e2f00fb 100644 (file)
@@ -9,6 +9,9 @@
 #include "UnicodeString.h"\r
 #include "PathContext.h"\r
 \r
+class PrediffingInfo;\r
+class PackingInfo;\r
+\r
 class CMergeFrameCommon: public CMDIChildWnd\r
 {\r
        DECLARE_DYNCREATE(CMergeFrameCommon)\r
@@ -18,7 +21,7 @@ public:
        void ActivateFrame(int nCmdShow);\r
        void SetLastCompareResult(int nResult);\r
        static void ShowIdenticalMessage(const PathContext& paths, bool bIdenticalAll, std::function<int (LPCTSTR, UINT, UINT)> funcMessageBox);\r
-       static String GetTitleString(const PathContext& paths, const String desc[]);\r
+       static String GetTitleString(const PathContext& paths, const String desc[], PackingInfo *pInfoUnpacker, PrediffingInfo *pInfoPrediffer);\r
        void SaveWindowState();\r
        void SetSharedMenu(HMENU hMenu) { m_hMenuShared = hMenu; }\r
        void RemoveBarBorder();\r
index 7877497..fc48002 100644 (file)
@@ -15,8 +15,9 @@ IMPLEMENT_DYNCREATE(COpenDoc, CDocument)
 COpenDoc::COpenDoc() :
        m_bRecurse(false)
 ,      m_dwFlags()
-,      m_infoHandler{}
 {
+       PackingInfo infoHandler;
+       m_strUnpackerPipeline = GetOptionsMgr()->GetBool(OPT_PLUGINS_ENABLED) ? infoHandler.GetPluginPipeline() : _T("");
 }
 
 BOOL COpenDoc::OnNewDocument()
index 2a48b05..f8ad00c 100644 (file)
@@ -22,8 +22,7 @@ public:
        PathContext m_files;
        bool    m_bRecurse;
        String  m_strExt;
-       String  m_strUnpacker;
-       PackingInfo m_infoHandler;
+       String  m_strUnpackerPipeline;
 
 protected:
        virtual BOOL OnNewDocument();
index 7d74cdc..6e6c700 100644 (file)
@@ -19,7 +19,7 @@
 #include "OpenDoc.h"
 #include "ProjectFile.h"
 #include "paths.h"
-#include "SelectUnpackerDlg.h"
+#include "SelectPluginDlg.h"
 #include "OptionsDef.h"
 #include "MainFrm.h"
 #include "OptionsMgr.h"
@@ -90,6 +90,8 @@ BEGIN_MESSAGE_MAP(COpenView, CFormView)
        ON_COMMAND(ID_EDIT_SELECT_ALL, (OnEditAction<EM_SETSEL, 0, -1>))
        ON_COMMAND_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnCompare)
        ON_UPDATE_COMMAND_UI_RANGE(ID_MERGE_COMPARE_TEXT, ID_MERGE_COMPARE_IMAGE, OnUpdateCompare)
+       ON_COMMAND_RANGE(ID_UNPACKERS_FIRST, ID_UNPACKERS_LAST, OnCompare)
+       ON_COMMAND_RANGE(ID_OPEN_WITH_UNPACKER, ID_OPEN_WITH_UNPACKER, OnCompare)
        ON_MESSAGE(WM_USER + 1, OnUpdateStatus)
        ON_WM_PAINT()
        ON_WM_LBUTTONUP()
@@ -133,6 +135,7 @@ void COpenView::DoDataExchange(CDataExchange* pDX)
        DDX_Control(pDX, IDC_PATH0_COMBO, m_ctlPath[0]);
        DDX_Control(pDX, IDC_PATH1_COMBO, m_ctlPath[1]);
        DDX_Control(pDX, IDC_PATH2_COMBO, m_ctlPath[2]);
+       DDX_Control(pDX, IDC_UNPACKER_COMBO, m_ctlUnpackerPipeline);
        DDX_CBStringExact(pDX, IDC_PATH0_COMBO, m_strPath[0]);
        DDX_CBStringExact(pDX, IDC_PATH1_COMBO, m_strPath[1]);
        DDX_CBStringExact(pDX, IDC_PATH2_COMBO, m_strPath[2]);
@@ -141,7 +144,7 @@ void COpenView::DoDataExchange(CDataExchange* pDX)
        DDX_Check(pDX, IDC_PATH2_READONLY, m_bReadOnly[2]);
        DDX_Check(pDX, IDC_RECURS_CHECK, m_bRecurse);
        DDX_CBStringExact(pDX, IDC_EXT_COMBO, m_strExt);
-       DDX_Text(pDX, IDC_UNPACKER_EDIT, m_strUnpacker);
+       DDX_CBStringExact(pDX, IDC_UNPACKER_COMBO, m_strUnpackerPipeline);
        //}}AFX_DATA_MAP
 }
 
@@ -209,8 +212,7 @@ void COpenView::OnInitialUpdate()
        m_files = pDoc->m_files;
        m_bRecurse = pDoc->m_bRecurse;
        m_strExt = pDoc->m_strExt;
-       m_strUnpacker = pDoc->m_strUnpacker;
-       m_infoHandler = pDoc->m_infoHandler;
+       m_strUnpackerPipeline = pDoc->m_strUnpackerPipeline;
        m_dwFlags[0] = pDoc->m_dwFlags[0];
        m_dwFlags[1] = pDoc->m_dwFlags[1];
        m_dwFlags[2] = pDoc->m_dwFlags[2];
@@ -218,6 +220,7 @@ void COpenView::OnInitialUpdate()
        m_ctlPath[0].SetFileControlStates();
        m_ctlPath[1].SetFileControlStates(true);
        m_ctlPath[2].SetFileControlStates(true);
+       m_ctlUnpackerPipeline.SetFileControlStates(true);
 
        for (int file = 0; file < m_files.GetSize(); file++)
        {
@@ -231,6 +234,8 @@ void COpenView::OnInitialUpdate()
        m_ctlPath[2].AttachSystemImageList();
        LoadComboboxStates();
 
+       m_ctlUnpackerPipeline.SetWindowText(m_strUnpackerPipeline.c_str());
+
        bool bDoUpdateData = true;
        for (auto& strPath: m_strPath)
        {
@@ -263,7 +268,7 @@ void COpenView::OnInitialUpdate()
        if (!GetOptionsMgr()->GetBool(OPT_VERIFY_OPEN_PATHS))
        {
                EnableDlgItem(IDOK, true);
-               EnableDlgItem(IDC_UNPACKER_EDIT, true);
+               EnableDlgItem(IDC_UNPACKER_COMBO, true);
                EnableDlgItem(IDC_SELECT_UNPACKER, true);
        }
 
@@ -277,10 +282,8 @@ void COpenView::OnInitialUpdate()
        if (!bOverwriteRecursive)
                m_bRecurse = GetOptionsMgr()->GetBool(OPT_CMP_INCLUDE_SUBDIRS);
 
-       m_strUnpacker = m_infoHandler.m_PluginName;
        UpdateData(FALSE);
        SetStatus(IDS_OPEN_FILESDIRS);
-       SetUnpackerStatus(IDS_USERCHOICE_NONE); 
 
        m_pDropHandler = new DropHandler(std::bind(&COpenView::OnDropFiles, this, std::placeholders::_1));
        RegisterDragDrop(m_hWnd, m_pDropHandler);
@@ -563,9 +566,16 @@ void COpenView::OnCompare(UINT nID)
        if (nFiles == 1)
        {
                if (strutils::compare_nocase(ext, ProjectFile::PROJECTFILE_EXT) == 0)
-                       LoadProjectFile(m_strPath[0]);
-               else
-                       GetMainFrame()->DoSelfCompare(nID, m_strPath[0], nullptr);
+               {
+                       theApp.LoadAndOpenProjectFile(m_strPath[0]);
+               }
+               else if (!paths::IsDirectory(m_strPath[0]))
+               {
+                       PackingInfo tmpPackingInfo(m_strUnpackerPipeline);
+                       if (ID_UNPACKERS_FIRST <= nID && nID <= ID_UNPACKERS_LAST)
+                               tmpPackingInfo.SetPluginPipeline(CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+                       GetMainFrame()->DoSelfCompare(nID, m_strPath[0], nullptr, &tmpPackingInfo);
+               }
                return;
        }
 
@@ -632,8 +642,7 @@ void COpenView::OnCompare(UINT nID)
        pDoc->m_files = m_files;
        pDoc->m_bRecurse = m_bRecurse;
        pDoc->m_strExt = m_strExt;
-       pDoc->m_strUnpacker = m_strUnpacker;
-       pDoc->m_infoHandler = m_infoHandler;
+       pDoc->m_strUnpackerPipeline = m_strUnpackerPipeline;
        pDoc->m_dwFlags[0] = m_dwFlags[0];
        pDoc->m_dwFlags[1] = m_dwFlags[1];
        pDoc->m_dwFlags[2] = m_dwFlags[2];
@@ -641,23 +650,44 @@ void COpenView::OnCompare(UINT nID)
        if (GetOptionsMgr()->GetBool(OPT_CLOSE_WITH_OK))
                GetParentFrame()->PostMessage(WM_CLOSE);
 
+       // Copy the values in pDoc as it will be invalid when COpenFrame is closed. 
+       PackingInfo tmpPackingInfo(pDoc->m_strUnpackerPipeline);
        PathContext tmpPathContext(pDoc->m_files);
+       std::array<DWORD, 3> dwFlags = pDoc->m_dwFlags;
+       bool recurse = pDoc->m_bRecurse;
        if (nID == IDOK)
        {
-               PackingInfo tmpPackingInfo(pDoc->m_infoHandler);
                GetMainFrame()->DoFileOpen(
-                       &tmpPathContext, std::array<DWORD, 3>(pDoc->m_dwFlags).data(),
-                       nullptr, _T(""), pDoc->m_bRecurse, nullptr, _T(""), &tmpPackingInfo);
+                       &tmpPathContext, dwFlags.data(),
+                       nullptr, _T(""), recurse, nullptr, &tmpPackingInfo, nullptr);
+       }
+       else if (ID_UNPACKERS_FIRST <= nID && nID <= ID_UNPACKERS_LAST)
+       {
+               tmpPackingInfo.SetPluginPipeline(CMainFrame::GetPluginPipelineByMenuId(nID, FileTransform::UnpackerEventNames, ID_UNPACKERS_FIRST));
+               GetMainFrame()->DoFileOpen(
+                       &tmpPathContext, dwFlags.data(),
+                       nullptr, _T(""), recurse, nullptr, &tmpPackingInfo, nullptr);
+       }
+       else if (nID == ID_OPEN_WITH_UNPACKER)
+       {
+               CSelectPluginDlg dlg(pDoc->m_strUnpackerPipeline, tmpPathContext[0], true, false, this);
+               if (dlg.DoModal() == IDOK)
+               {
+                       tmpPackingInfo.SetPluginPipeline(dlg.GetPluginPipeline());
+                       GetMainFrame()->DoFileOpen(
+                               &tmpPathContext, dwFlags.data(),
+                               nullptr, _T(""), recurse, nullptr, &tmpPackingInfo, nullptr);
+               }
        }
        else
        {
-               GetMainFrame()->DoFileOpen(nID, &m_files, pDoc->m_dwFlags.data());
+               GetMainFrame()->DoFileOpen(nID, &tmpPathContext, dwFlags.data(), nullptr, _T(""), &tmpPackingInfo);
        }
 }
 
 void COpenView::OnUpdateCompare(CCmdUI *pCmdUI)
 {
-       bool bFile = GetDlgItem(IDC_UNPACKER_EDIT)->IsWindowEnabled();
+       bool bFile = GetDlgItem(IDC_UNPACKER_COMBO)->IsWindowEnabled();
        if (!bFile)
        {
                UpdateData(true);
@@ -732,6 +762,8 @@ void COpenView::OnLoadProject()
                m_bReadOnly[2] = projItem.GetRightReadOnly();
        }
        m_strExt = projItem.GetFilter();
+       if (projItem.HasUnpacker())
+               m_strUnpackerPipeline = projItem.GetUnpacker();
 
        UpdateData(FALSE);
        LangMessageBox(IDS_PROJFILE_LOAD_SUCCESS, MB_ICONINFORMATION);
@@ -779,6 +811,8 @@ void COpenView::OnSaveProject()
                projItem.SetFilter(strExt);
        }
        projItem.SetSubfolders(m_bRecurse);
+       if (!m_strUnpackerPipeline.empty())
+               projItem.SetUnpacker(m_strUnpackerPipeline);
        project.Items().push_back(projItem);
 
        if (!theApp.SaveProjectFile(fileName, project))
@@ -797,7 +831,16 @@ void COpenView::DropDown(NMHDR* pNMHDR, LRESULT* pResult, UINT nID, UINT nPopupI
        CMenu* pPopup = menu.GetSubMenu(0);
        if (pPopup != nullptr)
        {
-               pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 
+               if (GetDlgItem(IDC_UNPACKER_COMBO)->IsWindowEnabled())
+               {
+                       UpdateData(TRUE);
+                       String tmpPath[3];
+                       for (int i = 0; i < 3; i++)
+                               tmpPath[i] = m_strPath[i].empty() ? _T("|.|") : m_strPath[i];
+                       String filteredFilenames = strutils::join(std::begin(tmpPath), std::end(tmpPath), _T("|"));
+                       CMainFrame::AppendPluginMenus(pPopup, filteredFilenames, FileTransform::UnpackerEventNames, true, ID_UNPACKERS_FIRST);
+               }
+               pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
                        rcButton.left, rcButton.bottom, GetMainFrame());
        }
        *pResult = 0;
@@ -841,6 +884,7 @@ void COpenView::LoadComboboxStates()
        m_ctlPath[1].LoadState(_T("Files\\Right"));
        m_ctlPath[2].LoadState(_T("Files\\Option"));
        m_ctlExt.LoadState(_T("Files\\Ext"));
+       m_ctlUnpackerPipeline.LoadState(_T("Files\\Unpacker"));
 }
 
 /** 
@@ -852,6 +896,7 @@ void COpenView::SaveComboboxStates()
        m_ctlPath[1].SaveState(_T("Files\\Right"));
        m_ctlPath[2].SaveState(_T("Files\\Option"));
        m_ctlExt.SaveState(_T("Files\\Ext"));
+       m_ctlUnpackerPipeline.SaveState(_T("Files\\Unpacker"));
 }
 
 struct UpdateButtonStatesThreadParams
@@ -975,8 +1020,6 @@ static UINT UpdateButtonStatesThread(LPVOID lpParam)
 void COpenView::UpdateResources()
 {
        theApp.m_pLangDlg->RetranslateDialog(m_hWnd, MAKEINTRESOURCE(IDD_OPEN));
-       if (m_strUnpacker != m_infoHandler.m_PluginName)
-               m_strUnpacker = theApp.LoadString(IDS_OPEN_UNPACKERDISABLED);
 }
 
 /** 
@@ -1122,16 +1165,10 @@ void COpenView::OnSelectUnpacker()
                return;
 
        // let the user select a handler
-       CSelectUnpackerDlg dlg(m_files[0], this);
-       PackingInfo infoUnpacker(PLUGIN_MODE::PLUGIN_AUTO);
-       dlg.SetInitialInfoHandler(&infoUnpacker);
-
+       CSelectPluginDlg dlg(m_strUnpackerPipeline, m_files[0], true, false, this);
        if (dlg.DoModal() == IDOK)
        {
-               m_infoHandler = dlg.GetInfoHandler();
-
-               m_strUnpacker = m_infoHandler.m_PluginName;
-
+               m_strUnpackerPipeline = dlg.GetPluginPipeline();
                UpdateData(FALSE);
        }
 }
@@ -1146,7 +1183,7 @@ LRESULT COpenView::OnUpdateStatus(WPARAM wParam, LPARAM lParam)
        EnableDlgItem(IDOK, bIsaFolderCompare || bIsaFileCompare || bProject);
 
        EnableDlgItem(IDC_FILES_DIRS_GROUP4, bIsaFileCompare);
-       EnableDlgItem(IDC_UNPACKER_EDIT, bIsaFileCompare);
+       EnableDlgItem(IDC_UNPACKER_COMBO, bIsaFileCompare);
        EnableDlgItem(IDC_SELECT_UNPACKER, bIsaFileCompare);
 
        EnableDlgItem(IDC_FILES_DIRS_GROUP3,  bIsaFolderCompare);
@@ -1182,18 +1219,6 @@ void COpenView::SetStatus(UINT msgID)
        SetDlgItemText(IDC_OPEN_STATUS, msg);
 }
 
-/**
- * @brief Set the plugin edit box text.
- * Plugin edit box is at the same time a plugin status view. This function
- * sets the status text.
- * @param [in] msgID Resource ID of status text to set.
- */
-void COpenView::SetUnpackerStatus(UINT msgID)
-{
-       String msg = (msgID == 0 ? m_strUnpacker : theApp.LoadString(msgID));
-       SetDlgItemText(IDC_UNPACKER_EDIT, msg);
-}
-
 /** 
  * @brief Called when "Select..." button for filters is selected.
  */
@@ -1242,51 +1267,6 @@ void COpenView::OnDropDownOptions(NMHDR *pNMHDR, LRESULT *pResult)
 }
 
 /** 
- * @brief Read paths and filter from project file.
- * Reads the given project file. After the file is read, found paths and
- * filter is updated to dialog GUI. Other possible settings found in the
- * project file are kept in memory and used later when loading paths
- * selected.
- * @param [in] path Path to the project file.
- * @return `true` if the project file was successfully loaded, `false` otherwise.
- */
-bool COpenView::LoadProjectFile(const String &path)
-{
-       String filterPrefix = _("[F] ");
-       ProjectFile prj;
-
-       if (!theApp.LoadProjectFile(path, prj))
-               return false;
-       if (prj.Items().size() == 0)
-               return false;
-       bool recurse;
-       ProjectFileItem& projItem = *prj.Items().begin();
-       projItem.GetPaths(m_files, recurse);
-       m_bRecurse = recurse;
-       m_dwFlags[0] &= ~FFILEOPEN_READONLY;
-       m_dwFlags[0] |= projItem.GetLeftReadOnly() ?    FFILEOPEN_READONLY : 0;
-       if (m_files.GetSize() < 3)
-       {
-               m_dwFlags[1] &= ~FFILEOPEN_READONLY;
-               m_dwFlags[1] |= projItem.GetRightReadOnly() ? FFILEOPEN_READONLY : 0;
-       }
-       else
-       {
-               m_dwFlags[1] &= ~FFILEOPEN_READONLY;
-               m_dwFlags[1] |= projItem.GetMiddleReadOnly() ? FFILEOPEN_READONLY : 0;
-               m_dwFlags[2] &= ~FFILEOPEN_READONLY;
-               m_dwFlags[2] |= projItem.GetRightReadOnly() ? FFILEOPEN_READONLY : 0;
-       }
-       if (projItem.HasFilter())
-       {
-               m_strExt = strutils::trim_ws(projItem.GetFilter());
-               if (m_strExt[0] != '*')
-                       m_strExt.insert(0, filterPrefix);
-       }
-       return true;
-}
-
-/** 
  * @brief Removes whitespaces from left and right paths
  * @note Assumes UpdateData(TRUE) is called before this function.
  */
index 24ace17..a8c4be5 100644 (file)
@@ -46,18 +46,18 @@ public:
        enum { IDD = IDD_OPEN };
        CSuperComboBox  m_ctlExt;
        CSuperComboBox  m_ctlPath[3];
+       CSuperComboBox  m_ctlUnpackerPipeline;
        String m_strPath[3];
        bool m_bReadOnly[3];
        PathContext m_files;
        bool    m_bRecurse;
        String  m_strExt;
-       String  m_strUnpacker;
+       String  m_strUnpackerPipeline;
        //}}AFX_DATA
 
 // other public data
        /// unpacker info
        std::array<DWORD, 3> m_dwFlags;
-       PackingInfo m_infoHandler;
 
 // Attributes
 public:
@@ -95,8 +95,6 @@ public:
 
 protected:
        void SetStatus(UINT msgID);
-       void SetUnpackerStatus(UINT msgID);
-       bool LoadProjectFile(const String &path);
        void TerminateThreadIfRunning();
        void TrimPaths();
        void LoadComboboxStates();
index 272a556..3280ffc 100644 (file)
@@ -270,8 +270,7 @@ extern const String OPT_PATCHCREATOR_INCLUDE_CMD_LINE OP("PatchCreator/IncludeCm
 
 // Plugins
 extern const String OPT_PLUGINS_ENABLED OP("Settings/PluginsEnabled");
-extern const String OPT_PLUGINS_DISABLED_LIST OP("Settings/PluginsDisabledList");
-extern const String OPT_PLUGINS_CUSTOM_FILTERS_LIST OP("Settings/PluginsCustomFiltersList");
+extern const String OPT_PLUGINS_CUSTOM_SETTINGS_LIST OP("Settings/PluginsCustomSettingsList");
 extern const String OPT_PLUGINS_UNPACKER_MODE OP("Settings/UnpackerMode");
 extern const String OPT_PLUGINS_PREDIFFER_MODE OP("Settings/PredifferMode");
 extern const String OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION OP("Plugins/UnpackDontCheckExtension");
index 5c28f66..a695502 100644 (file)
@@ -199,11 +199,10 @@ void Init(COptionsMgr *pOptions)
        pOptions->InitOption(OPT_ARCHIVE_FILTER_INDEX, 1);
 
        pOptions->InitOption(OPT_PLUGINS_ENABLED, true);
-       pOptions->InitOption(OPT_PLUGINS_DISABLED_LIST, _T(""));
-       pOptions->InitOption(OPT_PLUGINS_CUSTOM_FILTERS_LIST, _T(""));
-       pOptions->InitOption(OPT_PLUGINS_UNPACKER_MODE, static_cast<int>(PLUGIN_MODE::PLUGIN_MANUAL));
-       pOptions->InitOption(OPT_PLUGINS_PREDIFFER_MODE, static_cast<int>(PLUGIN_MODE::PLUGIN_MANUAL));
-       pOptions->InitOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, false);
+       pOptions->InitOption(OPT_PLUGINS_CUSTOM_SETTINGS_LIST, _T(""));
+       pOptions->InitOption(OPT_PLUGINS_UNPACKER_MODE, false);
+       pOptions->InitOption(OPT_PLUGINS_PREDIFFER_MODE, false);
+       pOptions->InitOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, true);
 
        pOptions->InitOption(OPT_PATCHCREATOR_PATCH_STYLE, 0);
        pOptions->InitOption(OPT_PATCHCREATOR_CONTEXT_LINES, 0);
index d89e39e..76f181f 100644 (file)
@@ -39,33 +39,24 @@ void PluginManager::FetchPluginInfos(const String& filteredFilenames,
        *infoPrediffer = &fi->m_infoPrediffer;
 }
 
-/**
- * @brief Store specified prediff choice for specified comparison
- */
-void PluginManager::SetPrediffSetting(const String& filteredFilenames, PLUGIN_MODE newsetting)
+void PluginManager::SetUnpackerSettingAll(bool automatic)
 {
-       PackingInfo * infoUnpacker = nullptr;
-       PrediffingInfo * infoPrediffer = nullptr;
-       FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
-       infoPrediffer->Initialize(newsetting);
+       FastMutex::ScopedLock lock(m_mutex);
+       for (PluginFileInfoMap::iterator it = m_pluginSettings.begin(); it != m_pluginSettings.end(); ++it)
+               it->second->m_infoUnpacker.Initialize(automatic);
 }
 
-void PluginManager::SetPrediffSettingAll(PLUGIN_MODE newsetting)
+void PluginManager::SetPrediffSettingAll(bool automatic)
 {
        FastMutex::ScopedLock lock(m_mutex);
        for (PluginFileInfoMap::iterator it = m_pluginSettings.begin(); it != m_pluginSettings.end(); ++it)
-       {
-               PluginFileInfoPtr fi;
-               fi.reset(new PluginFileInfo);
-               fi->m_infoPrediffer.Initialize(newsetting);
-               (*it).second = fi;
-       }
+               it->second->m_infoPrediffer.Initialize(automatic);
 }
 
-void PluginManager::SetPrediffer(const String& filteredFilenames, const String & prediffer)
+void PluginManager::SetPrediffer(const String& filteredFilenames, const String& predifferPipeline)
 {
        PackingInfo * infoUnpacker = nullptr;
        PrediffingInfo * infoPrediffer = nullptr;
        FetchPluginInfos(filteredFilenames, &infoUnpacker, &infoPrediffer);
-       infoPrediffer->m_PluginName = prediffer;
+       infoPrediffer->SetPluginPipeline(predifferPipeline);
 }
\ No newline at end of file
index 6f5d474..279a8de 100644 (file)
@@ -29,10 +29,10 @@ public:
        typedef std::map<String, PluginFileInfoPtr> PluginFileInfoMap;
 
        ~PluginManager();
-       void Reset() { m_pluginSettings.clear(); };
-       void SetPrediffSetting(const String& filteredFilenames, PLUGIN_MODE newsetting);
-       void SetPrediffSettingAll(PLUGIN_MODE newsetting);
-       void SetPrediffer(const String& filteredFilenames, const String& prediffer);
+       void Clear() { m_pluginSettings.clear(); };
+       void SetUnpackerSettingAll(bool automatic);
+       void SetPrediffSettingAll(bool automatic);
+       void SetPrediffer(const String& filteredFilenames, const String& predifferPipeline);
        // Implement IPluginInfos
        virtual void FetchPluginInfos(const String& filteredFilenames, 
                                       PackingInfo ** infoUnpacker, 
index 8129ae7..9782095 100644 (file)
@@ -20,6 +20,7 @@
 #include <cassert>
 #include <iostream>
 #include <sstream>
+#include <set>
 #include <Poco/Mutex.h>
 #include <Poco/ScopedLock.h>
 #include <Poco/RegularExpression.h>
@@ -37,9 +38,6 @@
 #include "coretools.h"
 #include "OptionsMgr.h"
 #include "OptionsDef.h"
-#include "codepage_detect.h"
-#include "UniFile.h"
-#include "WinMergePluginBase.h"
 
 using std::vector;
 using Poco::RegularExpression;
@@ -69,7 +67,7 @@ static vector<String> theScriptletList;
 static vector<HANDLE> theScriptletHandleList;
 static bool scriptletsLoaded=false;
 static FastMutex scriptletsSem;
-static std::unordered_map<String, String> customFiltersMap;
+static std::unordered_map<StringView, std::unordered_map<StringView, StringView>> customSettingsMap;
 
 template<class T> struct AutoReleaser
 {
@@ -167,46 +165,6 @@ int GetPropertyGetsFromScript(IDispatch *piDispatch, vector<String>& namesArray,
 }
 
 
-// search a function name in a scriptlet or activeX dll
-bool SearchScriptForMethodName(LPDISPATCH piDispatch, const wchar_t *functionName)
-{
-       vector<String> namesArray;
-       vector<int> IdArray;
-       const int nFnc = GetMethodsFromScript(piDispatch, namesArray, IdArray);
-
-       const String tfuncname = ucr::toTString(functionName);
-       for (int iFnc = 0 ; iFnc < nFnc ; iFnc++)
-       {
-               if (namesArray[iFnc] == tfuncname)
-                       return true;
-       }
-       return false;
-}
-
-// search a property name (with get interface) in a scriptlet or activeX dll
-bool SearchScriptForDefinedProperties(IDispatch *piDispatch, const wchar_t *functionName)
-{
-       vector<String> namesArray;
-       vector<int> IdArray;
-       const int nFnc = GetPropertyGetsFromScript(piDispatch, namesArray, IdArray);
-
-       const String tfuncname = ucr::toTString(functionName);
-       for (int iFnc = 0 ; iFnc < nFnc ; iFnc++)
-       {
-               if (namesArray[iFnc] == tfuncname)
-                       return true;
-       }
-       return false;
-}
-
-
-int CountMethodsInScript(LPDISPATCH piDispatch)
-{
-       vector<String> namesArray;
-       vector<int> IdArray;
-       return GetMethodsFromScript(piDispatch, namesArray, IdArray);
-}
-
 /** 
  * @return ID of the function or -1 if no function with this index
  */
@@ -312,8 +270,6 @@ bool PluginInfo::TestAgainstRegList(const String& szTest) const
                if (pos == String::npos)
                        pos = 0;
                sLine = sLine.substr(0, pos);
-               if (sPiece.empty())
-                       continue;
                sPiece = strutils::makeupper(strutils::trim_ws_begin(sPiece));
 
                if (::TestAgainstRegList(&m_filters, sPiece))
@@ -323,6 +279,22 @@ bool PluginInfo::TestAgainstRegList(const String& szTest) const
        return false;
 }
 
+std::optional<StringView> PluginInfo::GetExtendedPropertyValue(const String& name) const
+{
+       for (auto& item : strutils::split(m_extendedProperties, ';'))
+       {
+               auto keyvalue = strutils::split(item, '=');
+               if (keyvalue[0] == name)
+               {
+                       if (keyvalue.size() > 1)
+                               return keyvalue[1];
+                       else
+                               return _("");
+               }
+       }
+       return {};
+}
+
 /**
  * @brief Log technical explanation, in English, of script error
  */
@@ -336,122 +308,40 @@ ScriptletError(const String & scriptletFilepath, const TCHAR *szError)
     LogErrorString(msg);
 }
 
-static std::unordered_set<String> GetDisabledPluginList()
-{
-       std::unordered_set<String> list;
-       std::basic_stringstream<TCHAR> ss(GetOptionsMgr()->GetString(OPT_PLUGINS_DISABLED_LIST));
-       String name;
-       while (std::getline(ss, name, _T('|')))
-               list.insert(name);
-       return list;
-}
-
-static std::unordered_map<String, String> GetCustomFiltersMap()
+static std::unordered_map<StringView, std::unordered_map<StringView, StringView>> GetCustomSettingsMap()
 {
-       std::unordered_map<String, String> map;
-       std::basic_stringstream<TCHAR> ss(GetOptionsMgr()->GetString(OPT_PLUGINS_CUSTOM_FILTERS_LIST));
-       String nameAndFiltersText;
-       while (std::getline(ss, nameAndFiltersText, _T('\t')))
+       std::unordered_map<StringView, std::unordered_map<StringView, StringView>> map;
+       const String& text = GetOptionsMgr()->GetString(OPT_PLUGINS_CUSTOM_SETTINGS_LIST);
+       for (const auto& nameAndKeyValues : strutils::split(text, '\t'))
        {
-               size_t pos = nameAndFiltersText.find_first_of(':');
-               if (pos != String::npos)
+               auto nv = strutils::split(nameAndKeyValues, '=');
+               if (nv.size() == 2)
                {
-                       String name = nameAndFiltersText.substr(0, pos);
-                       String filtersText = nameAndFiltersText.substr(pos + 1);
-                       map.emplace(name, filtersText);
+                       map.insert_or_assign(nv[0], std::unordered_map<StringView, StringView>{});
+                       for (const auto& keyValue : strutils::split(nv[1], '|'))
+                       {
+                               const auto kv = strutils::split(keyValue, ':');
+                               map[nv[0]].insert_or_assign(kv[0], kv.size() > 1 ? kv[1] : _T(""));
+                       }
                }
        }
-       map.emplace(_T("||initialized||"), _T(""));
+       map.insert_or_assign(_T("||initialized||"), std::unordered_map<StringView, StringView>{});
        return map;
 }
 
-static String GetCustomFilters(const String& name, const String& filtersTextDefault)
+static String GetCustomSetting(const String& name, const String& key, const String& default)
 {
        FastMutex::ScopedLock lock(scriptletsSem);
-       if (customFiltersMap.empty())
-               customFiltersMap = GetCustomFiltersMap();
-       if (customFiltersMap.find(name) != customFiltersMap.end())
-               return customFiltersMap[name];
-       else
-               return filtersTextDefault;
-}
-
-class UnpackerGeneratedFromEditorScript: public WinMergePluginBase
-{
-public:
-       UnpackerGeneratedFromEditorScript(IDispatch *pDispatch, const std::wstring funcname, int id)
-               : WinMergePluginBase(
-                       L"FILE_PACK_UNPACK",
-                       strutils::format_string1(_T("Unpacker to execute %1 script (automatically generated)") , funcname),
-                       _T("\\.nomatch$"))
-               , m_pDispatch(pDispatch)
-               , m_funcid(id)
-       {
-               m_pDispatch->AddRef();
-       }
-
-       virtual ~UnpackerGeneratedFromEditorScript()
+       if (customSettingsMap.empty())
+               customSettingsMap = GetCustomSettingsMap();
+       if (customSettingsMap.find(name) != customSettingsMap.end()
+               && customSettingsMap[name].find(key) != customSettingsMap[name].end())
        {
-               m_pDispatch->Release();
+               StringView value = customSettingsMap[name][key];
+               return { value.data(), value.length() };
        }
-
-       static HRESULT ReadFile(const String& path, String& text)
-       {
-               UniMemFile file;
-               if (!file.OpenReadOnly(path))
-                       return E_ACCESSDENIED;
-               file.ReadBom();
-               if (!file.HasBom())
-               {
-                       int iGuessEncodingType = GetOptionsMgr()->GetInt(OPT_CP_DETECT);
-                       int64_t fileSize = file.GetFileSize();
-                       FileTextEncoding encoding = codepage_detect::Guess(
-                               paths::FindExtension(path), file.GetBase(), static_cast<size_t>(
-                                       fileSize < static_cast<int64_t>(codepage_detect::BufSize) ?
-                                               fileSize : static_cast<int64_t>(codepage_detect::BufSize)),
-                               iGuessEncodingType);
-                       file.SetCodepage(encoding.m_codepage);
-               }
-               file.ReadStringAll(text);
-               file.Close();
-               return S_OK;
-       }
-
-       static HRESULT WriteFile(const String& path, const String& text)
-       {
-               UniStdioFile fileOut;
-               if (!fileOut.Open(path, _T("wb")))
-                       return E_ACCESSDENIED;
-               fileOut.SetUnicoding(ucr::UNICODESET::UTF8);
-               fileOut.SetBom(true);
-               fileOut.WriteBom();
-               fileOut.WriteString(text);
-               fileOut.Close();
-               return S_OK;
-       }
-
-       HRESULT STDMETHODCALLTYPE UnpackFile(BSTR fileSrc, BSTR fileDst, VARIANT_BOOL* pbChanged, INT* pSubcode, VARIANT_BOOL* pbSuccess) override
-       {
-               String text;
-               HRESULT hr = ReadFile(fileSrc, text);
-               if (FAILED(hr))
-                       return hr;
-               int changed = 0;
-               if (!plugin::InvokeTransformText(text, changed, m_pDispatch, m_funcid))
-                       return E_FAIL;
-               hr = WriteFile(fileDst, text);
-               if (FAILED(hr))
-                       return hr;
-               *pSubcode = 0;
-               *pbChanged = VARIANT_TRUE;
-               *pbSuccess = VARIANT_TRUE;
-               return S_OK;
-       }
-
-private:
-       IDispatch *m_pDispatch;
-       int m_funcid;
-};
+       return default;
+}
 
 /**
  * @brief Tiny structure that remembers current scriptlet & event info for calling Log
@@ -482,11 +372,23 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
        // Ensure that interface is released if any bad exit or exception
        AutoReleaser<IDispatch> drv(lpDispatch);
 
+       std::vector<String> propNamesArray;
+       std::vector<String> methodNamesArray;
+       std::vector<int> IdArray;
+       const int nPropFnc = plugin::GetPropertyGetsFromScript(lpDispatch, propNamesArray, IdArray);
+       const int nMethodFnc = plugin::GetMethodsFromScript(lpDispatch, methodNamesArray, IdArray);
+       propNamesArray.resize(nPropFnc);
+       methodNamesArray.resize(nMethodFnc);
+       auto SearchScriptForDefinedProperties = [&propNamesArray](const TCHAR* name) -> bool
+       { return std::find(propNamesArray.begin(), propNamesArray.end(), name) != propNamesArray.end(); };
+       auto SearchScriptForMethodName = [&methodNamesArray](const TCHAR* name) -> bool
+       { return std::find(methodNamesArray.begin(), methodNamesArray.end(), name) != methodNamesArray.end(); };
+
        // Is this plugin for this transformationEvent ?
        VARIANT ret;
        // invoke mandatory method get PluginEvent
        VariantInit(&ret);
-       if (!plugin::SearchScriptForDefinedProperties(lpDispatch, L"PluginEvent"))
+       if (!SearchScriptForDefinedProperties(L"PluginEvent"))
        {
                scinfo.Log(_T("PluginEvent method missing"));
                return -20; // error
@@ -507,29 +409,29 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
        bool bFound = true;
        if (m_event == _T("BUFFER_PREDIFF"))
        {
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PrediffBufferW");
+               bFound &= SearchScriptForMethodName(L"PrediffBufferW");
        }
        else if (m_event == _T("FILE_PREDIFF"))
        {
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PrediffFile");
+               bFound &= SearchScriptForMethodName(L"PrediffFile");
        }
        else if (m_event == _T("BUFFER_PACK_UNPACK"))
        {
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"UnpackBufferA");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PackBufferA");
+               bFound &= SearchScriptForMethodName(L"UnpackBufferA");
+               bFound &= SearchScriptForMethodName(L"PackBufferA");
        }
        else if (m_event == _T("FILE_PACK_UNPACK"))
        {
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"UnpackFile");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PackFile");
+               bFound &= SearchScriptForMethodName(L"UnpackFile");
+               bFound &= SearchScriptForMethodName(L"PackFile");
        }
        else if (m_event == _T("FILE_FOLDER_PACK_UNPACK"))
        {
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"IsFolder");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"UnpackFile");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PackFile");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"UnpackFolder");
-               bFound &= plugin::SearchScriptForMethodName(lpDispatch, L"PackFolder");
+               bFound &= SearchScriptForMethodName(L"IsFolder");
+               bFound &= SearchScriptForMethodName(L"UnpackFile");
+               bFound &= SearchScriptForMethodName(L"PackFile");
+               bFound &= SearchScriptForMethodName(L"UnpackFolder");
+               bFound &= SearchScriptForMethodName(L"PackFolder");
        }
        if (!bFound)
        {
@@ -542,7 +444,7 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
        // there may be several functions inside one script, count the number of functions
        if (m_event == _T("EDITOR_SCRIPT"))
        {
-               m_nFreeFunctions = plugin::CountMethodsInScript(lpDispatch);
+               m_nFreeFunctions = static_cast<int>(methodNamesArray.size());
                if (m_nFreeFunctions == 0)
                        // error (Plugin doesn't offer any method, what is this ?)
                        return -50;
@@ -550,7 +452,7 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
 
 
        // get optional property PluginDescription
-       if (plugin::SearchScriptForDefinedProperties(lpDispatch, L"PluginDescription"))
+       if (SearchScriptForDefinedProperties(L"PluginDescription"))
        {
                h = ::invokeW(lpDispatch, &ret, L"PluginDescription", opGet[0], nullptr);
                if (FAILED(h) || ret.vt != VT_BSTR)
@@ -569,7 +471,7 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
 
        // get PluginFileFilters
        bool hasPluginFileFilters = false;
-       if (plugin::SearchScriptForDefinedProperties(lpDispatch, L"PluginFileFilters"))
+       if (SearchScriptForDefinedProperties(L"PluginFileFilters"))
        {
                h = ::invokeW(lpDispatch, &ret, L"PluginFileFilters", opGet[0], nullptr);
                if (FAILED(h) || ret.vt != VT_BSTR)
@@ -588,7 +490,7 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
        VariantClear(&ret);
 
        // get optional property PluginIsAutomatic
-       if (plugin::SearchScriptForDefinedProperties(lpDispatch, L"PluginIsAutomatic"))
+       if (SearchScriptForDefinedProperties(L"PluginIsAutomatic"))
        {
                h = ::invokeW(lpDispatch, &ret, L"PluginIsAutomatic", opGet[0], nullptr);
                if (FAILED(h) || ret.vt != VT_BOOL)
@@ -596,29 +498,29 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
                        scinfo.Log(_T("Plugin had PluginIsAutomatic property, but error getting its value"));
                        return -80; // error (Plugin had PluginIsAutomatic property, but error getting its value)
                }
-               m_bAutomatic = !!ret.boolVal;
+               m_bAutomaticDefault = !!ret.boolVal;
        }
        else
        {
-               if (hasPluginFileFilters)
+               if (hasPluginFileFilters && m_event != _T("EDITOR_SCRIPT"))
                {
                        scinfo.Log(_T("Plugin had PluginFileFilters property, but lacked PluginIsAutomatic property"));
                        // PluginIsAutomatic property is mandatory for Plugins with PluginFileFilters property
                        return -90;
                }
                // default to false when Plugin doesn't have property
-               m_bAutomatic = false;
+               m_bAutomaticDefault = false;
        }
        VariantClear(&ret);
 
        // get optional property PluginUnpackedFileExtenstion
-       if (plugin::SearchScriptForDefinedProperties(lpDispatch, L"PluginUnpackedFileExtension"))
+       if (SearchScriptForDefinedProperties(L"PluginUnpackedFileExtension"))
        {
                h = ::invokeW(lpDispatch, &ret, L"PluginUnpackedFileExtension", opGet[0], nullptr);
                if (FAILED(h) || ret.vt != VT_BSTR)
                {
                        scinfo.Log(_T("Plugin had PluginUnpackedFileExtension property, but error getting its value"));
-                       return -100; // error (Plugin had PluginUnpackedFileExtenstion property, but error getting its value)
+                       return -100; // error (Plugin had PluginUnpackedFileExtension property, but error getting its value)
                }
                m_ext = ucr::toTString(ret.bstrVal);
        }
@@ -628,12 +530,50 @@ int PluginInfo::MakeInfo(const String & scriptletFilepath, IDispatch *lpDispatch
        }
        VariantClear(&ret);
 
+       // get optional property PluginExtendedProperties
+       if (SearchScriptForDefinedProperties(_T("PluginExtendedProperties")))
+       {
+               h = ::invokeW(lpDispatch, &ret, L"PluginExtendedProperties", opGet[0], nullptr);
+               if (FAILED(h) || ret.vt != VT_BSTR)
+               {
+                       scinfo.Log(_T("Plugin had PluginExtendedProperties property, but error getting its value"));
+                       return -110; // error (Plugin had PluginExtendedProperties property, but error getting its value)
+               }
+               m_extendedProperties = ucr::toTString(ret.bstrVal);
+               m_argumentsRequired = GetExtendedPropertyValue(L"ArgumentsRequired").has_value();
+
+       }
+       else
+       {
+               m_extendedProperties.clear();
+               m_argumentsRequired = false;
+       }
+       VariantClear(&ret);
+
+       // get optional property PluginArguments
+       if (SearchScriptForDefinedProperties(L"PluginArguments"))
+       {
+               h = ::invokeW(lpDispatch, &ret, L"PluginArguments", opGet[0], nullptr);
+               if (FAILED(h) || ret.vt != VT_BSTR)
+               {
+                       scinfo.Log(_T("Plugin had PluginArguments property, but error getting its value"));
+                       return -120; // error (Plugin had PluginArguments property, but error getting its value)
+               }
+               m_argumentsDefault = ucr::toTString(ret.bstrVal);
+               m_hasArgumentsProperty = true;
+       }
+       else
+       {
+               m_argumentsDefault.clear();
+               m_hasArgumentsProperty = false;
+       }
+
+       // get optional property PluginVariables
+       m_hasVariablesProperty = SearchScriptForDefinedProperties(L"PluginVariables");
+
        // keep the filename
        m_name = paths::FindFileName(scriptletFilepath);
 
-       m_filtersText = GetCustomFilters(m_name, m_filtersTextDefault);
-       LoadFilterString();
-
        // Clear the autorelease holder
        drv.p = nullptr;
 
@@ -780,19 +720,79 @@ static void RemoveScriptletCandidate(const String &scriptletFilepath)
        }
 }
 
+static void ResolveNameConflict(std::map<std::wstring, PluginArrayPtr> plugins)
+{
+       std::vector<std::vector<String>> eventsAry = 
+       {
+               { L"FILE_FOLDER_PACK_UNPACK", L"FILE_PACK_UNPACK", L"BUFFER_PACK_UNPACK"},
+               { L"FILE_PREDIFF", L"BUFFER_PREDIFF" },
+               { L"EDITOR_SCRIPT"},
+       };
+       for (const auto& events: eventsAry)
+       {
+               std::set<String> pluginNames;
+               for (const auto& event : events)
+               {
+                       if (plugins.find(event) != plugins.end())
+                       {
+                               for (const auto& plugin : *plugins[event])
+                               {
+                                       String name = paths::RemoveExtension(plugin->m_name);
+                                       if (pluginNames.find(name) != pluginNames.end())
+                                       {
+                                               if (pluginNames.find(plugin->m_name) != pluginNames.end())
+                                               {
+                                                       for (int i = 0; ; i++)
+                                                       {
+                                                               String nameNew = name + strutils::format(_T("(%d)"), i + 2);
+                                                               if (pluginNames.find(nameNew) == pluginNames.end())
+                                                               {
+                                                                       name = nameNew;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       name = plugin->m_name;
+                                               }
+                                       }
+                                       plugin->m_name = name;
+                                       pluginNames.insert(name);
+                               }
+                       }
+               }
+       }
+}
+
+static void LoadCustomSettings(std::map<std::wstring, PluginArrayPtr> plugins)
+{
+       for (const auto& [event, pluginAry] : plugins)
+       {
+               for (const auto& plugin : *pluginAry)
+               {
+                       String uniqueName = event + _T(".") + plugin->m_name;
+                       plugin->m_disabled = (GetCustomSetting(uniqueName, _T("disabled"), _T("false"))[0] != 'f');
+                       plugin->m_bAutomatic = GetCustomSetting(uniqueName, _T("automatic"), plugin->m_bAutomaticDefault ? _T("true") : _T("false"))[0] == 't';
+                       plugin->m_arguments = GetCustomSetting(uniqueName, _T("arguments"), plugin->m_argumentsDefault);
+                       plugin->m_filtersText = GetCustomSetting(uniqueName, _T("filters"), plugin->m_filtersTextDefault);
+                       plugin->LoadFilterString();
+               }
+       }
+}
+
 /** 
  * @brief Get available scriptlets for an event
  *
  * @return Returns an array of valid LPDISPATCH
  */
-static std::map<String, PluginArrayPtr> GetAvailableScripts() 
+static std::map<String, PluginArrayPtr> GetAvailableScripts()
 {
        vector<String>& scriptlets = LoadTheScriptletList();
-       std::unordered_set<String> disabled_plugin_list = GetDisabledPluginList();
        std::map<std::wstring, PluginArrayPtr> plugins;
 
        std::list<String> badScriptlets;
-       for (size_t i = 0 ; i < scriptlets.size() ; i++)
+       for (size_t i = 0; i < scriptlets.size(); i++)
        {
                // Note all the info about the plugin
                PluginInfoPtr plugin(new PluginInfo);
@@ -802,7 +802,6 @@ static std::map<String, PluginArrayPtr> GetAvailableScripts()
                if (rtn == 1)
                {
                        // Plugin has this event
-                       plugin->m_disabled = (disabled_plugin_list.find(plugin->m_name) != disabled_plugin_list.end());
                        if (plugins.find(plugin->m_event) == plugins.end())
                                plugins[plugin->m_event].reset(new PluginArray);
                        plugins[plugin->m_event]->push_back(plugin);
@@ -814,24 +813,11 @@ static std::map<String, PluginArrayPtr> GetAvailableScripts()
                }
        }
 
-       if (plugins.find(L"EDITOR_SCRIPT") != plugins.end())
+       if (CAllThreadsScripts::GetInternalPluginsLoader())
        {
-               for (auto plugin : *plugins[L"EDITOR_SCRIPT"])
-               {
-                       std::vector<String> namesArray;
-                       std::vector<int> idArray;
-                       int validFuncs = plugin::GetMethodsFromScript(plugin->m_lpDispatch, namesArray, idArray);
-                       for (int i = 0; i < validFuncs; ++i)
-                       {
-                               if (plugins.find(L"FILE_PACK_UNPACK") == plugins.end())
-                                       plugins[L"FILE_PACK_UNPACK"].reset(new PluginArray);
-                               PluginInfoPtr pluginNew(new PluginInfo());
-                               IDispatch *pDispatch = new UnpackerGeneratedFromEditorScript(plugin->m_lpDispatch, namesArray[i], idArray[i]);
-                               pDispatch->AddRef();
-                               pluginNew->MakeInfo(plugin->m_filepath + _T(":") + namesArray[i], pDispatch);
-                               plugins[L"FILE_PACK_UNPACK"]->push_back(pluginNew);
-                       }
-               }
+               String errmsg;
+               if (!CAllThreadsScripts::GetInternalPluginsLoader()(plugins, errmsg))
+                       AppErrorMessageBox(errmsg);
        }
 
        // Remove any bad plugins from the cache
@@ -842,6 +828,9 @@ static std::map<String, PluginArrayPtr> GetAvailableScripts()
                badScriptlets.pop_front();
        }
 
+       ResolveNameConflict(plugins);
+       LoadCustomSettings(plugins);
+
        return plugins;
 }
 
@@ -899,24 +888,27 @@ PluginArray * CScriptsOfThread::GetAvailableScripts(const wchar_t *transformatio
 
 void CScriptsOfThread::SaveSettings()
 {
-       std::vector<String> listDisabled;
-       std::vector<String> listCustomFilters;
        if (m_aPluginsByEvent.empty())
                m_aPluginsByEvent = ::GetAvailableScripts();
+       std::vector<String> list;
        for (auto [key, pArray] : m_aPluginsByEvent)
        {
-               for (size_t j = 0; j < pArray->size(); ++j)
+               for (const auto& plugin: *pArray)
                {
-                       const PluginInfoPtr & plugin = pArray->at(j);
+                       std::vector<String> ary;
                        if (plugin->m_disabled)
-                               listDisabled.emplace_back(plugin->m_name);
+                               ary.push_back(_T("disabled"));
                        if (plugin->m_filtersTextDefault != plugin->m_filtersText)
-                               listCustomFilters.emplace_back(plugin->m_name + _T(":") + plugin->m_filtersText);
-                       customFiltersMap.insert_or_assign(plugin->m_name, plugin->m_filtersText);
+                               ary.push_back(_T("filters:") + plugin->m_filtersText);
+                       if (plugin->m_argumentsDefault != plugin->m_arguments)
+                               ary.push_back(_T("arguments:") + plugin->m_arguments);
+                       if (plugin->m_bAutomaticDefault != plugin->m_bAutomatic)
+                               ary.push_back(String(_T("automatic:")) + (plugin->m_bAutomatic ? _T("true") : _T("false")));
+                       if (!ary.empty())
+                               list.push_back(plugin->m_event + _T(".") + plugin->m_name + _T("=") + strutils::join(ary.begin(), ary.end(), _T("|")));
                }
        }
-       GetOptionsMgr()->SaveOption(OPT_PLUGINS_DISABLED_LIST, strutils::join(listDisabled.begin(), listDisabled.end(), _T("|")));
-       GetOptionsMgr()->SaveOption(OPT_PLUGINS_CUSTOM_FILTERS_LIST, strutils::join(listCustomFilters.begin(), listCustomFilters.end(), _T("\t")));
+       GetOptionsMgr()->SaveOption(OPT_PLUGINS_CUSTOM_SETTINGS_LIST, strutils::join(list.begin(), list.end(), _T("\t")));
 }
 
 void CScriptsOfThread::FreeAllScripts()
@@ -974,6 +966,10 @@ PluginInfo * CScriptsOfThread::GetPluginByName(const wchar_t *transformationEven
                        for (size_t j = 0; j < pArray->size(); j++)
                                if (pArray->at(j)->m_name == name)
                                        return pArray->at(j).get();
+                       String name2 = paths::RemoveExtension(name);
+                       for (size_t j = 0; j < pArray->size(); j++)
+                               if (pArray->at(j)->m_name == name2)
+                                       return pArray->at(j).get();
                }
        }
        return nullptr;
@@ -1031,6 +1027,7 @@ CScriptsOfThread * CAllThreadsScripts::GetActiveSet()
        assert(false);
        return nullptr;
 }
+
 CScriptsOfThread * CAllThreadsScripts::GetActiveSetNoAssert()
 {
        FastMutex::ScopedLock lock(m_aAvailableThreadsLock);
@@ -1047,6 +1044,16 @@ bool CAllThreadsScripts::bInMainThread(CScriptsOfThread * scripts)
        return (scripts == m_aAvailableThreads[0]);
 }
 
+void CAllThreadsScripts::ReloadCustomSettings()
+{
+       {
+               FastMutex::ScopedLock lock(scriptletsSem);
+               customSettingsMap.clear();
+       }
+       for (auto& thread : m_aAvailableThreads)
+               LoadCustomSettings(thread->m_aPluginsByEvent);
+}
+
 ////////////////////////////////////////////////////////////////////////////////////
 // class CAssureScriptsForThread : control creation/destruction of CScriptsOfThread
 
@@ -1510,7 +1517,12 @@ bool InvokeTransformText(String & text, int & changed, IDispatch *piScript, int
        // argument text  
        VARIANT pvPszBuf;
        pvPszBuf.vt = VT_BSTR;
-       pvPszBuf.bstrVal = SysAllocString(ucr::toUTF16(text).c_str());
+#ifdef _UNICODE
+       pvPszBuf.bstrVal = SysAllocStringLen(text.data(), static_cast<unsigned>(text.length()));
+#else
+       std::wstring wtext = ucr::toUTF16(text);
+       pvPszBuf.bstrVal = SysAllocStringLen(wtext.data(), static_cast<unsigned>(wtext.length()));
+#endif
        // argument transformed text 
        VARIANT vTransformed;
        vTransformed.vt = VT_BSTR;
@@ -1522,7 +1534,12 @@ bool InvokeTransformText(String & text, int & changed, IDispatch *piScript, int
 
        if (! FAILED(h) && vTransformed.bstrVal)
        {
-               text = ucr::toTString(vTransformed.bstrVal);
+#ifdef _UNICODE
+               text = String(vTransformed.bstrVal, SysStringLen(vTransformed.bstrVal));
+#else
+               std::wstring wtext2 = std::wstring(vTransformed.bstrVal, SysStringLen(vTransformed.bstrVal));
+               text = ucr::toTString(wtext2);
+#endif
                changed = true;
        }
        else
@@ -1573,4 +1590,28 @@ bool InvokeShowSettingsDialog(IDispatch *piScript)
        return (bSuccess);
 }
 
+bool InvokePutPluginArguments(const String& args, LPDISPATCH piScript)
+{
+       // argument text  
+       VARIANT vbstrArgs;
+       vbstrArgs.vt = VT_BSTR;
+       std::wstring wargs = ucr::toUTF16(args);
+       vbstrArgs.bstrVal = SysAllocStringLen(wargs.data(), static_cast<unsigned>(wargs.size()));
+
+       HRESULT h = ::safeInvokeW(piScript, nullptr, L"PluginArguments", opPut[1], vbstrArgs);
+       return SUCCEEDED(h);
+}
+
+bool InvokePutPluginVariables(const String& vars, LPDISPATCH piScript)
+{
+       // argument text  
+       VARIANT vbstrVars;
+       vbstrVars.vt = VT_BSTR;
+       std::wstring wvars = ucr::toUTF16(vars);
+       vbstrVars.bstrVal = SysAllocStringLen(wvars.data(), static_cast<unsigned>(wvars.size()));
+
+       HRESULT h = ::safeInvokeW(piScript, nullptr, L"PluginVariables", opPut[1], vbstrVars);
+       return SUCCEEDED(h);
+}
+
 }
index 3574a26..97be898 100644 (file)
@@ -14,6 +14,7 @@
 #include <Poco/Foundation.h>
 #include <string>
 #include <vector>
+#include <optional>
 #include <windows.h>
 #include <oleauto.h>
 #include <memory>
@@ -36,7 +37,12 @@ class PluginInfo
 {
 public:
        PluginInfo()
-               : m_lpDispatch(nullptr), m_filters(NULL), m_bAutomatic(false), m_nFreeFunctions(0), m_disabled(false)
+               : m_lpDispatch(nullptr)
+               , m_filters(NULL)
+               , m_bAutomatic(false)
+               , m_nFreeFunctions(0)
+               , m_disabled(false)
+               , m_hasArgumentsProperty(false)
        {       
        }
 
@@ -58,17 +64,26 @@ public:
         */
        bool TestAgainstRegList(const String& szTest) const;
 
+       std::optional<StringView> GetExtendedPropertyValue(const String& name) const;
+
 public:
        String      m_filepath;
        LPDISPATCH  m_lpDispatch;
        String      m_name; // usually filename, except for special cases (like auto or no)
        String      m_ext;
+       String      m_extendedProperties;
+       String      m_arguments;
+       String      m_argumentsDefault;
        String      m_filtersText;
        String      m_filtersTextDefault;
        String      m_description;
        String      m_event;
        bool        m_bAutomatic;
+       bool        m_bAutomaticDefault;
        bool        m_disabled;
+       bool        m_hasArgumentsProperty;
+       bool        m_hasVariablesProperty;
+       bool        m_argumentsRequired;
        std::vector<FileFilterElementPtr> m_filters;
        /// only for plugins with free function names (EDITOR_SCRIPT)
        int         m_nFreeFunctions;
@@ -138,9 +153,14 @@ public:
        static CScriptsOfThread * GetActiveSet();
        /// by convention, the scripts for main thread must be created before all others
        static bool bInMainThread(CScriptsOfThread * scripts);
+       using InternalPluginLoaderFuncPtr = bool (*)(std::map<String, PluginArrayPtr>& aPluginsByEvent, String& errmsg);
+       static InternalPluginLoaderFuncPtr GetInternalPluginsLoader() { return m_funcInternalPluginsLoader; }
+       static void RegisterInternalPluginsLoader(InternalPluginLoaderFuncPtr func) { m_funcInternalPluginsLoader = func; }
+       static void ReloadCustomSettings();
 private:
        // fixed size array, advantage : no mutex to allocate/free
        static std::vector<CScriptsOfThread *> m_aAvailableThreads;
+       static inline InternalPluginLoaderFuncPtr m_funcInternalPluginsLoader = nullptr;
 };
 
 /**
@@ -174,11 +194,6 @@ bool IsWindowsScriptThere();
 int GetMethodsFromScript(LPDISPATCH piDispatch, std::vector<String>& namesArray, std::vector<int>& IdArray);
 
 /**
- * @brief Get the number of methods in the script
- * @note For free function scripts (EDITOR_SCRIPT)
- */
-int CountMethodsInScript(LPDISPATCH piDispatch);
-
 /**
  * @brief Get the ID of the a free function
  * @param methodOrdinal : index of the free function (0,1,2...)
@@ -244,4 +259,13 @@ bool InvokePrediffFile(const String& fileSource, const String& fileDest, int & n
  */
 bool InvokeShowSettingsDialog(LPDISPATCH piScript);
 
+/**
+ * @brief Set value to the plugin "PluginArguments" property 
+ */
+bool InvokePutPluginArguments(const String& args, LPDISPATCH piScript);
+
+/**
+ * @brief Set value to the plugin "PluginVariables" property 
+ */
+bool InvokePutPluginVariables(const String& args, LPDISPATCH piScript);
 }
index 47c2e09..9f76dd5 100644 (file)
@@ -21,7 +21,7 @@ IMPLEMENT_DYNAMIC(PluginsListDlg, CTrDialog)
 BEGIN_MESSAGE_MAP(PluginsListDlg, CTrDialog)
        ON_BN_CLICKED(IDOK, OnBnClickedOk)
        ON_BN_CLICKED(IDC_PLUGIN_SETTINGS, OnBnClickedPluginSettings)
-       ON_BN_CLICKED(IDC_PLUGIN_FILEFILTERS_DEFAULTS, OnBnClickedFileFiltesDefaults)
+       ON_BN_CLICKED(IDC_PLUGIN_DEFAULTS, OnBnClickedFileFiltesDefaults)
        ON_CBN_DROPDOWN(IDC_PLUGIN_FILEFILTERS, OnDropDownPatterns)
        ON_CBN_CLOSEUP(IDC_PLUGIN_FILEFILTERS, OnCloseUpPatterns)
        ON_NOTIFY(NM_DBLCLK, IDC_PLUGINSLIST_LIST, OnNMDblclkList)
@@ -123,13 +123,16 @@ void PluginsListDlg::AddPluginsToList(const wchar_t *pluginEvent, const String&
                m_list.SetItemText(ind, 1, pluginType.c_str());
                m_list.SetItemText(ind, 2, plugin->m_description.c_str());
                m_list.SetCheck(ind, !plugin->m_disabled);
+               m_list.SetItemData(ind, reinterpret_cast<DWORD_PTR>(plugin.get()));
        }
 }
 
 PluginInfo *PluginsListDlg::GetSelectedPluginInfo() const
 {
-       String name = m_list.GetItemText(m_list.GetNextItem(-1, LVNI_SELECTED), 0);
-       return CAllThreadsScripts::GetActiveSet()->GetPluginByName(nullptr, name);
+       int ind = m_list.GetNextItem(-1, LVNI_SELECTED);
+       if (ind < 0)
+               return nullptr;
+       return reinterpret_cast<PluginInfo *>(m_list.GetItemData(ind));
 }
 
 /**
@@ -149,6 +152,7 @@ void PluginsListDlg::OnBnClickedOk()
        }
 
        CAllThreadsScripts::GetActiveSet()->SaveSettings();
+       CAllThreadsScripts::ReloadCustomSettings();
        OnOK();
 }
 
@@ -177,7 +181,11 @@ void PluginsListDlg::OnBnClickedFileFiltesDefaults()
 {
        PluginInfo *plugin = GetSelectedPluginInfo();
        if (plugin)
+       {
                SetDlgItemText(IDC_PLUGIN_FILEFILTERS, plugin->m_filtersTextDefault);
+               SetDlgItemText(IDC_PLUGIN_ARGUMENTS, plugin->m_argumentsDefault);
+               CheckDlgButton(IDC_PLUGIN_AUTOMATIC, plugin->m_bAutomaticDefault);
+       }
 }
 
 void PluginsListDlg::OnNMDblclkList(NMHDR *pNMHDR, LRESULT *pResult)
@@ -193,6 +201,8 @@ void PluginsListDlg::OnLVNItemChanging(NMHDR *pNMHDR, LRESULT *pResult)
                GetDlgItemText(IDC_PLUGIN_FILEFILTERS, plugin->m_filtersText);
                WildcardRemoveDuplicatePatterns(plugin->m_filtersText);
                plugin->LoadFilterString();
+               GetDlgItemText(IDC_PLUGIN_ARGUMENTS, plugin->m_arguments);
+               plugin->m_bAutomatic = !!IsDlgButtonChecked(IDC_PLUGIN_AUTOMATIC);
        }
 }
 
@@ -200,7 +210,11 @@ void PluginsListDlg::OnLVNItemChanged(NMHDR *pNMHDR, LRESULT *pResult)
 {
        PluginInfo *plugin = GetSelectedPluginInfo();
        if (plugin)
+       {
                SetDlgItemText(IDC_PLUGIN_FILEFILTERS, plugin->m_filtersText);
+               SetDlgItemText(IDC_PLUGIN_ARGUMENTS, plugin->m_arguments);
+               CheckDlgButton(IDC_PLUGIN_AUTOMATIC, plugin->m_bAutomatic);
+       }
 }
 
 /**
index 0fc486e..188b38e 100755 (executable)
@@ -40,6 +40,8 @@ const char Subfolders_element_name[] = "subfolders";
 const char Left_ro_element_name[] = "left-readonly";
 const char Middle_ro_element_name[] = "middle-readonly";
 const char Right_ro_element_name[] = "right-readonly";
+const char Unpacker_element_name[] = "unpacker";
+const char Prediffer_element_name[] = "prediffer";
 
 namespace
 {
@@ -121,6 +123,16 @@ public:
                {
                        currentItem.m_bRightReadOnly = atoi(std::string(ch + start, length).c_str()) != 0;
                }
+               else if (nodename == Unpacker_element_name)
+               {
+                       currentItem.m_unpacker += xmlch2tstr(ch + start, length);
+                       currentItem.m_bHasUnpacker = true;
+               }
+               else if (nodename == Prediffer_element_name)
+               {
+                       currentItem.m_prediffer += xmlch2tstr(ch + start, length);
+                       currentItem.m_bHasPrediffer = true;
+               }
        }
        void ignorableWhitespace(const XMLChar ch[], int start, int length)     {}
        void processingInstruction(const XMLString& target, const XMLString& data) {}
@@ -145,6 +157,8 @@ const String ProjectFile::PROJECTFILE_EXT = toTString("WinMerge");
 , m_bHasRight(false)
 , m_bHasFilter(false)
 , m_bHasSubfolders(false)
+, m_bHasUnpacker(false)
+, m_bHasPrediffer(false)
 , m_subfolders(-1)
 , m_bLeftReadOnly(false)
 , m_bMiddleReadOnly(false)
@@ -283,6 +297,10 @@ bool ProjectFile::Save(const String& path) const
                                if (!item.m_paths.GetMiddle().empty())
                                        writeElement(writer, Middle_ro_element_name, item.m_bMiddleReadOnly ? "1" : "0");
                                writeElement(writer, Right_ro_element_name, item.m_bRightReadOnly ? "1" : "0");
+                               if (!item.m_unpacker.empty())
+                                       writeElement(writer, Unpacker_element_name, toUTF8(item.m_unpacker));
+                               if (!item.m_prediffer.empty())
+                                       writeElement(writer, Prediffer_element_name, toUTF8(item.m_prediffer));
                        }
                        writer.endElement("", "", Paths_element_name);
                }
index 760a775..7806fbf 100755 (executable)
@@ -20,6 +20,8 @@ public:
        bool HasRight() const;
        bool HasFilter() const;
        bool HasSubfolders() const;
+       bool HasUnpacker() const;
+       bool HasPrediffer() const;
 
        String GetLeft(bool * pReadOnly = nullptr) const;
        bool GetLeftReadOnly() const;
@@ -29,12 +31,16 @@ public:
        bool GetRightReadOnly() const;
        String GetFilter() const;
        int GetSubfolders() const;
+       String GetUnpacker() const;
+       String GetPrediffer() const;
 
        void SetLeft(const String& sLeft, const bool * pReadOnly = nullptr);
        void SetMiddle(const String& sMiddle, const bool * pReadOnly = nullptr);
        void SetRight(const String& sRight, const bool * pReadOnly = nullptr);
        void SetFilter(const String& sFilter);
        void SetSubfolders(bool bSubfolder);
+       void SetUnpacker(const String& sUnpacker);
+       void SetPrediffer(const String& sPrediffer);
 
        void GetPaths(PathContext& files, bool & bSubFolders) const;
        void SetPaths(const PathContext& files, bool bSubFolders = false);
@@ -51,6 +57,10 @@ private:
        bool m_bLeftReadOnly; /**< Is left path opened as read-only */
        bool m_bMiddleReadOnly; /**< Is middle path opened as read-only */
        bool m_bRightReadOnly; /**< Is right path opened as read-only */
+       bool m_bHasUnpacker; /**< Has unpacker? */
+       String m_unpacker; /**< Unpacker name or pipeline */
+       bool m_bHasPrediffer; /**< Has prediffer? */
+       String m_prediffer; /**< Prediffer name or pipeline */
 };
 
 /**
@@ -117,6 +127,24 @@ inline bool ProjectFileItem::HasSubfolders() const
 }
 
 /** 
+ * @brief Returns if unpacker is defined in projectfile.
+ * @return true if project file has unpacker definition.
+ */
+inline bool ProjectFileItem::HasUnpacker() const
+{
+       return m_bHasUnpacker;
+}
+
+/** 
+ * @brief Returns if prediffer is defined in projectfile.
+ * @return true if project file has prediffer definition.
+ */
+inline bool ProjectFileItem::HasPrediffer() const
+{
+       return m_bHasPrediffer;
+}
+
+/** 
  * @brief Returns if left path is specified read-only.
  * @return true if left path is read-only, false otherwise.
  */
@@ -179,6 +207,42 @@ inline void ProjectFileItem::SetSubfolders(bool bSubfolder)
 }
 
 /** 
+ * @brief Returns unpacker name or pipeline
+ * @return Unpacker name or pipeline
+ */
+inline String ProjectFileItem::GetUnpacker() const
+{
+       return m_unpacker;
+}
+
+/** 
+ * @brief Set unpacker name or pipeline.
+ * @param [in] sUnpacker New unpacker name or pipeline to set.
+ */
+inline void ProjectFileItem::SetUnpacker(const String& sUnpacker)
+{
+       m_unpacker = sUnpacker;
+}
+
+/** 
+ * @brief Returns prediffer name or pipeline
+ * @return Prediffer name or pipeline
+ */
+inline String ProjectFileItem::GetPrediffer() const
+{
+       return m_prediffer;
+}
+
+/** 
+ * @brief Set prediffer name or pipeline.
+ * @param [in] sPrediffer New prediffer name or pipeline to set.
+ */
+inline void ProjectFileItem::SetPrediffer(const String& sPrediffer)
+{
+       m_prediffer = sPrediffer;
+}
+
+/** 
  * @brief 
  *
  * @param [in] paths Files in project
diff --git a/Src/SelectPluginDlg.cpp b/Src/SelectPluginDlg.cpp
new file mode 100644 (file)
index 0000000..1ccfbee
--- /dev/null
@@ -0,0 +1,260 @@
+/////////////////////////////////////////////////////////////////////////////
+//    WinMerge:  an interactive diff/merge utility
+//    Copyright (C) 1997-2000  Thingamahoochie Software
+//    Author: Dean Grimm
+//    SPDX-License-Identifier: GPL-2.0-or-later
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @file  SelectPluginDlg.cpp
+ *
+ * @brief Unpacker plugin selection dialog implementation.
+ */
+
+#include "stdafx.h"
+#include "SelectPluginDlg.h"
+#include "Plugins.h"
+#include "FileTransform.h"
+#include "OptionsMgr.h"
+#include "OptionsDef.h"
+#include "unicoder.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CSelectPluginDlg dialog
+
+void CSelectPluginDlg::Initialize(bool unpacker)
+{
+       //{{AFX_DATA_INIT(CSelectPluginDlg)
+       m_bNoExtensionCheck = false;
+       m_strDescription = _T("");
+       m_strExtensions = _T("");
+       m_strArguments = _T("");
+       //}}AFX_DATA_INIT
+
+       // texts for the default unpackers
+       noPlugin.reset(new PluginInfo);
+       noPlugin->m_lpDispatch = nullptr;
+       noPlugin->m_name = _("<None>");
+       automaticPlugin.reset(new PluginInfo);
+       automaticPlugin->m_lpDispatch = nullptr;
+       automaticPlugin->m_name = _("<Automatic>");
+       automaticPlugin->m_description = _("The adapted unpacker is applied to both files (one file only needs the extension).");
+
+       std::vector<std::wstring> events = unpacker ?  FileTransform::UnpackerEventNames : FileTransform::PredifferEventNames;
+       m_Plugins = FileTransform::CreatePluginMenuInfos(m_filteredFilenames, events, 0).second;
+}
+
+
+CSelectPluginDlg::CSelectPluginDlg(const String& pluginPipeline, const String& filename,
+       bool unpacker /*= true */, bool argumentRequired/*= false  */, CWnd* pParent /*= nullptr*/)
+       : CTrDialog(CSelectPluginDlg::IDD, pParent)
+       , m_strPluginPipeline(pluginPipeline)
+       , m_filteredFilenames(filename)
+       , m_bUnpacker(unpacker)
+       , m_bArgumentRequired(argumentRequired)
+{
+       Initialize(unpacker);
+}
+
+CSelectPluginDlg::~CSelectPluginDlg()
+{
+}
+
+void CSelectPluginDlg::DoDataExchange(CDataExchange* pDX)
+{
+       CTrDialog::DoDataExchange(pDX);
+       //{{AFX_DATA_MAP(CSelectPluginDlg)
+       DDX_Control(pDX, IDC_PLUGIN_NAME, m_cboPluginName);
+       DDX_Check(pDX, IDC_PLUGIN_ALLOW_ALL, m_bNoExtensionCheck);
+       DDX_Text(pDX, IDC_PLUGIN_DESCRIPTION, m_strDescription);
+       DDX_Text(pDX, IDC_PLUGIN_SUPPORTED_EXTENSIONS, m_strExtensions);
+       DDX_Text(pDX, IDC_PLUGIN_ARGUMENTS, m_strArguments);
+       DDX_Control(pDX, IDC_PLUGIN_PIPELINE, m_ctlPluginPipeline);
+       DDX_CBStringExact(pDX, IDC_PLUGIN_PIPELINE, m_strPluginPipeline);
+       //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CSelectPluginDlg, CTrDialog)
+       //{{AFX_MSG_MAP(CSelectPluginDlg)
+       ON_BN_CLICKED(IDC_PLUGIN_ALLOW_ALL, OnUnpackerAllowAll)
+       ON_CBN_SELCHANGE(IDC_PLUGIN_NAME, OnSelchangeUnpackerName)
+       ON_CBN_SELENDOK(IDC_PLUGIN_NAME, OnSelchangeUnpackerName)
+       ON_BN_CLICKED(IDC_PLUGIN_ADDPIPE, OnClickedAddPipe)
+       ON_EN_CHANGE(IDC_PLUGIN_PIPELINE, OnChangePipeline)
+       //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CSelectPluginDlg message handlers
+
+void CSelectPluginDlg::OnOK() 
+{
+       GetOptionsMgr()->SaveOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, m_bNoExtensionCheck);
+       m_ctlPluginPipeline.SaveState(m_bUnpacker ? _T("Files\\Unpacker") : _T("Files\\Prediffer"));
+
+       CTrDialog::OnOK();
+}
+
+BOOL CSelectPluginDlg::OnInitDialog() 
+{
+       CTrDialog::OnInitDialog();
+
+       m_bNoExtensionCheck = GetOptionsMgr()->GetBool(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION);
+
+       prepareListbox();
+       m_ctlPluginPipeline.SetFileControlStates(true);
+       m_ctlPluginPipeline.LoadState(m_bUnpacker ? _T("Files\\Unpacker") : _T("Files\\Prediffer"));
+
+       UpdateData(FALSE);
+
+       if (m_bArgumentRequired)
+       {
+               SetWindowText(_("Specify plugin arguments").c_str());
+               String args;
+               CString pipeline;
+               GetDlgItemText(IDC_PLUGIN_ARGUMENTS, args);
+               m_ctlPluginPipeline.GetWindowText(pipeline);
+               m_strPluginPipeline = pipeline + _T(" ") + args.c_str();
+               m_ctlPluginPipeline.SetWindowText(m_strPluginPipeline.c_str());
+               m_ctlPluginPipeline.SetFocus();
+               return FALSE;
+       }
+
+       return TRUE;  // return TRUE unless you set the focus to a control
+                     // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CSelectPluginDlg::prepareListbox() 
+{
+       int sel = -1;
+       int i = 0;
+       String errorMessage;
+       auto parseResult = PluginForFile::ParsePluginPipeline(m_strPluginPipeline, errorMessage);
+       String lastPluginName = parseResult.empty() ? _T("") : parseResult.back().name;
+       m_cboPluginName.AddString(noPlugin->m_name.c_str());
+       m_cboPluginName.AddString(automaticPlugin->m_name.c_str());
+
+       std::vector<String> processTypes;
+       for (const auto& [processType, pluginList] : m_Plugins)
+               processTypes.push_back(processType);
+
+       auto itFound = std::find(processTypes.begin(), processTypes.end(), _("&Others"));
+       if (itFound != processTypes.end())
+       {
+               processTypes.erase(itFound);
+               processTypes.push_back(_("&Others"));
+       }
+
+       for (const auto& processType : processTypes)
+       {
+               const auto& pluginList = m_Plugins[processType];
+               String processType2 = processType;
+               auto it = processType2.find(_("(&"));
+               if (it != String::npos)
+                       processType2.erase(it, it + 2);
+               strutils::replace(processType2, _T("&"), _T(""));
+               if (!processType2.empty())
+                       m_cboPluginName.AddString((_T("[") + processType2 + _T("]")).c_str());
+               for (const auto& [caption, name, id, plugin] : pluginList)
+               {
+                       if (!name.empty() && name != _T("<Automatic>"))
+                       {
+                               if (m_bNoExtensionCheck || plugin->TestAgainstRegList(m_filteredFilenames) || lastPluginName == name)
+                               {
+                                       m_cboPluginName.AddString(name.c_str());
+                                       if (lastPluginName == name)
+                                               sel = m_cboPluginName.GetCount() - 1;
+                               }
+                       }
+               }
+       }
+       if (lastPluginName == _T("<Automatic>"))
+               sel = 1;
+       if (sel == -1)
+       {
+               m_cboPluginName.SelectString(-1, noPlugin->m_name.c_str());
+       }
+       else
+       {
+               m_cboPluginName.SetCurSel(sel);
+               OnSelchangeUnpackerName();
+       }
+}
+
+void CSelectPluginDlg::OnUnpackerAllowAll() 
+{
+       UpdateData ();
+
+       m_cboPluginName.ResetContent();
+
+       prepareListbox();
+
+       UpdateData (FALSE);
+}
+
+void CSelectPluginDlg::OnClickedAddPipe()
+{
+       m_strPluginPipeline += _T("|");
+       UpdateData(FALSE);
+}
+
+void CSelectPluginDlg::OnChangePipeline()
+{
+       UpdateData(TRUE);
+}
+
+void CSelectPluginDlg::OnSelchangeUnpackerName() 
+{
+       PluginInfo* pPlugin = nullptr;
+       int i = m_cboPluginName.GetCurSel();
+       if (i == 0)
+       {
+               pPlugin = noPlugin.get();
+               m_strPluginPipeline.clear();
+       }
+       else if (i == 1)
+       {
+               pPlugin = automaticPlugin.get();
+               m_strPluginPipeline = _T("<Automatic>");
+       }
+       else
+       {
+               // initialize with the default unpacker
+               CString cstrPluginName;
+               m_cboPluginName.GetWindowText(cstrPluginName);
+               String pluginName = cstrPluginName.Trim();
+               for (const auto& [processType, pluginList] : m_Plugins)
+               {
+                       for (const auto& [caption, name, id, plugin] : pluginList)
+                       {
+                               if (pluginName == name)
+                               {
+                                       String pluginPipeline = strutils::trim_ws(m_strPluginPipeline);
+                                       if (!pluginPipeline.empty() && pluginPipeline.back() == '|')
+                                               pluginPipeline += _T("dummy");
+                                       String errorMessage;
+                                       auto parseResult = PluginForFile::ParsePluginPipeline(pluginPipeline, errorMessage);
+                                       if (parseResult.empty())
+                                               parseResult.push_back({ name, {}, '\0' });
+                                       parseResult.back().name = name;
+                                       m_strPluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+                                       pPlugin = plugin;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if (pPlugin)
+       {
+               m_strDescription = pPlugin->m_description;
+               m_strExtensions = pPlugin->m_filtersText;
+               m_strArguments = pPlugin->m_arguments;
+       }
+
+       UpdateData (FALSE);
+}
similarity index 61%
rename from Src/SelectUnpackerDlg.h
rename to Src/SelectPluginDlg.h
index 84d8bf9..7e6f825 100644 (file)
@@ -5,7 +5,7 @@
 //    SPDX-License-Identifier: GPL-2.0-or-later
 /////////////////////////////////////////////////////////////////////////////
 /**
- *  @file SelectUnpackerDlg.h : 
+ *  @file SelectPluginDlg.h : 
  *
  *  @brief Declaration file for the dialog SelectUnpacker
  */ 
 #include <vector>
 #include <memory>
 #include "TrDialogs.h"
+#include "SuperComboBox.h"
 #include "UnicodeString.h"
 
 /////////////////////////////////////////////////////////////////////////////
-// CSelectUnpackerDlgDlg dialog
+// CSelectPluginDlgDlg dialog
 
-class PackingInfo;
 class PluginInfo;
 
-class CSelectUnpackerDlg : public CTrDialog
+class CSelectPluginDlg : public CTrDialog
 {
 private:
 // Construction
-       void Initialize();
+       void Initialize(bool unpacker);
 
 public:
 // Construction
-       CSelectUnpackerDlg(const String& filename, CWnd* pParent /*= nullptr*/);
-       CSelectUnpackerDlg(const String& filename1, const String& filename2, CWnd* pParent /*= nullptr*/);
-       ~CSelectUnpackerDlg();
+       CSelectPluginDlg(const String& pluginPipeline, const String& filename, bool unpacker = true, bool argumentRequired = false, CWnd* pParent = nullptr);
+       ~CSelectPluginDlg();
 
-       void SetInitialInfoHandler(PackingInfo * infoHandler);
-       const PackingInfo GetInfoHandler();
+       const String& CSelectPluginDlg::GetPluginPipeline() const { return m_strPluginPipeline; }
 
 // Dialog Data
-       //{{AFX_DATA(CSelectUnpackerDlg)
-       enum { IDD = IDD_PLUGINS_SELECTUNPACKER };
-       CComboBox       m_cboUnpackerName;
+       //{{AFX_DATA(CSelectPluginDlg)
+       enum { IDD = IDD_PLUGINS_SELECTPLUGIN };
+       CComboBox       m_cboPluginName;
        bool    m_bNoExtensionCheck;
        String  m_strDescription;
        String  m_strExtensions;
+       String  m_strArguments;
+       String  m_strPluginPipeline;
+       CSuperComboBox m_ctlPluginPipeline;
+       
        //}}AFX_DATA
 
 
 // Overrides
        // ClassWizard generated virtual function overrides
-       //{{AFX_VIRTUAL(CSelectUnpackerDlg)
+       //{{AFX_VIRTUAL(CSelectPluginDlg)
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
        //}}AFX_VIRTUAL
@@ -57,29 +59,28 @@ public:
 // Implementation
 protected:
        /// arrays for string describing the available plugins
-       CPtrArray  m_UnpackerPlugins;
+       std::map<String, std::vector<std::tuple<String, String, unsigned, PluginInfo *>>> m_Plugins;
 
        // const data "no plugin"
        std::unique_ptr<PluginInfo> noPlugin;
        // const data "automatic plugin"
        std::unique_ptr<PluginInfo> automaticPlugin;
+       bool m_bUnpacker;
+       bool m_bArgumentRequired;
 
        // input value
        String m_filteredFilenames;
 
-       /// current plugin choice
-       PluginInfo * m_pPlugin;
-       /// current plugin choice
-       String m_strPluginName;
-
        void prepareListbox();
 
        // Generated message map functions
-       //{{AFX_MSG(CSelectUnpackerDlg)
+       //{{AFX_MSG(CSelectPluginDlg)
        virtual void OnOK();
        virtual BOOL OnInitDialog() override;
        afx_msg void OnUnpackerAllowAll();
        afx_msg void OnSelchangeUnpackerName();
+       afx_msg void OnClickedAddPipe();
+       afx_msg void OnChangePipeline();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
 };
diff --git a/Src/SelectUnpackerDlg.cpp b/Src/SelectUnpackerDlg.cpp
deleted file mode 100644 (file)
index 9f6c533..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//    WinMerge:  an interactive diff/merge utility
-//    Copyright (C) 1997-2000  Thingamahoochie Software
-//    Author: Dean Grimm
-//    SPDX-License-Identifier: GPL-2.0-or-later
-/////////////////////////////////////////////////////////////////////////////
-/**
- * @file  SelectUnpackerDlg.cpp
- *
- * @brief Unpacker plugin selection dialog implementation.
- */
-
-#include "stdafx.h"
-#include "SelectUnpackerDlg.h"
-#include "Plugins.h"
-#include "FileTransform.h"
-#include "OptionsMgr.h"
-#include "OptionsDef.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#endif
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-// CSelectUnpackerDlg dialog
-
-void CSelectUnpackerDlg::Initialize()
-{
-       //{{AFX_DATA_INIT(CSelectUnpackerDlg)
-       m_bNoExtensionCheck = false;
-       m_strDescription = _T("");
-       m_strExtensions = _T("");
-       //}}AFX_DATA_INIT
-
-       // texts for the default unpackers
-       noPlugin.reset(new PluginInfo);
-       noPlugin->m_lpDispatch = nullptr;
-       noPlugin->m_name = _("<None>");
-       automaticPlugin.reset(new PluginInfo);
-       automaticPlugin->m_lpDispatch = nullptr;
-       automaticPlugin->m_name = _("<Automatic>");
-       automaticPlugin->m_description = _("The adapted unpacker is applied to both files (one file only needs the extension).");
-
-       m_pPlugin = noPlugin.get();
-
-       PluginArray * piFileScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"FILE_PACK_UNPACK");
-       PluginArray * piBufferScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"BUFFER_PACK_UNPACK");
-       PluginArray * piFileFolderScriptArray = 
-               CAllThreadsScripts::GetActiveSet()->GetAvailableScripts(L"FILE_FOLDER_PACK_UNPACK");
-
-       // add the default unpackers to the unpackers list
-       m_UnpackerPlugins.Add(noPlugin.get());
-       m_UnpackerPlugins.Add(automaticPlugin.get());
-       // add the real unpackers to the unpackers list
-       size_t i;
-       for (i = 0 ; i < piFileFolderScriptArray->size() ; i++)
-       {
-               // during the dialog, we use a pointer to the scriptsOfThreads array
-               const PluginInfoPtr& plugin = piFileFolderScriptArray->at(i);
-               if (!plugin->m_disabled)
-               {
-                       m_UnpackerPlugins.Add(plugin.get());
-               }
-       }
-       for (i = 0 ; i < piFileScriptArray->size() ; i++)
-       {
-               // during the dialog, we use a pointer to the scriptsOfThreads array
-               const PluginInfoPtr& plugin = piFileScriptArray->at(i);
-               if (!plugin->m_disabled)
-               {
-                       m_UnpackerPlugins.Add(plugin.get());
-               }
-       }
-       for (i = 0 ; i < piBufferScriptArray->size() ; i++)
-       {
-               // during the dialog, we use a pointer to the scriptsOfThreads array
-               const PluginInfoPtr& plugin = piBufferScriptArray->at(i);
-               if (!plugin->m_disabled)
-               {
-                       m_UnpackerPlugins.Add(plugin.get());
-               }
-       }
-}
-
-
-CSelectUnpackerDlg::CSelectUnpackerDlg(const String& filename, CWnd* pParent /*= nullptr*/)
-       : CTrDialog(CSelectUnpackerDlg::IDD, pParent), m_filteredFilenames(filename)
-{
-       Initialize();
-}
-
-CSelectUnpackerDlg::CSelectUnpackerDlg(const String& filename1, const String& filename2, CWnd* pParent /*= nullptr*/)
-       : CTrDialog(CSelectUnpackerDlg::IDD, pParent), m_filteredFilenames(filename1 + _T("|") + filename2)
-{
-       Initialize();
-}
-
-
-CSelectUnpackerDlg::~CSelectUnpackerDlg()
-{
-}
-
-
-void CSelectUnpackerDlg::SetInitialInfoHandler(PackingInfo * infoHandler)
-{
-       // default value
-       m_pPlugin = noPlugin.get();
-
-       if (infoHandler != nullptr && infoHandler->m_PluginOrPredifferMode != PLUGIN_MODE::PLUGIN_MANUAL)
-               // automatic unpacker
-               m_pPlugin = automaticPlugin.get();
-       else if (infoHandler)
-       {
-               // find the initial unpacker
-               int i;
-               for (i = 0 ; i < m_UnpackerPlugins.GetSize() ; i++)
-               {
-                       PluginInfo * pPlugin = static_cast<PluginInfo*> (m_UnpackerPlugins.GetAt(i));
-                       if (pPlugin->m_name == infoHandler->m_PluginName)
-                               m_pPlugin = pPlugin;
-               }
-       }
-}
-
-const PackingInfo CSelectUnpackerDlg::GetInfoHandler()
-{
-       if (m_pPlugin == noPlugin.get())
-               return PackingInfo(PLUGIN_MODE::PLUGIN_MANUAL);
-       else if (m_pPlugin == automaticPlugin.get())
-               return PackingInfo(PLUGIN_MODE::PLUGIN_AUTO);
-       else
-       {
-               // build a real plugin unpacker
-               PackingInfo infoHandler;
-               infoHandler.m_PluginOrPredifferMode = PLUGIN_MODE::PLUGIN_MANUAL;
-               infoHandler.m_PluginName = m_strPluginName;
-               int i;
-               for (i = 0 ; i < m_UnpackerPlugins.GetSize() ; i++)
-               {
-                       PluginInfo * pPlugin = static_cast<PluginInfo*> (m_UnpackerPlugins.GetAt(i));
-                       if (m_pPlugin == pPlugin)
-                               break;
-               }
-               return infoHandler;
-       }
-}
-
-
-
-void CSelectUnpackerDlg::DoDataExchange(CDataExchange* pDX)
-{
-       CTrDialog::DoDataExchange(pDX);
-       //{{AFX_DATA_MAP(CSelectUnpackerDlg)
-       DDX_Control(pDX, IDC_UNPACKER_NAME, m_cboUnpackerName);
-       DDX_Check(pDX, IDC_UNPACKER_ALLOW_ALL, m_bNoExtensionCheck);
-       DDX_Text(pDX, IDC_UNPACKER_DESCRIPTION, m_strDescription);
-       DDX_Text(pDX, IDC_UNPACKER_SUPPORTED_EXTENSIONS, m_strExtensions);
-       //}}AFX_DATA_MAP
-}
-
-
-BEGIN_MESSAGE_MAP(CSelectUnpackerDlg, CTrDialog)
-       //{{AFX_MSG_MAP(CSelectUnpackerDlg)
-       ON_BN_CLICKED(IDC_UNPACKER_ALLOW_ALL, OnUnpackerAllowAll)
-       ON_CBN_SELCHANGE(IDC_UNPACKER_NAME, OnSelchangeUnpackerName)
-       ON_CBN_SELENDOK(IDC_UNPACKER_NAME, OnSelchangeUnpackerName)
-       //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// CSelectUnpackerDlg message handlers
-
-void CSelectUnpackerDlg::OnOK() 
-{
-       GetOptionsMgr()->SaveOption(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION, m_bNoExtensionCheck);
-
-       CTrDialog::OnOK();
-}
-
-BOOL CSelectUnpackerDlg::OnInitDialog() 
-{
-       CTrDialog::OnInitDialog();
-
-       m_bNoExtensionCheck = GetOptionsMgr()->GetBool(OPT_PLUGINS_UNPACK_DONT_CHECK_EXTENSION);
-
-       prepareListbox();
-
-       return TRUE;  // return TRUE unless you set the focus to a control
-                     // EXCEPTION: OCX Property Pages should return FALSE
-}
-
-void CSelectUnpackerDlg::prepareListbox() 
-{
-       int sel = -1;
-       int i;
-       for (i = 0 ; i < m_UnpackerPlugins.GetSize() ; i++)
-       {
-               PluginInfo * pPlugin = static_cast<PluginInfo*> (m_UnpackerPlugins.GetAt(i));
-               if (pPlugin == noPlugin.get() || pPlugin == automaticPlugin.get() 
-                               || m_bNoExtensionCheck 
-                         || pPlugin->TestAgainstRegList(m_filteredFilenames))
-               {
-                       m_cboUnpackerName.AddString(pPlugin->m_name.c_str());
-                       if (pPlugin == m_pPlugin)
-                               sel = m_cboUnpackerName.GetCount()-1;
-               }
-       }
-
-       if (sel == -1)
-               m_cboUnpackerName.SelectString(-1, noPlugin->m_name.c_str());
-       else
-               m_cboUnpackerName.SetCurSel(sel);
-
-       OnSelchangeUnpackerName();
-}
-
-void CSelectUnpackerDlg::OnUnpackerAllowAll() 
-{
-       UpdateData ();
-
-       m_cboUnpackerName.ResetContent();
-
-       prepareListbox();
-
-       UpdateData (FALSE);
-}
-
-void CSelectUnpackerDlg::OnSelchangeUnpackerName() 
-{
-       int i = m_cboUnpackerName.GetCurSel();
-       if (i == -1)
-       {
-               m_pPlugin = noPlugin.get();
-       }
-       else
-       {
-               // initialize with the default unpacker
-               m_pPlugin = static_cast<PluginInfo*> (m_UnpackerPlugins.GetAt(0));
-               PluginInfo * pPlugin;
-               CString cstrPluginName;
-               m_cboUnpackerName.GetWindowText(cstrPluginName);
-               m_strPluginName = cstrPluginName;
-               for (int j = 0 ; j < m_UnpackerPlugins.GetSize() ; j++)
-               {
-                       pPlugin = static_cast<PluginInfo*> (m_UnpackerPlugins.GetAt(j));
-                       if (m_strPluginName == pPlugin->m_name)
-                       {
-                               m_pPlugin = pPlugin;
-                               break;
-                       }
-               }
-       }
-
-       m_strPluginName = m_pPlugin->m_name;
-       m_strDescription = m_pPlugin->m_description;
-       m_strExtensions = m_pPlugin->m_filtersText;
-
-       UpdateData (FALSE);
-}
index 23dd7d1..4c86541 100644 (file)
@@ -19,7 +19,6 @@ public:
        TempFile() {}
        ~TempFile();
        String Create(const String& prefix = _T(""), const String& ext = _T(""));
-       String CreateFromFile(const String& filepath, const String& prefix);
        /**
         * @brief Get temp file path (including filename).
         * @return Full path to temp file.
diff --git a/Src/UniMarkdownFile.cpp b/Src/UniMarkdownFile.cpp
deleted file mode 100644 (file)
index d600b41..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/**
- *  @file UniMarkdownFile.cpp
- *
- *  @brief Implementation of UniMarkdownFile class.
- */ 
-
-#include "pch.h"
-#include "UniMarkdownFile.h"
-#include <cassert>
-#include "markdown.h"
-
-static void CollapseWhitespace(String &line);
-
-/**
- * @brief Constructor.
- */
-UniMarkdownFile::UniMarkdownFile()
-: m_pMarkdown(nullptr)
-, m_depth(0)
-, m_bMove(false)
-, m_transparent(nullptr)
-{
-}
-
-/**
- * @brief Open the XML file.
- * @param [in] filename Filename (and path) of the file to open.
- * @param [in] mode access mode.
- * @return true if succeeds, false otherwise.
- */
-bool UniMarkdownFile::DoOpen(const String& filename, AccessMode mode)
-{
-       m_depth = 0;
-       bool bOpen = UniMemFile::DoOpen(filename, mode);
-       if (bOpen)
-       {
-               // CMarkdown wants octets, so we may need to transcode to UTF8.
-               // As transcoding strips the BOM, we must check for it in advance.
-               if (IsUnicode())
-                       m_codepage = ucr::CP_UTF_8;
-               // The CMarkdown::File constructor cares about transcoding.
-               CMarkdown::File f(
-                       reinterpret_cast<const TCHAR *>(m_base),
-                       static_cast<unsigned>(m_filesize),
-                       CMarkdown::File::Mapping | CMarkdown::File::Octets);
-               // The file mapping may have been recreated due to transcoding.
-               m_data = m_current = m_base = reinterpret_cast<unsigned char *>(f.pImage);
-               m_filesize = f.cbImage;
-               // Prevent the CMarkdown::File destructor from unmapping the view.
-               f.pImage = nullptr;
-               m_pMarkdown.reset(new CMarkdown(f));
-               Move();
-       }
-       return bOpen;
-}
-
-/**
- * @brief Close the file.
- */
-void UniMarkdownFile::Close()
-{
-       UniMemFile::Close();
-}
-
-/**
- * @brief Collapse whitespace characters from the given line.
- * @param [in, out] Line to handle.
- */
-static void CollapseWhitespace(String &line)
-{
-       int nEatSpace = -2;
-       for (size_t i = line.length() ; i-- ; )
-       {
-               switch (line[i])
-               {
-               case '\r':
-               case '\n':
-               case '\t':
-               case ' ':
-                       if (++nEatSpace < 0 || nEatSpace == 0 && line[i + 1] == '<')
-                               ++nEatSpace;
-                       line[i] = ' ';
-                       break;
-               case '>':
-                       if (nEatSpace >= 0 && line[i + 1 + nEatSpace] != '<')
-                               ++nEatSpace;
-               default:
-                       if (nEatSpace > 0)
-                               line.erase(i + 1, nEatSpace);
-                       nEatSpace = -1;
-                       break;
-               }
-       }
-       if (++nEatSpace > 0)
-               line.erase(0, nEatSpace);
-}
-
-void UniMarkdownFile::Move()
-{
-       m_bMove = m_pMarkdown->Move();
-       const char *first = m_pMarkdown->first;
-       const char *ahead = m_pMarkdown->ahead;
-       m_transparent = nullptr;
-       if (first < ahead)
-       {
-               switch (*++first)
-               {
-               case '?':
-                       m_pMarkdown->Scan();
-                       m_transparent = (unsigned char *)m_pMarkdown->upper;
-                       break;
-               case '!':
-                       if (first < ahead)
-                       {
-                               switch (*++first)
-                               {
-                               case '[':
-                               case '-':
-                                       m_pMarkdown->Scan();
-                                       m_transparent = (unsigned char *)m_pMarkdown->upper;
-                                       break;
-                               }
-                       }
-                       break;
-               }
-       }
-}
-
-String UniMarkdownFile::maketstring(const char *lpd, size_t len)
-{
-       bool lossy = false;
-       String s;
-       ucr::maketstring(s, lpd, len, m_codepage, &lossy);
-       if (lossy)
-               ++m_txtstats.nlosses;
-       return s;
-}
-
-bool UniMarkdownFile::ReadString(String &line, String &eol, bool *lossy)
-{
-       line.erase();
-       eol.erase();
-       int nlosses = m_txtstats.nlosses;
-       int nDepth = 0;
-       bool bDone = false;
-       if (m_current < (const unsigned char *)m_pMarkdown->lower)
-       {
-               line = maketstring((const char *)m_current, m_pMarkdown->lower - (const char *)m_current);
-               CollapseWhitespace(line);
-               bDone = !line.empty();
-               m_current = (unsigned char *)m_pMarkdown->lower;
-       }
-       while (m_current < m_base + m_filesize && !bDone)
-       {
-               if (m_current < m_transparent)
-               {
-                       // Leave whitespace alone when inside <? ?>, <!-- -->, or <![*[ ]]>.
-                       unsigned char * current = m_current;
-                       if (m_current == (const unsigned char *)m_pMarkdown->first)
-                       {
-                               nDepth = m_depth;
-                       }
-                       while (m_current < m_transparent && *m_current != '\r' && *m_current != '\n')
-                       {
-                               ++m_current;
-                       }
-                       line = maketstring((const char *)current, m_current - current);
-                       if (m_current < m_transparent)
-                       {
-                               unsigned char eol1 = *m_current++;
-                               if (m_current < m_transparent && *m_current == (eol1 ^ ('\r'^'\n')))
-                               {
-                                       ++m_current;
-                                       ++m_txtstats.ncrlfs;
-                               }
-                               else
-                               {
-                                       ++(eol1 == '\r' ? m_txtstats.ncrs : m_txtstats.nlfs);
-                               }
-                       }
-                       bDone = true;
-               }
-               else
-               {
-                       while (m_current < m_base + m_filesize && isspace(*m_current))
-                       {
-                               unsigned char eol1 = *m_current++;
-                               if (eol1 == '\r' || eol1 == '\n')
-                               {
-                                       if (m_current < m_base + m_filesize && *m_current == (eol1 ^ ('\r'^'\n')))
-                                       {
-                                               ++m_current;
-                                               ++m_txtstats.ncrlfs;
-                                       }
-                                       else
-                                       {
-                                               ++(eol1 == '\r' ? m_txtstats.ncrs : m_txtstats.nlfs);
-                                       }
-                               }
-                       }
-                       nDepth = m_depth;
-                       bool bPull = false;
-                       if (m_bMove && m_pMarkdown->Pull())
-                       {
-                               ++m_depth;
-                               bPull = true;
-                       }
-                       Move();
-                       bDone = m_bMove;
-                       if (!bDone)
-                       {
-                               --m_depth;
-                               bDone = m_pMarkdown->Push();
-                               if (bPull && bDone)
-                                       Move();
-                       }
-                       if (bDone)
-                       {
-                               line = maketstring((const char *)m_current, m_pMarkdown->first - (const char *)m_current);
-                               CollapseWhitespace(line);
-                               m_current = (unsigned char *)m_pMarkdown->first;
-                       }
-                       else if (m_current < m_base + m_filesize)
-                       {
-                               bDone = true;
-                               line = maketstring((const char *)m_current, m_base + m_filesize - m_current);
-                               CollapseWhitespace(line);
-                               m_current = m_base + m_filesize;
-                       }
-                       bDone = !line.empty();
-               }
-       }
-       assert(line.find_first_of(_T("\r\n")) == String::npos);
-       if (nDepth > 0)
-               line.insert(0U, nDepth, _T('\t'));
-       if (bDone)
-               eol = _T("\n");
-       if (lossy)
-               *lossy = nlosses != m_txtstats.nlosses;
-       return bDone;
-}
diff --git a/Src/UniMarkdownFile.h b/Src/UniMarkdownFile.h
deleted file mode 100644 (file)
index 8da411d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- *  @file UniMarkdownFile.h
- *
- *  @brief Declaration of UniMarkdownFile class.
- */
-#pragma once
-
-#include <memory>
-#include "Common/UniFile.h"
-
-class CMarkdown;
-
-/**
- * @brief XML file reader class.
- */
-class UniMarkdownFile : public UniMemFile
-{
-public:
-       UniMarkdownFile();
-       virtual bool ReadString(String & line, String & eol, bool * lossy) override;
-       virtual void Close() override;
-
-protected:
-       virtual bool DoOpen(const String& filename, AccessMode mode) override;
-
-private:
-       void Move();
-       String maketstring(const char *lpd, size_t len);
-
-       int m_depth;
-       bool m_bMove;
-       unsigned char *m_transparent;
-       std::unique_ptr<CMarkdown> m_pMarkdown;
-};
index c62b2f3..90a310f 100644 (file)
@@ -12,6 +12,9 @@ public:
                DISPID_PluginIsAutomatic,
                DISPID_PluginFileFilters,
                DISPID_PluginUnpackedFileExtension,
+               DISPID_PluginExtendedProperties,
+               DISPID_PluginArguments,
+               DISPID_PluginVariables,
                DISPID_PrediffFile,
                DISPID_UnpackFile,
                DISPID_PackFile,
@@ -24,12 +27,15 @@ public:
 
        WinMergePluginBase(const std::wstring& sEvent, const std::wstring& sDescription = L"",
                const std::wstring& sFileFilters = L"", const std::wstring& sUnpackedFileExtension = L"", 
+               const std::wstring& sExtendedProperties = L"", const std::wstring& sArguments = L"", 
                bool bIsAutomatic = true)
                : m_nRef(0)
                , m_sEvent(sEvent)
                , m_sDescription(sDescription)
                , m_sFileFilters(sFileFilters)
                , m_sUnpackedFileExtension(sUnpackedFileExtension)
+               , m_sExtendedProperties(sExtendedProperties)
+               , m_sArguments(sArguments)
                , m_bIsAutomatic(bIsAutomatic)
        {
                static PARAMDATA paramData_Prediff[] =
@@ -40,20 +46,27 @@ public:
                { {L"fileSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"subcode", VT_I4}, };
                static PARAMDATA paramData_IsFolder[] =
                { {L"fileSrc", VT_BSTR}, };
+               static PARAMDATA paramData_Arguments[] =
+               { {L"args", VT_BSTR}, };
+               static PARAMDATA paramData_Variables[] =
+               { {L"vars", VT_BSTR}, };
                static PARAMDATA paramData_UnpackFolder[] =
                { {L"fileSrc", VT_BSTR}, {L"folderDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"pSubcode", VT_I4 | VT_BYREF}, };
                static PARAMDATA paramData_PackFolder[] =
                { {L"folderSrc", VT_BSTR}, {L"fileDst", VT_BSTR}, {L"pbChanged", VT_BOOL | VT_BYREF}, {L"subcode", VT_I4}, };
-               static PARAMDATA paramData_Empty[] =
-               { {L"", VT_EMPTY} };
                static METHODDATA methodData_FILE_PREDIFF[] =
                {
-                       { L"PluginEvent",                 nullptr,                DISPID_PluginEvent,                 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
-                       { L"PluginDescription",           nullptr,                DISPID_PluginDescription,           1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
-                       { L"PluginIsAutomatic",           nullptr,                DISPID_PluginIsAutomatic,           2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL  },
-                       { L"PluginFileFilters",           nullptr,                DISPID_PluginFileFilters,           3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
-                       { L"PrediffFile",                 paramData_Prediff,      DISPID_PrediffFile,                 4, CC_STDCALL, 3, DISPATCH_METHOD,      VT_BOOL  },
-                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,          5, CC_STDCALL, 0, DISPATCH_METHOD,      VT_EMPTY },
+                       { L"PluginEvent",                 nullptr,                DISPID_PluginEvent,                 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginDescription",           nullptr,                DISPID_PluginDescription,           1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginIsAutomatic",           nullptr,                DISPID_PluginIsAutomatic,           2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL },
+                       { L"PluginFileFilters",           nullptr,                DISPID_PluginFileFilters,           3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginExtendedProperties",    nullptr,                DISPID_PluginExtendedProperties,    4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             nullptr,                DISPID_PluginArguments,             5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             paramData_Arguments,    DISPID_PluginArguments,             5, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"PluginVariables",             nullptr,                DISPID_PluginVariables,             6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginVariables",             paramData_Variables,    DISPID_PluginVariables,             6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"PrediffFile",                 paramData_Prediff,      DISPID_PrediffFile,                 7, CC_STDCALL, 3, DISPATCH_METHOD,      VT_BOOL },
+                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,          8, CC_STDCALL, 0, DISPATCH_METHOD,      VT_VOID },
                };
                static METHODDATA methodData_FILE_PACK_UNPACK[] =
                {
@@ -61,10 +74,15 @@ public:
                        { L"PluginDescription",           nullptr,                DISPID_PluginDescription,           1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
                        { L"PluginIsAutomatic",           nullptr,                DISPID_PluginIsAutomatic,           2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL  },
                        { L"PluginFileFilters",           nullptr,                DISPID_PluginFileFilters,           3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
-                       { L"PluginUnpackedFileExtension", nullptr,                DISPID_PluginUnpackedFileExtension, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
-                       { L"UnpackFile",                  paramData_UnpackFile,   DISPID_UnpackFile,                  5, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL  },
-                       { L"PackFile",                    paramData_PackFile,     DISPID_PackFile ,                   6, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL  },
-                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,          7, CC_STDCALL, 0, DISPATCH_METHOD,      VT_EMPTY },
+                       { L"PluginExtendedProperties",    nullptr,                DISPID_PluginExtendedProperties,    4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
+                       { L"PluginUnpackedFileExtension", nullptr,                DISPID_PluginUnpackedFileExtension, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR  },
+                       { L"PluginArguments",             nullptr,                DISPID_PluginArguments,             6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             paramData_Arguments,    DISPID_PluginArguments,             6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"PluginVariables",             nullptr,                DISPID_PluginVariables,             7, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginVariables",             paramData_Variables,    DISPID_PluginVariables,             7, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"UnpackFile",                  paramData_UnpackFile,   DISPID_UnpackFile,                  8, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL  },
+                       { L"PackFile",                    paramData_PackFile,     DISPID_PackFile ,                   9, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL  },
+                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,         10, CC_STDCALL, 0, DISPATCH_METHOD,      VT_VOID  },
                };
                static METHODDATA methodData_FILE_FOLDER_PACK_UNPACK[] =
                {
@@ -72,18 +90,29 @@ public:
                        { L"PluginDescription",           nullptr,                DISPID_PluginDescription,           1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
                        { L"PluginIsAutomatic",           nullptr,                DISPID_PluginIsAutomatic,           2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BOOL },
                        { L"PluginFileFilters",           nullptr,                DISPID_PluginFileFilters,           3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
-                       { L"PluginUnpackedFileExtension", nullptr,                DISPID_PluginUnpackedFileExtension, 4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
-                       { L"UnpackFile",                  paramData_UnpackFile,   DISPID_UnpackFile,                  5, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
-                       { L"PackFile",                    paramData_PackFile,     DISPID_PackFile ,                   6, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
-                       { L"IsFolder",                    paramData_IsFolder,     DISPID_IsFolder,                    7, CC_STDCALL, 1, DISPATCH_METHOD,      VT_BOOL },
-                       { L"UnpackFolder",                paramData_UnpackFolder, DISPID_UnpackFolder,                8, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
-                       { L"PackFolder",                  paramData_PackFolder,   DISPID_PackFolder,                  9, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
-                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,         10, CC_STDCALL, 0, DISPATCH_METHOD,      VT_EMPTY },
+                       { L"PluginExtendedProperties",    nullptr,                DISPID_PluginExtendedProperties,    4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginUnpackedFileExtension", nullptr,                DISPID_PluginUnpackedFileExtension, 5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             nullptr,                DISPID_PluginArguments,             6, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             paramData_Arguments,    DISPID_PluginArguments,             6, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"PluginVariables",             nullptr,                DISPID_PluginVariables,             7, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginVariables",             paramData_Variables,    DISPID_PluginVariables,             7, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"UnpackFile",                  paramData_UnpackFile,   DISPID_UnpackFile,                  8, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
+                       { L"PackFile",                    paramData_PackFile,     DISPID_PackFile ,                   9, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
+                       { L"IsFolder",                    paramData_IsFolder,     DISPID_IsFolder,                   10, CC_STDCALL, 1, DISPATCH_METHOD,      VT_BOOL },
+                       { L"UnpackFolder",                paramData_UnpackFolder, DISPID_UnpackFolder,               11, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
+                       { L"PackFolder",                  paramData_PackFolder,   DISPID_PackFolder,                 12, CC_STDCALL, 4, DISPATCH_METHOD,      VT_BOOL },
+                       { L"ShowSettingsDialog",          nullptr,                DISPID_ShowSettingsDialog,         13, CC_STDCALL, 0, DISPATCH_METHOD,      VT_VOID },
                };
                static METHODDATA methodData_EDITOR_SCRIPT[] =
                {
                        { L"PluginEvent",                 nullptr,                DISPID_PluginEvent,                 0, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
                        { L"PluginDescription",           nullptr,                DISPID_PluginDescription,           1, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginFileFilters",           nullptr,                DISPID_PluginFileFilters,           2, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginExtendedProperties",    nullptr,                DISPID_PluginExtendedProperties,    3, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             nullptr,                DISPID_PluginArguments,             4, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginArguments",             paramData_Arguments,    DISPID_PluginArguments,             4, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
+                       { L"PluginVariables",             nullptr,                DISPID_PluginVariables,             5, CC_STDCALL, 0, DISPATCH_PROPERTYGET, VT_BSTR },
+                       { L"PluginVariables",             paramData_Variables,    DISPID_PluginVariables,             5, CC_STDCALL, 1, DISPATCH_PROPERTYPUT, VT_VOID },
                };
                const METHODDATA* pMethodData;
                size_t methodDataCount = 0;
@@ -266,6 +295,36 @@ public:
                                pVarResult->vt = VT_BSTR;
                                hr = get_PluginUnpackedFileExtension(&pVarResult->bstrVal);
                                break;
+                       case DISPID_PluginExtendedProperties:
+                               pVarResult->vt = VT_BSTR;
+                               hr = get_PluginExtendedProperties(&pVarResult->bstrVal);
+                               break;
+                       case DISPID_PluginArguments:
+                               pVarResult->vt = VT_BSTR;
+                               hr = get_PluginArguments(&pVarResult->bstrVal);
+                               break;
+                       case DISPID_PluginVariables:
+                               pVarResult->vt = VT_BSTR;
+                               hr = get_PluginVariables(&pVarResult->bstrVal);
+                               break;
+                       }
+               }
+               else if (wFlags == DISPATCH_PROPERTYPUT)
+               {
+                       switch (dispIdMember)
+                       {
+                       case DISPID_PluginArguments:
+                       {
+                               BSTR bstrArgs = pDispParams->rgvarg[0].bstrVal;
+                               hr = put_PluginArguments(bstrArgs);
+                               break;
+                       }
+                       case DISPID_PluginVariables:
+                       {
+                               BSTR bstrVars = pDispParams->rgvarg[0].bstrVal;
+                               hr = put_PluginVariables(bstrVars);
+                               break;
+                       }
                        }
                }
                if (hr == DISP_E_EXCEPTION && pExcepInfo)
@@ -479,6 +538,36 @@ public:
                return S_OK;
        }
 
+       virtual HRESULT STDMETHODCALLTYPE get_PluginExtendedProperties(BSTR* pVal)
+       {
+               *pVal = SysAllocString(m_sExtendedProperties.c_str());
+               return S_OK;
+       }
+
+       virtual HRESULT STDMETHODCALLTYPE get_PluginArguments(BSTR* pVal)
+       {
+               *pVal = SysAllocString(m_sArguments.c_str());
+               return S_OK;
+       }
+
+       virtual HRESULT STDMETHODCALLTYPE put_PluginArguments(BSTR val)
+       {
+               m_sArguments = std::wstring{ val, SysStringLen(val) };
+               return S_OK;
+       }
+
+       virtual HRESULT STDMETHODCALLTYPE get_PluginVariables(BSTR* pVal)
+       {
+               *pVal = SysAllocString(m_sVariables.c_str());
+               return S_OK;
+       }
+
+       virtual HRESULT STDMETHODCALLTYPE put_PluginVariables(BSTR val)
+       {
+               m_sVariables = std::wstring{ val, SysStringLen(val) };
+               return S_OK;
+       }
+
        bool AddFunction(const std::wstring& name, ScriptFuncPtr pFunc)
        {
                static PARAMDATA paramData_ScriptFunc[] =
@@ -506,6 +595,9 @@ protected:
        std::wstring m_sDescription;
        std::wstring m_sFileFilters;
        std::wstring m_sUnpackedFileExtension;
+       std::wstring m_sExtendedProperties;
+       std::wstring m_sArguments;
+       std::wstring m_sVariables;
        bool m_bIsAutomatic;
 };
 
index d25ee31..a022245 100644 (file)
@@ -123,6 +123,12 @@ String FindExtension(const String& path)
        return ::PathFindExtension(path.c_str());
 }
 
+String RemoveExtension(const String& path)
+{
+       String ext = FindExtension(path);
+       return path.substr(0, path.length() - ext.length());
+}
+
 /** 
  * @brief Strip trailing slas.
  * This function strips trailing slash from given path. Root paths are special
index 04e45c4..ae96c3d 100644 (file)
@@ -31,6 +31,7 @@ bool EndsWithSlash(const String& s);
 PATH_EXISTENCE DoesPathExist(const String& szPath, bool (*IsArchiveFile)(const String&) = nullptr);
 String FindFileName(const String& path);
 String FindExtension(const String& path);
+String RemoveExtension(const String& path);
 void normalize(String & sPath);
 String GetLongPath(const String& szPath, bool bExpandEnvs = true);
 bool CreateIfNeeded(const String& szPath);
index c470cb5..fc6a6e3 100644 (file)
@@ -36,7 +36,7 @@
 #define IDD_LOAD_SAVE_CODEPAGE          231\r
 #define IDD_CONFIRM_COPY                236\r
 #define IDD_PLUGINS_LIST                237\r
-#define IDD_PLUGINS_SELECTUNPACKER      238\r
+#define IDD_PLUGINS_SELECTPLUGIN        238\r
 #define IDD_DIR_FILTER                  240\r
 #define IDD_ENCODINGERROR               241\r
 #define IDD_SELECT_FILES_OR_FOLDERS     247\r
 #define IDC_FILES_DIRS_GROUP2           1084\r
 #define IDC_FILES_DIRS_GROUP3           1085\r
 #define IDC_FILES_DIRS_GROUP4           1086\r
-#define IDC_UNPACKER_NAME               1089\r
-#define IDC_UNPACKER_ALLOW_ALL          1090\r
-#define IDC_UNPACKER_SUPPORTED_EXTENSIONS 1091\r
-#define IDC_UNPACKER_DESCRIPTION        1092\r
-#define IDC_UNPACKER_EDIT               1093\r
-#define IDC_SELECT_UNPACKER             1094\r
-#define IDC_EXT_EDITOR_BROWSE           1095\r
-#define IDC_EXT_EDITOR_PATH             1096\r
-#define IDC_DIFF_SWAPFILES              1097\r
-#define IDC_DIFF_OPENTOEDITOR           1098\r
-#define IDC_FILES_DIRS_GROUP3X          1100\r
-#define IDC_FILES_DIRS_GROUP4X          1101\r
+#define IDC_PLUGIN_NAME                 1087\r
+#define IDC_PLUGIN_ALLOW_ALL            1088\r
+#define IDC_PLUGIN_SUPPORTED_EXTENSIONS 1089\r
+#define IDC_PLUGIN_DESCRIPTION          1090\r
+#define IDC_PLUGIN_ARGUMENTS            1091\r
+#define IDC_PLUGIN_COMBO                1092\r
+#define IDC_PLUGIN_PIPELINE             1093\r
+#define IDC_PLUGIN_ADDPIPE              1094\r
+#define IDC_UNPACKER_COMBO              1095\r
+#define IDC_SELECT_UNPACKER             1096\r
+#define IDC_EXT_EDITOR_BROWSE           1097\r
+#define IDC_EXT_EDITOR_PATH             1098\r
+#define IDC_DIFF_SWAPFILES              1099\r
+#define IDC_DIFF_OPENTOEDITOR           1100\r
+#define IDC_FILES_DIRS_GROUP3X          1101\r
+#define IDC_FILES_DIRS_GROUP4X          1102\r
 #define IDC_COMPARISON_STOP             1105\r
 #define IDC_COMPARISON_PAUSE            1106\r
 #define IDC_COMPARISON_CONTINUE         1107\r
 #define IDC_DIR_ITEM_EQUAL_TEXT_COLOR   1363\r
 #define IDC_USE_DIR_COMPARE_COLORS      1364\r
 #define IDC_PLUGIN_FILEFILTERS          1365\r
-#define IDC_PLUGIN_FILEFILTERS_DEFAULTS 1366\r
-#define IDC_RENDERING_MODE              1367\r
+#define IDC_PLUGIN_DEFAULTS             1366\r
+#define IDC_PLUGIN_AUTOMATIC            1367\r
+#define IDC_RENDERING_MODE              1368\r
 #define IDC_DIFF_IGNORECP               1377\r
 #define IDC_RESET                       1378\r
 #define IDC_LEFT1                       1379\r
 #define ID_MERGE_COMPARE_TABLE          32871\r
 #define ID_MERGE_COMPARE_HEX            32872\r
 #define ID_MERGE_COMPARE_IMAGE          32873\r
-#define ID_MERGE_COMPARE_XML            32874\r
 #define ID_MERGE_COMPARE_LEFT1_LEFT2    32875\r
 #define ID_MERGE_COMPARE_RIGHT1_RIGHT2  32876\r
 #define ID_MERGE_COMPARE_LEFT1_RIGHT2   32877\r
 #define ID_MERGE_COMPARE_LEFT2_RIGHT1   32878\r
 #define ID_UNPACK_MANUAL                32880\r
 #define ID_UNPACK_AUTO                  32881\r
-#define ID_POPUP_OPEN_WITH_UNPACKER     32882\r
+#define ID_OPEN_WITH_UNPACKER           32882\r
 #define ID_NO_PREDIFFER                 32883\r
 #define ID_SUGGESTED_PLUGINS            32884\r
 #define ID_NOT_SUGGESTED_PLUGINS        32885\r
 #define ID_RELOAD_PLUGINS               32886\r
+#define ID_NO_UNPACKER                  32887\r
+#define ID_APPLY_PREDIFFER              32888\r
 #define ID_WINDOW_CHANGE_PANE           32896\r
 #define ID_WINDOW_CLOSEALL              32897\r
+#define ID_SELECT_PREDIFFER             32898\r
+#define ID_SELECT_UNPACKER              32899\r
 #define ID_HELP_CONTENTS                32912\r
 #define ID_HELP_GETCONFIG               32913\r
 #define ID_HELP_GNULICENSE              32914\r
-#define ID_PREDIFF_MANUAL               32929\r
-#define ID_PREDIFF_AUTO                 32930\r
+#define ID_PREDIFFER_SETTINGS_NONE      32920\r
+#define ID_PREDIFFER_SETTINGS_AUTO      32921\r
+#define ID_PREDIFFER_SETTINGS_SELECT    32922\r
+#define ID_UNPACKER_SETTINGS_NONE       32923\r
+#define ID_UNPACKER_SETTINGS_AUTO       32924\r
+#define ID_UNPACKER_SETTINGS_SELECT     32925\r
 #define ID_NO_EDIT_SCRIPTS              32931\r
 #define ID_NO_SCT_SCRIPTS               32932\r
 #define ID_FILE_OPEN_REGISTERED         32944\r
 #define ID_DIR_SHELL_CONTEXT_MENU_LEFT  33002\r
 #define ID_DIR_SHELL_CONTEXT_MENU_MIDDLE 33003\r
 #define ID_DIR_SHELL_CONTEXT_MENU_RIGHT 33004\r
-#define ID_SCRIPT_FIRST                 33012\r
-#define ID_SCRIPT_LAST                  33059\r
-#define ID_PREDIFFERS_FIRST             33060\r
-#define ID_PREDIFFERS_LAST              33107\r
+#define ID_SCRIPT_FIRST                 33010\r
+#define ID_SCRIPT_LAST                  33039\r
+#define ID_PREDIFFERS_FIRST             33040\r
+#define ID_PREDIFFERS_LAST              33069\r
+#define ID_UNPACKERS_FIRST              33070\r
+#define ID_UNPACKERS_LAST               33110\r
 #define ID_DISPLAY_MOVED_NONE           33111\r
 #define ID_DISPLAY_MOVED_ALL            33112\r
 #define ID_LOCBAR_GOTODIFF              33114\r
 #define IDS_COLHDR_NIDIFFS              41814\r
 #define IDS_COLHDR_NSDIFFS              41815\r
 #define IDS_COLHDR_BINARY               41816\r
+#define IDS_COLHDR_UNPACKER             41817\r
+#define IDS_COLHDR_PREDIFFER            41818\r
 #define IDS_CANT_COMPARE_FILES          41831\r
 #define IDS_ABORTED_ITEM                41832\r
 #define IDS_FILE_SKIPPED                41833\r
 #define IDS_COLDESC_NIDIFFS             41944\r
 #define IDS_COLDESC_NSDIFFS             41945\r
 #define IDS_COLDESC_BINARY              41946\r
+#define IDS_COLDESC_UNPACKER            41947\r
+#define IDS_COLDESC_PREDIFFER           41948\r
 #define IDS_DIRECTORY_REPORT_TITLE      41962\r
 #define IDS_REPORT_COMMALIST            41963\r
 #define IDS_REPORT_TABLIST              41964\r
 #define IDS_IGNSUB_STR5                 44178\r
 #define IDS_SINGLEINSTANCE_STR1         44179\r
 #define IDS_SINGLEINSTANCE_STR2         44180\r
+#define IDS_PLUGIN_ALL                  44200\r
+#define IDS_PLUGIN_PROCESS_TYPE1        44201\r
+#define IDS_PLUGIN_PROCESS_TYPE2        44202\r
+#define IDS_PLUGIN_PROCESS_TYPE3        44203\r
+#define IDS_PLUGIN_PROCESS_TYPE4        44204\r
+#define IDS_PLUGIN_PROCESS_TYPE5        44205\r
+#define IDS_PLUGIN_PROCESS_TYPE6        44206\r
+#define IDS_PLUGIN_PROCESS_TYPE7        44207\r
+#define IDS_PLUGIN_PROCESS_TYPE8        44208\r
+#define IDS_PLUGIN_PROCESS_TYPE9        44209\r
+#define IDS_PLUGIN_MENU_CAPTION1        44211\r
+#define IDS_PLUGIN_MENU_CAPTION2        44212\r
+#define IDS_PLUGIN_MENU_CAPTION3        44213\r
+#define IDS_PLUGIN_MENU_CAPTION4        44214\r
+#define IDS_PLUGIN_MENU_CAPTION5        44215\r
+#define IDS_PLUGIN_MENU_CAPTION6        44216\r
+#define IDS_PLUGIN_MENU_CAPTION7        44217\r
+#define IDS_PLUGIN_MENU_CAPTION8        44218\r
+#define IDS_PLUGIN_MENU_CAPTION9        44219\r
+#define IDS_PLUGIN_MENU_CAPTION10       44220\r
+#define IDS_PLUGIN_MENU_CAPTION11       44221\r
+#define IDS_PLUGIN_MENU_CAPTION12       44222\r
+#define IDS_PLUGIN_MENU_CAPTION13       44223\r
+#define IDS_PLUGIN_MENU_CAPTION14       44224\r
+#define IDS_PLUGIN_MENU_CAPTION15       44225\r
+#define IDS_PLUGIN_MENU_CAPTION16       44226\r
+#define IDS_PLUGIN_MENU_CAPTION17       44227\r
+#define IDS_PLUGIN_MENU_CAPTION18       44228\r
+#define IDS_PLUGIN_MENU_CAPTION19       44229\r
+#define IDS_PLUGIN_MENU_CAPTION20       44230\r
+#define IDS_PLUGIN_MENU_CAPTION21       44231\r
+#define IDS_PLUGIN_MENU_CAPTION22       44232\r
+#define IDS_PLUGIN_MENU_CAPTION23       44233\r
+#define IDS_PLUGIN_MENU_CAPTION24       44234\r
+#define IDS_PLUGIN_MENU_CAPTION25       44235\r
+#define IDS_PLUGIN_MENU_CAPTION26       44236\r
+#define IDS_PLUGIN_MENU_CAPTION27       44237\r
+#define IDS_PLUGIN_MENU_CAPTION28       44238\r
+#define IDS_PLUGIN_MENU_CAPTION29       44239\r
+#define IDS_PLUGIN_MENU_CAPTION30       44240\r
+#define IDS_PLUGIN_MISSING_PLUGIN_NAME  44241\r
+#define IDS_PLUGIN_MISSING_QUOTATION_MARK 44242\r
+#define IDS_PLUGIN_TITLE1               44243\r
 \r
 // Next default values for new objects\r
 // \r
index b5a3e3e..485b3fa 100644 (file)
Binary files a/Testing/Data/Office/excel.xls and b/Testing/Data/Office/excel.xls differ
index 8aa5d9e..9556d6e 100644 (file)
     </ClCompile>
     <ClCompile Include="..\..\Src\stringdiffs.cpp" />
     <ClCompile Include="..\..\Src\SubstitutionList.cpp" />
-    <ClCompile Include="..\..\Src\UniMarkdownFile.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Use</PrecompiledHeader>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Use</PrecompiledHeader>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">pch.h</PrecompiledHeaderFile>
-    </ClCompile>
     <ClCompile Include="..\..\Src\Common\varprop.cpp">
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
       <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pch.h</PrecompiledHeaderFile>
     <ClInclude Include="..\..\Src\Common\UniFile.h" />
     <ClInclude Include="..\..\Src\stringdiffs.h" />
     <ClInclude Include="..\..\Src\SubstitutionList.h" />
-    <ClInclude Include="..\..\Src\UniMarkdownFile.h" />
     <ClInclude Include="..\..\Src\Common\varprop.h" />
     <ClInclude Include="..\..\Src\CompareEngines\ByteComparator.h" />
     <ClInclude Include="..\..\Src\CompareEngines\ByteCompare.h" />
index 3e6e830..16251f5 100644 (file)
     <ClCompile Include="..\..\Src\Common\UniFile.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\Src\UniMarkdownFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\Src\Common\varprop.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\..\Src\Common\UniFile.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\Src\UniMarkdownFile.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\Src\Common\varprop.h">
       <Filter>Header Files</Filter>
     </ClInclude>
index 5211796..196cd23 100644 (file)
@@ -55,10 +55,256 @@ namespace
                PrediffingInfo *ip = nullptr;
                PluginManager pm;
                IPluginInfos *ppi = &pm;
-               int subcode = 0;
+               std::vector<int> subcodes;
                ppi->FetchPluginInfos(_T("../../Data/Office/excel.xls|../../Data/Office/excel.xls"), &iu, &ip);
                String file = paths::ConcatPath(oldModulePath, _T("..\\..\\Data\\Office\\excel.xls"));
-               FileTransform::Unpacking(file, _T(".*\\.xls"), iu, &subcode);
+               iu->Unpacking(&subcodes, file, _T(".*\\.xls"), { file });
+       }
+
+       TEST_F(PluginsTest, ParsePluginPipeline)
+       {
+               String errorMessage;
+               auto parseResult = PluginForFile::ParsePluginPipeline(_T(""), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(0, parseResult.size());
+               String pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T(""), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(0, parseResult.size());
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T(""), pluginPipeline);
+
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("<Automatic>"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("<Automatic>"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("<Automatic>"), pluginPipeline);
+
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" <Automatic> "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("<Automatic>"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("<Automatic>"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("'a b'"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("'a b'"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("'a''b'"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a'b"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("'a''b'"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("a' 'b"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("'a b'"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("a' '\"b\""), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(0, parseResult[0].args.size());
+               EXPECT_EQ('"', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("\"a b\""), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("\"a b"), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand dir c:\\"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(_T("c:\\"), parseResult[0].args[1]);
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand dir c:\\"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" ExecFilterCommand  dir  c:\\ "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(_T("c:\\"), parseResult[0].args[1]);
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand dir c:\\"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand  'dir  c:\\ '"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand 'dir  c:\\ '"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand  'dir  c:\\ ' "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand 'dir  c:\\ '"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" 'a b'  'dir  c:\\ ' "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("'a b' 'dir  c:\\ '"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" 'a b'  dir  c:\\  "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(_T("c:\\"), parseResult[0].args[1]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("'a b' 'dir' 'c:\\'"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" 'a b'  \"dir  c:\\ \" "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(1, parseResult.size());
+               EXPECT_EQ(_T("a b"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('"', parseResult[0].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("\"a b\" \"dir  c:\\ \""), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand dir|MakeUpper"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               EXPECT_EQ(_T("MakeUpper"), parseResult[1].name);
+               EXPECT_EQ(0, parseResult[1].args.size());
+               EXPECT_EQ(0, parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand dir|MakeUpper"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand dir | MakeUpper "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               EXPECT_EQ(_T("MakeUpper"), parseResult[1].name);
+               EXPECT_EQ(0, parseResult[1].args.size());
+               EXPECT_EQ(0, parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand dir|MakeUpper"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" ExecFilterCommand dir | MakeUpper "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir"), parseResult[0].args[0]);
+               EXPECT_EQ(0, parseResult[0].quoteChar);
+               EXPECT_EQ(_T("MakeUpper"), parseResult[1].name);
+               EXPECT_EQ(0, parseResult[1].args.size());
+               EXPECT_EQ(0, parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand dir|MakeUpper"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" ExecFilterCommand 'dir  c:\\ ' | MakeUpper "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               EXPECT_EQ(_T("MakeUpper"), parseResult[1].name);
+               EXPECT_EQ(0, parseResult[1].args.size());
+               EXPECT_EQ(0, parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand 'dir  c:\\ '|MakeUpper"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("ExecFilterCommand 'dir c:\\'|ExecFilterCommand 'sort'"), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir c:\\"), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[1].name);
+               EXPECT_EQ(_T("sort"), parseResult[1].args[0]);
+               EXPECT_EQ('\'', parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand 'dir c:\\'|ExecFilterCommand 'sort'"), pluginPipeline);
+
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" ExecFilterCommand 'dir  c:\\ ' | ExecFilterCommand ' sort ' "), errorMessage);
+               EXPECT_TRUE(errorMessage.empty());
+               EXPECT_EQ(2, parseResult.size());
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[0].name);
+               EXPECT_EQ(_T("dir  c:\\ "), parseResult[0].args[0]);
+               EXPECT_EQ('\'', parseResult[0].quoteChar);
+               EXPECT_EQ(_T("ExecFilterCommand"), parseResult[1].name);
+               EXPECT_EQ(_T(" sort "), parseResult[1].args[0]);
+               EXPECT_EQ('\'', parseResult[1].quoteChar);
+               pluginPipeline = PluginForFile::MakePluginPipeline(parseResult);
+               EXPECT_EQ(_T("ExecFilterCommand 'dir  c:\\ '|ExecFilterCommand ' sort '"), pluginPipeline);
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("|"), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T(" | "), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("MakeUpper|"), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("MakeUpper | "), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("MakeUpper||"), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+
+               parseResult = PluginForFile::ParsePluginPipeline(_T("MakeUpper | | "), errorMessage);
+               EXPECT_TRUE(!errorMessage.empty());
+       }
+
+       TEST_F(PluginsTest, ReplaceVariable)
+       {
+               String result;
+               EXPECT_STREQ(_T(""), PluginForFile::MakeArguments(std::vector<String>{_T("")}, { _T("abc") }).c_str());
+               EXPECT_STREQ(_T("%"), PluginForFile::MakeArguments(std::vector<String>{_T("%")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("abc"), PluginForFile::MakeArguments(std::vector<String>{_T("%1")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("%1"), PluginForFile::MakeArguments(std::vector<String>{_T("%%1")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("%1a"), PluginForFile::MakeArguments(std::vector<String>{_T("%%1a")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T(""), PluginForFile::MakeArguments(std::vector<String>{_T("%2")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("%TIME%"), PluginForFile::MakeArguments(std::vector<String>{_T("%TIME%")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("aaaabcaaa"), PluginForFile::MakeArguments(std::vector<String>{_T("aaa%1aaa")}, {_T("abc")}).c_str());
+               EXPECT_STREQ(_T("abcdef"), PluginForFile::MakeArguments(std::vector<String>{_T("%1%2")}, { _T("abc"), _T("def") }).c_str());
        }
 
 }  // namespace
index 05a83d2..b604e5f 100644 (file)
@@ -143,4 +143,30 @@ TEST_F(LeftAndRightTest, GetFilter)
        ASSERT_TRUE(filter.empty());\r
 }\r
 \r
+/**\r
+ * @brief Make sure prediffer is not get.\r
+ */\r
+TEST_F(LeftAndRightTest, GetPrediffer)\r
+{\r
+       // We don't have a prediffer\r
+       bool bHasPrediffer = m_pProjectFileItem->HasPrediffer();\r
+       ASSERT_TRUE(bHasPrediffer == false);\r
+\r
+       String prediffer = m_pProjectFileItem->GetPrediffer();\r
+       ASSERT_TRUE(prediffer.empty());\r
+}\r
+\r
+/**\r
+ * @brief Make sure unpacker is not get.\r
+ */\r
+TEST_F(LeftAndRightTest, GetUnpacker)\r
+{\r
+       // We don't have a unpacker\r
+       bool bHasUnpacker = m_pProjectFileItem->HasUnpacker();\r
+       ASSERT_TRUE(bHasUnpacker == false);\r
+\r
+       String unpacker = m_pProjectFileItem->GetUnpacker();\r
+       ASSERT_TRUE(unpacker.empty());\r
+}\r
+\r
 }\r
index d8837f3..045a3f4 100644 (file)
@@ -144,4 +144,30 @@ TEST_F(LeftAndRightNonRecursiveTest, GetFilter)
        ASSERT_TRUE(filter.empty());\r
 }\r
 \r
+/**\r
+ * @brief Make sure prediffer is not get.\r
+ */\r
+TEST_F(LeftAndRightNonRecursiveTest, GetPrediffer)\r
+{\r
+       // We don't have a prediffer\r
+       bool bHasPrediffer = m_pProjectFileItem->HasPrediffer();\r
+       ASSERT_TRUE(bHasPrediffer == false);\r
+\r
+       String prediffer = m_pProjectFileItem->GetPrediffer();\r
+       ASSERT_TRUE(prediffer.empty());\r
+}\r
+\r
+/**\r
+ * @brief Make sure unpacker is not get.\r
+ */\r
+TEST_F(LeftAndRightNonRecursiveTest, GetUnpacker)\r
+{\r
+       // We don't have a unpacker\r
+       bool bHasUnpacker = m_pProjectFileItem->HasUnpacker();\r
+       ASSERT_TRUE(bHasUnpacker == false);\r
+\r
+       String unpacker = m_pProjectFileItem->GetUnpacker();\r
+       ASSERT_TRUE(unpacker.empty());\r
+}\r
+\r
 }\r
index f4f1ddd..18388a6 100644 (file)
@@ -17,6 +17,10 @@ static const TCHAR LeftPath[] = _T("C:\\Temp\\Left");
 static const TCHAR RightPath[] = _T("C:\\Temp\\Right");\r
 /** @brief Filter we should get from file. */\r
 static const TCHAR Filter[] = _T("Filter Name");\r
+/** @brief Prediffer we should get from file. */\r
+static const TCHAR Prediffer[] = _T("IgnoreColumns.dll");\r
+/** @brief Unpacker we should get from file. */\r
+static const TCHAR Unpacker[] = _T("CompareMSExcelFiles.sct");\r
 \r
 namespace\r
 {\r
@@ -145,4 +149,30 @@ TEST_F(PathAndFilterTest, GetFilter)
        ASSERT_TRUE(filter.compare(Filter) == 0);\r
 }\r
 \r
+/**\r
+ * @brief Read prediffer.\r
+ */\r
+TEST_F(PathAndFilterTest, GetPrediffer)\r
+{\r
+       // Now we have a prediffer\r
+       bool bHasPrediffer = m_pProjectFileItem->HasPrediffer();\r
+       ASSERT_TRUE(bHasPrediffer == true);\r
+\r
+       String prediffer = m_pProjectFileItem->GetPrediffer();\r
+       ASSERT_TRUE(prediffer.compare(Prediffer) == 0);\r
+}\r
+\r
+/**\r
+ * @brief Read unpacker.\r
+ */\r
+TEST_F(PathAndFilterTest, GetUnpacker)\r
+{\r
+       // Now we have a unpacker\r
+       bool bHasUnpacker = m_pProjectFileItem->HasUnpacker();\r
+       ASSERT_TRUE(bHasUnpacker == true);\r
+\r
+       String unpacker = m_pProjectFileItem->GetUnpacker();\r
+       ASSERT_TRUE(unpacker.compare(Unpacker) == 0);\r
+}\r
+\r
 }\r
index 6b13847..7e1cb29 100644 (file)
@@ -141,4 +141,30 @@ TEST_F(SimpleLeftTest, GetFilter)
        ASSERT_TRUE(filter.empty());\r
 }\r
 \r
+/**\r
+ * @brief Make sure prediffer is not get.\r
+ */\r
+TEST_F(SimpleLeftTest, GetPrediffer)\r
+{\r
+       // We don't have a prediffer\r
+       bool bHasPrediffer = m_pProjectFileItem->HasPrediffer();\r
+       ASSERT_TRUE(bHasPrediffer == false);\r
+\r
+       String prediffer = m_pProjectFileItem->GetPrediffer();\r
+       ASSERT_TRUE(prediffer.empty());\r
+}\r
+\r
+/**\r
+ * @brief Make sure unpacker is not get.\r
+ */\r
+TEST_F(SimpleLeftTest, GetUnpacker)\r
+{\r
+       // We don't have a unpacker\r
+       bool bHasUnpacker = m_pProjectFileItem->HasUnpacker();\r
+       ASSERT_TRUE(bHasUnpacker == false);\r
+\r
+       String unpacker = m_pProjectFileItem->GetUnpacker();\r
+       ASSERT_TRUE(unpacker.empty());\r
+}\r
+\r
 }\r
index ded725c..737d008 100644 (file)
@@ -142,4 +142,30 @@ TEST_F(SimpleRightTest, GetFilter)
        ASSERT_TRUE(filter.empty());\r
 }\r
 \r
+/**\r
+ * @brief Make sure prediffer is not get.\r
+ */\r
+TEST_F(SimpleRightTest, GetPrediffer)\r
+{\r
+       // We don't have a prediffer\r
+       bool bHasPrediffer = m_pProjectFileItem->HasPrediffer();\r
+       ASSERT_TRUE(bHasPrediffer == false);\r
+\r
+       String prediffer = m_pProjectFileItem->GetPrediffer();\r
+       ASSERT_TRUE(prediffer.empty());\r
+}\r
+\r
+/**\r
+ * @brief Make sure unpacker is not get.\r
+ */\r
+TEST_F(SimpleRightTest, GetUnpacker)\r
+{\r
+       // We don't have a unpacker\r
+       bool bHasUnpacker = m_pProjectFileItem->HasUnpacker();\r
+       ASSERT_TRUE(bHasUnpacker == false);\r
+\r
+       String unpacker = m_pProjectFileItem->GetUnpacker();\r
+       ASSERT_TRUE(unpacker.empty());\r
+}\r
+\r
 }\r
index ae1980b..2ff4f44 100644 (file)
@@ -4,5 +4,7 @@
                <left>C:\Temp\Left</left>\r
                <right>C:\Temp\Right</right>\r
                <filter>Filter Name</filter>\r
+               <prediffer>IgnoreColumns.dll</prediffer>\r
+               <unpacker>CompareMSExcelFiles.sct</unpacker>\r
        </paths>\r
 </project>\r
index 055f8f4..0231bf1 100644 (file)
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
       <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
     </ClCompile>
-    <ClCompile Include="..\..\..\Src\UniMarkdownFile.cpp">
-      <PrecompiledHeader>Use</PrecompiledHeader>
-      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
-      <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName)2.pch</PrecompiledHeaderOutputFile>
-    </ClCompile>
     <ClCompile Include="..\..\..\Src\Common\varprop.cpp">
       <PrecompiledHeader>Use</PrecompiledHeader>
       <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
     <ClInclude Include="..\..\..\Src\stringdiffsi.h" />
     <ClInclude Include="..\..\..\Src\Common\unicoder.h" />
     <ClInclude Include="..\..\..\Src\Common\UnicodeString.h" />
-    <ClInclude Include="..\..\..\Src\UniMarkdownFile.h" />
     <ClInclude Include="..\..\..\Src\Common\varprop.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
index c06dd77..4260b4b 100644 (file)
     <ClCompile Include="..\..\..\Src\Common\UniFile.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\Src\UniMarkdownFile.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\..\Src\Common\varprop.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="..\..\..\Src\Common\UnicodeString.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\Src\UniMarkdownFile.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\..\Src\Common\varprop.h">
       <Filter>Header Files</Filter>
     </ClInclude>
index 2d1529a..e6259ef 100644 (file)
@@ -35,7 +35,6 @@ CRegOptionsMgr m_option;
 
 COptionsMgr * GetOptionsMgr()
 {
-       m_option.InitOption(OPT_PLUGINS_DISABLED_LIST, _T(""));
-       m_option.InitOption(OPT_PLUGINS_CUSTOM_FILTERS_LIST, _T(""));
+       m_option.InitOption(OPT_PLUGINS_CUSTOM_SETTINGS_LIST, _T(""));
        return &m_option;
 }
index 0235b0d..7b0753b 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)
 ArchiveSupport=Archive Support
 ShellExtension32bit=32-bit WinMerge ShellExtension
-Patch=GnuWin32 Patch for Windows
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq
 
 ;Localization Components
 Languages=Languages
index 7fa05e9..823590c 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Hizkuntzak\r
index a0df652..d85f0c0 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed (editor hex Gr
 WinIMerge=WinIMerge (Diferenciar/Unir Imagens)\r
 ArchiveSupport=Suporte pra Arquivos Compactados\r
 ShellExtension32bit=Extensão do Shell de 32 bits do WinMerge\r
-Patch=Patch do GnuWin32 pra Windows\r
+Commands=Patch do GnuWin32 pra Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Idiomas\r
index 509d7b4..f516fc1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 3184f05..0003461 100755 (executable)
@@ -19,7 +19,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Idiomes\r
index cfbe84d..5e2775d 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(
 WinIMerge=WinIMerge(ͼÏñ²îÒì/ºÏ²¢)\r
 ArchiveSupport=ѹËõÎļþÖ§³Ö\r
 ShellExtension32bit=32 λ WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=ÓïÑÔ°ü£¨²Ëµ¥ºÍ¶Ô»°¿ò£©\r
index 509d7b4..f516fc1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index bfa8bd0..4b440ab 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Jezici\r
index 509d7b4..f516fc1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 39bf568..e170f01 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Sprog\r
index f7f6e8d..ea8b313 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Afbeeldingsvergelijker/-samenvoeger)\r
 ArchiveSupport=Archiefondersteuning\r
 ShellExtension32bit=32-bit WinMerge-contextmenu\r
-Patch=GnuWin32-patch voor Windows\r
+Commands=GnuWin32-patch voor Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Talen\r
index 509d7b4..f516fc1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 509d7b4..f516fc1 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 01f1b74..d25c27a 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Aide archive\r
 ShellExtension32bit=Menu contextuel WinMerge 32-bit\r
-Patch=Patch GnuWin32 pour Windows\r
+Commands=Patch GnuWin32 pour Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Langages\r
index b81c27e..3043de8 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Editor hexadecimal gratu
 WinIMerge=WinIMerge(Diferenciar/Mesturar Imaxes)\r
 ArchiveSupport=Soporte de Archivos\r
 ShellExtension32bit=Extensión do Shell de 32-bit para WinMerge\r
-Patch=Parche GnuWin32 para Windows\r
+Commands=Parche GnuWin32 para Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Idiomas\r
index 94dbeb4..bff5579 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed (Freier Hex-Editor)
 WinIMerge=WinIMerge (Bildvergleich)\r
 ArchiveSupport=Archivsupport\r
 ShellExtension32bit=32-Bit-WinMerge-Shellintegration\r
-Patch=GnuWin32-Patch für Windows\r
+Commands=GnuWin32-Patch für Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Sprachen\r
index 428bf80..379b8aa 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Ãëþóóåò\r
index 2c3ffde..fffeed1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Ingyenes hexa editor)
 WinIMerge=WinIMerge(Kép Eltérés/Egyesítés)\r
 ArchiveSupport=Archivum támogatása\r
 ShellExtension32bit=32-bit WinMerge helyi menü kiterjesztés\r
-Patch=GnuWin32 Patch a Windowshoz\r
+Commands=GnuWin32 Patch a Windowshoz/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Nyelvek\r
index 9665c7f..c891c51 100755 (executable)
@@ -19,7 +19,7 @@ Frhed=Frhed (editor hex gratuito)
 WinIMerge=WinIMerge (differenza/unione immagini)\r
 ArchiveSupport=Supporto archivi\r
 ShellExtension32bit=Estensione shell 32bit WinMerge\r
-Patch=Patch per Windows GnuWin32\r
+Commands=Patch per Windows GnuWin32/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Lingue\r
index 50358a7..8931a8c 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=\8c¾\8cê\r
index 509d7b4..f516fc1 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 693f9f3..2fad6e8 100644 (file)
@@ -18,7 +18,7 @@ Frhed=
 WinIMerge=\84WinIMerge\93 (vaizdø Diff/Merge)\r
 ArchiveSupport=Archyvø palaikymas\r
 ShellExtension32bit=32-bitø \84WinMerge ShellExtension\93\r
-Patch=GnuWin32 pataisa \84Windows\93\r
+Commands=GnuWin32 pataisa \84Windows\93/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Kalbos\r
index 6a6dd71..4585efd 100755 (executable)
@@ -22,7 +22,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Språk\r
index 4f1f1c5..5696209 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages= ÒÈÇäåÇ \r
index 3a060ad..f708878 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed (Free hex editor)
 WinIMerge=WinIMerge (Image Diff/Merge)\r
 ArchiveSupport=Wsparcie dla archiwów\r
 ShellExtension32bit=32-bitowe rozszerzenie pow³oki WinMerge\r
-Patch=GnuWin32 ³atka dla systemu Windows\r
+Commands=GnuWin32 ³atka dla systemu Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Jêzyki\r
index f53cf4e..632dd2b 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Editor hex gratuito)
 WinIMerge=WinIMerge (Dividir/Juntar Imagens)\r
 ArchiveSupport=Suporte de ficheiros\r
 ShellExtension32bit=Extensão Shell WinMerge 32 bits\r
-Patch=Pacote GnuWin32 para Windows\r
+Commands=Pacote GnuWin32 para Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Idiomas\r
index 37df48a..7bcff98 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 0444e04..1382080 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Ïîääåðæêà àðõèâîâ\r
 ShellExtension32bit=32-áèòíîå ðàñøèðåíèå îáîëî÷êè WinMerge\r
-Patch=GnuWin32 ïàò÷ äëÿ Windows\r
+Commands=GnuWin32 ïàò÷ äëÿ Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=ßçûêè èíòåðôåéñà (ìåíþ è äèàëîãè)\r
index 509d7b4..f516fc1 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 6063200..3018675 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index a30c885..71acddc 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Jazyky\r
index e56ac60..0979d89 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Brezpla
 WinIMerge=WinIMerge (Slika razlik/zdru\9eitev)\r
 ArchiveSupport=Podpora arhivov\r
 ShellExtension32bit=32-bitna raz\9airitev lupine WinMerge\r
-Patch=GnuWin32 popravek za Windows\r
+Commands=GnuWin32 popravek za Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Jeziki\r
index 9336919..faf8bd9 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Editor hexadecimal gratuito)
 WinIMerge=WinIMerge(Diferenciar/Mezclar Imágenes)\r
 ArchiveSupport=Soporte de Archivado\r
 ShellExtension32bit=Extensión del Shell de 32-bit para WinMerge\r
-Patch=Parche GnuWin32 para Windows\r
+Commands=Parche GnuWin32 para Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Idiomas\r
index 0c2389f..3abab69 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(Fri hex redigerare)
 WinIMerge=WinIMerge(Avbilds Skillnads/Enande)\r
 ArchiveSupport=Arkiv Stöd\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Språk\r
index 2684e9d..7afdedc 100755 (executable)
@@ -18,7 +18,7 @@ Frhed=Frhed(
 WinIMerge=WinIMerge(Görsel Fark/Birleþtirme)\r
 ArchiveSupport=Arþiv Desteði\r
 ShellExtension32bit=32-bit WinMerge Kabuk Eklentisi\r
-Patch=GnuWin32 Windows Yamasý\r
+Commands=GnuWin32 Windows Yamasý/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Diller\r
index 5f8a887..1ceb4da 100644 (file)
@@ -18,7 +18,7 @@ Frhed=Frhed(Free hex editor)
 WinIMerge=WinIMerge(Image Diff/Merge)\r
 ArchiveSupport=Archive Support\r
 ShellExtension32bit=32-bit WinMerge ShellExtension\r
-Patch=GnuWin32 Patch for Windows\r
+Commands=GnuWin32 Patch for Windows/HTML Tidy/jq\r
 \r
 ;Localization Components\r
 Languages=Languages\r
index 791a1e2..674f046 100644 (file)
@@ -37,7 +37,7 @@
 </head>
 <body>
 <h1>Translations Status</h1>
-<p>Status from <strong>2021-05-27</strong>:</p>
+<p>Status from <strong>2021-06-20</strong>:</p>
 <h2>WinMerge</h2>
 <table class="status">
   <tr>
   </tr>
   <tr>
     <td class="left">Arabic</td>
-    <td class="right">1030</td>
-    <td class="right translated">914</td>
+    <td class="right">1068</td>
+    <td class="right translated">908</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">116</td>
-    <td class="right">89 %</td>
+    <td class="right untranslated">160</td>
+    <td class="right">85 %</td>
     <td class="center">2019-12-30</td>
   </tr>
   <tr>
     <td class="left">Basque</td>
-    <td class="right">1030</td>
-    <td class="right translated">650</td>
+    <td class="right">1068</td>
+    <td class="right translated">644</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">380</td>
-    <td class="right">63 %</td>
+    <td class="right untranslated">424</td>
+    <td class="right">60 %</td>
     <td class="center">2013-02-03</td>
   </tr>
   <tr>
     <td class="left">Brazilian</td>
-    <td class="right">1030</td>
-    <td class="right translated">1029</td>
+    <td class="right">1068</td>
+    <td class="right translated">1024</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">1</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">44</td>
+    <td class="right">96 %</td>
     <td class="center">2021-02-14</td>
   </tr>
   <tr>
     <td class="left">Bulgarian</td>
-    <td class="right">1030</td>
-    <td class="right translated">955</td>
+    <td class="right">1068</td>
+    <td class="right translated">951</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">75</td>
-    <td class="right">93 %</td>
+    <td class="right untranslated">117</td>
+    <td class="right">89 %</td>
     <td class="center">2021-02-11</td>
   </tr>
   <tr>
     <td class="left">Catalan</td>
-    <td class="right">1030</td>
-    <td class="right translated">575</td>
+    <td class="right">1068</td>
+    <td class="right translated">570</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">455</td>
-    <td class="right">56 %</td>
+    <td class="right untranslated">498</td>
+    <td class="right">53 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseSimplified</td>
-    <td class="right">1030</td>
-    <td class="right translated">987</td>
+    <td class="right">1068</td>
+    <td class="right translated">981</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">43</td>
-    <td class="right">96 %</td>
+    <td class="right untranslated">87</td>
+    <td class="right">92 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">ChineseTraditional</td>
-    <td class="right">1030</td>
-    <td class="right translated">867</td>
+    <td class="right">1068</td>
+    <td class="right translated">861</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">163</td>
-    <td class="right">84 %</td>
+    <td class="right untranslated">207</td>
+    <td class="right">81 %</td>
     <td class="center">2010-02-19</td>
   </tr>
   <tr>
     <td class="left">Croatian</td>
-    <td class="right">1030</td>
-    <td class="right translated">641</td>
+    <td class="right">1068</td>
+    <td class="right translated">635</td>
     <td class="right fuzzy">1</td>
-    <td class="right untranslated">388</td>
-    <td class="right">62 %</td>
+    <td class="right untranslated">432</td>
+    <td class="right">60 %</td>
     <td class="center">2009-02-13</td>
   </tr>
   <tr>
     <td class="left">Czech</td>
-    <td class="right">1030</td>
-    <td class="right translated">613</td>
+    <td class="right">1068</td>
+    <td class="right translated">610</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">417</td>
-    <td class="right">60 %</td>
+    <td class="right untranslated">458</td>
+    <td class="right">57 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Danish</td>
-    <td class="right">1030</td>
-    <td class="right translated">650</td>
+    <td class="right">1068</td>
+    <td class="right translated">644</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">380</td>
-    <td class="right">63 %</td>
+    <td class="right untranslated">424</td>
+    <td class="right">60 %</td>
     <td class="center">2013-01-13</td>
   </tr>
   <tr>
     <td class="left">Dutch</td>
-    <td class="right">1030</td>
-    <td class="right translated">1027</td>
+    <td class="right">1068</td>
+    <td class="right translated">1022</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">3</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">46</td>
+    <td class="right">96 %</td>
     <td class="center">2018-09-06</td>
   </tr>
   <tr>
     <td class="left">English</td>
-    <td class="right">1031</td>
-    <td class="right translated">1031</td>
+    <td class="right">1069</td>
+    <td class="right translated">1069</td>
     <td class="right fuzzy">0</td>
     <td class="right untranslated">0</td>
     <td class="right">100 %</td>
-    <td class="center">2021-05-27</td>
+    <td class="center">2021-06-20</td>
   </tr>
   <tr>
     <td class="left">Finnish</td>
-    <td class="right">1030</td>
-    <td class="right translated">914</td>
+    <td class="right">1068</td>
+    <td class="right translated">908</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">116</td>
-    <td class="right">89 %</td>
+    <td class="right untranslated">160</td>
+    <td class="right">85 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">French</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-29</td>
   </tr>
   <tr>
     <td class="left">Galician</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-18</td>
   </tr>
   <tr>
     <td class="left">German</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-24</td>
   </tr>
   <tr>
     <td class="left">Greek</td>
-    <td class="right">1030</td>
-    <td class="right translated">613</td>
+    <td class="right">1068</td>
+    <td class="right translated">608</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">417</td>
-    <td class="right">60 %</td>
+    <td class="right untranslated">460</td>
+    <td class="right">57 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Hungarian</td>
-    <td class="right">1030</td>
-    <td class="right translated">1027</td>
+    <td class="right">1068</td>
+    <td class="right translated">1022</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">3</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">46</td>
+    <td class="right">96 %</td>
     <td class="center">2021-03-15</td>
   </tr>
   <tr>
     <td class="left">Italian</td>
-    <td class="right">1030</td>
-    <td class="right translated">917</td>
+    <td class="right">1068</td>
+    <td class="right translated">911</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">113</td>
-    <td class="right">89 %</td>
+    <td class="right untranslated">157</td>
+    <td class="right">85 %</td>
     <td class="center">2019-07-12</td>
   </tr>
   <tr>
     <td class="left">Japanese</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1068</td>
     <td class="right fuzzy">0</td>
     <td class="right untranslated">0</td>
     <td class="right">100 %</td>
-    <td class="center">2021-03-31</td>
+    <td class="center">2021-06-20</td>
   </tr>
   <tr>
     <td class="left">Korean</td>
-    <td class="right">1030</td>
-    <td class="right translated">998</td>
+    <td class="right">1068</td>
+    <td class="right translated">993</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">32</td>
-    <td class="right">97 %</td>
+    <td class="right untranslated">75</td>
+    <td class="right">93 %</td>
     <td class="center">2021-03-30</td>
   </tr>
   <tr>
     <td class="left">Lithuanian</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-26</td>
   </tr>
   <tr>
     <td class="left">Norwegian</td>
-    <td class="right">1030</td>
-    <td class="right translated">642</td>
+    <td class="right">1068</td>
+    <td class="right translated">636</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">388</td>
-    <td class="right">62 %</td>
+    <td class="right untranslated">432</td>
+    <td class="right">60 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Persian</td>
-    <td class="right">1030</td>
-    <td class="right translated">653</td>
+    <td class="right">1068</td>
+    <td class="right translated">647</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">377</td>
-    <td class="right">63 %</td>
+    <td class="right untranslated">421</td>
+    <td class="right">61 %</td>
     <td class="center">2013-08-15</td>
   </tr>
   <tr>
     <td class="left">Polish</td>
-    <td class="right">1030</td>
-    <td class="right translated">1020</td>
+    <td class="right">1068</td>
+    <td class="right translated">1015</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">10</td>
-    <td class="right">99 %</td>
+    <td class="right untranslated">53</td>
+    <td class="right">95 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Portuguese</td>
-    <td class="right">1030</td>
-    <td class="right translated">1029</td>
+    <td class="right">1068</td>
+    <td class="right translated">1024</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">1</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">44</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-10</td>
   </tr>
   <tr>
     <td class="left">Romanian</td>
-    <td class="right">1030</td>
-    <td class="right translated">571</td>
+    <td class="right">1068</td>
+    <td class="right translated">565</td>
     <td class="right fuzzy">44</td>
-    <td class="right untranslated">415</td>
-    <td class="right">60 %</td>
+    <td class="right untranslated">459</td>
+    <td class="right">57 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Russian</td>
-    <td class="right">1030</td>
-    <td class="right translated">1011</td>
+    <td class="right">1068</td>
+    <td class="right translated">1007</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">19</td>
-    <td class="right">98 %</td>
+    <td class="right untranslated">61</td>
+    <td class="right">94 %</td>
     <td class="center">2021-04-29</td>
   </tr>
   <tr>
     <td class="left">Serbian</td>
-    <td class="right">1030</td>
-    <td class="right translated">641</td>
+    <td class="right">1068</td>
+    <td class="right translated">635</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">389</td>
-    <td class="right">62 %</td>
+    <td class="right untranslated">433</td>
+    <td class="right">59 %</td>
     <td class="center"></td>
   </tr>
   <tr>
     <td class="left">Sinhala</td>
-    <td class="right">1030</td>
-    <td class="right translated">571</td>
-    <td class="right fuzzy">63</td>
-    <td class="right untranslated">396</td>
-    <td class="right">62 %</td>
+    <td class="right">1068</td>
+    <td class="right translated">569</td>
+    <td class="right fuzzy">59</td>
+    <td class="right untranslated">440</td>
+    <td class="right">59 %</td>
     <td class="center">2010-12-12</td>
   </tr>
   <tr>
     <td class="left">Slovak</td>
-    <td class="right">1030</td>
-    <td class="right translated">987</td>
+    <td class="right">1068</td>
+    <td class="right translated">981</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">43</td>
-    <td class="right">96 %</td>
+    <td class="right untranslated">87</td>
+    <td class="right">92 %</td>
     <td class="center">2020-11-02</td>
   </tr>
   <tr>
     <td class="left">Slovenian</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-24</td>
   </tr>
   <tr>
     <td class="left">Spanish</td>
-    <td class="right">1030</td>
-    <td class="right translated">883</td>
+    <td class="right">1068</td>
+    <td class="right translated">877</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">147</td>
-    <td class="right">86 %</td>
+    <td class="right untranslated">191</td>
+    <td class="right">82 %</td>
     <td class="center">2020-04-03</td>
   </tr>
   <tr>
     <td class="left">Swedish</td>
-    <td class="right">1030</td>
-    <td class="right translated">1029</td>
+    <td class="right">1068</td>
+    <td class="right translated">1024</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">1</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">44</td>
+    <td class="right">96 %</td>
     <td class="center">2021-04-10</td>
   </tr>
   <tr>
     <td class="left">Turkish</td>
-    <td class="right">1030</td>
-    <td class="right translated">1030</td>
+    <td class="right">1068</td>
+    <td class="right translated">1025</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">0</td>
-    <td class="right">100 %</td>
+    <td class="right untranslated">43</td>
+    <td class="right">96 %</td>
     <td class="center">2021-05-24</td>
   </tr>
   <tr>
     <td class="left">Ukrainian</td>
-    <td class="right">1030</td>
-    <td class="right translated">647</td>
+    <td class="right">1068</td>
+    <td class="right translated">641</td>
     <td class="right fuzzy">0</td>
-    <td class="right untranslated">383</td>
-    <td class="right">63 %</td>
+    <td class="right untranslated">427</td>
+    <td class="right">60 %</td>
     <td class="center">2009-06-13</td>
   </tr>
 </table>
index f26927c..deba785 100644 (file)
@@ -1,47 +1,47 @@
 # Translations Status
 
-Status from **2021-05-27**:
+Status from **2021-06-20**:
 
 ## WinMerge
 
 | Language             | Total | Translated | Fuzzy | Untranslated | Complete | Last Update |
 |:---------------------|------:|-----------:|------:|-------------:|---------:|:-----------:|
-| Arabic               |  1030 |        914 |     0 |          116 |     89 % |  2019-12-30 |
-| Basque               |  1030 |        650 |     0 |          380 |     63 % |  2013-02-03 |
-| Brazilian            |  1030 |       1029 |     0 |            1 |    100 % |  2021-02-14 |
-| Bulgarian            |  1030 |        955 |     0 |           75 |     93 % |  2021-02-11 |
-| Catalan              |  1030 |        575 |     0 |          455 |     56 % |             |
-| ChineseSimplified    |  1030 |        987 |     0 |           43 |     96 % |             |
-| ChineseTraditional   |  1030 |        867 |     0 |          163 |     84 % |  2010-02-19 |
-| Croatian             |  1030 |        641 |     1 |          388 |     62 % |  2009-02-13 |
-| Czech                |  1030 |        613 |     0 |          417 |     60 % |             |
-| Danish               |  1030 |        650 |     0 |          380 |     63 % |  2013-01-13 |
-| Dutch                |  1030 |       1027 |     0 |            3 |    100 % |  2018-09-06 |
-| English              |  1031 |       1031 |     0 |            0 |    100 % |  2021-05-27 |
-| Finnish              |  1030 |        914 |     0 |          116 |     89 % |             |
-| French               |  1030 |       1030 |     0 |            0 |    100 % |  2021-04-29 |
-| Galician             |  1030 |       1030 |     0 |            0 |    100 % |  2021-04-18 |
-| German               |  1030 |       1030 |     0 |            0 |    100 % |  2021-04-24 |
-| Greek                |  1030 |        613 |     0 |          417 |     60 % |             |
-| Hungarian            |  1030 |       1027 |     0 |            3 |    100 % |  2021-03-15 |
-| Italian              |  1030 |        917 |     0 |          113 |     89 % |  2019-07-12 |
-| Japanese             |  1030 |       1030 |     0 |            0 |    100 % |  2021-03-31 |
-| Korean               |  1030 |        998 |     0 |           32 |     97 % |  2021-03-30 |
-| Lithuanian           |  1030 |       1030 |     0 |            0 |    100 % |  2021-04-26 |
-| Norwegian            |  1030 |        642 |     0 |          388 |     62 % |             |
-| Persian              |  1030 |        653 |     0 |          377 |     63 % |  2013-08-15 |
-| Polish               |  1030 |       1020 |     0 |           10 |     99 % |             |
-| Portuguese           |  1030 |       1029 |     0 |            1 |    100 % |  2021-04-10 |
-| Romanian             |  1030 |        571 |    44 |          415 |     60 % |             |
-| Russian              |  1030 |       1011 |     0 |           19 |     98 % |  2021-04-29 |
-| Serbian              |  1030 |        641 |     0 |          389 |     62 % |             |
-| Sinhala              |  1030 |        571 |    63 |          396 |     62 % |  2010-12-12 |
-| Slovak               |  1030 |        987 |     0 |           43 |     96 % |  2020-11-02 |
-| Slovenian            |  1030 |       1030 |     0 |            0 |    100 % |  2021-04-24 |
-| Spanish              |  1030 |        883 |     0 |          147 |     86 % |  2020-04-03 |
-| Swedish              |  1030 |       1029 |     0 |            1 |    100 % |  2021-04-10 |
-| Turkish              |  1030 |       1030 |     0 |            0 |    100 % |  2021-05-24 |
-| Ukrainian            |  1030 |        647 |     0 |          383 |     63 % |  2009-06-13 |
+| Arabic               |  1068 |        908 |     0 |          160 |     85 % |  2019-12-30 |
+| Basque               |  1068 |        644 |     0 |          424 |     60 % |  2013-02-03 |
+| Brazilian            |  1068 |       1024 |     0 |           44 |     96 % |  2021-02-14 |
+| Bulgarian            |  1068 |        951 |     0 |          117 |     89 % |  2021-02-11 |
+| Catalan              |  1068 |        570 |     0 |          498 |     53 % |             |
+| ChineseSimplified    |  1068 |        981 |     0 |           87 |     92 % |             |
+| ChineseTraditional   |  1068 |        861 |     0 |          207 |     81 % |  2010-02-19 |
+| Croatian             |  1068 |        635 |     1 |          432 |     60 % |  2009-02-13 |
+| Czech                |  1068 |        610 |     0 |          458 |     57 % |             |
+| Danish               |  1068 |        644 |     0 |          424 |     60 % |  2013-01-13 |
+| Dutch                |  1068 |       1022 |     0 |           46 |     96 % |  2018-09-06 |
+| English              |  1069 |       1069 |     0 |            0 |    100 % |  2021-06-20 |
+| Finnish              |  1068 |        908 |     0 |          160 |     85 % |             |
+| French               |  1068 |       1025 |     0 |           43 |     96 % |  2021-04-29 |
+| Galician             |  1068 |       1025 |     0 |           43 |     96 % |  2021-04-18 |
+| German               |  1068 |       1025 |     0 |           43 |     96 % |  2021-04-24 |
+| Greek                |  1068 |        608 |     0 |          460 |     57 % |             |
+| Hungarian            |  1068 |       1022 |     0 |           46 |     96 % |  2021-03-15 |
+| Italian              |  1068 |        911 |     0 |          157 |     85 % |  2019-07-12 |
+| Japanese             |  1068 |       1068 |     0 |            0 |    100 % |  2021-06-20 |
+| Korean               |  1068 |        993 |     0 |           75 |     93 % |  2021-03-30 |
+| Lithuanian           |  1068 |       1025 |     0 |           43 |     96 % |  2021-04-26 |
+| Norwegian            |  1068 |        636 |     0 |          432 |     60 % |             |
+| Persian              |  1068 |        647 |     0 |          421 |     61 % |  2013-08-15 |
+| Polish               |  1068 |       1015 |     0 |           53 |     95 % |             |
+| Portuguese           |  1068 |       1024 |     0 |           44 |     96 % |  2021-04-10 |
+| Romanian             |  1068 |        565 |    44 |          459 |     57 % |             |
+| Russian              |  1068 |       1007 |     0 |           61 |     94 % |  2021-04-29 |
+| Serbian              |  1068 |        635 |     0 |          433 |     59 % |             |
+| Sinhala              |  1068 |        569 |    59 |          440 |     59 % |  2010-12-12 |
+| Slovak               |  1068 |        981 |     0 |           87 |     92 % |  2020-11-02 |
+| Slovenian            |  1068 |       1025 |     0 |           43 |     96 % |  2021-04-24 |
+| Spanish              |  1068 |        877 |     0 |          191 |     82 % |  2020-04-03 |
+| Swedish              |  1068 |       1024 |     0 |           44 |     96 % |  2021-04-10 |
+| Turkish              |  1068 |       1025 |     0 |           43 |     96 % |  2021-05-24 |
+| Ukrainian            |  1068 |        641 |     0 |          427 |     60 % |  2009-06-13 |
 
 ## ShellExtension
 
index f18458a..03d24b8 100644 (file)
@@ -1,16 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <status>
-  <update>2021-05-27</update>
+  <update>2021-06-20</update>
   <translations project="WinMerge">
     <translation>
       <language>Arabic</language>
       <file>Arabic.po</file>
       <update>2019-12-30</update>
       <strings>
-        <count>1030</count>
-        <translated>914</translated>
+        <count>1068</count>
+        <translated>908</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>116</untranslated>
+        <untranslated>160</untranslated>
       </strings>
     </translation>
     <translation>
       <file>Basque.po</file>
       <update>2013-02-03</update>
       <strings>
-        <count>1030</count>
-        <translated>650</translated>
+        <count>1068</count>
+        <translated>644</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>380</untranslated>
+        <untranslated>424</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Brazilian.po</file>
       <update>2021-02-14</update>
       <strings>
-        <count>1030</count>
-        <translated>1029</translated>
+        <count>1068</count>
+        <translated>1024</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>1</untranslated>
+        <untranslated>44</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Bulgarian.po</file>
       <update>2021-02-11</update>
       <strings>
-        <count>1030</count>
-        <translated>955</translated>
+        <count>1068</count>
+        <translated>951</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>75</untranslated>
+        <untranslated>117</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Catalan.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>575</translated>
+        <count>1068</count>
+        <translated>570</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>455</untranslated>
+        <untranslated>498</untranslated>
       </strings>
       <translators>
         <translator>
       <file>ChineseSimplified.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>987</translated>
+        <count>1068</count>
+        <translated>981</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>43</untranslated>
+        <untranslated>87</untranslated>
       </strings>
       <translators>
         <translator>
       <file>ChineseTraditional.po</file>
       <update>2010-02-19</update>
       <strings>
-        <count>1030</count>
-        <translated>867</translated>
+        <count>1068</count>
+        <translated>861</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>163</untranslated>
+        <untranslated>207</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Croatian.po</file>
       <update>2009-02-13</update>
       <strings>
-        <count>1030</count>
-        <translated>641</translated>
+        <count>1068</count>
+        <translated>635</translated>
         <fuzzy>1</fuzzy>
-        <untranslated>388</untranslated>
+        <untranslated>432</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Czech.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>613</translated>
+        <count>1068</count>
+        <translated>610</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>417</untranslated>
+        <untranslated>458</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Danish.po</file>
       <update>2013-01-13</update>
       <strings>
-        <count>1030</count>
-        <translated>650</translated>
+        <count>1068</count>
+        <translated>644</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>380</untranslated>
+        <untranslated>424</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Dutch.po</file>
       <update>2018-09-06</update>
       <strings>
-        <count>1030</count>
-        <translated>1027</translated>
+        <count>1068</count>
+        <translated>1022</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>3</untranslated>
+        <untranslated>46</untranslated>
       </strings>
       <translators>
         <translator>
     <translation template="1">
       <language>English</language>
       <file>English.pot</file>
-      <update>2021-05-27</update>
+      <update>2021-06-20</update>
       <strings>
-        <count>1031</count>
-        <translated>1031</translated>
+        <count>1069</count>
+        <translated>1069</translated>
         <fuzzy>0</fuzzy>
         <untranslated>0</untranslated>
       </strings>
       <file>Finnish.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>914</translated>
+        <count>1068</count>
+        <translated>908</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>116</untranslated>
+        <untranslated>160</untranslated>
       </strings>
     </translation>
     <translation>
       <file>French.po</file>
       <update>2021-04-29</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator maintainer="1">
       <file>Galician.po</file>
       <update>2021-04-18</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator>
       <file>German.po</file>
       <update>2021-04-24</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator maintainer="1">
       <file>Greek.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>613</translated>
+        <count>1068</count>
+        <translated>608</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>417</untranslated>
+        <untranslated>460</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Hungarian.po</file>
       <update>2021-03-15</update>
       <strings>
-        <count>1030</count>
-        <translated>1027</translated>
+        <count>1068</count>
+        <translated>1022</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>3</untranslated>
+        <untranslated>46</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Italian.po</file>
       <update>2019-07-12</update>
       <strings>
-        <count>1030</count>
-        <translated>917</translated>
+        <count>1068</count>
+        <translated>911</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>113</untranslated>
+        <untranslated>157</untranslated>
       </strings>
       <translators>
         <translator>
     <translation>
       <language>Japanese</language>
       <file>Japanese.po</file>
-      <update>2021-03-31</update>
+      <update>2021-06-20</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1068</translated>
         <fuzzy>0</fuzzy>
         <untranslated>0</untranslated>
       </strings>
       <file>Korean.po</file>
       <update>2021-03-30</update>
       <strings>
-        <count>1030</count>
-        <translated>998</translated>
+        <count>1068</count>
+        <translated>993</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>32</untranslated>
+        <untranslated>75</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Lithuanian.po</file>
       <update>2021-04-26</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Norwegian.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>642</translated>
+        <count>1068</count>
+        <translated>636</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>388</untranslated>
+        <untranslated>432</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Persian.po</file>
       <update>2013-08-15</update>
       <strings>
-        <count>1030</count>
-        <translated>653</translated>
+        <count>1068</count>
+        <translated>647</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>377</untranslated>
+        <untranslated>421</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Polish.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>1020</translated>
+        <count>1068</count>
+        <translated>1015</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>10</untranslated>
+        <untranslated>53</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Portuguese.po</file>
       <update>2021-04-10</update>
       <strings>
-        <count>1030</count>
-        <translated>1029</translated>
+        <count>1068</count>
+        <translated>1024</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>1</untranslated>
+        <untranslated>44</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Romanian.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>571</translated>
+        <count>1068</count>
+        <translated>565</translated>
         <fuzzy>44</fuzzy>
-        <untranslated>415</untranslated>
+        <untranslated>459</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Russian.po</file>
       <update>2021-04-29</update>
       <strings>
-        <count>1030</count>
-        <translated>1011</translated>
+        <count>1068</count>
+        <translated>1007</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>19</untranslated>
+        <untranslated>61</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Serbian.po</file>
       <update></update>
       <strings>
-        <count>1030</count>
-        <translated>641</translated>
+        <count>1068</count>
+        <translated>635</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>389</untranslated>
+        <untranslated>433</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Sinhala.po</file>
       <update>2010-12-12</update>
       <strings>
-        <count>1030</count>
-        <translated>571</translated>
-        <fuzzy>63</fuzzy>
-        <untranslated>396</untranslated>
+        <count>1068</count>
+        <translated>569</translated>
+        <fuzzy>59</fuzzy>
+        <untranslated>440</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Slovak.po</file>
       <update>2020-11-02</update>
       <strings>
-        <count>1030</count>
-        <translated>987</translated>
+        <count>1068</count>
+        <translated>981</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>43</untranslated>
+        <untranslated>87</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Slovenian.po</file>
       <update>2021-04-24</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Spanish.po</file>
       <update>2020-04-03</update>
       <strings>
-        <count>1030</count>
-        <translated>883</translated>
+        <count>1068</count>
+        <translated>877</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>147</untranslated>
+        <untranslated>191</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Swedish.po</file>
       <update>2021-04-10</update>
       <strings>
-        <count>1030</count>
-        <translated>1029</translated>
+        <count>1068</count>
+        <translated>1024</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>1</untranslated>
+        <untranslated>44</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Turkish.po</file>
       <update>2021-05-24</update>
       <strings>
-        <count>1030</count>
-        <translated>1030</translated>
+        <count>1068</count>
+        <translated>1025</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>0</untranslated>
+        <untranslated>43</untranslated>
       </strings>
       <translators>
         <translator>
       <file>Ukrainian.po</file>
       <update>2009-06-13</update>
       <strings>
-        <count>1030</count>
-        <translated>647</translated>
+        <count>1068</count>
+        <translated>641</translated>
         <fuzzy>0</fuzzy>
-        <untranslated>383</untranslated>
+        <untranslated>427</untranslated>
       </strings>
       <translators>
         <translator>
index 28a688d..5598d39 100644 (file)
@@ -51,8 +51,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "تحديد الاختلاف في الس&طر\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "تحديد الاختلاف في السطر"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -72,6 +72,12 @@ msgstr "&نسخ"
 msgid "&Paste"
 msgstr "&لصق"
 
+msgid "&Scripts"
+msgstr "لغة نصية (سكريبت)"
+
+msgid "< Empty >"
+msgstr "<فارغ>"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "ال&ذهاب إلى...\tCtrl+G"
 
@@ -221,9 +227,6 @@ msgstr "المشاريع الأخيرة"
 msgid "Recent F&iles Or Folders"
 msgstr "الملفات أو المجلدات الأخيرة"
 
-msgid "< Empty >"
-msgstr "<فارغ>"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&خروج\tCtrl+Q"
 
@@ -512,9 +515,6 @@ msgstr "إ&عادة تحميل\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "إعادة مقارنة بصيغة أخرى"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&تراجع"
 
@@ -530,9 +530,6 @@ msgstr "&نسخ"
 msgid "&Paste\tCtrl+V"
 msgstr "&لصق"
 
-msgid "Select Line &Difference\tF4"
-msgstr "تحديد الاختلاف في السطر"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "&بحث"
 
@@ -698,11 +695,14 @@ msgstr "إضافة نقطة مزامنة\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "مسح كل نقاط المزامنة"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "الفروقات المسبقة"
 
-msgid "&Scripts"
-msgstr "لغة نصية (سكريبت)"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "فصل"
@@ -865,14 +865,20 @@ msgstr "&نسخ المسار الكامل"
 msgid "Copy &Filename"
 msgstr "نسخ اسم الملف"
 
-msgid "Prediffer Settings"
-msgstr "إعدادات الاختلافات المسبقة"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<لا يوجد>"
+
+msgid "<Automatic>"
+msgstr "<تلقائي>"
 
-msgid "&No prediffer"
-msgstr "لا يوجد اختلافات مسبقة"
+msgid "&Select..."
+msgstr "&تحديد..."
 
-msgid "Auto prediffer"
-msgstr "اختÙ\84اÙ\81ات Ù\85سبÙ\82Ø© ØªÙ\84Ù\82ائÙ\8aة"
+msgid "Prediffer Settings"
+msgstr "إعدادات Ø§Ù\84اختÙ\84اÙ\81ات Ø§Ù\84Ù\85سبÙ\82ة"
 
 msgid "G&o to Diff"
 msgstr "الذهاب إلى أداة مقارنة الملفات Diff"
@@ -993,9 +999,6 @@ msgstr "بحث..."
 msgid " Folder: Filter"
 msgstr " مجلد: مرشح"
 
-msgid "&Select..."
-msgstr "&تحديد..."
-
 msgid " File: Unpacker Plugin"
 msgstr " ملف: إضافة فك الحزمة"
 
@@ -1295,14 +1298,11 @@ msgstr "التحرك إلى الأ&على"
 msgid "Move &Down"
 msgstr "التحرك إلى الأ&سفل"
 
-msgid "Select Unpacker"
-msgstr "اختيار أداة فك الحزمة"
-
-msgid "File unpacker:"
-msgstr "أداة فك الملف:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "عرض كل أدوات فك الحزم، لا تتحقق من امتداد الملف."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "قائمة امتدادات الملفات:"
@@ -1310,6 +1310,18 @@ msgstr "قائمة امتدادات الملفات:"
 msgid "Description:"
 msgstr "الوصف:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "عرض كل أدوات فك الحزم، لا تتحقق من امتداد الملف."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "إيقاف"
 
@@ -1773,6 +1785,12 @@ msgstr "تفعيل الإضافات"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "دمج الطرفية"
 
@@ -2727,6 +2745,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "ثنائي"
 
+msgid "Unpacker"
+msgstr "فك الحزمة"
+
+msgid "Prediffer"
+msgstr "اختلافات مسبقة"
+
 msgid "Unable to compare files"
 msgstr "لا يمكن مقارنة الملفات"
 
@@ -2925,6 +2949,12 @@ msgstr "عدد الاختلافات في الملف. هذه العدد لا يش
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "ضع علامة النجمة (*) إذا كان الملف ثنائي."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "قارن بين %1 و %2"
@@ -3188,12 +3218,6 @@ msgstr ""
 msgid "Type"
 msgstr "النوع"
 
-msgid "Unpacker"
-msgstr "فك الحزمة"
-
-msgid "Prediffer"
-msgstr "اختلافات مسبقة"
-
 msgid "Editor script"
 msgstr "محرر اللغة النصية (سكريبت)"
 
@@ -3365,12 +3389,6 @@ msgstr "إعدادات الإضافات"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH غير موجود - .sct سكربت معطل"
 
-msgid "<None>"
-msgstr "<لا يوجد>"
-
-msgid "<Automatic>"
-msgstr "<تلقائي>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "إ&ذهب إلى السطر %1"
@@ -3589,3 +3607,101 @@ msgstr "السماح بتشغيل عنصر واحد فقط"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 17d41db..53d5708 100644 (file)
@@ -59,8 +59,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "Hautatu &Lerro Ezberdintasuna\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Hautatu Lerro &Ezberdintasunak\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -85,6 +86,14 @@ msgstr "&Kopiatu"
 msgid "&Paste"
 msgstr "&Itsatsi"
 
+#, c-format
+msgid "&Scripts"
+msgstr "E&skriptak"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Hutsik >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Joan hona...\tCtrl+G"
 
@@ -264,10 +273,6 @@ msgstr "Azken Egitasmoak"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Hutsik >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Ir&ten\tCtrl+Q"
 
@@ -642,10 +647,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Desegin\tCtrl+Z"
 
@@ -666,10 +667,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Itsatsi\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Hautatu Lerro &Ezberdintasunak\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Bilatu...\tCtrl+F"
 
@@ -884,13 +881,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "Au&rrezberdintasuna"
 
-#, c-format
-msgid "&Scripts"
-msgstr "E&skriptak"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1082,17 +1081,24 @@ msgstr "Kopiatu Helburu O&soa"
 msgid "Copy &Filename"
 msgstr "Kopiatu &Agirizena"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Aurrezberdintasun Ezarpenak"
+msgid "<None>"
+msgstr "<Ezer ez>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Berezgaitasunez>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Ez aurrezberd"
+msgid "&Select..."
+msgstr "&Hautatu..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Berez aurrezberd"
+msgid "Prediffer Settings"
+msgstr "Aurrezberdintasun Ezarpenak"
 
 msgid "G&o to Diff"
 msgstr "Jo&an Ezberd"
@@ -1248,10 +1254,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "&Hautatu..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1629,16 +1631,11 @@ msgstr "Mugitu &Gora"
 msgid "Move &Down"
 msgstr "Mugitu &Behera"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Hautatu Despaketatzailea"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Agiri Despaketatzailea:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Erakutsi despaketatzaile denak, ez egiaztatu luzapena."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1648,6 +1645,18 @@ msgstr "Luzapen zerrenda:"
 msgid "Description:"
 msgstr "Azalpena:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Erakutsi despaketatzaile denak, ez egiaztatu luzapena."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Gelditu"
@@ -2238,6 +2247,12 @@ msgstr "Gaitu &pluginak"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Shell Baterapena"
@@ -3295,6 +3310,14 @@ msgid "Binary"
 msgstr "Binarioa"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Despaketatzailea"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Aurrezberd"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Ezinezkoa agiriak alderatzea"
 
@@ -3537,6 +3560,12 @@ msgstr "Agirian dauden ezberdintasun zenbatekoa. Zenbateko honek ez ditu barnebi
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Erakutsi asteriskoa (*) agiria binarioa bada."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Alderatu %1 %2-rekin"
@@ -3837,14 +3866,6 @@ msgid "Type"
 msgstr "Mota"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Despaketatzailea"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Aurrezberd"
-
-#, c-format
 msgid "Editor script"
 msgstr "Editatzaile eskripta"
 
@@ -3967,14 +3988,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH ez da aurkitu - .sct eskriptak ezgaituta"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ezer ez>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Berezgaitasunez>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "&Joan lerro honetara: %1"
 
@@ -4200,3 +4213,101 @@ msgstr "Ahalbidetu ekinbide bat bakarrik "
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index f598044..ae8013c 100644 (file)
@@ -58,8 +58,9 @@ msgstr "Copiar a(s) linha(s) selecionada(s) da esquerda"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Copiar a(s) linha(s) selecionada(s) da direita"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Selecionar a Diferença da Linha\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Selecionar a &Diferença da Linha\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Adicionar esta mudança aos &filtros de substituição"
@@ -84,6 +85,14 @@ msgstr "&Copiar"
 msgid "&Paste"
 msgstr "&Colar"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Scripts"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Vazio >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Ir para...\tCtrl+G"
 
@@ -263,10 +272,6 @@ msgstr "Projetos Recentes"
 msgid "Recent F&iles Or Folders"
 msgstr "Arquivos ou P&astas Recentes"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Vazio >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "S&air\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr "Reco&mparar Como"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Desfazer\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Colar\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Selecionar a &Diferença da Linha\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "A&char...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr "Adicionar &Ponto de Sincronização\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Limpar Pont&os de Sincronização"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Copiar o Caminho Completo"
 msgid "Copy &Filename"
 msgstr "Copiar &o Nome do Arquivo"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Configurações do Prediffer"
+msgid "<None>"
+msgstr "<Nenhum>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automático>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Sem prediffer"
+msgid "&Select..."
+msgstr "&Selecionar..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Auto prediffer"
+msgid "Prediffer Settings"
+msgstr "Configurações do Prediffer"
 
 msgid "G&o to Diff"
 msgstr "I&r para o Diff"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr " Pasta: Filtro"
 
 #, c-format
-msgid "&Select..."
-msgstr "&Selecionar..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Arquivo: Plugin do Desempacotador"
 
@@ -1627,16 +1629,11 @@ msgstr "Mover &pra Cima"
 msgid "Move &Down"
 msgstr "Mover &pra Baixo"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Selecionar o Desempacotador"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Desempacotador do arquivo:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Exibir todos os desempacotadores, não verificar a extensão."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Lista das extensões:"
 msgid "Description:"
 msgstr "Descrição:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Exibir todos os desempacotadores, não verificar a extensão."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Parar"
@@ -2243,6 +2252,12 @@ msgstr "&Ativar plugins"
 msgid "File filters:"
 msgstr "Filtros de arquivo:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Integração com o Shell"
@@ -3351,6 +3366,14 @@ msgid "Binary"
 msgstr "Binário"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Desempacotador"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Incapaz de comparar os arquivos"
 
@@ -3593,6 +3616,12 @@ msgstr "Número de diferenças no arquivo. Este número não inclui as diferenç
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Mostrar um asterisco (*) se o arquivo é binário."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Comparar o %1 com o %2"
@@ -3908,14 +3937,6 @@ msgid "Type"
 msgstr "Tipo"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Desempacotador"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "Script do editor"
 
@@ -4126,14 +4147,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH não encontrado - scripts .sct desativados"
 
 #, c-format
-msgid "<None>"
-msgstr "<Nenhum>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automático>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "I&r pra Linha %1"
 
@@ -4366,3 +4379,101 @@ msgstr "Permitir só uma instância a executar"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Permitir só uma instância a executar e esperar a instância terminar"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 7774743..5afb498 100644 (file)
@@ -47,8 +47,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Избиране на разликите на реда\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Избиране &различията на реда\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Добавяне на промяна към заместващи &филтри"
@@ -68,6 +68,12 @@ msgstr "&Копиране"
 msgid "&Paste"
 msgstr "По&ставяне"
 
+msgid "&Scripts"
+msgstr "&Скриптове"
+
+msgid "< Empty >"
+msgstr "<празно>"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Отиване &към…\tCtrl+G"
 
@@ -217,9 +223,6 @@ msgstr "Последни проекти"
 msgid "Recent F&iles Or Folders"
 msgstr "Последни &файлове и папки"
 
-msgid "< Empty >"
-msgstr "<празно>"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Изход\tCtrl+Q"
 
@@ -508,9 +511,6 @@ msgstr "Пре&зареждане\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Сравняване &като"
 
-msgid "&XML"
-msgstr "Файлове на &XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&Отменяне\tCtrl+Z"
 
@@ -526,9 +526,6 @@ msgstr "&Копиране\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "&Поставяне\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Избиране &различията на реда\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "Търс&ене…\tCtrl+F"
 
@@ -694,11 +691,14 @@ msgstr "Добавяне точка за &синхронизация\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Изтриване точки за &синхронизация"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr ""
 
-msgid "&Scripts"
-msgstr "&Скриптове"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Ра&зделяне"
@@ -861,13 +861,19 @@ msgstr "&Копиране на пълния път"
 msgid "Copy &Filename"
 msgstr "Копиране на &името"
 
-msgid "Prediffer Settings"
+msgid "Unpacker Settings"
 msgstr ""
 
-msgid "&No prediffer"
-msgstr ""
+msgid "<None>"
+msgstr "<Няма>"
+
+msgid "<Automatic>"
+msgstr "<Автоматично>"
 
-msgid "Auto prediffer"
+msgid "&Select..."
+msgstr "&Избиране…"
+
+msgid "Prediffer Settings"
 msgstr ""
 
 msgid "G&o to Diff"
@@ -987,9 +993,6 @@ msgstr "Разглеждане…"
 msgid " Folder: Filter"
 msgstr " Папка: Филтър"
 
-msgid "&Select..."
-msgstr "&Избиране…"
-
 msgid " File: Unpacker Plugin"
 msgstr " Файл: Unpacker добавка"
 
@@ -1293,13 +1296,10 @@ msgstr "На&горе"
 msgid "Move &Down"
 msgstr "На&долу"
 
-msgid "Select Unpacker"
-msgstr "Избиране на приложение"
-
-msgid "File unpacker:"
-msgstr "Файлов разархиватор:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
+msgid "Plugin &Name:"
 msgstr ""
 
 msgid "Extensions list:"
@@ -1308,6 +1308,18 @@ msgstr "Списък на разширенията:"
 msgid "Description:"
 msgstr "Описание:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr ""
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Спиране"
 
@@ -1775,6 +1787,12 @@ msgstr "Включване на &добавките"
 msgid "File filters:"
 msgstr "Филтри за файлове:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Сливане със системата"
 
@@ -2772,6 +2790,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Двоичен"
 
+msgid "Unpacker"
+msgstr ""
+
+msgid "Prediffer"
+msgstr ""
+
 msgid "Unable to compare files"
 msgstr "Не може да бъде извършено сравняване на файлове"
 
@@ -2970,6 +2994,12 @@ msgstr "Брой различия във файла. Не включва пре
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Показва звездичка (*), ако файлът е двоичен."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Сравняване на %1 с %2"
@@ -3260,12 +3290,6 @@ msgstr ""
 msgid "Type"
 msgstr "Вид"
 
-msgid "Unpacker"
-msgstr ""
-
-msgid "Prediffer"
-msgstr ""
-
 msgid "Editor script"
 msgstr ""
 
@@ -3444,12 +3468,6 @@ msgstr "Настройки на добавките"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH не е намерен - скриптовете на .sct са забранени"
 
-msgid "<None>"
-msgstr "<Няма>"
-
-msgid "<Automatic>"
-msgstr "<Автоматично>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "От&иване на ред %1"
@@ -3668,3 +3686,101 @@ msgstr "Позволи само едно стартирано копие"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 246130f..e948fb7 100644 (file)
@@ -55,8 +55,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Selecciona la diferència a la línia\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Selecciona &la diferència a la línia\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -81,6 +82,14 @@ msgstr "C&opia"
 msgid "&Paste"
 msgstr "Engan&xa"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Seqüències d'ordres"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Buit >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Vés a...\tCtrl+G"
 
@@ -260,10 +269,6 @@ msgstr "Projectes re&cents"
 msgid "Recent F&iles Or Folders"
 msgstr "Fitxers i carpetes recents"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Buit >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Surt\tCtrl+Q"
 
@@ -638,10 +643,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr ""
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Desfés\tControl+Z"
 
@@ -662,10 +663,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Engan&xa\tControl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Selecciona &la diferència a la línia\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Cerca...\tControl+F"
 
@@ -880,13 +877,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediferenciació"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Seqüències d'ordres"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1079,17 +1078,24 @@ msgstr "&Copia el camí sencer al fitxer"
 msgid "Copy &Filename"
 msgstr "Copia el nom del &fitxer"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Ajustos de prediferenciació"
+msgid "<None>"
+msgstr "<Cap>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automàtic>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Sense prediferenciació"
+msgid "&Select..."
+msgstr "T&ria..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Prediferenciació &automàtica"
+msgid "Prediffer Settings"
+msgstr "Ajustos de prediferenciació"
 
 msgid "G&o to Diff"
 msgstr "Vé&s a la diferència"
@@ -1245,10 +1251,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "T&ria..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1626,16 +1628,11 @@ msgstr ""
 msgid "Move &Down"
 msgstr ""
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Tria el desempaquetador"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "&Desempaquetador de fitxer:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "&Visualitza tots els desempaquetadors sense verificar l'extensió."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1645,6 +1642,18 @@ msgstr "&Llistat d'extensions:"
 msgid "Description:"
 msgstr "&Descripció:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "&Visualitza tots els desempaquetadors sense verificar l'extensió."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "&Atura"
@@ -2234,6 +2243,12 @@ msgstr ""
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr ""
@@ -3238,6 +3253,14 @@ msgid "Binary"
 msgstr "Binari"
 
 #, c-format
+msgid "Unpacker"
+msgstr ""
+
+#, c-format
+msgid "Prediffer"
+msgstr ""
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "No es pot comparar els fitxers"
 
@@ -3480,6 +3503,12 @@ msgstr "Nombre de diferències al fitxer. Aquest nombre no inclou les diferènci
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Mostra un asterisc (*) si el fitxer és binari."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Compara %1 amb %2"
@@ -3767,14 +3796,6 @@ msgid "Type"
 msgstr ""
 
 #, c-format
-msgid "Unpacker"
-msgstr ""
-
-#, c-format
-msgid "Prediffer"
-msgstr ""
-
-#, c-format
 msgid "Editor script"
 msgstr ""
 
@@ -3897,14 +3918,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "No s'ha trobat el WSH - seqüències d'ordres .sct inhabilitades"
 
 #, c-format
-msgid "<None>"
-msgstr "<Cap>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automàtic>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Va fins a la línia %1"
 
@@ -4131,3 +4144,101 @@ msgstr "Permet d'executar només una instància"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index dd8a6ec..d015cdd 100644 (file)
@@ -53,8 +53,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "选中行内差异(&S)\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "选中行内差异(&D)\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -74,6 +74,12 @@ msgstr "复制(&C)"
 msgid "&Paste"
 msgstr "粘贴(&P)"
 
+msgid "&Scripts"
+msgstr "脚本(&S)"
+
+msgid "< Empty >"
+msgstr "< 空 >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "转到(&G)...\tCtrl+G"
 
@@ -223,9 +229,6 @@ msgstr "最近打开的工程"
 msgid "Recent F&iles Or Folders"
 msgstr "最近打开的文件或文件夹(&I)"
 
-msgid "< Empty >"
-msgstr "< 空 >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "退出(&X)\tCtrl+Q"
 
@@ -514,9 +517,6 @@ msgstr "重新加载(&L)\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "重新比较(&M)"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "撤销(&U)\tCtrl+Z"
 
@@ -532,9 +532,6 @@ msgstr "复制(&C)\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "粘贴(&P)\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "选中行内差异(&D)\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "查找(&I)...\tCtrl+F"
 
@@ -700,11 +697,14 @@ msgstr "添加同步点(&S)\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "清除同步点(&H)"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "预处理(&P)"
 
-msgid "&Scripts"
-msgstr "脚本(&S)"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "分隔(&L)"
@@ -867,14 +867,20 @@ msgstr "复制完整路径(&C)"
 msgid "Copy &Filename"
 msgstr "复制文件名(&F)"
 
-msgid "Prediffer Settings"
-msgstr "设置预处理器"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<无>"
+
+msgid "<Automatic>"
+msgstr "<自动>"
 
-msgid "&No prediffer"
-msgstr "无预处理器(&N)"
+msgid "&Select..."
+msgstr "选择(&S)..."
 
-msgid "Auto prediffer"
-msgstr "è\87ªå\8a¨é¢\84å¤\84ç\90\86"
+msgid "Prediffer Settings"
+msgstr "设置é¢\84å¤\84ç\90\86å\99¨"
 
 msgid "G&o to Diff"
 msgstr "转到差异(&O)"
@@ -993,9 +999,6 @@ msgstr "浏览..."
 msgid " Folder: Filter"
 msgstr " 文件夹: 过滤器"
 
-msgid "&Select..."
-msgstr "选择(&S)..."
-
 msgid " File: Unpacker Plugin"
 msgstr " 文件: 解包插件"
 
@@ -1296,14 +1299,11 @@ msgstr "上移(&U)"
 msgid "Move &Down"
 msgstr "下移(&D)"
 
-msgid "Select Unpacker"
-msgstr "选择解包程序"
-
-msgid "File unpacker:"
-msgstr "文件解包程序:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "不检查扩展名,显示所有解包器。"
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "扩展名:"
@@ -1311,6 +1311,18 @@ msgstr "扩展名:"
 msgid "Description:"
 msgstr "描述:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "不检查扩展名,显示所有解包器。"
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "停止"
 
@@ -1778,6 +1790,12 @@ msgstr "启用插件(&E)"
 msgid "File filters:"
 msgstr "文件过滤器:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "外壳集成"
 
@@ -2753,6 +2771,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "二进制"
 
+msgid "Unpacker"
+msgstr "解包器"
+
+msgid "Prediffer"
+msgstr "预处理器"
+
 msgid "Unable to compare files"
 msgstr "无法比较文件"
 
@@ -2949,6 +2973,12 @@ msgstr "文件中的差异数。不包括忽略的差异。"
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "在二进制文件处显示星号(*)。"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "比较 %1 和 %2"
@@ -3226,12 +3256,6 @@ msgstr "新模式"
 msgid "Type"
 msgstr "类型"
 
-msgid "Unpacker"
-msgstr "解包器"
-
-msgid "Prediffer"
-msgstr "预处理器"
-
 msgid "Editor script"
 msgstr "编辑器脚本"
 
@@ -3404,12 +3428,6 @@ msgstr "插件设置"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH 未找到 - .sct 脚本已禁用"
 
-msgid "<None>"
-msgstr "<无>"
-
-msgid "<Automatic>"
-msgstr "<自动>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "转到第 %1 行(&O)"
@@ -3628,3 +3646,101 @@ msgstr "只允许运行一个实例"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 5005c7a..adc7f47 100644 (file)
@@ -58,8 +58,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "選取行內差異(&S)\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "選取行內差異(&D)\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -84,6 +85,14 @@ msgstr "複製(&C)"
 msgid "&Paste"
 msgstr "貼上(&P)"
 
+#, c-format
+msgid "&Scripts"
+msgstr "隨譯即行碼(&S)"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< 無 >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "跳至(&G)...\tCtrl+G"
 
@@ -263,10 +272,6 @@ msgstr "最近開啟的專案"
 msgid "Recent F&iles Or Folders"
 msgstr "最近開啟檔案或資料夾(&I)"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< 無 >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "結束(&X)\tCtrl+Q"
 
@@ -643,10 +648,6 @@ msgid "Reco&mpare As"
 msgstr "重新比較(&M)"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "復原(&U)\tCtrl+Z"
 
@@ -667,10 +668,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "貼上(&P)\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "選取行內差異(&D)\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "尋找(&I)...\tCtrl+F"
 
@@ -889,13 +886,15 @@ msgstr "新增同步點(&S)\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "清除同步點(&H)"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "先行處理器(&P)"
 
-#, c-format
-msgid "&Scripts"
-msgstr "隨譯即行碼(&S)"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1088,17 +1087,24 @@ msgstr "複製完整路徑(&C)"
 msgid "Copy &Filename"
 msgstr "複製檔名(&F)"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "先行處理器設定"
+msgid "<None>"
+msgstr "<無>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<自動>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "不要先行處理器(&N)"
+msgid "&Select..."
+msgstr "選取(&S)..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "自動先行處理器"
+msgid "Prediffer Settings"
+msgstr "先行處理器設定"
 
 msgid "G&o to Diff"
 msgstr "至差異區塊(&O)"
@@ -1254,10 +1260,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "選取(&S)..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1637,16 +1639,11 @@ msgstr "上移(&U)"
 msgid "Move &Down"
 msgstr "下移(&D)"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "選取解壓縮程式"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "檔案解壓縮程式:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "顯示所有解壓縮程式,不要檢查副檔名"
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1656,6 +1653,18 @@ msgstr "副檔名清單:"
 msgid "Description:"
 msgstr "描述:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "顯示所有解壓縮程式,不要檢查副檔名"
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "停止"
@@ -2248,6 +2257,12 @@ msgstr "啟用外掛(&E)"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "併入檔案總管介面"
@@ -3303,6 +3318,14 @@ msgid "Binary"
 msgstr "二進制"
 
 #, c-format
+msgid "Unpacker"
+msgstr "解壓縮程式"
+
+#, c-format
+msgid "Prediffer"
+msgstr "先行處理器"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "無法比較檔案"
 
@@ -3545,6 +3568,12 @@ msgstr "檔案中的差異個數。此數不包括被忽略的差異。"
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "是二進制檔,就顯示星號 (*)"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "比較 %1 和 %2"
@@ -3843,14 +3872,6 @@ msgstr ""
 msgid "Type"
 msgstr "類型"
 
-#, c-format
-msgid "Unpacker"
-msgstr "解壓縮程式"
-
-#, c-format
-msgid "Prediffer"
-msgstr "先行處理器"
-
 # What does "Editor script" mean? Perhaps "editing scripts" or "scripts to edit"?
 #, c-format
 msgid "Editor script"
@@ -3975,14 +3996,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "找不到 WSH - 停用 .sct 指令碼"
 
 #, c-format
-msgid "<None>"
-msgstr "<無>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<自動>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "至第 %1 行(&O)"
 
@@ -4209,3 +4222,101 @@ msgstr "不能同時執行一個以上本程式"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 1517f19..d2e69cc 100644 (file)
@@ -56,8 +56,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Označi različite retke\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Istakni &razliku\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -82,6 +83,14 @@ msgstr "&Kopiraj"
 msgid "&Paste"
 msgstr "&Zalijepi"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Skripte"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< ništa >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Idi &na redak\tCtrl+G"
 
@@ -261,10 +270,6 @@ msgstr "Zadnje usporedbe"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< ništa >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "I&zlaz\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Poništi\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Zalijepi\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Istakni &razliku\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Nađi...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Dodaci"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Skripte"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Kopiraj stazu"
 msgid "Copy &Filename"
 msgstr "Kopiraj &naziv datoteke"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Dodaci - postavke "
+msgid "<None>"
+msgstr "Ništa"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "Automatski"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Nema dodataka"
+msgid "&Select..."
+msgstr "Oda&bir..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Automatski dodaci"
+msgid "Prediffer Settings"
+msgstr "Dodaci - postavke "
 
 msgid "G&o to Diff"
 msgstr "Idi &na razliku"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "Oda&bir..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1627,16 +1629,11 @@ msgstr "Pomakni &gore"
 msgid "Move &Down"
 msgstr "Pomakni &dole"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Izbor arhivera"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Arhiver datoteka:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Prikaži sve arhivere bez provjere ekstenzije."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Popis ekstenzija"
 msgid "Description:"
 msgstr "Opis:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Prikaži sve arhivere bez provjere ekstenzije."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stani"
@@ -2237,6 +2246,12 @@ msgstr "&Omogući dodatke"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Shell integracija"
@@ -3294,6 +3309,14 @@ msgid "Binary"
 msgstr "Binarno"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Raspakiravač"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Ne mogu usporediti datoteke"
 
@@ -3536,6 +3559,12 @@ msgstr "Broj razlika u datoteci. Zanemarene razlike nisu uključene."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Prikaži zvjezdicu (*) uz binarnu datoteku."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Usporedi %1 s %2"
@@ -3836,14 +3865,6 @@ msgid "Type"
 msgstr "Tip"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Raspakiravač"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "Uređivač skripti"
 
@@ -3966,14 +3987,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH dodatak nije nađen! - .sct skripte su onemogućene"
 
 #, c-format
-msgid "<None>"
-msgstr "Ništa"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "Automatski"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Idi &na redak"
 
@@ -4200,3 +4213,101 @@ msgstr "Samo jedna instanca WinMerge-a"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 5daafd3..14e65d4 100644 (file)
@@ -56,7 +56,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
 msgstr "Vybrat roz&díl v řádku\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -82,6 +83,14 @@ msgstr "&Kopírovat"
 msgid "&Paste"
 msgstr "&Vložit"
 
+#, c-format
+msgid "&Scripts"
+msgstr "Skrip&ty"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< žádné >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Př&ejít na...\tCtrl+G"
 
@@ -261,10 +270,6 @@ msgstr "Naposledy použité"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< žádné >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Konec\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr ""
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Zpět\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Vložit\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Vybrat roz&díl v řádku\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Najít...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr ""
 
-#, c-format
-msgid "&Scripts"
-msgstr "Skrip&ty"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,16 +1079,23 @@ msgstr "Kopírovat celé &umístění"
 msgid "Copy &Filename"
 msgstr "Kopírovat &název souboru"
 
-#, c-format
-msgid "Prediffer Settings"
+msgid "Unpacker Settings"
 msgstr ""
 
 #, c-format
-msgid "&No prediffer"
-msgstr ""
+msgid "<None>"
+msgstr "<žádný>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<automaticky>"
+
+#, c-format
+msgid "&Select..."
+msgstr "Vy&brat..."
 
 #, c-format
-msgid "Auto prediffer"
+msgid "Prediffer Settings"
 msgstr ""
 
 msgid "G&o to Diff"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "Vy&brat..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1629,16 +1631,11 @@ msgstr "&Nahoru"
 msgid "Move &Down"
 msgstr "&Dolů"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Zvolit převaděč"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "&Převaděč souborů:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "&Zobrazit všechny převaděče (nekontrolovat podle přípony)."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1648,6 +1645,18 @@ msgstr "Seznam přípon:"
 msgid "Description:"
 msgstr "Popis:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "&Zobrazit všechny převaděče (nekontrolovat podle přípony)."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Zastavit"
@@ -2237,6 +2246,12 @@ msgstr "&Povolit pluginy"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Systémová integrace"
@@ -3241,6 +3256,14 @@ msgid "Binary"
 msgstr "Binární"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Převaděč"
+
+#, c-format
+msgid "Prediffer"
+msgstr ""
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Soubory nelze porovnat"
 
@@ -3483,6 +3506,12 @@ msgstr "Počet rozdílů v souboru. Neobsahuje ignorované rozdíly."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Ukáže hvězdičku (*), pokud je soubor binární"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Porovnání %1 s %2"
@@ -3769,14 +3798,6 @@ msgid "Type"
 msgstr "Typ"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Převaděč"
-
-#, c-format
-msgid "Prediffer"
-msgstr ""
-
-#, c-format
 msgid "Editor script"
 msgstr ""
 
@@ -3899,14 +3920,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "Program Windows Script Host nebyl nalezen - skripty .sct jsou vypnuté"
 
 #, c-format
-msgid "<None>"
-msgstr "<žádný>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<automaticky>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "&Přejít na řádek %1"
 
@@ -4133,3 +4146,101 @@ msgstr "Povolit pouze jedno hlavní okno aplikace"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 0e6b3f3..cd4e5e0 100644 (file)
@@ -57,8 +57,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Vælg linjeforskel\tF4""
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Vælg &linjeforskel\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -83,6 +84,14 @@ msgstr "Ko&pier"
 msgid "&Paste"
 msgstr "&Indsæt"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Scripts"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Tom >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Gå &til...\tCtrl+G"
 
@@ -262,10 +271,6 @@ msgstr "Seneste Projekt"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Tom >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Afslut\tCtrl+Q"
 
@@ -640,10 +645,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Fortryd\tCtrl+Z"
 
@@ -664,10 +665,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Indsæt\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Vælg &linjeforskel\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "S&øg...\tCtrl+F"
 
@@ -882,13 +879,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1081,17 +1080,24 @@ msgstr "&Kopier det fulde stinavn"
 msgid "Copy &Filename"
 msgstr "Kopier &filnavn"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Prediffer indstillinger"
+msgid "<None>"
+msgstr "<Ingen>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatisk>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Ingen prediffer"
+msgid "&Select..."
+msgstr "Væ&lg..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "&Automatisk prediffer"
+msgid "Prediffer Settings"
+msgstr "Prediffer indstillinger"
 
 msgid "G&o to Diff"
 msgstr "Gå til &forskel"
@@ -1247,10 +1253,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "Væ&lg..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1630,16 +1632,11 @@ msgstr "Flyt &op"
 msgid "Move &Down"
 msgstr "Flyt &ned"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Vælg udpakker"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Fil udpakker:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Vis all udpakkerer, tjek ikke extension."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1649,6 +1646,18 @@ msgstr "Extension liste:"
 msgid "Description:"
 msgstr "Beskrivelse:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Vis all udpakkerer, tjek ikke extension."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stop"
@@ -2242,6 +2251,12 @@ msgstr "&Aktiver plugins"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Shell Integration"
@@ -3314,6 +3329,14 @@ msgid "Binary"
 msgstr "Binær"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Udpakker"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Kan ikke sammenligne filer"
 
@@ -3562,6 +3585,12 @@ msgstr "Antel forskelle i filen. Dette tal omfatter ikke ignorerede forskelle."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Vis stjerne (*) hvis fil er binær."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Sammenlign %1 med %2"
@@ -3872,14 +3901,6 @@ msgid "Type"
 msgstr "Type"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Udpakker"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "Editor script"
 
@@ -4004,14 +4025,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH ikke fundet - .sct scripts afbrudt"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ingen>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatisk>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "G&å til linje %1"
 
@@ -4238,3 +4251,101 @@ msgstr "Tillad kun et eksempel ad gangen"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index c487f33..9c953f0 100644 (file)
@@ -51,7 +51,7 @@ msgstr "Geselecteerde regel(s) vanaf links kopiëren"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Geselecteerde regel(s) vanaf rechts kopiëren"
 
-msgid "&Select Line Difference\tF4"
+msgid "Select Line &Difference\tF4"
 msgstr "Regelverschil selecteren\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -72,6 +72,12 @@ msgstr "Kopiëren"
 msgid "&Paste"
 msgstr "Plakken"
 
+msgid "&Scripts"
+msgstr "Scripts"
+
+msgid "< Empty >"
+msgstr "< Leeg >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Gaan naar...\tCtrl+G"
 
@@ -221,9 +227,6 @@ msgstr "Recente Projecten"
 msgid "Recent F&iles Or Folders"
 msgstr "Recente bestanden of mappen"
 
-msgid "< Empty >"
-msgstr "< Leeg >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Afsluiten\tCtrl+Q"
 
@@ -512,9 +515,6 @@ msgstr "Opnieuw laden\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Opnieuw vergelijken als"
 
-msgid "&XML"
-msgstr "XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "Ongedaan maken\tCtrl+Z"
 
@@ -530,9 +530,6 @@ msgstr "Kopiëren\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "Plakken\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Regelverschil selecteren\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "Zoeken...\tCtrl+F"
 
@@ -698,11 +695,14 @@ msgstr "Synchronisatiepunt toevoegen\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Synchronisatiepunten wissen"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "Voorvergelijking"
 
-msgid "&Scripts"
-msgstr "Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Splitsen"
@@ -865,14 +865,20 @@ msgstr "Volledig pad kopiëren"
 msgid "Copy &Filename"
 msgstr "Bestandsnaam kopiëren"
 
-msgid "Prediffer Settings"
-msgstr "Instellingen voorvergelijking"
+msgid "Unpacker Settings"
+msgstr ""
 
-msgid "&No prediffer"
-msgstr "Geen voorvergelijking"
+msgid "<None>"
+msgstr "<None>"
 
-msgid "Auto prediffer"
-msgstr "Automatische voorvergelijking"
+msgid "<Automatic>"
+msgstr "<Automatic>"
+
+msgid "&Select..."
+msgstr "Selecteren..."
+
+msgid "Prediffer Settings"
+msgstr "Instellingen voorvergelijking"
 
 msgid "G&o to Diff"
 msgstr "Ga naar verschil"
@@ -991,9 +997,6 @@ msgstr "Bladeren..."
 msgid " Folder: Filter"
 msgstr "Map: filter"
 
-msgid "&Select..."
-msgstr "Selecteren..."
-
 msgid " File: Unpacker Plugin"
 msgstr "Bestand: uitpak-plugin"
 
@@ -1301,14 +1304,11 @@ msgstr "Omhoog verplaatsen"
 msgid "Move &Down"
 msgstr "Omlaag verplaatsen"
 
-msgid "Select Unpacker"
-msgstr "Uitpakker kiezen"
-
-msgid "File unpacker:"
-msgstr "Bestandsuitpakker:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Alle uitpakkers weergeven zonder extensie te controleren."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Lijst extensies:"
@@ -1316,6 +1316,18 @@ msgstr "Lijst extensies:"
 msgid "Description:"
 msgstr "Beschrijving:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Alle uitpakkers weergeven zonder extensie te controleren."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Stoppen"
 
@@ -1785,6 +1797,12 @@ msgstr "Plugins inschakelen"
 msgid "File filters:"
 msgstr "Bestandsfilters:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Shell-integratie"
 
@@ -2773,6 +2791,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binair"
 
+msgid "Unpacker"
+msgstr "Uitpakker"
+
+msgid "Prediffer"
+msgstr "Voorvergelijken"
+
 msgid "Unable to compare files"
 msgstr "Kan bestanden niet vergelijken"
 
@@ -2972,6 +2996,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Geeft een asterisk (*) weer als het bestand binair is."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1 met %2 vergelijken"
@@ -3253,12 +3283,6 @@ msgstr "Nieuw patroon"
 msgid "Type"
 msgstr "Type"
 
-msgid "Unpacker"
-msgstr "Uitpakker"
-
-msgid "Prediffer"
-msgstr "Voorvergelijken"
-
 msgid "Editor script"
 msgstr "Editor-script"
 
@@ -3449,12 +3473,6 @@ msgstr "Plugin-instellingen"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH niet gevonden - .sct scripts uitgeschakeld"
 
-msgid "<None>"
-msgstr "<None>"
-
-msgid "<Automatic>"
-msgstr "<Automatic>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Naar regel %1 gaan"
@@ -3675,3 +3693,101 @@ msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
 "Slechts één draaiende instantie toestaan en wachten totdat de instantie "
 "beëindigd is"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 69180d7..caf896b 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: 2021-05-27 08:43+0000\n"
+"POT-Creation-Date: 2021-06-20 13:28+0000\n"
 "PO-Revision-Date: \n"
 "Last-Translator: \n"
 "Language-Team: English <winmerge-translate@lists.sourceforge.net>\n"
@@ -44,7 +44,7 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
+msgid "Select Line &Difference\tF4"
 msgstr ""
 
 msgid "Add this change to Substitution &Filters"
@@ -65,6 +65,12 @@ msgstr ""
 msgid "&Paste"
 msgstr ""
 
+msgid "&Scripts"
+msgstr ""
+
+msgid "< Empty >"
+msgstr ""
+
 msgid "&Go to...\tCtrl+G"
 msgstr ""
 
@@ -214,9 +220,6 @@ msgstr ""
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-msgid "< Empty >"
-msgstr ""
-
 msgid "E&xit\tCtrl+Q"
 msgstr ""
 
@@ -505,9 +508,6 @@ msgstr ""
 msgid "Reco&mpare As"
 msgstr ""
 
-msgid "&XML"
-msgstr ""
-
 msgid "&Undo\tCtrl+Z"
 msgstr ""
 
@@ -523,9 +523,6 @@ msgstr ""
 msgid "&Paste\tCtrl+V"
 msgstr ""
 
-msgid "Select Line &Difference\tF4"
-msgstr ""
-
 msgid "F&ind...\tCtrl+F"
 msgstr ""
 
@@ -691,10 +688,13 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr ""
 
-msgid "&Scripts"
+msgid "Apply Pre&differ..."
 msgstr ""
 
 msgid "Sp&lit"
@@ -858,13 +858,19 @@ msgstr ""
 msgid "Copy &Filename"
 msgstr ""
 
-msgid "Prediffer Settings"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr ""
+
+msgid "<Automatic>"
 msgstr ""
 
-msgid "&No prediffer"
+msgid "&Select..."
 msgstr ""
 
-msgid "Auto prediffer"
+msgid "Prediffer Settings"
 msgstr ""
 
 msgid "G&o to Diff"
@@ -984,9 +990,6 @@ msgstr ""
 msgid " Folder: Filter"
 msgstr ""
 
-msgid "&Select..."
-msgstr ""
-
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1284,19 +1287,28 @@ msgstr ""
 msgid "Move &Down"
 msgstr ""
 
-msgid "Select Unpacker"
+msgid "Select Plugin"
+msgstr ""
+
+msgid "Plugin &Name:"
+msgstr ""
+
+msgid "Extensions list:"
+msgstr ""
+
+msgid "Description:"
 msgstr ""
 
-msgid "File unpacker:"
+msgid "Default arguments:"
 msgstr ""
 
 msgid "Display all unpackers, don't check the extension."
 msgstr ""
 
-msgid "Extensions list:"
+msgid "&Plugin Pipeline:"
 msgstr ""
 
-msgid "Description:"
+msgid "&Add pipe"
 msgstr ""
 
 msgid "Stop"
@@ -1758,6 +1770,12 @@ msgstr ""
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr ""
 
@@ -2497,6 +2515,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr ""
 
+msgid "Unpacker"
+msgstr ""
+
+msgid "Prediffer"
+msgstr ""
+
 msgid "Unable to compare files"
 msgstr ""
 
@@ -2689,6 +2713,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr ""
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr ""
@@ -2908,12 +2938,6 @@ msgstr ""
 msgid "Type"
 msgstr ""
 
-msgid "Unpacker"
-msgstr ""
-
-msgid "Prediffer"
-msgstr ""
-
 msgid "Editor script"
 msgstr ""
 
@@ -3012,12 +3036,6 @@ msgstr ""
 msgid "WSH not found - .sct scripts disabled"
 msgstr ""
 
-msgid "<None>"
-msgstr ""
-
-msgid "<Automatic>"
-msgstr ""
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr ""
@@ -3231,3 +3249,101 @@ msgstr ""
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
 
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
+
index ca94b09..0d3c532 100644 (file)
@@ -54,7 +54,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
 msgstr "Valitse riviero\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -80,6 +81,14 @@ msgstr "&Kopioi"
 msgid "&Paste"
 msgstr "Lii&tä"
 
+#, c-format
+msgid "&Scripts"
+msgstr "Skriptit"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Tyhjä >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Siirry...\tCtrl+G"
 
@@ -259,10 +268,6 @@ msgstr "Viimeiset projektit"
 msgid "Recent F&iles Or Folders"
 msgstr "Viimeaikaiset t&iedostot tai kansiot"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Tyhjä >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Poistu\tCtrl+Q"
 
@@ -637,10 +642,6 @@ msgid "Reco&mpare As"
 msgstr "Vertaa uudelleen"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "Kumoa\tCtrl+Z"
 
@@ -661,10 +662,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Liitä\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Valitse riviero\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Ets&i...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr "Lisää &synkronointipiste\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Poista syn&kronointipisteet"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "Esivertailu"
 
-#, c-format
-msgid "&Scripts"
-msgstr "Skriptit"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "Kopioi täysi polku"
 msgid "Copy &Filename"
 msgstr "Kopioi tiedostonimi"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Esivertailun asetukset"
+msgid "<None>"
+msgstr "<Ei mitään>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Ei esivertailua"
+msgid "<Automatic>"
+msgstr "<Automaattinen>"
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Automaattinen esivertailu"
+msgid "&Select..."
+msgstr "Valitse..."
+
+#, c-format
+msgid "Prediffer Settings"
+msgstr "Esivertailun asetukset"
 
 msgid "G&o to Diff"
 msgstr "Siirry eroon"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr " Kansio: Suodin"
 
 #, c-format
-msgid "&Select..."
-msgstr "Valitse..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Tiedosto: Purkaja-lisäosa"
 
@@ -1627,16 +1629,11 @@ msgstr "Siirrä ylös"
 msgid "Move &Down"
 msgstr "Siirrä alas"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Valitse purkaja"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Tiedoston purkaja:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Näytä kaikki purkajat, älä tarkista tiedostopäätettä."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Päätelista:"
 msgid "Description:"
 msgstr "Kuvaus:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Näytä kaikki purkajat, älä tarkista tiedostopäätettä."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Pysäytä"
@@ -2241,6 +2250,12 @@ msgstr "Ota laajennukset käyttöön"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Shell integraatio"
@@ -3313,6 +3328,14 @@ msgid "Binary"
 msgstr "Binääri"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Purkaja"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Esivertailu"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Tiedostoja ei voi verrata"
 
@@ -3555,6 +3578,12 @@ msgstr "Erojen määrä tiedostossa. Tämä luku ei sisällä ohitettuja eroja."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Näyttää tähden(*), jos tiedosto on binäärinen."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Vertaa %1 -> %2"
@@ -3858,14 +3887,6 @@ msgid "Type"
 msgstr "Tyyppi"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Purkaja"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Esivertailu"
-
-#, c-format
 msgid "Editor script"
 msgstr "Muokkainskripti"
 
@@ -4060,14 +4081,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH ei löytynyt - .sct skriptit poistettu käytöstä"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ei mitään>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automaattinen>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Siirry riville %1"
 
@@ -4300,3 +4313,101 @@ msgstr "Vain yksi instanssi kerrallaan"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index c9e377d..88dac0b 100644 (file)
@@ -63,7 +63,8 @@ msgstr "Copier les lignes sélectionnées depuis la gauche"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Copier les lignes sélectionnées depuis la droite"
 
-msgid "&Select Line Difference\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
 msgstr "&Sélectionner la ligne différente\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -89,6 +90,14 @@ msgstr "Co&pier"
 msgid "&Paste"
 msgstr "Co&ller"
 
+#, c-format
+msgid "&Scripts"
+msgstr "Appli&quer un script"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Vide >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Atteindre...\tCtrl+G"
 
@@ -268,10 +277,6 @@ msgstr "Projets récents"
 msgid "Recent F&iles Or Folders"
 msgstr "F&ichiers ou dossiers récents"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Vide >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Quitter\tCtrl+Q"
 
@@ -646,10 +651,6 @@ msgid "Reco&mpare As"
 msgstr "Recomparer comme"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "Ann&uler\tCtrl+Z"
 
@@ -670,10 +671,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Co&ller\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "&Sélectionner la ligne différente\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Rec&hercher...\tCtrl+F"
 
@@ -888,13 +885,15 @@ msgstr "Ajouter point de &synchronisation\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Effacer les points de sync&hronisation"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Pré-comparer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "Appli&quer un script"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1087,17 +1086,24 @@ msgstr "Copier le c&hemin complet"
 msgid "Copy &Filename"
 msgstr "Copier le nom de &fichier"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Paramètres de pré-comparaison"
+msgid "<None>"
+msgstr "<Aucun>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatique>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Au&cun"
+msgid "&Select..."
+msgstr "C&hoisir..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Au&tomatique"
+msgid "Prediffer Settings"
+msgstr "Paramètres de pré-comparaison"
 
 msgid "G&o to Diff"
 msgstr "Atteindre la différence courante"
@@ -1253,10 +1259,6 @@ msgid " Folder: Filter"
 msgstr " Dossier : filtre"
 
 #, c-format
-msgid "&Select..."
-msgstr "C&hoisir..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Fichier : Plugin décompresseur"
 
@@ -1634,16 +1636,11 @@ msgstr "&Monter"
 msgid "Move &Down"
 msgstr "&Descendre"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Sélectionner le décompresseur"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Décompresseur :"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Afficher tous les décompresseurs, ignorer les extensions."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1653,6 +1650,18 @@ msgstr "Liste des extensions :"
 msgid "Description:"
 msgstr "Description :"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Afficher tous les décompresseurs, ignorer les extensions."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Arrêter"
@@ -2250,6 +2259,12 @@ msgstr "&Activer les plugins"
 msgid "File filters:"
 msgstr "Filtres de fichier :"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Intégration à l'explorateur"
@@ -3360,6 +3375,14 @@ msgid "Binary"
 msgstr "Binaire"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Décompresseur"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Pré-comparaison"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Impossible de comparer les fichiers"
 
@@ -3602,6 +3625,12 @@ msgstr "Nombre de différences dans le fichier. Ce nombre n'inclut pas les diff
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Indique un astérisque (*) si le fichier est binaire."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Comparer %1 avec %2"
@@ -3917,14 +3946,6 @@ msgid "Type"
 msgstr "Type"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Décompresseur"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Pré-comparaison"
-
-#, c-format
 msgid "Editor script"
 msgstr "Éditeur de script"
 
@@ -4135,14 +4156,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH non trouvé - les scripts .sct sont désactivés"
 
 #, c-format
-msgid "<None>"
-msgstr "<Aucun>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatique>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Atteindre la ligne %1"
 
@@ -4375,3 +4388,101 @@ msgstr "Permettre une seule instance en exécution"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Autoriser une seule instance à s'exécuter et attendre que l'instance se termine"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index f5283de..03a6da5 100644 (file)
@@ -57,8 +57,9 @@ msgstr "Copiar liñas seleccionadas da esquerda"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Copiar liñas seleccionadas da dereita"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Seleccionar a diferenza entre liñas\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Seleccionar diferen&zas de liña\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Engadir este cambio aos &Filtros de substitución"
@@ -83,6 +84,14 @@ msgstr "&Copiar"
 msgid "&Paste"
 msgstr "&Pegar"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Scripts"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Baleiro >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Ir a…\tCtrl+G"
 
@@ -262,10 +271,6 @@ msgstr "Proxectos recentes"
 msgid "Recent F&iles Or Folders"
 msgstr "Arqu&ivos ou cartafoles recentes"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Baleiro >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "S&aír\tCtrl+Q"
 
@@ -640,10 +645,6 @@ msgid "Reco&mpare As"
 msgstr "Volver comparar como"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Desfacer\tCtrl+Z"
 
@@ -664,10 +665,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Pegar\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Seleccionar diferen&zas de liña\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "B&uscar…\tCtrl+F"
 
@@ -882,13 +879,15 @@ msgstr "Engadir punto de &sincronización\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Eliminar puntos de sincroni&zación"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "Prec&omparación"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1081,17 +1080,24 @@ msgstr "&Copiar ruta completa"
 msgid "Copy &Filename"
 msgstr "Copiar nome do &arquivo"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Configuración da precomparación"
+msgid "<None>"
+msgstr "<Ningún>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automático>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Sen precomparación"
+msgid "&Select..."
+msgstr "&Seleccionar…"
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Precomparación automática"
+msgid "Prediffer Settings"
+msgstr "Configuración da precomparación"
 
 msgid "G&o to Diff"
 msgstr "I&r ás diferenzas"
@@ -1247,10 +1253,6 @@ msgid " Folder: Filter"
 msgstr " Cartafol: Filtro"
 
 #, c-format
-msgid "&Select..."
-msgstr "&Seleccionar…"
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Arquivo: Complemento de desempaquetamento"
 
@@ -1628,16 +1630,11 @@ msgstr "Mover E&nriba"
 msgid "Move &Down"
 msgstr "Mover E&mbaixo"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Seleccionar desempaquetador"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Desempaquetador de arquivos:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Amosar todos os desempaquetadores, non verificar a extensión."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1647,6 +1644,18 @@ msgstr "Listaxe de extensións:"
 msgid "Description:"
 msgstr "Descrición:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Amosar todos os desempaquetadores, non verificar a extensión."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Parar"
@@ -2244,6 +2253,12 @@ msgstr "&Activar complementos"
 msgid "File filters:"
 msgstr "Filtros de arquivo:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Integración na Shell"
@@ -3352,6 +3367,14 @@ msgid "Binary"
 msgstr "Binario"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Desempaquetador"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Precomparación"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Non se puido comparar os arquivos"
 
@@ -3594,6 +3617,12 @@ msgstr "Número de diferenzas no arquivo. Este número non inclúe as diferenzas
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Amosa un asterisco (*) se o arquivo é binario."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Comparar %1 con %2"
@@ -3909,14 +3938,6 @@ msgid "Type"
 msgstr "Tipo"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Desempaquetador"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Precomparación"
-
-#, c-format
 msgid "Editor script"
 msgstr "Script do Editor"
 
@@ -4127,14 +4148,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH non atopado - scripts .sct desactivados"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ningún>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automático>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "I&r á liña %1"
 
@@ -4367,3 +4380,101 @@ msgstr "Permitir executar só unha instancia"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Permitir só a execución dunha instancia e esperar a que a instancia remate"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 1fea14e..ccb522b 100644 (file)
@@ -56,7 +56,8 @@ msgstr "Ausgewählte Zeile(n) von links kopieren"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Ausgewählte Zeile(n) von rechts kopieren"
 
-msgid "&Select Line Difference\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
 msgstr "Zeilen&unterschied markieren\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -82,6 +83,14 @@ msgstr "&Kopieren"
 msgid "&Paste"
 msgstr "&Einfügen"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Skripte"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Leer >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Gehe zu...\tStrg+G"
 
@@ -261,10 +270,6 @@ msgstr "Kürzliche Projekte"
 msgid "Recent F&iles Or Folders"
 msgstr "Kürzlich&e Dateien oder Ordner"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Leer >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Beenden\tStrg+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr "Erneut ver&gleichen als"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Rückgängig\tStrg+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Einfügen\tStrg+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Zeilen&unterschied markieren\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Suchen...\tStrg+F"
 
@@ -881,13 +878,15 @@ msgstr "&Synchronisationspunkt hinzufügen\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "S&ynchronisationspunkt entfernen"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Skripte"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Vollständigen Pfad kopieren"
 msgid "Copy &Filename"
 msgstr "&Dateinamen kopieren"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "&Prediffer-Einstellungen"
+msgid "<None>"
+msgstr "<Keine>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatisch>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Kein Prediffer"
+msgid "&Select..."
+msgstr "Auswählen..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "&Auto-Prediffer"
+msgid "Prediffer Settings"
+msgstr "&Prediffer-Einstellungen"
 
 msgid "G&o to Diff"
 msgstr "Zum Unterschied g&ehen"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr " Ordner: Filter"
 
 #, c-format
-msgid "&Select..."
-msgstr "Auswählen..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Datei: Entpacker-Plugin"
 
@@ -1627,16 +1629,11 @@ msgstr "Nach &oben"
 msgid "Move &Down"
 msgstr "Nach &unten"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Entpacker auswählen"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Datei-Entpacker:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Alle Entpacker anzeigen, die Erweiterung nicht überprüfen."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Erweiterungsliste:"
 msgid "Description:"
 msgstr "Beschreibung:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Alle Entpacker anzeigen, die Erweiterung nicht überprüfen."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stopp"
@@ -2235,6 +2244,12 @@ msgstr "&Plugins aktivieren"
 msgid "File filters:"
 msgstr "Dateifilter:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Shell-Integration"
@@ -3115,6 +3130,14 @@ msgid "Binary"
 msgstr "Binär"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Entpacker"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Dateien können nicht verglichen werden"
 
@@ -3357,6 +3380,12 @@ msgstr "Anzahl der Unterschiede in der Datei. Die Zahl enthält nicht die ignori
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Zeigt ein Asterisk (*), wenn die Datei binär ist."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1 mit %2 vergleichen"
@@ -3620,14 +3649,6 @@ msgid "Type"
 msgstr "Typ"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Entpacker"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "Editor-Skript"
 
@@ -3750,14 +3771,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH nicht gefunden - SCT-Skripte deaktiviert."
 
 #, c-format
-msgid "<None>"
-msgstr "<Keine>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatisch>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Gehe zu &Zeile %1"
 
@@ -3984,3 +3997,101 @@ msgstr "Nur eine Instanz zulassen"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Nur eine Instanz zulassen und warten, bis die Instanz beendet ist"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 7c2d907..95d00bb 100644 (file)
@@ -55,8 +55,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "Επιλογή Δια&φοράς Γραμμής\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Επιλο&γή Διαφοράς Γραμμής\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -81,6 +82,14 @@ msgstr "Αντι&γραφή"
 msgid "&Paste"
 msgstr "Προ&σάρτηση"
 
+#, c-format
+msgid "&Scripts"
+msgstr "Μακ&ροεντολές"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Άδειο >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Μετά&βαση...\tCtrl+G"
 
@@ -260,10 +269,6 @@ msgstr "Πρόσ&φατα Έργα"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Άδειο >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Έξοδο&ς\tCtrl+Q"
 
@@ -638,10 +643,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr ""
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "Α&ναίρεση\tCtrl+Z"
 
@@ -662,10 +663,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Προ&σάρτηση\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Επιλο&γή Διαφοράς Γραμμής\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Ανα&ζήτηση...\tCtrl+F"
 
@@ -880,13 +877,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "Προεπε&ξεργαστής Διαφορών"
 
-#, c-format
-msgid "&Scripts"
-msgstr "Μακ&ροεντολές"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1079,17 +1078,24 @@ msgstr "Αντιγραφή πλήρους Δια&δρομής"
 msgid "Copy &Filename"
 msgstr "Αντιγραφή Ο&νόματος"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Ρυθμίσεις Προεπεξεργαστή Διαφορών"
+msgid "<None>"
+msgstr "<Ουδέν>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Αυτόματο>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Χωρίς προεπεξεργασία διαφορών"
+msgid "&Select..."
+msgstr "&Επιλογή..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Î\91Ï\85Ï\84Ï\8cμαÏ\84η ÎµÏ\80ιλογή Ï\80Ï\81οεÏ\80εξεÏ\81γαÏ\83Ï\84ή Î´ιαφορών"
+msgid "Prediffer Settings"
+msgstr "ΡÏ\85θμίÏ\83ειÏ\82 Î Ï\81οεÏ\80εξεÏ\81γαÏ\83Ï\84ή Î\94ιαφορών"
 
 msgid "G&o to Diff"
 msgstr "Μετά&βαση σε Διαφορά"
@@ -1245,10 +1251,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "&Επιλογή..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1626,16 +1628,11 @@ msgstr "Μετακίνηση προς τα &άνω"
 msgid "Move &Down"
 msgstr "Μετακίνηση προς τα &κάτω"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Επιλογή Αποσυμπιεστικού"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Αποσυμπιεστικό Αρχείων:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Εμφάνιση όλων των αποσυμπιεστικών, να μην ελέγχεται η επέκταση."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1645,6 +1642,18 @@ msgstr "Κατάλογος Επεκτάσεων:"
 msgid "Description:"
 msgstr "Περιγραφή:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Εμφάνιση όλων των αποσυμπιεστικών, να μην ελέγχεται η επέκταση."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Τερματισμός"
@@ -2234,6 +2243,12 @@ msgstr "Ενεργοποίηση Αρθρωμάτων"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr ""
@@ -3272,6 +3287,14 @@ msgid "Binary"
 msgstr "Δυαδικό"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Αποσυμπιεστικό"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Προεπεξεργαστής Διαφορών"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Η σύγκριση των αρχείων είναι αδύνατη"
 
@@ -3514,6 +3537,12 @@ msgstr "Αριθμός διαφορών στο αρχείο. Αυτός ο αρ
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Εμφανίζει έναν αστερίσκο (*) εάν το αρχείο είναι δυαδικό."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Σύγκριση %1 με %2"
@@ -3814,14 +3843,6 @@ msgid "Type"
 msgstr "Τύπος"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Αποσυμπιεστικό"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Προεπεξεργαστής Διαφορών"
-
-#, c-format
 msgid "Editor script"
 msgstr "Μακροεντολές Επεξεργαστή Κειμένου"
 
@@ -3944,14 +3965,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "Το Περιβάλλον Διερμηνείας Windows (WSH) δε βρέθηκε - η χρήση αρχείων δέσμης ενεργειών .sct είναι απενεργοποιημένη"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ουδέν>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Αυτόματο>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Μετά&βαση στη Γραμμή %1"
 
@@ -4178,3 +4191,101 @@ msgstr "Επιτρέπεται μόνο μία υπόσταση του WinMerge
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index db9b5dc..ece2dff 100644 (file)
@@ -58,8 +58,9 @@ msgstr "A kijelölt sor(ok) másolása balról"
 msgid "Copy Selected Line(s) from Right"
 msgstr "A kijelölt sor(ok) másolása jobbról"
 
-msgid "&Select Line Difference\tF4"
-msgstr "Az eltérés kijelölése\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Eltérés kijelölése\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Adja hozzá ezt a változást a Helyettesítő szűrőkhöz"
@@ -84,6 +85,14 @@ msgstr "&Másolás"
 msgid "&Paste"
 msgstr "&Beillesztés"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Szkriptek"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Üres >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Ugrás...\tCtrl+G"
 
@@ -263,10 +272,6 @@ msgstr "Legutóbbi projektek"
 msgid "Recent F&iles Or Folders"
 msgstr "Legutóbbi fájlok és mappák"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Üres >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Kilépés\tCtrl+Q"
 
@@ -641,10 +646,6 @@ msgid "Reco&mpare As"
 msgstr "Újra összehasonlítás mint"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Visszavonás\tCtrl+Z"
 
@@ -665,10 +666,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Beillesztés\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Eltérés kijelölése\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Keresé&s...\tCtrl+F"
 
@@ -883,13 +880,15 @@ msgstr "Hozzáadás és szinkronizációs pont\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Szinkronizációs pontok törlése"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Elővizsgáló"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Szkriptek"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1082,17 +1081,24 @@ msgstr "&Teljes útvonal másolása"
 msgid "Copy &Filename"
 msgstr "&Fájlnév másolása"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Elővizsgáló beállítások"
+msgid "<None>"
+msgstr "<Nincs>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatikus>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Nincs elővizsgálat"
+msgid "&Select..."
+msgstr "&Kiválasztás..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Automatikus elővizsgálat"
+msgid "Prediffer Settings"
+msgstr "Elővizsgáló beállítások"
 
 msgid "G&o to Diff"
 msgstr "Ugrás &eltérésre"
@@ -1248,10 +1254,6 @@ msgid " Folder: Filter"
 msgstr " Mappa: Szűrő"
 
 #, c-format
-msgid "&Select..."
-msgstr "&Kiválasztás..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Fájlkitömörítő"
 
@@ -1629,16 +1631,11 @@ msgstr "Mozgatás fel"
 msgid "Move &Down"
 msgstr "Mozgatás le"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Kicsomagoló kiválasztása"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Fájl kicsomagoló:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Minden kicsomagoló mutatása kiterjesztéstől függetlenül."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1648,6 +1645,18 @@ msgstr "Kiterjesztések listája:"
 msgid "Description:"
 msgstr "Leírás:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Minden kicsomagoló mutatása kiterjesztéstől függetlenül."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Leállítás"
@@ -2245,6 +2254,12 @@ msgstr "Bővítmény&ek bekapcsolása"
 msgid "File filters:"
 msgstr "Fájlszűrők:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Integrálás az Intézőbe"
@@ -3353,6 +3368,14 @@ msgid "Binary"
 msgstr "Bináris"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Kitömörítő"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Elővizsgáló"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Nem lehet összehasonlítani a fájlokat"
 
@@ -3595,6 +3618,12 @@ msgstr "Különbségek száma a fájlban. Ez a szám nem tartalmazza a mellőzö
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "(*) látható, ha a fájl bináris."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1 összehasonlítása ezzel: %2"
@@ -3910,14 +3939,6 @@ msgid "Type"
 msgstr "Típus"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Kitömörítő"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Elővizsgáló"
-
-#, c-format
 msgid "Editor script"
 msgstr "Szkript szerkesztő"
 
@@ -4128,14 +4149,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "A WSH nem található - Az .sct szkriptek le lesznek tiltva"
 
 #, c-format
-msgid "<None>"
-msgstr "<Nincs>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatikus>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "&Ugrás a(z) %1. sorra"
 
@@ -4367,3 +4380,101 @@ msgstr "Csak egy példány futhat egyszerre"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Csak egy példány futhat és megvárja, amíg a példány leáll"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 6eef00e..d12a8d8 100644 (file)
@@ -50,8 +50,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Seleziona differenze riga\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Seleziona &differenze di riga\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -71,6 +71,12 @@ msgstr "C&opia"
 msgid "&Paste"
 msgstr "I&ncolla"
 
+msgid "&Scripts"
+msgstr "&Script"
+
+msgid "< Empty >"
+msgstr "< Vuoto >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Vai a...\tCtrl+G"
 
@@ -220,9 +226,6 @@ msgstr "Progetti recenti"
 msgid "Recent F&iles Or Folders"
 msgstr "F&ile o cartelle recenti"
 
-msgid "< Empty >"
-msgstr "< Vuoto >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Esci\tCtrl+Q"
 
@@ -511,9 +514,6 @@ msgstr "&Ricarica\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Riconfronta come"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&Annulla\tCtrl+Z"
 
@@ -529,9 +529,6 @@ msgstr "C&opia\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "I&ncolla\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Seleziona &differenze di riga\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "Tro&va...\tCtrl+F"
 
@@ -697,11 +694,14 @@ msgstr "Aggiungi punto di &sincronizzazione\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "A&zzera punti sincronizzazione"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-msgid "&Scripts"
-msgstr "&Script"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "&Dividi"
@@ -864,14 +864,20 @@ msgstr "Copia &percorso completo"
 msgid "Copy &Filename"
 msgstr "Copia nome del &file"
 
-msgid "Prediffer Settings"
-msgstr "Impostazioni prediffer"
+msgid "Unpacker Settings"
+msgstr ""
 
-msgid "&No prediffer"
-msgstr "&Nessun prediffer"
+msgid "<None>"
+msgstr "<Nessuno>"
 
-msgid "Auto prediffer"
-msgstr "Prediffer &automatico"
+msgid "<Automatic>"
+msgstr "<Automatico>"
+
+msgid "&Select..."
+msgstr "Sele&ziona..."
+
+msgid "Prediffer Settings"
+msgstr "Impostazioni prediffer"
 
 msgid "G&o to Diff"
 msgstr "Vai alla &differenza"
@@ -990,9 +996,6 @@ msgstr "Sfoglia..."
 msgid " Folder: Filter"
 msgstr "Cartella: filtro"
 
-msgid "&Select..."
-msgstr "Sele&ziona..."
-
 msgid " File: Unpacker Plugin"
 msgstr "File: plugin Decompressore"
 
@@ -1292,14 +1295,11 @@ msgstr "Sposta &su"
 msgid "Move &Down"
 msgstr "Sposta &giù"
 
-msgid "Select Unpacker"
-msgstr "Seleziona decompressore"
-
-msgid "File unpacker:"
-msgstr "Decompressore di file:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Visualizza tutti i decompressori, non verificare l'estensione."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Elenco estensioni:"
@@ -1307,6 +1307,18 @@ msgstr "Elenco estensioni:"
 msgid "Description:"
 msgstr "Descrizione:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Visualizza tutti i decompressori, non verificare l'estensione."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Stop"
 
@@ -1772,6 +1784,12 @@ msgstr "&Abilita plugin"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integrazione shell sistema"
 
@@ -2734,6 +2752,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binario"
 
+msgid "Unpacker"
+msgstr "Decompressore"
+
+msgid "Prediffer"
+msgstr "Prediffer"
+
 msgid "Unable to compare files"
 msgstr "Impossibile confrontare i file"
 
@@ -2934,6 +2958,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Visualizza un asterisco (*) se il file è binario."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Confronta %1 con %2"
@@ -3207,12 +3237,6 @@ msgstr ""
 msgid "Type"
 msgstr "Tipo"
 
-msgid "Unpacker"
-msgstr "Decompressore"
-
-msgid "Prediffer"
-msgstr "Prediffer"
-
 msgid "Editor script"
 msgstr "Editor script"
 
@@ -3386,12 +3410,6 @@ msgstr "Impostazioni plugin"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH non trovato - script .sct disattivati"
 
-msgid "<None>"
-msgstr "<Nessuno>"
-
-msgid "<Automatic>"
-msgstr "<Automatico>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Vai alla &linea %1"
@@ -3610,3 +3628,101 @@ msgstr "Permetti l'esecuzione di un'unica istanza del programma"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index daa253e..41f116e 100644 (file)
@@ -12,7 +12,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: 2021-03-31 21:52+0900\n"
+"PO-Revision-Date: 2021-06-20 13:31+0900\n"
 "Last-Translator: Takashi Sawanaka <sawanaka@d1.dion.ne.jp>\n"
 "Language-Team: Japanese <winmerge-translate@lists.sourceforge.net>\n"
 "MIME-Version: 1.0\n"
@@ -21,7 +21,7 @@ msgstr ""
 "X-Poedit-SourceCharset: UTF-8\n"
 "X-Poedit-Basepath: ..\n"
 "Language: ja\n"
-"X-Generator: Poedit 2.4.2\n"
+"X-Generator: Poedit 3.0\n"
 
 #. LANGUAGE, SUBLANGUAGE
 msgid "LANG_ENGLISH, SUBLANG_ENGLISH_US"
@@ -51,8 +51,8 @@ msgstr "選択した行を左からコピー"
 msgid "Copy Selected Line(s) from Right"
 msgstr "選択した行を右からコピー"
 
-msgid "&Select Line Difference\tF4"
-msgstr "行内差異を選択(&S)\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "行内差異を選択(&D)\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "この差異を置換フィルターに追加する(&F)"
@@ -72,6 +72,12 @@ msgstr "コピー(&C)"
 msgid "&Paste"
 msgstr "貼り付け(&P)"
 
+msgid "&Scripts"
+msgstr "スクリプト(&S)"
+
+msgid "< Empty >"
+msgstr "< なし >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "移動(&G)...\tCtrl+G"
 
@@ -221,9 +227,6 @@ msgstr "最近使用したプロジェクト"
 msgid "Recent F&iles Or Folders"
 msgstr "最近使用したファイルまたはフォルダー(&I)"
 
-msgid "< Empty >"
-msgstr "< なし >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "終了(&X)\tCtrl+Q"
 
@@ -512,9 +515,6 @@ msgstr "再読み込み(&L)\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "形式を指定して再比較(&M)"
 
-msgid "&XML"
-msgstr "XML(&X)"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "元に戻す(&U)\tCtrl+Z"
 
@@ -530,9 +530,6 @@ msgstr "コピー(&C)\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "貼り付け(&P)\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "行内差異を選択(&D)\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "検索(&I)...\tCtrl+F"
 
@@ -698,11 +695,14 @@ msgstr "同期ポイントの追加(&S)\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "同期ポイントのクリア(&H)"
 
+msgid "Unpac&ker"
+msgstr "展開プラグイン(&K)"
+
 msgid "&Prediffer"
 msgstr "比較前処理プラグイン(&P)"
 
-msgid "&Scripts"
-msgstr "スクリプト(&S)"
+msgid "Apply Pre&differ..."
+msgstr "比較前処理プラグインを適用(&D)..."
 
 msgid "Sp&lit"
 msgstr "分割(&L)"
@@ -865,14 +865,20 @@ msgstr "フルパスをコピー(&C)"
 msgid "Copy &Filename"
 msgstr "ファイル名をコピー(&F)"
 
-msgid "Prediffer Settings"
-msgstr "比較前処理プラグイン設定"
+msgid "Unpacker Settings"
+msgstr "展開プラグイン設定"
 
-msgid "&No prediffer"
-msgstr "使用しない(&N)"
+msgid "<None>"
+msgstr "<なし>"
 
-msgid "Auto prediffer"
-msgstr "自動"
+msgid "<Automatic>"
+msgstr "<自動>"
+
+msgid "&Select..."
+msgstr "選択(&S)..."
+
+msgid "Prediffer Settings"
+msgstr "比較前処理プラグイン設定"
 
 msgid "G&o to Diff"
 msgstr "差異へ移動(&O)"
@@ -991,9 +997,6 @@ msgstr "参照..."
 msgid " Folder: Filter"
 msgstr " フォルダー: フィルター"
 
-msgid "&Select..."
-msgstr "選択(&S)..."
-
 msgid " File: Unpacker Plugin"
 msgstr " ファイル: 展開プラグイン"
 
@@ -1295,14 +1298,11 @@ msgstr "上へ(&U)"
 msgid "Move &Down"
 msgstr "下へ(&D)"
 
-msgid "Select Unpacker"
-msgstr "展開プラグインの選択"
-
-msgid "File unpacker:"
-msgstr "ファイル展開プラグイン:"
+msgid "Select Plugin"
+msgstr "プラグインの選択"
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "拡張子を無視してすべての展開プラグインを表示する。"
+msgid "Plugin &Name:"
+msgstr "プラグイン名(&N):"
 
 msgid "Extensions list:"
 msgstr "拡張子一覧:"
@@ -1310,6 +1310,18 @@ msgstr "拡張子一覧:"
 msgid "Description:"
 msgstr "説明:"
 
+msgid "Default arguments:"
+msgstr "デフォルト引数:"
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "拡張子を無視してすべての展開プラグインを表示する。"
+
+msgid "&Plugin Pipeline:"
+msgstr "プラグインパイプライン(&P):"
+
+msgid "&Add pipe"
+msgstr "パイプを追加(&A)"
+
 msgid "Stop"
 msgstr "停止"
 
@@ -1777,6 +1789,12 @@ msgstr "プラグインを有効にする(&E)"
 msgid "File filters:"
 msgstr "ファイルフィルター:"
 
+msgid "&Plugin arguments:"
+msgstr "プラグイン引数(&P):"
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr "自動展開/自動比較前処理をこのプラグインで有効にする"
+
 msgid "Shell Integration"
 msgstr "シェル統合"
 
@@ -2740,6 +2758,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "バイナリ"
 
+msgid "Unpacker"
+msgstr "展開プラグイン"
+
+msgid "Prediffer"
+msgstr "比較前処理プラグイン"
+
 msgid "Unable to compare files"
 msgstr "ファイルを比較できません"
 
@@ -2894,7 +2918,7 @@ msgid "Middle side file version, only for some filetypes."
 msgstr "中央ファイルのバージョンです。一部のファイル形式に限り表示されます。"
 
 msgid "Short comparison result."
-msgstr "ç\9f­ã\81\84å½¢å¼\8fã\81®æ¯\94è¼\83çµ\90æ\9e\9cã\82\92表示ã\81§す。"
+msgstr "ç\9f­ã\81\84å½¢å¼\8fã\81®æ¯\94è¼\83çµ\90æ\9e\9cã\82\92表示ã\81\97ã\81¾す。"
 
 msgid "Left side attributes."
 msgstr "左側の属性です。"
@@ -2932,6 +2956,12 @@ msgstr "ファイル内の差異の数です。この数値は無視した差異
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "バイナリ ファイルの場合にアスタリスク (*) を表示します。"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr "展開プラグイン名またはパイプラインを表示します。"
+
+msgid "Prediffer plugin name or pipeline."
+msgstr "比較前処理プラグイン名またはパイプラインを表示します。"
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1 と %2 の比較"
@@ -3206,12 +3236,6 @@ msgstr "新しいパターン"
 msgid "Type"
 msgstr "タイプ"
 
-msgid "Unpacker"
-msgstr "展開プラグイン"
-
-msgid "Prediffer"
-msgstr "比較前処理プラグイン"
-
 msgid "Editor script"
 msgstr "エディター スクリプト"
 
@@ -3398,12 +3422,6 @@ msgstr "プラグイン設定"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH が見つかりません - .sct スクリプトは無効化されました"
 
-msgid "<None>"
-msgstr "<なし>"
-
-msgid "<Automatic>"
-msgstr "<自動>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "行 %1 に移動(&O)"
@@ -3622,3 +3640,101 @@ msgstr "1つのみインスタンスを起動する"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "1つのみインスタンスを起動し、既起動インスタンスの終了を待つ"
+
+msgid "Al&l"
+msgstr "すべて(&L)"
+
+msgid "Prettification"
+msgstr "整形"
+
+msgid "Content Extraction"
+msgstr "内容抽出"
+
+msgid "Visualization"
+msgstr "視覚化"
+
+msgid "Data Query"
+msgstr "データ問い合わせ"
+
+msgid "&Others"
+msgstr "その他(&O)"
+
+msgid "Make Uppercase"
+msgstr "大文字に変換"
+
+msgid "Make Lowercase"
+msgstr "小文字に変換"
+
+msgid "Remove Duplicate Lines"
+msgstr "重複行を削除"
+
+msgid "Count Duplicate Lines"
+msgstr "重複行をカウント"
+
+msgid "Sort Lines Ascending"
+msgstr "昇順にソート"
+
+msgid "Sort Lines Descending"
+msgstr "降順にソート"
+
+msgid "Apply Filter Command..."
+msgstr "フィルタコマンドを適用..."
+
+msgid "Tokenize..."
+msgstr "トークン分割..."
+
+msgid "Trim Spaces"
+msgstr "行頭行末の空白を削除"
+
+msgid "Insert Date"
+msgstr "日付を挿入"
+
+msgid "Insert Time"
+msgstr "時刻を挿入"
+
+msgid "Apply Patch..."
+msgstr "パッチ適用..."
+
+msgid "Ignore Columns"
+msgstr "指定列を無視"
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr "コメントを無視(C系言語)"
+
+msgid "Ignore CSV Fields"
+msgstr "CSVの指定列を無視"
+
+msgid "Ignore TSV Fields"
+msgstr "TSVの指定列を無視"
+
+msgid "Apply Prediff Substitution Filters"
+msgstr "比較前処理置換フィルタ"
+
+msgid "Prettify JSON"
+msgstr "JSON整形"
+
+msgid "Prettify XML"
+msgstr "XML整形"
+
+msgid "Visualize Graphviz"
+msgstr "Graphviz視覚化"
+
+msgid "Query CSV Data..."
+msgstr "CSVデータの問い合わせ..."
+
+msgid "Query TSV Data..."
+msgstr "TSVデータの問い合わせ..."
+
+msgid "Query JSON Data..."
+msgstr "JSONデータの問い合わせ..."
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr "プラグインパイプラインにプラグイン名が指定されていません: %1"
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr "プラグインパイプラインが引用符で閉じていません: %1"
+
+msgid "Specify plugin arguments"
+msgstr "プラグイン引数を指定してください"
index a3764aa..4a36e23 100644 (file)
@@ -61,8 +61,9 @@ msgstr "왼쪽에서 선택한 줄 복사"
 msgid "Copy Selected Line(s) from Right"
 msgstr "오른쪽에서 선택한 줄 복사"
 
-msgid "&Select Line Difference\tF4"
-msgstr "줄 차이점 선택(&S)\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "줄 차이점 선택(&D)\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -87,6 +88,14 @@ msgstr "복사(&C)"
 msgid "&Paste"
 msgstr "붙여넣기(&P)"
 
+#, c-format
+msgid "&Scripts"
+msgstr "스크립트(&S)"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< 비어 있음 >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "이동(&G)\tCtrl+G"
 
@@ -266,10 +275,6 @@ msgstr "최근 프로젝트"
 msgid "Recent F&iles Or Folders"
 msgstr "최근 파일/폴더(&I)"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< 비어 있음 >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "종료(&X)\tCtrl+Q"
 
@@ -644,10 +649,6 @@ msgid "Reco&mpare As"
 msgstr "다시 비교(&M)"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "실행 취소(&U)\tCtrl+Z"
 
@@ -668,10 +669,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "붙여넣기(&P)\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "줄 차이점 선택(&D)\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "찾기(&I)...\tCtrl+F"
 
@@ -886,13 +883,15 @@ msgstr "동기화 지점 추가(&S)\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "동기화 지점 지우기(&H)"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "스크립트(&S)"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1085,17 +1084,24 @@ msgstr "전체 경로 복사(&C)"
 msgid "Copy &Filename"
 msgstr "파일 이름 복사(&F)"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Prediffer 설정"
+msgid "<None>"
+msgstr "<없음>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<자동>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "prediffer 없음(&N)"
+msgid "&Select..."
+msgstr "선택(&S)..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "자동 prediffer"
+msgid "Prediffer Settings"
+msgstr "Prediffer 설정"
 
 msgid "G&o to Diff"
 msgstr "차이점으로 이동(&O)"
@@ -1251,10 +1257,6 @@ msgid " Folder: Filter"
 msgstr " 폴더: 필터"
 
 #, c-format
-msgid "&Select..."
-msgstr "선택(&S)..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " 파일: 언패커 플러그인"
 
@@ -1632,16 +1634,11 @@ msgstr "위로(&U)"
 msgid "Move &Down"
 msgstr "아래로(&D)"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "언패커 선택"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "파일 언패커:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "모든 언패커를 표시하고, 확장자를 확인하지 않기."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1651,6 +1648,18 @@ msgstr "확장자 목록:"
 msgid "Description:"
 msgstr "설명:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "모든 언패커를 표시하고, 확장자를 확인하지 않기."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "중지"
@@ -2244,6 +2253,12 @@ msgstr "플러그인 사용"
 msgid "File filters:"
 msgstr "파일 필터:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "쉘 통합"
@@ -3319,6 +3334,14 @@ msgid "Binary"
 msgstr "바이너리"
 
 #, c-format
+msgid "Unpacker"
+msgstr "언패커"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "파일을 비교할 수 없습니다"
 
@@ -3561,6 +3584,12 @@ msgstr "파일 내 차이점의 개수. 이 숫자는 무시된 차이점을 포
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "바이너리 파일이면 * 표시를 보입니다"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1을 %2와 비교"
@@ -3866,14 +3895,6 @@ msgid "Type"
 msgstr "형식"
 
 #, c-format
-msgid "Unpacker"
-msgstr "언패커"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "편집기 스크립트"
 
@@ -4068,14 +4089,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH이 없습니다 - .sct 스크립트 비활성화"
 
 #, c-format
-msgid "<None>"
-msgstr "<없음>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<자동>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "%1줄로 이동(&O)"
 
@@ -4308,3 +4321,101 @@ msgstr "중복 실행 금지하기"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "중복 실행 금지 및 기존 실행 종료 대기"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 7cc67c3..b027d18 100644 (file)
@@ -53,8 +53,8 @@ msgstr "Kopijuoti pažymėtą eilutę (-es) iš kairės"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Kopijuoti pažymėtą eilutę (-es) iš dešinės"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Pažymėti skirtumą\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Pažymėti &skirtumą"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Įtraukti šį skirtumą į Keitinių &filtrus"
@@ -74,6 +74,12 @@ msgstr "&Kopijuoti"
 msgid "&Paste"
 msgstr "Įter&pti"
 
+msgid "&Scripts"
+msgstr "&Skriptai"
+
+msgid "< Empty >"
+msgstr "< Tuščia >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Per&eiti į...\tCtrl+G"
 
@@ -223,9 +229,6 @@ msgstr "Paskutinieji projektai"
 msgid "Recent F&iles Or Folders"
 msgstr "Paskiausiai naudoti fa&ilai ar katalogai"
 
-msgid "< Empty >"
-msgstr "< Tuščia >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Išeiti\tCtrl+Q"
 
@@ -514,9 +517,6 @@ msgstr "&Atnaujinti\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Paly&ginti iš naujo kaip"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "Atša&ukti\tCtrl+Z"
 
@@ -532,9 +532,6 @@ msgstr "&Kopijuoti\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "Įter&pti\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Pažymėti &skirtumą"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "R&asti...\tCtrl+F"
 
@@ -700,11 +697,14 @@ msgstr "Įdėti &sinchronizavimo tašką\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Išvalyti sinc&hronizavino taškus"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "&Parengėjas"
 
-msgid "&Scripts"
-msgstr "&Skriptai"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Pada&linti"
@@ -867,14 +867,20 @@ msgstr "Kopijuoti pilną &kelią"
 msgid "Copy &Filename"
 msgstr "Kopijuoti &failo vardą"
 
-msgid "Prediffer Settings"
-msgstr "Parengėjo nuostatos"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Nėra>"
+
+msgid "<Automatic>"
+msgstr "<Automatinis>"
 
-msgid "&No prediffer"
-msgstr "&Nėra parengėjo"
+msgid "&Select..."
+msgstr "Pa&rinkti..."
 
-msgid "Auto prediffer"
-msgstr "Automatinis parengėjas"
+msgid "Prediffer Settings"
+msgstr "Parengėjo nuostatos"
 
 msgid "G&o to Diff"
 msgstr "Pereiti prie skirtum&o"
@@ -993,9 +999,6 @@ msgstr "Rasti..."
 msgid " Folder: Filter"
 msgstr " Katalogams: Filtras"
 
-msgid "&Select..."
-msgstr "Pa&rinkti..."
-
 msgid " File: Unpacker Plugin"
 msgstr " Failams: Išpakuotojas"
 
@@ -1293,14 +1296,11 @@ msgstr "Perkelti a&ukštyn"
 msgid "Move &Down"
 msgstr "Perkelti ž&emyn"
 
-msgid "Select Unpacker"
-msgstr "Parinkti išpakuotoją"
-
-msgid "File unpacker:"
-msgstr "Failo išpakuotojas:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Rodyti visus išpakuotojus netikrinant plėtinių."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Plėtinių sąrašas:"
@@ -1308,6 +1308,18 @@ msgstr "Plėtinių sąrašas:"
 msgid "Description:"
 msgstr "Aprašas:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Rodyti visus išpakuotojus netikrinant plėtinių."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Sustoti"
 
@@ -1767,6 +1779,12 @@ msgstr "Įjungti &papildinius"
 msgid "File filters:"
 msgstr "Failų filtrai:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integr. Windows aplinkoje"
 
@@ -2506,6 +2524,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binarinis"
 
+msgid "Unpacker"
+msgstr "Išpakavimo programa"
+
+msgid "Prediffer"
+msgstr "Parengėjas"
+
 msgid "Unable to compare files"
 msgstr "Neįmanoma palyginti failų"
 
@@ -2698,6 +2722,12 @@ msgstr "Skirtumų skaičius faile. Šis skaičius neapima ignoruotų skirtumų."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Rodyti žvaigždutę (*) jei failas yra binarinis."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Lyginti %1 su %2"
@@ -2917,12 +2947,6 @@ msgstr "Naujas šablonas"
 msgid "Type"
 msgstr "Tipas"
 
-msgid "Unpacker"
-msgstr "Išpakavimo programa"
-
-msgid "Prediffer"
-msgstr "Parengėjas"
-
 msgid "Editor script"
 msgstr "Redaktoriaus skriptas"
 
@@ -3021,12 +3045,6 @@ msgstr "Papildinio nuostatos"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "Nerastas WSH - .sct skriptai išjungti"
 
-msgid "<None>"
-msgstr "<Nėra>"
-
-msgid "<Automatic>"
-msgstr "<Automatinis>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "E&iti į %1 eilutę"
@@ -3239,3 +3257,101 @@ msgstr "Leisti vykdyti tik vieną programos egzempliorių"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Leisti vykdyti tik vieną programos egzempliorių ir sulaukti, kol jo vykdymas baigsis"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 1dd33fd..f4c2faa 100644 (file)
@@ -56,7 +56,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
 msgstr "&Marker linjeforskjell\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -82,6 +83,14 @@ msgstr "Ko&pier"
 msgid "&Paste"
 msgstr "&Lim inn"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Skript"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Tom >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Gå &til...\tCtrl+G"
 
@@ -261,10 +270,6 @@ msgstr "Seneste prosjekter"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Tom >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Avslutt\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Angre\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Lim inn\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "&Marker linjeforskjell\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "S&øk...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Skript"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Kopier full bane"
 msgid "Copy &Filename"
 msgstr "Kopier &filnavn"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Prediffer-innstillinger"
+msgid "<None>"
+msgstr "<Ingen>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatisk>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Ingen prediffer"
+msgid "&Select..."
+msgstr "&Velg..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Auto-prediffer"
+msgid "Prediffer Settings"
+msgstr "Prediffer-innstillinger"
 
 msgid "G&o to Diff"
 msgstr "G&å til forskjell"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "&Velg..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1627,16 +1629,11 @@ msgstr "Flytt &opp"
 msgid "Move &Down"
 msgstr "Flytt &ned"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Velg utpakker"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Filutpakker:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Vis alle utpakkere, ikke kontroller filtype."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Filetypeliste:"
 msgid "Description:"
 msgstr "Beskrivelse:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Vis alle utpakkere, ikke kontroller filtype."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stopp"
@@ -2237,6 +2246,12 @@ msgstr "&Aktiver programtillegg"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Skall-integrasjon"
@@ -3294,6 +3309,14 @@ msgid "Binary"
 msgstr "Binær"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Utpakker"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Kan ikke sammenligne filer"
 
@@ -3536,6 +3559,12 @@ msgstr "Antall forskjeller i filen. Dette antall inkluderer ikke ignorerte forsk
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Viser asterisk (*) hvis filen er binær."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Sammenligning %1 med %2"
@@ -3836,14 +3865,6 @@ msgid "Type"
 msgstr "Type"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Utpakker"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "Redigeringsskript"
 
@@ -3966,14 +3987,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH ikke funnet - .sct skript ikke aktivert"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ingen>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatisk>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "G&å til linje %1"
 
@@ -4200,3 +4213,101 @@ msgstr "Tillat bare en instans å kjøre"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index cda096e..c19ee2b 100644 (file)
@@ -57,8 +57,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&S انتخاب خط تفاوت \tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "&D انتخاب خط تفاوت \tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -83,6 +84,14 @@ msgstr "&C رونوشت برداري "
 msgid "&Paste"
 msgstr "&P چسباندن "
 
+#, c-format
+msgid "&Scripts"
+msgstr "&S دست نويسها "
+
+#, c-format
+msgid "< Empty >"
+msgstr "<خالي>"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&G برو به ... \tCtrl+G"
 
@@ -262,10 +271,6 @@ msgstr " پروژه هاي) طرحهاي اخير) "
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "<خالي>"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&x خروج \tCtrl+Q"
 
@@ -640,10 +645,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&U بي اثر شدن آخرين دستور \tCtrl+Z"
 
@@ -664,10 +665,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&P چسباندن \tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "&D انتخاب خط تفاوت \tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&i يافتن  ...  \tCtrl+F"
 
@@ -882,13 +879,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&P پيش فرق گذار "
 
-#, c-format
-msgid "&Scripts"
-msgstr "&S دست نويسها "
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1081,17 +1080,24 @@ msgstr "&C رونوشت برداري کل مسير "
 msgid "Copy &Filename"
 msgstr "&F رونوشت برداري نام پرونده"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr " تنظيمهاي پيش فرق گذار  "
+msgid "<None>"
+msgstr "<هيچکدام>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<خودکار>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&N بدون پيش فرق گذار "
+msgid "&Select..."
+msgstr "&S انتخاب ... "
 
 #, c-format
-msgid "Auto prediffer"
-msgstr " پيش فرق گذار خودکار "
+msgid "Prediffer Settings"
+msgstr " تنظيمهاي پيش فرق گذار  "
 
 msgid "G&o to Diff"
 msgstr "&o برو به محل تفاوت "
@@ -1247,10 +1253,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "&S انتخاب ... "
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1632,16 +1634,11 @@ msgstr "&U جابجايي به بالا "
 msgid "Move &Down"
 msgstr " جابجايي به پايين "
 
-#, c-format
-msgid "Select Unpacker"
-msgstr " انتخاب بازکننده بسته "
-
-#, c-format
-msgid "File unpacker:"
-msgstr " باز کننده بسته پرونده : "
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr " تمام بازکننده هاي بسته را نمايش بده، توسعه را بررسي نکن "
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1651,6 +1648,18 @@ msgstr " فهرست توسعه ها : "
 msgid "Description:"
 msgstr " توصيف : "
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr " تمام بازکننده هاي بسته را نمايش بده، توسعه را بررسي نکن "
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr " ايست "
@@ -2244,6 +2253,12 @@ msgstr "&E فعال سازي افزايه ها "
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr " يکپارچه سازي پوسته "
@@ -3317,6 +3332,14 @@ msgid "Binary"
 msgstr " دودويي "
 
 #, c-format
+msgid "Unpacker"
+msgstr " باز کننده بسته "
+
+#, c-format
+msgid "Prediffer"
+msgstr " پيش فرق گذار "
+
+#, c-format
 msgid "Unable to compare files"
 msgstr " ناتوان از همسنجي پرونده هاست"
 
@@ -3566,6 +3589,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr " نمايش يک ستاره * در صورتيکه پرونده دودويي باشد "
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr " همسنجي  %1 با  %2"
@@ -3879,14 +3908,6 @@ msgid "Type"
 msgstr " نوع "
 
 #, c-format
-msgid "Unpacker"
-msgstr " باز کننده بسته "
-
-#, c-format
-msgid "Prediffer"
-msgstr " پيش فرق گذار "
-
-#, c-format
 msgid "Editor script"
 msgstr "دست نوشته براي ويراستار   "
 
@@ -4009,14 +4030,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr " .sct پيدا نشد -  دست نوشته ها غير فعال شد WSH  "
 
 #, c-format
-msgid "<None>"
-msgstr "<هيچکدام>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<خودکار>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "&G   برو به خط  %1 "
 
@@ -4243,3 +4256,101 @@ msgstr "اجازه اجراي همزمان تنها يک نسخه از نرم ا
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 3018027..f818476 100644 (file)
@@ -50,7 +50,7 @@ msgstr "Kopiuj zaznaczone wiersze z lewej"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Kopiuj zaznaczone wiersze z prawej"
 
-msgid "&Select Line Difference\tF4"
+msgid "Select Line &Difference\tF4"
 msgstr "Zaznacz różniące się wiersze\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -71,6 +71,12 @@ msgstr "Kopiuj"
 msgid "&Paste"
 msgstr "Wklej"
 
+msgid "&Scripts"
+msgstr "&Skrypty"
+
+msgid "< Empty >"
+msgstr "< Pusty >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Idź do...\tCtrl+G"
 
@@ -220,9 +226,6 @@ msgstr "Ostatnie projekty"
 msgid "Recent F&iles Or Folders"
 msgstr "Ostatnie pliki lub foldery"
 
-msgid "< Empty >"
-msgstr "< Pusty >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Zakończ\tCtrl+Q"
 
@@ -511,9 +514,6 @@ msgstr "Odśwież\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Ponownie porównaj jako"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "Cofnij\tCtrl+Z"
 
@@ -529,9 +529,6 @@ msgstr "Kopiuj\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "Wklej\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Zaznacz różniące się wiersze\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "Znajdź...\tCtrl+F"
 
@@ -697,11 +694,14 @@ msgstr "Dodaj punkt &synchronizacji\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Wyczyść punkty sync&hronizacji"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "Różnicowanie wstępne"
 
-msgid "&Scripts"
-msgstr "&Skrypty"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Podzie&lone"
@@ -864,14 +864,20 @@ msgstr "Kopiuj pełną ś&cieżkę"
 msgid "Copy &Filename"
 msgstr "Kopiuj nazwę pliku"
 
-msgid "Prediffer Settings"
-msgstr "Ustawienia różnicowania wstępnego"
+msgid "Unpacker Settings"
+msgstr ""
 
-msgid "&No prediffer"
-msgstr "Bez róż&nicowania wstępnego"
+msgid "<None>"
+msgstr "<Brak>"
 
-msgid "Auto prediffer"
-msgstr "Automatyczne różnicowanie wstępne"
+msgid "<Automatic>"
+msgstr "<Automatycznie>"
+
+msgid "&Select..."
+msgstr "Wybierz..."
+
+msgid "Prediffer Settings"
+msgstr "Ustawienia różnicowania wstępnego"
 
 msgid "G&o to Diff"
 msgstr "Idź d&o różnicy"
@@ -990,9 +996,6 @@ msgstr "Przeglądaj..."
 msgid " Folder: Filter"
 msgstr " Folder: filtr"
 
-msgid "&Select..."
-msgstr "Wybierz..."
-
 msgid " File: Unpacker Plugin"
 msgstr " Plik: wypakowana wtyczka"
 
@@ -1290,14 +1293,11 @@ msgstr "W górę"
 msgid "Move &Down"
 msgstr "W dół"
 
-msgid "Select Unpacker"
-msgstr "Wybierz program rozpakowujący"
-
-msgid "File unpacker:"
-msgstr "Plik rozpakowujący:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Pokaż wszystkie programy rozpakowujące, nie sprawdzaj rozszerzenia."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Lista rozszerzeń:"
@@ -1305,6 +1305,18 @@ msgstr "Lista rozszerzeń:"
 msgid "Description:"
 msgstr "Opis:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Pokaż wszystkie programy rozpakowujące, nie sprawdzaj rozszerzenia."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Zatrzymaj"
 
@@ -1764,6 +1776,12 @@ msgstr "Włącz wtyczki"
 msgid "File filters:"
 msgstr "Filtry plików:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integracja z powłoką"
 
@@ -2503,6 +2521,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binarny"
 
+msgid "Unpacker"
+msgstr "Program rozpakowujący"
+
+msgid "Prediffer"
+msgstr "Różnicowanie wstępne"
+
 msgid "Unable to compare files"
 msgstr "Nie można porównać plików"
 
@@ -2695,6 +2719,12 @@ msgstr "Liczba różnic w pliku. Liczba ta nie zawiera zignorowanych różnic."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Pokazuje gwiazdkę (*) jeśli plik jest binarny."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Porównaj %1 z %2"
@@ -2914,12 +2944,6 @@ msgstr "Nowy wzorzec"
 msgid "Type"
 msgstr "Typ"
 
-msgid "Unpacker"
-msgstr "Program rozpakowujący"
-
-msgid "Prediffer"
-msgstr "Różnicowanie wstępne"
-
 msgid "Editor script"
 msgstr "Skrypt edytora"
 
@@ -3018,12 +3042,6 @@ msgstr "Ustawienia wtyczki"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "Nie znaleziono WSH – skrypty .sct wyłączone"
 
-msgid "<None>"
-msgstr "<Brak>"
-
-msgid "<Automatic>"
-msgstr "<Automatycznie>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Idź do wiersza %1"
@@ -3236,3 +3254,101 @@ msgstr "Zezwól na uruchomienie tylko jednej instancji programu"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Zezwól na uruchomienie tylko jednej instancji i poczekaj, aż zakończy pracę"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index f39cded..1ce89e2 100644 (file)
@@ -53,8 +53,8 @@ msgstr "Copiar linha(s) selecionada(s) da esquerda"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Copiar linha(s) selecionada(s) da direita"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Selecionar diferença de linha\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Selecionar Diferenças de Linha\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Adicionar esta alteração aos &Filtros de Substituição"
@@ -74,6 +74,12 @@ msgstr "Co&piar"
 msgid "&Paste"
 msgstr "Co&lar"
 
+msgid "&Scripts"
+msgstr "Scripts"
+
+msgid "< Empty >"
+msgstr "< Vazio >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Ir para...\tCtrl+G"
 
@@ -223,9 +229,6 @@ msgstr "Projetos Recentes"
 msgid "Recent F&iles Or Folders"
 msgstr "&Ficheiros ou Pastas Recentes"
 
-msgid "< Empty >"
-msgstr "< Vazio >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "S&air\tCtrl+Q"
 
@@ -514,9 +517,6 @@ msgstr "Re&carregar\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Voltar a Comparar Como"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&Desfazer\tCtrl+Z"
 
@@ -532,9 +532,6 @@ msgstr "&Copiar...\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "&Colar\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Selecionar Diferenças de Linha\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "Procurar...\tCtrl+F"
 
@@ -700,11 +697,14 @@ msgstr "Adicionar Ponto de Sincronização"
 msgid "Clear Sync&hronization Points"
 msgstr "Limpar Pontos de Sincronização"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "Pré-diferenciar"
 
-msgid "&Scripts"
-msgstr "Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Di&vidir"
@@ -867,14 +867,20 @@ msgstr "Copiar Localização Completa"
 msgid "Copy &Filename"
 msgstr "Co&piar Nome do Ficheiro"
 
-msgid "Prediffer Settings"
-msgstr "Definições de pré-diferenciação"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Nenhum>"
+
+msgid "<Automatic>"
+msgstr "<Automático>"
 
-msgid "&No prediffer"
-msgstr "Não pré-diferenciar"
+msgid "&Select..."
+msgstr "Selecionar..."
 
-msgid "Auto prediffer"
-msgstr "Pré-diferenciação manual"
+msgid "Prediffer Settings"
+msgstr "Definições de pré-diferenciação"
 
 msgid "G&o to Diff"
 msgstr "Ir para Diff"
@@ -993,9 +999,6 @@ msgstr "Procurar..."
 msgid " Folder: Filter"
 msgstr " Pasta: Filtro"
 
-msgid "&Select..."
-msgstr "Selecionar..."
-
 msgid " File: Unpacker Plugin"
 msgstr " Ficheiro: Unpacker Plugin"
 
@@ -1303,14 +1306,11 @@ msgstr "Mover para &Cima"
 msgid "Move &Down"
 msgstr "Mover para &Baixo"
 
-msgid "Select Unpacker"
-msgstr "Selecionar Extrator"
-
-msgid "File unpacker:"
-msgstr "Extrator de ficheiros:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Mostrar todos os extratores, não verificar extensões."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Lista de extensões:"
@@ -1318,6 +1318,18 @@ msgstr "Lista de extensões:"
 msgid "Description:"
 msgstr "Descrição:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Mostrar todos os extratores, não verificar extensões."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Parar"
 
@@ -1788,6 +1800,12 @@ msgstr "&Ativar plugins"
 msgid "File filters:"
 msgstr "Filtros de ficheiro:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integração Shell"
 
@@ -2791,6 +2809,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binário"
 
+msgid "Unpacker"
+msgstr "Extrator"
+
+msgid "Prediffer"
+msgstr "Pré-diferenciar"
+
 msgid "Unable to compare files"
 msgstr "Não é possível comparar ficheiros"
 
@@ -2993,6 +3017,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Apresenta um asterisco (*) se ficheiro for binário."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Comparar %1 com %2"
@@ -3285,12 +3315,6 @@ msgstr "Novo Padrão"
 msgid "Type"
 msgstr "Tipo"
 
-msgid "Unpacker"
-msgstr "Extrator"
-
-msgid "Prediffer"
-msgstr "Pré-diferenciar"
-
 msgid "Editor script"
 msgstr "Editor script"
 
@@ -3481,12 +3505,6 @@ msgstr "Definições de Plugins"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH não encontrado - scripts .sct desativados"
 
-msgid "<None>"
-msgstr "<Nenhum>"
-
-msgid "<Automatic>"
-msgstr "<Automático>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Ir para linha %1"
@@ -3707,3 +3725,101 @@ msgstr "Permitir apenas uma execução"
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
 "Permitir apenas executar uma instância e esperar que a instância termine"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index e2af001..1d3e147 100644 (file)
@@ -56,8 +56,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Selectează diferenţele pe linie\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Selectează &diferenţele pe linie\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -82,6 +83,14 @@ msgstr "&Copie"
 msgid "&Paste"
 msgstr "Li&peşte"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Script-uri"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Gol >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Mergi la...\tCtrl+G"
 
@@ -261,10 +270,6 @@ msgstr "Proiecte recente"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Gol >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Ieşir&e\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "An&ulează\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Li&peşte\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Selectează &diferenţele pe linie\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Găseşte...\tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Prediferenţiator"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Script-uri"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Copie calea întreagă"
 msgid "Copy &Filename"
 msgstr "Copie numele de &fişier"
 
-#, c-format
-msgid "Prediffer Settings"
-msgstr "Setări prediferenţiator"
+msgid "Unpacker Settings"
+msgstr ""
+
+#, fuzzy, c-format
+msgid "<None>"
+msgstr "<Deloc>"
+
+#, fuzzy, c-format
+msgid "<Automatic>"
+msgstr "<Automat>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Fără predifere&nţiator"
+msgid "&Select..."
+msgstr "&Selectează..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Auto prediferenţiator"
+msgid "Prediffer Settings"
+msgstr "Setări prediferenţiator"
 
 msgid "G&o to Diff"
 msgstr "Mergi la difere&nţă"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "&Selectează..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1627,16 +1629,11 @@ msgstr "Mută mai s&us"
 msgid "Move &Down"
 msgstr "Mută mai &jos"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Selectează dezarhivator"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Dezarhivator fişiere:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Afişează toate dezarhivatoarele, fară a verifica extensia."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1646,6 +1643,18 @@ msgstr "Listă extensii:"
 msgid "Description:"
 msgstr "Descriere:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Afişează toate dezarhivatoarele, fară a verifica extensia."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stop"
@@ -2235,6 +2244,12 @@ msgstr ""
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr ""
@@ -3273,6 +3288,14 @@ msgid "Binary"
 msgstr "Binar"
 
 #, c-format
+msgid "Unpacker"
+msgstr ""
+
+#, c-format
+msgid "Prediffer"
+msgstr ""
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Imposibil de comparat fişierele"
 
@@ -3515,6 +3538,12 @@ msgstr "Număr de diferenţe în fişier. Acest număr nu include diferenţele i
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Arată un asterisc (*) dacă fişierul este binar."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Compară %1 cu %2"
@@ -3815,14 +3844,6 @@ msgid "Type"
 msgstr ""
 
 #, c-format
-msgid "Unpacker"
-msgstr ""
-
-#, c-format
-msgid "Prediffer"
-msgstr ""
-
-#, c-format
 msgid "Editor script"
 msgstr ""
 
@@ -3944,14 +3965,6 @@ msgstr "Setări pentru plug-in-uri"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "Nu s-a găsit WSH - scripurile .sct sunt dezactivate"
 
-#, fuzzy, c-format
-msgid "<None>"
-msgstr "<Deloc>"
-
-#, fuzzy, c-format
-msgid "<Automatic>"
-msgstr "<Automat>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "&Mergi la linia %1"
@@ -4179,3 +4192,101 @@ msgstr "Permite rularea unei singure instanţe"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index dc6d669..2673eb6 100644 (file)
@@ -52,8 +52,8 @@ msgstr "Копировать выбранные строки слева"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Копировать выбранные строки справа"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Выбрать отличие\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Выбрать отличие\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Добавить это изменение в &фильтры замены"
@@ -73,6 +73,12 @@ msgstr "&Копировать"
 msgid "&Paste"
 msgstr "&Вставить"
 
+msgid "&Scripts"
+msgstr "&Скрипты"
+
+msgid "< Empty >"
+msgstr "< Нет >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Перейти к...\tCtrl+G"
 
@@ -222,9 +228,6 @@ msgstr "Недавние проекты"
 msgid "Recent F&iles Or Folders"
 msgstr "Недавние файлы и папки"
 
-msgid "< Empty >"
-msgstr "< Нет >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "В&ыход\tCtrl+Q"
 
@@ -513,9 +516,6 @@ msgstr "Обновить\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "Пересравнить как"
 
-msgid "&XML"
-msgstr ""
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&Отменить\tCtrl+Z"
 
@@ -531,9 +531,6 @@ msgstr "&Копировать\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "&Вставить\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Выбрать отличие\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "&Найти...\tCtrl+F"
 
@@ -699,11 +696,14 @@ msgstr "Добавить точку синхронизации\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Очистить точки синхронизации"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "&Предсравнение"
 
-msgid "&Scripts"
-msgstr "&Скрипты"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Разделить"
@@ -866,14 +866,20 @@ msgstr "Копировать полный путь"
 msgid "Copy &Filename"
 msgstr "Копировать имя файла"
 
-msgid "Prediffer Settings"
-msgstr "Параметры предсравнения"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Нет>"
 
-msgid "&No prediffer"
-msgstr "&Без предсравнения"
+msgid "<Automatic>"
+msgstr "<Автоматически>"
 
-msgid "Auto prediffer"
-msgstr "&Автопредсравнение"
+msgid "&Select..."
+msgstr "Выбрать..."
+
+msgid "Prediffer Settings"
+msgstr "Параметры предсравнения"
 
 msgid "G&o to Diff"
 msgstr "Перейти к &отличию"
@@ -992,9 +998,6 @@ msgstr "Обзор..."
 msgid " Folder: Filter"
 msgstr " Папка: Фильтр"
 
-msgid "&Select..."
-msgstr "Выбрать..."
-
 msgid " File: Unpacker Plugin"
 msgstr " Файл: плагин распаковщика"
 
@@ -1292,14 +1295,11 @@ msgstr "&Вверх"
 msgid "Move &Down"
 msgstr "В&низ"
 
-msgid "Select Unpacker"
-msgstr "Выбор распаковщика"
-
-msgid "File unpacker:"
-msgstr "Файл распаковщика:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Показывать все распаковщики, не проверять расширение."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Список расширений:"
@@ -1307,6 +1307,18 @@ msgstr "Список расширений:"
 msgid "Description:"
 msgstr "Описание:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Показывать все распаковщики, не проверять расширение."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Остановить"
 
@@ -1766,6 +1778,12 @@ msgstr "&Включить плагины"
 msgid "File filters:"
 msgstr "Фильтры файлов:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Интеграция в оболочку"
 
@@ -2505,6 +2523,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Двоичный"
 
+msgid "Unpacker"
+msgstr "Распаковщик"
+
+msgid "Prediffer"
+msgstr "Предсравнение"
+
 msgid "Unable to compare files"
 msgstr "Не удается сравнить файлы"
 
@@ -2697,6 +2721,12 @@ msgstr "Количество отличий в файле. Это количес
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Показать звездочку (*) если файл двоичный."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Сравнение %1 с %2"
@@ -2916,12 +2946,6 @@ msgstr "Новый шаблон"
 msgid "Type"
 msgstr "Тип"
 
-msgid "Unpacker"
-msgstr "Распаковщик"
-
-msgid "Prediffer"
-msgstr "Предсравнение"
-
 msgid "Editor script"
 msgstr "Редактор скриптов"
 
@@ -3020,12 +3044,6 @@ msgstr "Настройки плагина"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH не найден - .sct скрипты отключены"
 
-msgid "<None>"
-msgstr "<Нет>"
-
-msgid "<Automatic>"
-msgstr "<Автоматически>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Перейти к строке %1"
@@ -3238,3 +3256,101 @@ msgstr "Разрешить запуск только одной копии"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Разрешить запуск только одной копии и дожидаться ее завершения"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 954e57d..b9cfc8f 100644 (file)
@@ -55,8 +55,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Изабери различите редове\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Истакни &разлику реда\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -81,6 +82,14 @@ msgstr "&Умножи"
 msgid "&Paste"
 msgstr "&Налепи"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Скрипте "
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Празан >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Иди на...\tCtrl+G"
 
@@ -259,10 +268,6 @@ msgstr "Последње поређење"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Празан >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Изла&з\tCtrl+Q"
 
@@ -637,10 +642,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "Опо&зови\tCtrl+Z"
 
@@ -661,10 +662,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Налепи\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Истакни &разлику реда\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Претраж&и...\tCtrl+F"
 
@@ -879,13 +876,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Дефинисано поређење"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Скрипте "
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr ""
@@ -1077,17 +1076,24 @@ msgstr "&Умножи путању"
 msgid "Copy &Filename"
 msgstr "Умножи на&зив датотеке"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Својства дефинисаног поређења"
+msgid "<None>"
+msgstr "<Ништа>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Нема дефинисаног поређења"
+msgid "<Automatic>"
+msgstr "<Аутоматски>"
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Аутоматски дефиниши поређење"
+msgid "&Select..."
+msgstr "&Изабери..."
+
+#, c-format
+msgid "Prediffer Settings"
+msgstr "Својства дефинисаног поређења"
 
 msgid "G&o to Diff"
 msgstr "Иди &на разлику"
@@ -1234,10 +1240,6 @@ msgstr "Преглед..."
 msgid " Folder: Filter"
 msgstr ""
 
-#, c-format
-msgid "&Select..."
-msgstr "&Изабери..."
-
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1612,15 +1614,10 @@ msgstr "Помери &горе"
 msgid "Move &Down"
 msgstr "Помери &доле"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Избор архивера"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Архивер датотека"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
+msgid "Plugin &Name:"
 msgstr ""
 
 #, c-format
@@ -1631,6 +1628,18 @@ msgstr "Попис наставака:"
 msgid "Description:"
 msgstr "Опис:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr ""
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Стани"
@@ -2220,6 +2229,12 @@ msgstr "Омогући додатк&е"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Интегриши у 'љуску'"
@@ -3269,6 +3284,14 @@ msgid "Binary"
 msgstr "Бинарни"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Распакивање"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Дефинисано поређење"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Не могу упоредити датотеке"
 
@@ -3511,6 +3534,12 @@ msgstr "Број разлика у датотеци.Овај број не ук
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Приказује звездицу (*), ако је датотека бинарна"
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Упореди %1 са %2"
@@ -3808,14 +3837,6 @@ msgid "Type"
 msgstr "Врста"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Распакивање"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Дефинисано поређење"
-
-#, c-format
 msgid "Editor script"
 msgstr "Уређивач рукописа"
 
@@ -3938,14 +3959,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH није нађен - .sct скрипте су онемогућене"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ништа>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Аутоматски>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "И&ди на ред %1"
 
@@ -4172,3 +4185,101 @@ msgstr "Дозволи само једну покренуту надлежнос
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 81cc5a1..f30229a 100644 (file)
@@ -53,8 +53,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "පේලි අතර වෙනස තේරීම\tF4"
+#, fuzzy, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Select Line &Difference\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -79,6 +80,14 @@ msgstr "පිටපත් කිරීම"
 msgid "&Paste"
 msgstr "ඇලවීම"
 
+#, fuzzy, c-format
+msgid "&Scripts"
+msgstr "&Scripts"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< හිස් >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "යන්න\tCtrl+G"
 
@@ -258,10 +267,6 @@ msgstr "මෑතදී කළ ව්‍යාපෘති"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< හිස් >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr " නික්මීම\tCtrl+Q"
 
@@ -636,10 +641,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "නිශ්ප්‍රභා කිරීම\tCtrl+Z"
 
@@ -659,10 +660,6 @@ msgstr "පිටපත් කිරීම\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "ඇලවීම\tCtrl+V"
 
-#, fuzzy, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Select Line &Difference\tF4"
-
 #, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "සොයන්න...\tCtrl+F"
@@ -878,13 +875,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, fuzzy, c-format
 msgid "&Prediffer"
 msgstr "&Prediffer"
 
-#, fuzzy, c-format
-msgid "&Scripts"
-msgstr "&Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1077,17 +1076,24 @@ msgstr "&Copy Full Path"
 msgid "Copy &Filename"
 msgstr "ගොනුවෙ නම  පිටපත් කිරීම"
 
-#, fuzzy, c-format
-msgid "Prediffer Settings"
-msgstr "Prediffer Settings"
+msgid "Unpacker Settings"
+msgstr ""
 
-#, fuzzy, c-format
-msgid "&No prediffer"
-msgstr "&No prediffer"
+#, c-format
+msgid "<None>"
+msgstr "<None>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatic>"
+
+#, c-format
+msgid "&Select..."
+msgstr "තෝරන්න..."
 
 #, fuzzy, c-format
-msgid "Auto prediffer"
-msgstr "Auto prediffer"
+msgid "Prediffer Settings"
+msgstr "Prediffer Settings"
 
 msgid "G&o to Diff"
 msgstr "G&oto Diff"
@@ -1243,10 +1249,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "තෝරන්න..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1624,15 +1626,10 @@ msgstr "ඉහළට ගෙනියන්න"
 msgid "Move &Down"
 msgstr "පහළට ගෙනියන්න"
 
-#, fuzzy, c-format
-msgid "Select Unpacker"
-msgstr "Select Unpacker"
-
-#, fuzzy, c-format
-msgid "File unpacker:"
-msgstr "File unpacker:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
+msgid "Plugin &Name:"
 msgstr ""
 
 #, fuzzy, c-format
@@ -1643,6 +1640,18 @@ msgstr "Extensions list:"
 msgid "Description:"
 msgstr " විස්තරය:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr ""
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "නවත්වන්න"
@@ -2232,6 +2241,12 @@ msgstr "&උපකාරක බලය වැඩිකිරීම"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "කවච සංකලනය කිරීම"
@@ -3285,6 +3300,14 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "ද්වීමය "
 
+#, fuzzy, c-format
+msgid "Unpacker"
+msgstr "Unpacker"
+
+#, fuzzy, c-format
+msgid "Prediffer"
+msgstr "Prediffer"
+
 #, c-format
 msgid "Unable to compare files"
 msgstr "ලිපිගොනු සංසන්දනය කිරීමට නොහැකිය"
@@ -3528,6 +3551,12 @@ msgstr "Number of differences in file. This number does not include ignored diff
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Shows an asterisk (*) if the file is binary."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Compare %1 with %2"
@@ -3825,14 +3854,6 @@ msgstr ""
 msgid "Type"
 msgstr "Type"
 
-#, fuzzy, c-format
-msgid "Unpacker"
-msgstr "Unpacker"
-
-#, fuzzy, c-format
-msgid "Prediffer"
-msgstr "Prediffer"
-
 #, c-format
 msgid "Editor script"
 msgstr "Editor script"
@@ -3956,14 +3977,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH not found - .sct scripts disabled"
 
 #, c-format
-msgid "<None>"
-msgstr "<None>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatic>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "G&o to Line %1"
 
@@ -4190,3 +4203,101 @@ msgstr "එක් දෘෂ්ටාන්තයක් පමණක් සිද
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 258179d..46b7ecb 100644 (file)
@@ -53,8 +53,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Vybrať rozdiely riadkov\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Vybrať riadky roz&dielov\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -74,6 +74,12 @@ msgstr "&Kopírovať"
 msgid "&Paste"
 msgstr "&Prilepiť"
 
+msgid "&Scripts"
+msgstr "&Skripty"
+
+msgid "< Empty >"
+msgstr "< Prázdne >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Prejsť na...\tCtrl+G"
 
@@ -223,9 +229,6 @@ msgstr "Naposledy otvorené projekty"
 msgid "Recent F&iles Or Folders"
 msgstr "Naposledy otvorené sú&bory alebo projekty"
 
-msgid "< Empty >"
-msgstr "< Prázdne >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Koniec\tCtrl+Q"
 
@@ -514,9 +517,6 @@ msgstr "Znova načítať\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "&Znovu porovnať ako"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "&Späť\tCtrl+Z"
 
@@ -532,9 +532,6 @@ msgstr "&Kopírovať\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "&Prilepiť\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Vybrať riadky roz&dielov\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "&Hľadať...\tCtrl+F"
 
@@ -700,11 +697,14 @@ msgstr "Pridať &synchronizačný bod\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Vymazať sync&hronizačné body"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "&Predbežné spracovanie rozdielov"
 
-msgid "&Scripts"
-msgstr "&Skripty"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Od&deliť"
@@ -867,14 +867,20 @@ msgstr "&Kopírovať plnú cestu"
 msgid "Copy &Filename"
 msgstr "Kopírovať názov &súboru"
 
-msgid "Prediffer Settings"
-msgstr "Nastavenia predspracovania rozdielov"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Žiadny>"
+
+msgid "<Automatic>"
+msgstr "<Automatické>"
 
-msgid "&No prediffer"
-msgstr "&Bez predspracovania rozdielov"
+msgid "&Select..."
+msgstr "&Vybrať..."
 
-msgid "Auto prediffer"
-msgstr "&Automatické predspracovanie rozdielov"
+msgid "Prediffer Settings"
+msgstr "Nastavenia predspracovania rozdielov"
 
 msgid "G&o to Diff"
 msgstr "Ch&oď na rozdiel"
@@ -993,9 +999,6 @@ msgstr "Prehľadávať..."
 msgid " Folder: Filter"
 msgstr " Priečinok: Filter"
 
-msgid "&Select..."
-msgstr "&Vybrať..."
-
 msgid " File: Unpacker Plugin"
 msgstr " File: Rozšírenie rozbaľovača"
 
@@ -1297,14 +1300,11 @@ msgstr "Posunúť &hore"
 msgid "Move &Down"
 msgstr "Posunúť &dole"
 
-msgid "Select Unpacker"
-msgstr "Vybrať pakovač"
-
-msgid "File unpacker:"
-msgstr "Súbor pakovača:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Zobraziť všetky pakovače, nekontrolovať príponu."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Zoznam prípon:"
@@ -1312,6 +1312,18 @@ msgstr "Zoznam prípon:"
 msgid "Description:"
 msgstr "Popis:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Zobraziť všetky pakovače, nekontrolovať príponu."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Zastaviť"
 
@@ -1777,6 +1789,12 @@ msgstr "&Povoliť rozšírenia"
 msgid "File filters:"
 msgstr "Filtre súborov:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integrácia prostredia"
 
@@ -2762,6 +2780,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binárny"
 
+msgid "Unpacker"
+msgstr "Archivačný program"
+
+msgid "Prediffer"
+msgstr "Predbežné spracovanie rozdielov"
+
 msgid "Unable to compare files"
 msgstr "Nemožno porovnať súbory"
 
@@ -2961,6 +2985,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Zobrazí hviezdičku (*) ak je súbor binárny."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Porovnať %1 s %2"
@@ -3248,12 +3278,6 @@ msgstr "Nový vzor"
 msgid "Type"
 msgstr "Typ"
 
-msgid "Unpacker"
-msgstr "Archivačný program"
-
-msgid "Prediffer"
-msgstr "Predbežné spracovanie rozdielov"
-
 msgid "Editor script"
 msgstr "Skript editora"
 
@@ -3427,12 +3451,6 @@ msgstr "Nastavenia rozšírení"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH nenájdené - .sct skripty sú zakázané"
 
-msgid "<None>"
-msgstr "<Žiadny>"
-
-msgid "<Automatic>"
-msgstr "<Automatické>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Ch&oď na riadok %1"
@@ -3651,3 +3669,101 @@ msgstr "Umožniť spustenie iba jednej inštancie"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index a81d172..ad0fd97 100644 (file)
@@ -57,8 +57,9 @@ msgstr "Kopiraj izbrane vrstice z leve"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Kopiraj izbrane vrstice z desne"
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Izberi razliko vrstice\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Izberi &razliko vrstice\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Dodaj to spremembmo med &Nadomestne filtre"
@@ -83,6 +84,14 @@ msgstr "&Kopiraj"
 msgid "&Paste"
 msgstr "&Prilepi"
 
+#, c-format
+msgid "&Scripts"
+msgstr "&Skripti"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Prazno >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Pojdi &na...\tCtrl+G"
 
@@ -262,10 +271,6 @@ msgstr "Nedavni projekti"
 msgid "Recent F&iles Or Folders"
 msgstr "Ne&davne datoteke ali mape"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Prazno >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "I&zhod\tCtrl+Q"
 
@@ -639,10 +644,6 @@ msgid "Reco&mpare As"
 msgstr "Znova primerjaj kot"
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Razveljavi\tCtrl+Z"
 
@@ -663,10 +664,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Prilepi\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Izberi &razliko vrstice\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "&Najdi... \tCtrl+F"
 
@@ -881,13 +878,15 @@ msgstr "Dodaj &sinhronizacijsko točko\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Počisti sin&hronizacijske točke"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Predpregled razlik"
 
-#, c-format
-msgid "&Scripts"
-msgstr "&Skripti"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1080,17 +1079,24 @@ msgstr "&Kopiraj celotno pot"
 msgid "Copy &Filename"
 msgstr "Kopiraj &ime datoteke"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Nastavitve predogleda razlik"
+msgid "<None>"
+msgstr "<Brez>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Samodejno>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Brez predogleda razlik"
+msgid "&Select..."
+msgstr "&Izberi..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Samodejni predogled razlik"
+msgid "Prediffer Settings"
+msgstr "Nastavitve predogleda razlik"
 
 msgid "G&o to Diff"
 msgstr "Pojdi &na razliko"
@@ -1246,10 +1252,6 @@ msgid " Folder: Filter"
 msgstr " Mapa: Filter"
 
 #, c-format
-msgid "&Select..."
-msgstr "&Izberi..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Datoteka: Vtičnik razpakovalca"
 
@@ -1626,16 +1628,11 @@ msgstr "Premakni navz&gor"
 msgid "Move &Down"
 msgstr "Premakni navz&dol"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Izberite razpakovalca"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Razpakovalec datoteke:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Prikaži vse razpakovalce, ne glede na končnico."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1645,6 +1642,18 @@ msgstr "Seznam končnic:"
 msgid "Description:"
 msgstr "Opis:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Prikaži vse razpakovalce, ne glede na končnico."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Ustavi"
@@ -2239,6 +2248,12 @@ msgstr "&Omogoči vtičnike"
 msgid "File filters:"
 msgstr "Filtri datotek:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Integracija v lupino"
@@ -3347,6 +3362,14 @@ msgid "Binary"
 msgstr "Dvojiško"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Razpakovalec"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Predpregled razlik"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Datotek ni mogoče primerjati"
 
@@ -3589,6 +3612,12 @@ msgstr "Število razlik v datoteki. Ta številka ne vsebuje prezrtih razlik."
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Prikaže zvezdico (*) če je datoteka dvojiška."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Primerjaj %1 z %2"
@@ -3904,14 +3933,6 @@ msgid "Type"
 msgstr "Vrsta"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Razpakovalec"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Predpregled razlik"
-
-#, c-format
 msgid "Editor script"
 msgstr "Urejevalnik skriptov"
 
@@ -4122,14 +4143,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH ni najden - skripti '.sct' so onemogočeni"
 
 #, c-format
-msgid "<None>"
-msgstr "<Brez>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Samodejno>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Pojdi &na vrstico %1"
 
@@ -4361,3 +4374,101 @@ msgstr "Dovoli zagon samo enega primerka programa"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Dovoli zagon le enega primerka, in počakaj, da se primerek dokonča"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index bcf2281..c9d4490 100644 (file)
@@ -54,8 +54,8 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Seleccionar dif. de línea\tF4"
+msgid "Select Line &Difference\tF4"
+msgstr "Seleccionar &dif. de línea\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -75,6 +75,12 @@ msgstr "&Copiar"
 msgid "&Paste"
 msgstr "&Pegar"
 
+msgid "&Scripts"
+msgstr "&Scripts"
+
+msgid "< Empty >"
+msgstr "< Vacío >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Ir &a...\tCtrl+G"
 
@@ -224,9 +230,6 @@ msgstr "Proyectos recientes"
 msgid "Recent F&iles Or Folders"
 msgstr "Arch&ivos o Carpetas Recientes"
 
-msgid "< Empty >"
-msgstr "< Vacío >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "&Salir\tCtrl+Q"
 
@@ -515,9 +518,6 @@ msgstr ""
 msgid "Reco&mpare As"
 msgstr "Recomparar como"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "Des&hacer\tCtrl+Z"
 
@@ -533,9 +533,6 @@ msgstr "&Copiar\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "&Pegar\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Seleccionar &dif. de línea\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "&Buscar...\tCtrl+F"
 
@@ -701,11 +698,14 @@ msgstr "Añadir Punto de &Sincronización\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Limpiar puntos de sincroni&zación"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "&Precomparación"
 
-msgid "&Scripts"
-msgstr "&Scripts"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "&Dividir"
@@ -868,14 +868,20 @@ msgstr "&Copiar ruta completa"
 msgid "Copy &Filename"
 msgstr "Copiar &nombre de archivo"
 
-msgid "Prediffer Settings"
-msgstr "Config. precomparación"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Ninguno>"
+
+msgid "<Automatic>"
+msgstr "<Automático>"
 
-msgid "&No prediffer"
-msgstr "Si&n precomparación"
+msgid "&Select..."
+msgstr "&Seleccionar..."
 
-msgid "Auto prediffer"
-msgstr "Auto precomparación"
+msgid "Prediffer Settings"
+msgstr "Config. precomparación"
 
 msgid "G&o to Diff"
 msgstr "Ir a &diferencia"
@@ -994,9 +1000,6 @@ msgstr "Examinar..."
 msgid " Folder: Filter"
 msgstr " Carpeta: Filtro"
 
-msgid "&Select..."
-msgstr "&Seleccionar..."
-
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1296,14 +1299,11 @@ msgstr "&Arriba"
 msgid "Move &Down"
 msgstr "A&bajo"
 
-msgid "Select Unpacker"
-msgstr "Seleccionar Desempaquetador"
-
-msgid "File unpacker:"
-msgstr "Desempaquet.:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Mostrar todos los desempaquetadores, no comprobar exts."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Extensiones:"
@@ -1311,6 +1311,18 @@ msgstr "Extensiones:"
 msgid "Description:"
 msgstr "Descripción:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Mostrar todos los desempaquetadores, no comprobar exts."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Detener"
 
@@ -1776,6 +1788,12 @@ msgstr "&Habilitar plugins"
 msgid "File filters:"
 msgstr "Filtros de archivos:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Integración"
 
@@ -2743,6 +2761,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binario"
 
+msgid "Unpacker"
+msgstr "Descompactador"
+
+msgid "Prediffer"
+msgstr "Precomparación"
+
 msgid "Unable to compare files"
 msgstr "No se pueden comparar los archivos"
 
@@ -2946,6 +2970,12 @@ msgstr ""
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Muestra un asterisco (*) si el archivo es binario."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Comparar %1 con %2"
@@ -3227,12 +3257,6 @@ msgstr ""
 msgid "Type"
 msgstr "Tipo"
 
-msgid "Unpacker"
-msgstr "Descompactador"
-
-msgid "Prediffer"
-msgstr "Precomparación"
-
 msgid "Editor script"
 msgstr "Editor de script"
 
@@ -3403,12 +3427,6 @@ msgstr "Configuración de plugins"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH no encontrado - scripts .sct deshabilitados"
 
-msgid "<None>"
-msgstr "<Ninguno>"
-
-msgid "<Automatic>"
-msgstr "<Automático>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "Ir a &línea %1"
@@ -3627,3 +3645,101 @@ msgstr "Permitir solo una instancia en ejecución"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 2c66d0e..cb79139 100644 (file)
@@ -58,8 +58,9 @@ msgstr "Kopiera Valda Linjer från Vänster"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Kopiera Valda Linjer från Höger"
 
-msgid "&Select Line Difference\tF4"
-msgstr "Markera Radskillnad\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Markera RadSkillnad\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr "Lägg till denna skillnad till Ersättningsfilter"
@@ -84,6 +85,14 @@ msgstr "Kopiera"
 msgid "&Paste"
 msgstr "Klistra in"
 
+#, c-format
+msgid "&Scripts"
+msgstr "Manus"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Tom >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Gå till ...\tCtrl+G"
 
@@ -263,10 +272,6 @@ msgstr "Nyliga Projekt"
 msgid "Recent F&iles Or Folders"
 msgstr "Nyliga Filer eller Mappar"
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Tom >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Avsluta\tCtrl+Q"
 
@@ -641,10 +646,6 @@ msgid "Reco&mpare As"
 msgstr "Återjämför som"
 
 #, c-format
-msgid "&XML"
-msgstr "XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "Ångra\tCtrl+Z"
 
@@ -665,10 +666,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "Klistra in\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Markera RadSkillnad\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Sök ...\tCtrl+F"
 
@@ -883,13 +880,15 @@ msgstr "Lägg till SynkroniseringsMarkör\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Rensa SynkroniseringsMarkörer"
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "PreDiffer"
 
-#, c-format
-msgid "&Scripts"
-msgstr "Manus"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1082,17 +1081,24 @@ msgstr "Kopiera hela Sökvägen"
 msgid "Copy &Filename"
 msgstr "Kopiera Filnamn"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "PreDiffer Inställningar"
+msgid "<None>"
+msgstr "<Ingen>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Automatisk>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "Ingen PreDiffer"
+msgid "&Select..."
+msgstr "Välj ..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "Auto PreDiffer"
+msgid "Prediffer Settings"
+msgstr "PreDiffer Inställningar"
 
 msgid "G&o to Diff"
 msgstr "Gå till Skillnad"
@@ -1248,10 +1254,6 @@ msgid " Folder: Filter"
 msgstr " Mapp: Filter"
 
 #, c-format
-msgid "&Select..."
-msgstr "Välj ..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr " Fil: UppackningsInsticksProgram"
 
@@ -1629,16 +1631,11 @@ msgstr "Flytta Upp"
 msgid "Move &Down"
 msgstr "Flytta Ned"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Välj Uppackare"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Fil-uppackare:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Visa alla uppackare, kontrollera inte filsuffixet."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1648,6 +1645,18 @@ msgstr "FilsuffixLista:"
 msgid "Description:"
 msgstr "Beskrivning:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Visa alla uppackare, kontrollera inte filsuffixet."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Stopp"
@@ -2245,6 +2254,12 @@ msgstr "Möjliggör InsticksProgram"
 msgid "File filters:"
 msgstr "FilFilter:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "GränssnittsIntegration"
@@ -3345,6 +3360,14 @@ msgid "Binary"
 msgstr "Binär"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Uppackare"
+
+#, c-format
+msgid "Prediffer"
+msgstr "PreDiffer"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Kan inte jämföra filerna"
 
@@ -3585,6 +3608,12 @@ msgstr "Antalet skillnader i filen. Detta antal omfattar inte åsidosatta skilln
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Visar stjärna (*) om filen är binär."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Jämför %1 med %2"
@@ -3899,14 +3928,6 @@ msgid "Type"
 msgstr "Typ"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Uppackare"
-
-#, c-format
-msgid "Prediffer"
-msgstr "PreDiffer"
-
-#, c-format
 msgid "Editor script"
 msgstr "RedigerarManus"
 
@@ -4100,14 +4121,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "Windows Script Host ('wscript.exe') hittades inte - .sct manus är förhindrade"
 
 #, c-format
-msgid "<None>"
-msgstr "<Ingen>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Automatisk>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Gå till rad %1"
 
@@ -4339,3 +4352,101 @@ msgstr "Tillåt endast en upplaga att köra"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Tillåt endast en upplaga att köra och vänta på upplagan att avsluta"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index f90f5e0..9e0ffd5 100644 (file)
@@ -50,7 +50,7 @@ msgstr "Seçilmiş satır(lar)ı soldan kopyala"
 msgid "Copy Selected Line(s) from Right"
 msgstr "Seçilmiş satır(lar)ı sağdan kopyala"
 
-msgid "&Select Line Difference\tF4"
+msgid "Select Line &Difference\tF4"
 msgstr "Satır &farkını seç\tF4"
 
 msgid "Add this change to Substitution &Filters"
@@ -71,6 +71,12 @@ msgstr "K&opyala"
 msgid "&Paste"
 msgstr "Ya&pıştır"
 
+msgid "&Scripts"
+msgstr "&Betikler"
+
+msgid "< Empty >"
+msgstr "< Boş >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "&Git...\tCtrl+G"
 
@@ -220,9 +226,6 @@ msgstr "Son kullanılan projeler"
 msgid "Recent F&iles Or Folders"
 msgstr "Son dosya ya da k&lasörler"
 
-msgid "< Empty >"
-msgstr "< Boş >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "Çı&kış\tCtrl+Q"
 
@@ -512,9 +515,6 @@ msgstr "Yeniden yük&le\tCtrl+F5"
 msgid "Reco&mpare As"
 msgstr "&Farklı karşılaştır"
 
-msgid "&XML"
-msgstr "&XML"
-
 msgid "&Undo\tCtrl+Z"
 msgstr "Geri a&l\tCtrl+Z"
 
@@ -530,9 +530,6 @@ msgstr "&Kopyala\tCtrl+C"
 msgid "&Paste\tCtrl+V"
 msgstr "Ya&pıştır\tCtrl+V"
 
-msgid "Select Line &Difference\tF4"
-msgstr "Satır &farkını seç\tF4"
-
 msgid "F&ind...\tCtrl+F"
 msgstr "&Bul...\tCtrl+F"
 
@@ -698,11 +695,14 @@ msgstr "Eşitleme noktası &ekle\tAlt+S"
 msgid "Clear Sync&hronization Points"
 msgstr "Eşitleme noktalarını &sil"
 
+msgid "Unpac&ker"
+msgstr ""
+
 msgid "&Prediffer"
 msgstr "Ön &farklılaştırıcı"
 
-msgid "&Scripts"
-msgstr "&Betikler"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 msgid "Sp&lit"
 msgstr "Bö&l"
@@ -865,14 +865,20 @@ msgstr "Tam yolu &kopyala"
 msgid "Copy &Filename"
 msgstr "&Dosya adını kopyala"
 
-msgid "Prediffer Settings"
-msgstr "Ön farklılaştırıcı ayarları"
+msgid "Unpacker Settings"
+msgstr ""
+
+msgid "<None>"
+msgstr "<Yok>"
+
+msgid "<Automatic>"
+msgstr "<Otomatik>"
 
-msgid "&No prediffer"
-msgstr "Ö&n farklılaştırıcı yok"
+msgid "&Select..."
+msgstr "Seçi&n..."
 
-msgid "Auto prediffer"
-msgstr "Otomatik ön farklılaştırıcı"
+msgid "Prediffer Settings"
+msgstr "Ön farklılaştırıcı ayarları"
 
 msgid "G&o to Diff"
 msgstr "Fa&rka git"
@@ -991,9 +997,6 @@ msgstr "Göz at..."
 msgid " Folder: Filter"
 msgstr " Klasör: Süzgeç"
 
-msgid "&Select..."
-msgstr "Seçi&n..."
-
 msgid " File: Unpacker Plugin"
 msgstr " Dosya: Ayıklayıcı eklentisi"
 
@@ -1299,14 +1302,11 @@ msgstr "Y&ukarı taşı"
 msgid "Move &Down"
 msgstr "Aşağı &taşı"
 
-msgid "Select Unpacker"
-msgstr "Ayıklayıcı seçin"
-
-msgid "File unpacker:"
-msgstr "Dosya ayıklayıcı:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Uzantıya bakılmadan tüm ayıklayıcılar görüntülensin."
+msgid "Plugin &Name:"
+msgstr ""
 
 msgid "Extensions list:"
 msgstr "Uzantı Listesi:"
@@ -1314,6 +1314,18 @@ msgstr "Uzantı Listesi:"
 msgid "Description:"
 msgstr "Açıklama:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Uzantıya bakılmadan tüm ayıklayıcılar görüntülensin."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 msgid "Stop"
 msgstr "Durdur"
 
@@ -1781,6 +1793,12 @@ msgstr "&Eklentiler kullanılsın"
 msgid "File filters:"
 msgstr "Dosya süzgeçleri:"
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 msgid "Shell Integration"
 msgstr "Sağ tık menüsü"
 
@@ -2782,6 +2800,12 @@ msgctxt "DirView|ColumnHeader"
 msgid "Binary"
 msgstr "Binary"
 
+msgid "Unpacker"
+msgstr "Ayıklayıcı"
+
+msgid "Prediffer"
+msgstr "Ön farklılaştırıcı"
+
 msgid "Unable to compare files"
 msgstr "Dosyalar karşılaştırılamıyor"
 
@@ -2980,6 +3004,12 @@ msgstr "Dosyadaki fark sayısı. Bu sayıya yok sayılan farklar katılmamışt
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Dosya binary ise yıldız (*) ile görüntülensin."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "%1 ile %2 ögesini karşılaştır"
@@ -3271,12 +3301,6 @@ msgstr "Yeni örnek"
 msgid "Type"
 msgstr "Tür"
 
-msgid "Unpacker"
-msgstr "Ayıklayıcı"
-
-msgid "Prediffer"
-msgstr "Ön farklılaştırıcı"
-
 msgid "Editor script"
 msgstr "Düzenleyici betiği"
 
@@ -3467,12 +3491,6 @@ msgstr "Eklenti ayarları"
 msgid "WSH not found - .sct scripts disabled"
 msgstr "Windows Script Host bulunamadı - .sct betikleri etkisizleştirildi"
 
-msgid "<None>"
-msgstr "<Yok>"
-
-msgid "<Automatic>"
-msgstr "<Otomatik>"
-
 #, c-format
 msgid "G&o to Line %1"
 msgstr "%1. &satıra git"
@@ -3691,3 +3709,101 @@ msgstr "Yalnız bir kopya çalışsın"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr "Yalnız bir kopyanın çalışsın ve kopyanın sonlandırılması beklensin"
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""
index 05c6282..8d625eb 100644 (file)
@@ -57,8 +57,9 @@ msgstr ""
 msgid "Copy Selected Line(s) from Right"
 msgstr ""
 
-msgid "&Select Line Difference\tF4"
-msgstr "&Вибрати відмінність\tF4"
+#, c-format
+msgid "Select Line &Difference\tF4"
+msgstr "Вибрати від&мінність\tF4"
 
 msgid "Add this change to Substitution &Filters"
 msgstr ""
@@ -83,6 +84,14 @@ msgstr "&Копіювати"
 msgid "&Paste"
 msgstr "&Вставити"
 
+#, c-format
+msgid "&Scripts"
+msgstr "С&ценарії"
+
+#, c-format
+msgid "< Empty >"
+msgstr "< Нема >"
+
 msgid "&Go to...\tCtrl+G"
 msgstr "Перейти до рядка...\tCtrl+G"
 
@@ -262,10 +271,6 @@ msgstr "Нещодавні проекти"
 msgid "Recent F&iles Or Folders"
 msgstr ""
 
-#, c-format
-msgid "< Empty >"
-msgstr "< Нема >"
-
 msgid "E&xit\tCtrl+Q"
 msgstr "В&ихід\tCtrl+Q"
 
@@ -640,10 +645,6 @@ msgid "Reco&mpare As"
 msgstr ""
 
 #, c-format
-msgid "&XML"
-msgstr "&XML"
-
-#, c-format
 msgid "&Undo\tCtrl+Z"
 msgstr "&Скасувати\tCtrl+Z"
 
@@ -664,10 +665,6 @@ msgid "&Paste\tCtrl+V"
 msgstr "&Вставити\tCtrl+V"
 
 #, c-format
-msgid "Select Line &Difference\tF4"
-msgstr "Вибрати від&мінність\tF4"
-
-#, c-format
 msgid "F&ind...\tCtrl+F"
 msgstr "Зна&йти...\tCtrl+F"
 
@@ -882,13 +879,15 @@ msgstr ""
 msgid "Clear Sync&hronization Points"
 msgstr ""
 
+msgid "Unpac&ker"
+msgstr ""
+
 #, c-format
 msgid "&Prediffer"
 msgstr "&Попереднє порівняння"
 
-#, c-format
-msgid "&Scripts"
-msgstr "С&ценарії"
+msgid "Apply Pre&differ..."
+msgstr ""
 
 #, c-format
 msgid "Sp&lit"
@@ -1081,17 +1080,24 @@ msgstr "&Скопіювати повний шлях"
 msgid "Copy &Filename"
 msgstr "Скопіювати &ім'я файлу"
 
+msgid "Unpacker Settings"
+msgstr ""
+
 #, c-format
-msgid "Prediffer Settings"
-msgstr "Параметри попереднього порівняння"
+msgid "<None>"
+msgstr "<Нема>"
+
+#, c-format
+msgid "<Automatic>"
+msgstr "<Автоматично>"
 
 #, c-format
-msgid "&No prediffer"
-msgstr "&Нема попереднього порівняння"
+msgid "&Select..."
+msgstr "Вибрати..."
 
 #, c-format
-msgid "Auto prediffer"
-msgstr "&Автоматичне попереднє порівняння"
+msgid "Prediffer Settings"
+msgstr "Параметри попереднього порівняння"
 
 msgid "G&o to Diff"
 msgstr "Перейти до &відмінності"
@@ -1247,10 +1253,6 @@ msgid " Folder: Filter"
 msgstr ""
 
 #, c-format
-msgid "&Select..."
-msgstr "Вибрати..."
-
-#, c-format
 msgid " File: Unpacker Plugin"
 msgstr ""
 
@@ -1628,16 +1630,11 @@ msgstr "&Вгору"
 msgid "Move &Down"
 msgstr "В&низ"
 
-#, c-format
-msgid "Select Unpacker"
-msgstr "Вибір розпакувальника"
-
-#, c-format
-msgid "File unpacker:"
-msgstr "Файл розпакувальника:"
+msgid "Select Plugin"
+msgstr ""
 
-msgid "Display all unpackers, don't check the extension."
-msgstr "Показувати всі розпакувальники, не перевіряючи розширення."
+msgid "Plugin &Name:"
+msgstr ""
 
 #, c-format
 msgid "Extensions list:"
@@ -1647,6 +1644,18 @@ msgstr "Список розширень:"
 msgid "Description:"
 msgstr "Опис:"
 
+msgid "Default arguments:"
+msgstr ""
+
+msgid "Display all unpackers, don't check the extension."
+msgstr "Показувати всі розпакувальники, не перевіряючи розширення."
+
+msgid "&Plugin Pipeline:"
+msgstr ""
+
+msgid "&Add pipe"
+msgstr ""
+
 #, c-format
 msgid "Stop"
 msgstr "Зупинити"
@@ -2238,6 +2247,12 @@ msgstr "&Ввімкнути доповнення"
 msgid "File filters:"
 msgstr ""
 
+msgid "&Plugin arguments:"
+msgstr ""
+
+msgid "Enable &automatic unpacking/prediffing for the plugin"
+msgstr ""
+
 #, c-format
 msgid "Shell Integration"
 msgstr "Вживлення в оболонку"
@@ -3293,6 +3308,14 @@ msgid "Binary"
 msgstr "Бінарний"
 
 #, c-format
+msgid "Unpacker"
+msgstr "Розпакувальник"
+
+#, c-format
+msgid "Prediffer"
+msgstr "Нехтувач"
+
+#, c-format
 msgid "Unable to compare files"
 msgstr "Неможливо порівняти файли"
 
@@ -3535,6 +3558,12 @@ msgstr "Кількість відмінностей у файлі. Ігноро
 msgid "Shows an asterisk (*) if the file is binary."
 msgstr "Показати зірочку (*) якщо файл бінарний."
 
+msgid "Unpacker plugin name or pipeline."
+msgstr ""
+
+msgid "Prediffer plugin name or pipeline."
+msgstr ""
+
 #, c-format
 msgid "Compare %1 with %2"
 msgstr "Порівняння %1 з %2"
@@ -3836,14 +3865,6 @@ msgid "Type"
 msgstr "Тип"
 
 #, c-format
-msgid "Unpacker"
-msgstr "Розпакувальник"
-
-#, c-format
-msgid "Prediffer"
-msgstr "Нехтувач"
-
-#, c-format
 msgid "Editor script"
 msgstr "Сценарій редактора"
 
@@ -3966,14 +3987,6 @@ msgid "WSH not found - .sct scripts disabled"
 msgstr "WSH не знайдений - .sct сценарії вимкнуті"
 
 #, c-format
-msgid "<None>"
-msgstr "<Нема>"
-
-#, c-format
-msgid "<Automatic>"
-msgstr "<Автоматично>"
-
-#, c-format
 msgid "G&o to Line %1"
 msgstr "Перейти до &рядка %1"
 
@@ -4200,3 +4213,101 @@ msgstr "Дозволити запуск лише однієї копії"
 
 msgid "Allow only one instance to run and wait for the instance to terminate"
 msgstr ""
+
+msgid "Al&l"
+msgstr ""
+
+msgid "Prettification"
+msgstr ""
+
+msgid "Content Extraction"
+msgstr ""
+
+msgid "Visualization"
+msgstr ""
+
+msgid "Data Query"
+msgstr ""
+
+msgid "&Others"
+msgstr ""
+
+msgid "Make Uppercase"
+msgstr ""
+
+msgid "Make Lowercase"
+msgstr ""
+
+msgid "Remove Duplicate Lines"
+msgstr ""
+
+msgid "Count Duplicate Lines"
+msgstr ""
+
+msgid "Sort Lines Ascending"
+msgstr ""
+
+msgid "Sort Lines Descending"
+msgstr ""
+
+msgid "Apply Filter Command..."
+msgstr ""
+
+msgid "Tokenize..."
+msgstr ""
+
+msgid "Trim Spaces"
+msgstr ""
+
+msgid "Insert Date"
+msgstr ""
+
+msgid "Insert Time"
+msgstr ""
+
+msgid "Apply Patch..."
+msgstr ""
+
+msgid "Ignore Columns"
+msgstr ""
+
+msgid "Ignore Comments (C-Family Languages)"
+msgstr ""
+
+msgid "Ignore CSV Fields"
+msgstr ""
+
+msgid "Ignore TSV Fields"
+msgstr ""
+
+msgid "Apply Prediff Substitution Filters"
+msgstr ""
+
+msgid "Prettify JSON"
+msgstr ""
+
+msgid "Prettify XML"
+msgstr ""
+
+msgid "Visualize Graphviz"
+msgstr ""
+
+msgid "Query CSV Data..."
+msgstr ""
+
+msgid "Query TSV Data..."
+msgstr ""
+
+msgid "Query JSON Data..."
+msgstr ""
+
+#, c-format
+msgid "Missing plugin name in plugin pipeline: %1"
+msgstr ""
+
+#, c-format
+msgid "Missing quotation mark in plugin pipeline: %1"
+msgstr ""
+
+msgid "Specify plugin arguments"
+msgstr ""