diff --git a/.gitignore b/.gitignore index 90ed677e..2a8a083f 100644 --- a/.gitignore +++ b/.gitignore @@ -273,3 +273,6 @@ autom4te.cache /redist/MapsTables/PythonExamples /redist/MapsTables/TestEncCnvtrs /genericinstaller +/.vs/config/applicationhost.config +/.vs/SEC VS2010/v14/.suo +/.vs/SEC VS2015/v14/.suo diff --git a/.vs/SEC VS2010/v14/.suo b/.vs/SEC VS2010/v14/.suo deleted file mode 100644 index e344b58b..00000000 Binary files a/.vs/SEC VS2010/v14/.suo and /dev/null differ diff --git a/.vs/SEC VS2015/v14/.suo b/.vs/SEC VS2015/v14/.suo deleted file mode 100644 index daeb8e36..00000000 Binary files a/.vs/SEC VS2015/v14/.suo and /dev/null differ diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config deleted file mode 100644 index dfded7b7..00000000 --- a/.vs/config/applicationhost.config +++ /dev/null @@ -1,1030 +0,0 @@ - - - - - - - - -
-
-
-
-
-
-
-
- - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
- -
-
- -
-
-
- - -
-
-
-
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Directory.Build.props b/Directory.Build.props index 6bc626c2..6f36b4e3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,9 +3,9 @@ SILConverters SILConverters 5.1 - 5.1.1.0 + 5.1.3.0 8A50226C-84D0-4CAF-AF8F-B0284643C415 - 2022 + 2023 SIL International \ No newline at end of file diff --git a/Installer/Converter Packages/IndicConverters/IndicConverters.wixproj b/Installer/Converter Packages/IndicConverters/IndicConverters.wixproj index 2c520679..648421ab 100644 --- a/Installer/Converter Packages/IndicConverters/IndicConverters.wixproj +++ b/Installer/Converter Packages/IndicConverters/IndicConverters.wixproj @@ -1,7 +1,7 @@  + - Debug x86 @@ -81,8 +81,8 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + + - + + + - + + + - + + + - + + + diff --git a/Installer/SEC Setup/License.rtf b/Installer/SEC Setup/License.rtf index bb912d2c..d241d751 100644 --- a/Installer/SEC Setup/License.rtf +++ b/Installer/SEC Setup/License.rtf @@ -1,62 +1,63 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;} -{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;} -{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} -{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f44\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f45\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\f47\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f48\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f49\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f50\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\f51\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f52\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f84\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;}{\f85\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;} -{\f87\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f88\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;}{\f89\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);}{\f90\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);} -{\f91\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f92\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);}{\f414\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f415\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} -{\f417\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f418\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f419\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f420\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);} -{\f421\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f422\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;} -{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);} -{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} -{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} -{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} -{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; -\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\red51\green51\blue51;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap -\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 -\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +{\rtf1\adeflang1081\ansi\ansicpg1252\uc1\adeff24\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f4\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Helvetica;} +{\f24\fbidi \froman\fcharset0\fprq2{\*\panose 00000400000000000000}Mangal{\*\falt Nirmala UI};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fhimajor\f31502\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f329\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\f330\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f332\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f333\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f334\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\f335\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f336\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f337\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f369\fbidi \fswiss\fcharset238\fprq2 Helvetica CE;} +{\f370\fbidi \fswiss\fcharset204\fprq2 Helvetica Cyr;}{\f372\fbidi \fswiss\fcharset161\fprq2 Helvetica Greek;}{\f373\fbidi \fswiss\fcharset162\fprq2 Helvetica Tur;}{\f374\fbidi \fswiss\fcharset177\fprq2 Helvetica (Hebrew);} +{\f375\fbidi \fswiss\fcharset178\fprq2 Helvetica (Arabic);}{\f376\fbidi \fswiss\fcharset186\fprq2 Helvetica Baltic;}{\f377\fbidi \fswiss\fcharset163\fprq2 Helvetica (Vietnamese);}{\f669\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} +{\f670\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f672\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f673\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f676\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;} +{\f677\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f699\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f700\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f702\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;} +{\f703\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f704\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\f705\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f706\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\f707\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Calibri Light CE;} +{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;} +{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;} +{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);} +{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} +{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\red51\green51\blue51;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af24\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused -Normal Table;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid6833241\rsid9134832}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim0}{\info{\operator Bob Eaton} -{\creatim\yr2021\mo8\dy28\hr17\min5}{\revtim\yr2021\mo8\dy28\hr17\min6}{\version2}{\edmins1}{\nofpages1}{\nofwords161}{\nofchars918}{\nofcharsws1077}{\vern29}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} -\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1081 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext11 \ssemihidden \sunhideused +Normal Table;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid3604928\rsid6833241\rsid9134832}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim0}{\info +{\operator Bob Eaton}{\creatim\yr2021\mo8\dy28\hr17\min5}{\revtim\yr2023\mo3\dy15\hr6\min59}{\version3}{\edmins1}{\nofpages1}{\nofwords161}{\nofchars918}{\nofcharsws1077}{\vern67}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml} +}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect \widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 \dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot9134832 \nouicompat \fet0{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1 \pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5 \pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa150\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 \cbpat8 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sa150\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 \cbpat8 \rtlch\fcs1 \af24\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid6833241 \hich\af4\dbch\af31505\loch\f4 The MIT License (MIT) \par }\pard \ltrpar\ql \li0\ri0\sa150\widctlpar\wrapdefault\faauto\rin0\lin0\itap0\pararsid9134832 \cbpat8 {\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid6833241 \hich\af4\dbch\af31505\loch\f4 Copyright }{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 -\f4\fs21\cf19\insrsid9134832\charrsid9134832 \loch\af4\dbch\af31505\hich\f4 \'a9}{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid9134832 \hich\af4\dbch\af31505\loch\f4 \hich\af4\dbch\af31505\loch\f4 2021}{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 -\f4\fs21\cf19\insrsid6833241 \hich\af4\dbch\af31505\loch\f4 SIL International +\f4\fs21\cf19\insrsid9134832\charrsid9134832 \loch\af4\dbch\af31505\hich\f4 \'a9}{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid9134832 \hich\af4\dbch\af31505\loch\f4 202}{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid3604928 +\hich\af4\dbch\af31505\loch\f4 3}{\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid6833241 \hich\af4\dbch\af31505\loch\f4 SIL International \par }\pard \ltrpar\ql \li0\ri0\sa150\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 \cbpat8 {\rtlch\fcs1 \af4\afs21 \ltrch\fcs0 \f4\fs21\cf19\insrsid6833241 \hich\af4\dbch\af31505\loch\f4 P\hich\af4\dbch\af31505\loch\f4 -ermission is hereby granted, free of charge, to any person obtain\hich\af4\dbch\af31505\loch\f4 -ing a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the S -\hich\af4\dbch\af31505\loch\f4 o\hich\af4\dbch\af31505\loch\f4 ftware, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -\par \hich\af4\dbch\af31505\loch\f4 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -\par \hich\af4\dbch\af31505\loch\f4 THE SOFTWARE IS PR\hich\af4\dbch\af31505\loch\f4 -OVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CL -\hich\af4\dbch\af31505\loch\f4 A\hich\af4\dbch\af31505\loch\f4 IM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +ermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, me +\hich\af4\dbch\af31505\loch\f4 r\hich\af4\dbch\af31505\loch\f4 ge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +\par \hich\af4\dbch\af31505\loch\f4 The above copyright notice and this permission notice shall be included in all c\hich\af4\dbch\af31505\loch\f4 opies or substantial portions of the Software. +\par \hich\af4\dbch\af31505\loch\f4 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO E +\hich\af4\dbch\af31505\loch\f4 +VENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \par }\pard \ltrpar\ql \li0\ri0\sa160\sl252\slmult1\widctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af37 \ltrch\fcs0 \f37\insrsid6833241 \par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a @@ -143,35 +144,25 @@ faadb081f196af190c6a98242f8467912ab0a651ad6a5a548d8cc3c1aafb6121653923699635d3ca \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; \lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2; -\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text; -\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; -\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; -\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; -\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; -\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; -\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; -\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; -\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; -\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; -\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; -\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; -\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; -\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid; +\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid; +\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1; +\lsdsemihidden1 \lsdlocked0 Revision;\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2; +\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; +\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdpriority62 \lsdlocked0 Light Grid Accent 5; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; @@ -213,8 +204,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000006096 -c7eb589cd701feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000b072 +0d953557d901feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/Installer/SEC Setup/SEC Setup.wixproj b/Installer/SEC Setup/SEC Setup.wixproj index 688af7a5..1b9a3b56 100644 --- a/Installer/SEC Setup/SEC Setup.wixproj +++ b/Installer/SEC Setup/SEC Setup.wixproj @@ -1,7 +1,7 @@  + - Release x86 @@ -66,8 +66,8 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -205,6 +207,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/BulkSFMConverter/packages.config b/src/BulkSFMConverter/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/BulkSFMConverter/packages.config +++ b/src/BulkSFMConverter/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/ClipboardEC/ClipboardEC.csproj b/src/ClipboardEC/ClipboardEC.csproj index d3f479cc..1422be36 100644 --- a/src/ClipboardEC/ClipboardEC.csproj +++ b/src/ClipboardEC/ClipboardEC.csproj @@ -1,6 +1,6 @@  - + Local 9.0.30729 @@ -109,6 +109,8 @@ AllRules.ruleset + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -196,6 +198,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/ClipboardEC/ClipboardEncConverter.cs b/src/ClipboardEC/ClipboardEncConverter.cs index 0c32efb7..b19c7dd9 100644 --- a/src/ClipboardEC/ClipboardEncConverter.cs +++ b/src/ClipboardEC/ClipboardEncConverter.cs @@ -856,11 +856,20 @@ private void CreateContextMenu() try { IEncConverter aEC = aECs[strText]; - strOutput = this.ConvertData(aEC,strInput); - // if( strOutput != null ) - // strText += String.Format(":\t{0}", strOutput); + + // if it's a Translator type, then hold off calling to the internet for conversion + // which takes time and is possibly unnecessary), put in a dummy result to see if + // that's really what they want + if (IsOnlineTranslator(aEC)) + { + strOutput = $"Click to convert w/ {aEC.Name}"; + } + else + { + strOutput = this.ConvertData(aEC, strInput); + } } - catch(Exception e) + catch (Exception e) { // since this is just a 'preview' (and exceptions can be expected), don't // allow them to be throw up. @@ -878,6 +887,20 @@ private void CreateContextMenu() } } + private static bool IsOnlineTranslator(IEncConverter aEC) + { + var isOnlineTranslator = (aEC.ProcessType & (int)ProcessTypeFlags.Translation) == (int)ProcessTypeFlags.Translation; + + // it could still be if it's a primary-fallback or daisy-chain converter that has one (but there's no interface way + // to get at the individual converters... :-( (and changing the interface would just break existing clients) + if ((aEC.ImplementType == EncConverters.strTypeSILcomp) || (aEC.ImplementType == EncConverters.strTypeSILfallback)) + { + isOnlineTranslator = true; // for now... + } + + return isOnlineTranslator; + } + private void NormalizeClick(Object sender, EventArgs e) { // Determine if clicked menu item is the Blue menu item. diff --git a/src/ClipboardEC/app.config b/src/ClipboardEC/app.config index 4cf6b3d2..8204e7fa 100644 --- a/src/ClipboardEC/app.config +++ b/src/ClipboardEC/app.config @@ -53,6 +53,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/ClipboardEC/packages.config b/src/ClipboardEC/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/ClipboardEC/packages.config +++ b/src/ClipboardEC/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/DChartHelper/DChartHelper.csproj b/src/DChartHelper/DChartHelper.csproj index 32ae205c..e9474f52 100644 --- a/src/DChartHelper/DChartHelper.csproj +++ b/src/DChartHelper/DChartHelper.csproj @@ -1,6 +1,6 @@  - + Debug x86 @@ -87,6 +87,8 @@ $(EcDistFilesPath)\win-$(Platform)\native\AIGuesserEC.dll + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -253,6 +255,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/DChartHelper/packages.config b/src/DChartHelper/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/DChartHelper/packages.config +++ b/src/DChartHelper/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.Designer.cs b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.Designer.cs index eb7a83e0..5eda8692 100644 --- a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.Designer.cs +++ b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.Designer.cs @@ -29,8 +29,8 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BackTranslationHelperForm)); this.backTranslationHelperCtrl = new BackTranslationHelper.BackTranslationHelperCtrl(); + this.textBoxStatus = new System.Windows.Forms.TextBox(); this.SuspendLayout(); // // backTranslationHelperCtrl @@ -38,22 +38,41 @@ private void InitializeComponent() this.backTranslationHelperCtrl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + // if you edit the form (e.g. to add a control), then the designer auto coding will change this "AutoSize = false" + // to (possibly true) and add an 'AutoSizeMode = GrowAndShrink'... but this will cause the embedded control to + // stop showing properly. It *must* be AutoSize = false. (keep this comment here too, so the next person sees it too) + // (I'm not sure if it's specifically necessary, but you might need to restore the PerformLayout at the bottom, + // which the editing of the form will remove too) this.backTranslationHelperCtrl.AutoSize = false; this.backTranslationHelperCtrl.Location = new System.Drawing.Point(0, 0); this.backTranslationHelperCtrl.Name = "backTranslationHelperCtrl"; - this.backTranslationHelperCtrl.NewTargetTexts = ((System.Collections.Generic.List)(resources.GetObject("backTranslationHelperCtrl.NewTargetTexts"))); - this.backTranslationHelperCtrl.Size = new System.Drawing.Size(790, 449); + this.backTranslationHelperCtrl.Size = new System.Drawing.Size(800, 428); this.backTranslationHelperCtrl.TabIndex = 1; // + // textBoxStatus + // + this.textBoxStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxStatus.Location = new System.Drawing.Point(0, 430); + this.textBoxStatus.Name = "textBoxStatus"; + this.textBoxStatus.ReadOnly = true; + this.textBoxStatus.Size = new System.Drawing.Size(800, 20); + this.textBoxStatus.TabIndex = 2; + this.textBoxStatus.Click += TextBoxStatus_Click; + // // BackTranslationHelperForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 450); + this.Controls.Add(this.textBoxStatus); this.Controls.Add(this.backTranslationHelperCtrl); this.Name = "BackTranslationHelperForm"; this.Text = "Back Translating from {0} - {1} in verse: {2}"; + this.Activated += new System.EventHandler(this.BackTranslationHelperForm_Activated); + this.Deactivate += new System.EventHandler(this.BackTranslationHelperForm_Deactivate); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BackTranslationHelperForm_FormClosing); + this.Load += new System.EventHandler(this.BackTranslationHelperForm_Load); this.ResumeLayout(false); this.PerformLayout(); } @@ -61,5 +80,6 @@ private void InitializeComponent() #endregion private BackTranslationHelper.BackTranslationHelperCtrl backTranslationHelperCtrl; + private System.Windows.Forms.TextBox textBoxStatus; } } \ No newline at end of file diff --git a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.cs b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.cs index 61811f0f..9a05748f 100644 --- a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.cs +++ b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.cs @@ -1,6 +1,8 @@ // Uncomment this define to enable code that helps in test creation for a new scenario // See UnitTest_PtxBackTrHelper::It_Can_Determine_Correct_Update_To_Target_Project in the TestBwdc project for details +#if DEBUG #define SerializeToCreateTestFiles +#endif using BackTranslationHelper; using Paratext.PluginInterfaces; @@ -10,6 +12,8 @@ using System.Linq; using System.Windows.Forms; using Newtonsoft.Json; +using System.Windows; +using System.Security.Policy; namespace SIL.ParatextBackTranslationHelperPlugin { @@ -29,6 +33,7 @@ public partial class BackTranslationHelperForm : Form, IBackTranslationHelperDat private BackTranslationHelperModel _model; private IWriteLock _writeLock = null; private readonly Action _setSyncReferenceGroup; + private bool _isNotInFocus; /// /// the current verse we're processing. (this generally is the 1st of a range if it is a combined verse). @@ -49,16 +54,29 @@ public partial class BackTranslationHelperForm : Form, IBackTranslationHelperDat private IVerseRef _verseReferenceLast; /// - /// this contains the tokens from the source project, but just the verse(s) that we're processing (e.g. v1 or could be v2-5) + /// this contains the tokens from the source project, but just the verse(s) that we're processing (e.g. v1 + /// or could be v2-5) /// Key is the [BookNum]_[ChapterNum]_[VerseNum] (e.g. ACT_001_001) /// private Dictionary> UsfmTokensSource { get; set; } = new Dictionary>(); /// - /// this contains the tokens from the target project, for all the verses in the current chapter (we need the whole chapter, - /// because we have to Put the entire chapter when we go to write it. + /// The number of text lines in the source data (i.e. the number of IUSFMTextTokens in the verse(s)) + /// + private int SourceDataLineCount { get; set; } + + /// + /// This contains the list of marker tokens immediately preceding the text tokens in the source data + /// + private List TextTokenMarkersSource { get; set; } = new List(); + + /// + /// this contains the tokens from the target project, for all the verses in the current chapter (we need the + /// whole chapter,because we have to Put the entire chapter when we go to write it. /// Key is the [BookNum]_[ChapterNum] (e.g. 44_001) - /// Key2 (of the SortedDictionary) is [BookNum]_[ChapterNum]_[VerseNum] (e.g. ACT_001_001) + /// Key2 (of the SortedDictionary) is [BookNum]_[ChapterNum]_[VerseNum] (e.g. ACT_001_001 + /// Note: beware that this could be out of date if the user edits the verse (or another) in Ptx after + /// we pulled these values. Cause it to requery if we lose focus. /// private Dictionary>> UsfmTokensTarget { get; set; } = new Dictionary>>(); @@ -79,19 +97,34 @@ public BackTranslationHelperForm(IPluginHost host, ParatextBackTranslationHelper // this form is the implementation of the way to get get data backTranslationHelperCtrl.BackTranslationHelperDataSource = this; + backTranslationHelperCtrl.RegisterForNotification(BackTranslationHelperCtrl.SubscribeableEventKeyTargetBackTranslationTextChanged, + TargetBackTranslationTextChanged); _host.VerseRefChanged += Host_VerseRefChanged; _projectSource.ScriptureDataChanged += ScriptureDataChangedHandlerSource; _projectTarget.ScriptureDataChanged += ScriptureDataChangedHandlerTarget; + } - Text = GetFrameText(_projectSource, _projectTarget, _verseReference); - Location = Properties.Settings.Default.WindowLocation; - WindowState = Properties.Settings.Default.DefaultWindowState; - if (MinimumSize.Height <= Properties.Settings.Default.WindowSize.Height && - MinimumSize.Width <= Properties.Settings.Default.WindowSize.Width) + private void TargetBackTranslationTextChanged(string value) + { + var translatedCount = GetTranslatedLines(value).Count; + System.Diagnostics.Debug.WriteLine($"PtxBTH: TargetBackTranslationTextChanged: SourceDataLineCount = '{SourceDataLineCount}', translatedCount = '{translatedCount}'"); + var statusText = String.Empty; + if (SourceDataLineCount != translatedCount) { - Size = Properties.Settings.Default.WindowSize; + statusText = String.Format("There {0} currently {1} line{2} of text in the Target Translation box vs. {3} text line{4} in the source verse ({5}: {6})", + (translatedCount > 1) ? "are" : "is", + translatedCount, + (translatedCount > 1) ? "s" : string.Empty, + SourceDataLineCount, + (SourceDataLineCount > 1) ? "s" : string.Empty, + (TextTokenMarkersSource.Count > 1) ? "one for each of these markers" : "for this marker", + String.Join(",", TextTokenMarkersSource.Select(m => $"\\{m.Marker}"))); } + + textBoxStatus.Text = statusText; + + Application.DoEvents(); // this says we need to do this for when it won't display the change: https://social.msdn.microsoft.com/Forums/vstudio/en-US/983d2e3b-9bcb-4c9c-9e85-59f8b2051b3e/program-updating-a-textbox-does-not-work?forum=csharpgeneral } private static string GetFrameText(IProject projectSource, IProject projectTarget, IVerseRef versesReference) @@ -104,23 +137,73 @@ private static string GetProjectName(IProject projectSource, IProject projectTar return String.Format(ProjectNameFormat, projectSource, projectTarget); } + private bool IsDirty(IVerseRef verseReference, int bookNum, int chapterNum) + { + return ((bookNum == 0) || (verseReference.BookNum == bookNum)) && ((chapterNum == 0) || (verseReference.ChapterNum == chapterNum)); + } + private void ScriptureDataChangedHandlerSource(IProject sender, int bookNum, int chapterNum) { - Unlock(); + System.Diagnostics.Debug.WriteLine($"PtxBTH: ScriptureDataChangedHandlerSource: bookNum = '{bookNum}', chapterNum = ‘{chapterNum}‘, IsModified: {backTranslationHelperCtrl.IsModified}, _verseReference: {_verseReference}"); + + // if the change was in the chapter we're processing, then clear what we think the data is, so we'll repull it later + if (IsDirty(_verseReference, bookNum, chapterNum)) + UsfmTokensSource.Clear(); } private void ScriptureDataChangedHandlerTarget(IProject sender, int bookNum, int chapterNum) { - Unlock(); + System.Diagnostics.Debug.WriteLine($"PtxBTH: ScriptureDataChangedHandlerTarget: bookNum = '{bookNum}', chapterNum = ‘{chapterNum}‘, IsModified: {backTranslationHelperCtrl.IsModified}, _verseReference: {_verseReference}, _isChangingTarget: {AreWeChangingTheTarget}"); + if (AreWeChangingTheTarget) // if we're the ones who changed it, then ignore + return; + + // if the change was in the chapter we're processing, then clear what we think the data is, so we'll repull it later + if (IsDirty(_verseReference, bookNum, chapterNum)) + UsfmTokensTarget.Clear(); + +#if TriedAndFailed + // UPDATE: Ptx by definition has the write lock right now, so we can't call GetNewReference here + // Go back to calling it in Activate + // unless we were editing it, and then force it to stay the same + if (backTranslationHelperCtrl.IsModified) + return; + + GetNewReference(_verseReference); +#endif } private void Host_VerseRefChanged(IPluginHost sender, IVerseRef newReference, SyncReferenceGroup group) { - // since this will initialize the _verseReference, which is intended to be the first of a series of verses... var newRef = (newReference.RepresentsMultipleVerses) ? newReference.AllVerses.First() : newReference; + System.Diagnostics.Debug.WriteLine($"PtxBTH: In Host_VerseRefChanged {newReference} (newRef: {newRef}) & {group}, _isNotInFocus: {_isNotInFocus}, IsModified: {backTranslationHelperCtrl.IsModified}"); + + // since this will initialize the _verseReference, which is intended to be the first + // of a series of verses... + // UPDATE: but not if the Form isn't in focus (so we don't thrash around converting stuff while + // the user may be editing stuff in Ptx) + if (_isNotInFocus && backTranslationHelperCtrl.IsModified) + { + textBoxStatus.Text = $"Staying on {_verseReference} because the Target Translation box was modified. Click here to update to current verse in Paratext"; + textBoxStatus.Tag = newRef; + Application.DoEvents(); // this says we need to do this for when it won't display the change: https://social.msdn.microsoft.com/Forums/vstudio/en-US/983d2e3b-9bcb-4c9c-9e85-59f8b2051b3e/program-updating-a-textbox-does-not-work?forum=csharpgeneral + return; + } + else + textBoxStatus.Tag = null; + GetNewReference(newRef); } + private void TextBoxStatus_Click(object sender, System.EventArgs e) + { + if (textBoxStatus.Tag != null) + { + backTranslationHelperCtrl.IsModified = false; + var newReference = (IVerseRef)textBoxStatus.Tag; + GetNewReference(newReference); + } + } + private void GetNewReference(IVerseRef newReference) { Unlock(); @@ -183,11 +266,12 @@ BackTranslationHelperModel IBackTranslationHelperDataSource.Model { get { + var currentTargetData = CurrentTargetData; var model = new BackTranslationHelperModel { SourceData = CurrentSourceData ?? "", - TargetData = CurrentTargetData, - TargetDataPreExisting = CurrentTargetData, + TargetData = currentTargetData, + TargetDataPreExisting = currentTargetData, TargetsPossible = new List() }; return model; @@ -198,18 +282,30 @@ private string CurrentSourceData { get { - var keyBookChapterVerse = GetBookChapterVerseKey(_verseReference); + var keyBookChapterVerse = GetBookChapterVerseRangeKey(_verseReference); if (!UsfmTokensSource.TryGetValue(keyBookChapterVerse, out List tokens)) { + System.Diagnostics.Debug.WriteLine($"PtxBTH: Loading UsfmTokensSource for {keyBookChapterVerse}"); tokens = _projectSource.GetUSFMTokens(_verseReference.BookNum, _verseReference.ChapterNum, _verseReference.VerseNum).ToList(); UsfmTokensSource.Add(keyBookChapterVerse, tokens); } + else + { + System.Diagnostics.Debug.WriteLine($"PtxBTH: Already have UsfmTokensSource for {keyBookChapterVerse}"); + } var data = tokens.OfType() - .Where(t => t.IsPublishableVernacular && IsMatchingVerse(t.VerseRef, _verseReference)) + .Where(t => IsPublishableVernacular(t, tokens) && IsMatchingVerse(t.VerseRef, _verseReference)) .ToDictionary(ta => ta, ta => ta.VerseRef); + if (!data.Any()) + return null; + + TextTokenMarkersSource = GetTextTokenMarkers(tokens, data.Keys.ToList()); + var textValues = data.Select(t => t.Key.Text); + SourceDataLineCount = textValues.Count(); + var sourceString = string.Join(Environment.NewLine, textValues); // set the verse reference to the last of a combined set of verses (which we can only get from the USFM markers) @@ -222,6 +318,51 @@ private string CurrentSourceData } } + // normally, text tokens are publishable, but there are some that aren't (e.g. the text content of an \id marker). + // And there's one case that seems like a bug to me, but which I've been told has worked that way forever and so + // there's no changing it now... vis-a-vis: + // the \va...\va* inline marker is defined differently depending on whether it comes immediately after a \v [num(s)] + // marker than if it comes elsewhere in a verse. The relevant difference is that when it comes immediately after a \v + // marker, it's value for IsPublishableVernacular (false) and IsMetadata (true) are opposite from the other case. + // So... if IsPubliableVernacular is false, at least check if this is that case, and return true, so we'll try to + // translate it as the others are (bkz we only send IsPub text segments for translation) + private static bool IsPublishableVernacular(IUSFMTextToken t, List tokens) + { + return t.IsPublishableVernacular || + (PreviousToken(t, tokens, out IUSFMMarkerToken mt) && (mt.Marker == "va") && mt.IsMetadata); + } + + private static bool PreviousToken(IUSFMTextToken t, List tokens, out IUSFMMarkerToken previousToken) + { + var index = tokens.IndexOf(t) - 1; + if ((index >= 0) && (index < tokens.Count) && (tokens[index] is IUSFMMarkerToken prevToken)) + { + previousToken = prevToken; + return true; + } + + previousToken = null; + return false; + } + + private List GetTextTokenMarkers(List tokens, List textTokens) + { + IUSFMMarkerToken lastMarkerToken = null; + var textTokenMarkers = new List(); + foreach (var token in tokens) + { + if (token is IUSFMMarkerToken) + { + lastMarkerToken = token as IUSFMMarkerToken; + } + else if (textTokens.Contains(token) && (lastMarkerToken != null)) + { + textTokenMarkers.Add(lastMarkerToken); + } + } + return textTokenMarkers; + } + private string CurrentTargetData { get @@ -232,23 +373,39 @@ private string CurrentTargetData // if this fails to return something, it means we can't edit it MessageBox.Show($"You don't have edit privilege on this chapter: {_verseReference}"); } + var bookChapterKey = GetBookChapterKey(_verseReference); if (!UsfmTokensTarget.TryGetValue(bookChapterKey, out SortedDictionary> vrefTokens)) { + System.Diagnostics.Debug.WriteLine($"PtxBTH: Loading UsfmTokensTarget for {bookChapterKey}"); var chapterTokens = _projectTarget.GetUSFMTokens(_verseReference.BookNum, _verseReference.ChapterNum).ToList(); var dict = chapterTokens.GroupBy(t => t.VerseRef, t => t, (key, g) => new { VerseRef = key, USFMTokens = g.ToList() }) - .ToDictionary(t => GetBookChapterVerseKey(t.VerseRef), t => t.USFMTokens); + .ToDictionary(t => GetBookChapterVerseRangeKey(t.VerseRef), t => t.USFMTokens); vrefTokens = new SortedDictionary>(dict); UsfmTokensTarget.Add(bookChapterKey, vrefTokens); } + else + { + System.Diagnostics.Debug.WriteLine($"PtxBTH: Already have UsfmTokensTarget for {bookChapterKey}"); + } + + var bookChapterVerseKey = GetBookChapterVerseRangeKey(_verseReference); - var bookChapterVerseKey = GetBookChapterVerseKey(_verseReference); - if (!vrefTokens.ContainsKey(bookChapterVerseKey)) + // issue: if Ptx is in "I'm just a single verse" mode (e.g. clicking up/down in the combo box at the top) + // then this will show a single verse even if the text is a multi-verse situation + // (e.g. 42_001_006, while the key in vrefTokens might be: 42_001_006-007). So figure out + // which one it *should* be so we can find a hit in vrefTokens + bookChapterVerseKey = TriangulateBookChapterVerseKey(bookChapterVerseKey, vrefTokens); + + if (String.IsNullOrEmpty(bookChapterVerseKey) || !vrefTokens.ContainsKey(bookChapterVerseKey)) return null; var tokens = vrefTokens[bookChapterVerseKey]; var data = tokens.OfType() - .Where(t => t.IsPublishableVernacular && IsMatchingVerse(t.VerseRef, _verseReference)); + .Where(t => IsPublishableVernacular(t, tokens) && IsMatchingVerse(t.VerseRef, _verseReference)); + + if (!data.Any()) + return null; var values = data.Select(t => t.Text); var verseData = string.Join(Environment.NewLine, values); @@ -256,13 +413,22 @@ private string CurrentTargetData } } + private static string TriangulateBookChapterVerseKey(string bookChapterVerseKey, SortedDictionary> vrefTokens) + { + if (vrefTokens.ContainsKey(bookChapterVerseKey)) + return bookChapterVerseKey; + + var vrefTokenKey = vrefTokens.FirstOrDefault(t => t.Value.Any(v => v.VerseRef.AllVerses.Any(sv => GetBookChapterVerseRangeKey(sv) == bookChapterVerseKey))).Key; + return vrefTokenKey; + } + private static string GetBookChapterKey(IVerseRef verseReference) { // get the key, which for the target data is the entire chapter (we have to Put as a whole chapter) return $"{verseReference.BookNum:D2}_{verseReference.ChapterNum:D3}"; } - private static string GetBookChapterVerseKey(IVerseRef verseReference) + private static string GetBookChapterVerseRangeKey(IVerseRef verseReference) { // get the key to see if we already have this data (TODO: add a 'it was changed in Ptx', so we can remove it from this collection) var bookChapterFirstVerse = $"{verseReference.BookNum:D2}_{verseReference.ChapterNum:D3}_{verseReference.VerseNum:D3}"; @@ -273,8 +439,9 @@ private static string GetBookChapterVerseKey(IVerseRef verseReference) private static bool IsMatchingVerse(IVerseRef verseReferenceFromToken, IVerseRef verseReference) { - return ((verseReferenceFromToken.ToString() == verseReference.ToString()) || - (verseReferenceFromToken?.AllVerses?.Any(vr => vr.ToString() == verseReference?.ToString()) ?? false)); + return ((verseReferenceFromToken?.ToString() == verseReference?.ToString()) || + (verseReferenceFromToken.AllVerses?.Any(vr => vr.ToString() == verseReference?.ToString()) ?? false) || + (verseReference?.AllVerses?.Any(vr => vr.ToString() == verseReferenceFromToken.ToString()) ?? false)); } private void ReleaseRequested(IWriteLock obj) @@ -325,7 +492,7 @@ void IBackTranslationHelperDataSource.SetDataUpdateProc(Action d.Value).ToList(); + _projectTarget.PutUSFMTokens(_writeLock, tokens, _verseReference.BookNum); Unlock(); + return true; } catch (Exception ex) { MessageBox.Show($"Exception caught:\n{ex.Message}"); } + finally + { + AreWeChangingTheTarget = false; + } + return false; } /// @@ -398,122 +588,79 @@ public static SortedDictionary> CalculateTargetTokens(I // ... in which case, we put one line of each translated version into one of the text tokens // 3) there are more lines of text translated than there were in Paratext // ... in which case, we'll duplicate the last text token and push the extra lines in it - var translatedValues = text?.Split(new[] { Environment.NewLine }, StringSplitOptions.None) - .ToList(); + var translatedValues = GetTranslatedLines(text); if ((translatedValues == null) || !translatedValues.Any()) // nothing to do return null; - // go thru all the ones we had and put the translated text into the text ones and transfer the non-text ones in order into the list to Put + // get the relevant target token collection (for the verse we're editing), so we can replace them. var keyBookChapter = GetBookChapterKey(verseReference); if (!usfmTokensTarget.TryGetValue(keyBookChapter, out SortedDictionary> vrefTokensTarget)) - { return null; - } - - // get the source project tokens (in case we need to copy from them) - var keyBookChapterVerse = GetBookChapterVerseKey(verseReference); - var sourceTokensFound = usfmTokensSource.TryGetValue(keyBookChapterVerse, out List tokensSource); - var keyBookChapterVerses = GetBookChapterVerseKey(versesReference); - // get the USFM tokens for the corresponding verse in the target project (if we don't have at least 1 IUSFMTextToken... - if (!vrefTokensTarget.TryGetValue(keyBookChapterVerses, out List tokensTarget) || - !tokensTarget.Any(t => t is IUSFMTextToken)) - { - // ... it could be that the user didn't put in any verse number/paragraphs/text yet... so just make a copy of the source tokens - // which will be replaced w/ the translated text below - if (!sourceTokensFound) - { - // if we didn't find those, then we'll have to start over - return null; - } - else - tokensTarget = tokensSource; + // get the source project tokens (so we can use those in the target project) + // if by chance, there are none, then it must be that we marked them 'dirty', so just return mull + // to have them be requeried + var keyBookChapterVerse = GetBookChapterVerseRangeKey(verseReference); + if (!usfmTokensSource.TryGetValue(keyBookChapterVerse, out List tokensSource)) + return null; - // it may have some verses, but no IUSFMTextTokens among them... - if (vrefTokensTarget.ContainsKey(keyBookChapterVerse)) - vrefTokensTarget[keyBookChapterVerse] = tokensTarget; - else - vrefTokensTarget.Add(keyBookChapterVerses, tokensTarget); - } + // NB: for reasons that are not clear, I was trying to maintain the markers that were in the target project + // and put the translated lines in those... but the entire point of this plugin is to make a back translation + // of the *source* project. So why wouldn't I just use the source project's tokens and put the translated + // bits in them. + // There may be fewer translated lines in the 'Target Translation' box than there were IUSFMTextToken in + // the source -- esp. if it the user started with the data from the existing Target project. But we'll just + // have to warn the user thru the UI of that issue. + // Bottom line, fit the translated lines into the IUSFMTextToken tokens of the *source* project in order + // (until we run out), and if there are more translated lines than IUSFMTextToken tokens, just add them as + // '\p's and let the user edit them in Paratext after we write them out to the target project + // BUT one issue does arise: if the source has a multiple combined verses and the target doesn't (or vice-versa) + // then we'll need to purge the existing (target) verse(s) so we can add the new (source-based) ones. + + // get the reference to the USFM tokens for the corresponding verse in the target project. If we don't + // have any, it probably means that the user didn't have any data in the target project yet... But + // it doesn't really matter, bkz we're just going to replace them with a copy of the source tokens + // anyway, which will be replaced w/ the translated text below + var keyBookChapterVerses = GetBookChapterVerseRangeKey(versesReference); + var tokensTarget = tokensSource; + + // before adding it back in, remove any data in the target collection for any and all verses in the source range + var matchingTokensInTarget = vrefTokensTarget.Where(kvp => kvp.Value.Any(t => IsMatchingVerse(t.VerseRef, verseReference))).ToList(); + matchingTokensInTarget.ForEach(kvp => vrefTokensTarget.Remove(kvp.Key)); + + if (vrefTokensTarget.ContainsKey(keyBookChapterVerses)) + vrefTokensTarget[keyBookChapterVerses] = tokensSource; + else + vrefTokensTarget.Add(keyBookChapterVerses, tokensSource); - // tokensTarget now contains just the tokens for the current verse + // go thru all the ones we had and put the translated text into the text ones and transfer the non-text ones in order into the list to Put var i = 0; - var purgedSomeParagraphs = false; - var lastTokenWasText = false; TextToken latestTextToken = null; var updatedTokens = new List(); - var countFewerTextTokensInTranslation = (tokensTarget.Count(t => t is IUSFMTextToken) - translatedValues.Count); foreach (var token in tokensTarget) { IUSFMToken updatedToken = token; - if ((token is IUSFMTextToken textToken) && textToken.IsPublishableVernacular && IsMatchingVerse((IVerseRef)textToken.VerseRef, verseReference)) + if ((token is IUSFMTextToken textToken) && + IsPublishableVernacular(textToken, tokensTarget) + && IsMatchingVerse((IVerseRef)textToken.VerseRef, verseReference)) { - if ((i >= translatedValues.Count) || (purgedSomeParagraphs && lastTokenWasText)) - { - // this means the source had multiple paragraphs, so ignore this unnecessary (source) text token - purgedSomeParagraphs = true; - continue; - } - latestTextToken = new TextToken(textToken) { - Text = translatedValues[i++] + Text = (i >= translatedValues.Count) + ? String.Empty // empty the source text, bkz we ran out of translated lines + : translatedValues[i++] }; updatedToken = latestTextToken; } - // if we have fewer lines than the source had, then skip adding any more paragraph markers unless it's the final token - if ((countFewerTextTokensInTranslation > 0) && IsParagraphToken(token) && (!IsParagraphToken(tokensTarget.Last()) || (token != tokensTarget.Last()))) - { - // this means we want to skip this paragraph token - purgedSomeParagraphs = true; - countFewerTextTokensInTranslation--; - continue; - } - - lastTokenWasText = IsScriptureTextToken(updatedToken); updatedTokens.Add(updatedToken); } - if (latestTextToken == null) - { - // this means the target (and source) verse had no IUSFMTextToken in it - // so there's nothing to do? - return null; - } - - // if there are still some translated portions we haven't processed yet, then insert them as copies of the last one we did - // just after the last one we did (w/ a paragraph token before it). - // if there are other markers *after* the last text token (e.g. a final paragraph token), then put the text (along - // with a preceding paragraph token) just after the last text token we added above + // if there are still some translated portions we haven't processed yet, then insert them as copies of the last text + // one we did just after the last one we did (w/ a paragraph token before it). var insertionIndex = updatedTokens.Count; - var lastTokenIsParagraph = IsParagraphToken(updatedTokens.Last()); - if (lastTokenIsParagraph) - insertionIndex--; - while (translatedValues.Count > i) { - // first skip past any markers common to both (but not if the final one was a \p - if (!lastTokenIsParagraph) - SkipPastIdenticalTokens(tokensSource, updatedTokens, ref insertionIndex); - - // if the source has one or more (non-scripture) markers at the next insertion point, we want to add them here. - // But the 'NextTokenFromSource*' function below will return a newly created paragraph (e.g. to put before - // a translated lines) if we run out of stuff in the source. In that case, only do this loop once - var isInsertedParagraph = false; - do - { - // first see if the next token in the source is a marker - isInsertedParagraph = NextTokenFromSourceOrTemplateParagraphMarker(out IUSFMToken marker); - - // if it's a text token, then skip adding it here and add it as a text token below - if (IsScriptureTextToken(marker)) - break; - - // add the non-text (read: marker) token first (and repeat of there are others) - updatedTokens.Insert(insertionIndex++, marker); - } while (!isInsertedParagraph); - // using the last text token we saw in the target as a template (which could possibly be from the source (read: untranslated)), // create a new one w/ the next translated value latestTextToken = new TextToken(latestTextToken) @@ -524,15 +671,6 @@ public static SortedDictionary> CalculateTargetTokens(I updatedTokens.Insert(insertionIndex++, latestTextToken); } - // in case the last one in the target happens to be common... - SkipPastIdenticalTokens(tokensSource, updatedTokens, ref insertionIndex); - - // add any remaining ones that are in the source, but not in the target - while (!purgedSomeParagraphs && (insertionIndex < tokensSource.Count)) - { - updatedTokens.Add(tokensSource[insertionIndex++]); - } - vrefTokensTarget[keyBookChapterVerses] = updatedTokens; #if SerializeToCreateTestFiles @@ -540,16 +678,12 @@ public static SortedDictionary> CalculateTargetTokens(I #endif return vrefTokensTarget; + } - // local function (to reduce the number of parameters needing to be passed) - bool NextTokenFromSourceOrTemplateParagraphMarker(out IUSFMToken marker) - { - var isFromSource = (tokensSource.Count > insertionIndex); - marker = isFromSource - ? tokensSource[insertionIndex] - : ParagraphToken(usfmTokensSource, usfmTokensTarget, latestTextToken); // fall back to a paragraph marker - return !isFromSource || IsParagraphToken(marker); // negative means isInsertedParagraph (or if the next one in the source was a paragraph) - } + private static List GetTranslatedLines(string text) + { + return text?.Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .ToList(); } #if SerializeToCreateTestFiles @@ -564,20 +698,6 @@ private static string ToJson(object obj) } #endif - private static bool IsScriptureTextToken(IUSFMToken token) - { - return (token is IUSFMTextToken textToken) && textToken.IsPublishableVernacular; - } - - private static void SkipPastIdenticalTokens(List tokensSource, List updatedTokens, ref int insertionIndex) - { - while ((insertionIndex < updatedTokens.Count) && (insertionIndex < tokensSource.Count) && - (updatedTokens[insertionIndex].ToString() == tokensSource[insertionIndex].ToString())) - { - insertionIndex++; - } - } - public static IUSFMToken ParagraphToken(Dictionary> usfmTokensSource, Dictionary>> usfmTokensTarget, TextToken previousTextToken) { @@ -596,33 +716,31 @@ public static IUSFMToken ParagraphToken(Dictionary> usf return new MarkerToken(paragraphToken, previousTextToken.VerseOffset + previousTextToken.Text.Length, previousTextToken.VerseRef); } - private static readonly List _paragraphMarkers = new List { "p", "m" }; + private static readonly List _paragraphMarkers = new() { "p", "m" }; private static bool IsParagraphToken(IUSFMToken token) { return (token is IUSFMMarkerToken markerToken) && (markerToken.Type == MarkerType.Paragraph) && _paragraphMarkers.Contains(markerToken.Marker); } - private void RequeryWarning(IVerseRef verseReference) - { - // if we don't already have it... it's probably because something was changed in the project - // TODO: do something! (probably just need to Initialize and UpdateData, so we'll have requeried everything) - var res = MessageBox.Show("It seems that something might have changed in the target project, which requires us to requery. Click 'Yes' to requery and start again. Click 'No' if you want to close this box (and copy the current text if you made changes for next time).", - ParatextBackTranslationHelperPlugin.PluginName, MessageBoxButtons.YesNo); - - if (res == DialogResult.Yes) - GetNewReference(verseReference); - } - protected override void OnShown(EventArgs e) { base.OnShown(e); - // On Windows XP, TXL comes up underneath Paratext. See if this fixes it: - TopMost = true; - TopMost = false; GetNewReference(_verseReference); } + private void BackTranslationHelperForm_Load(object sender, EventArgs e) + { + Text = GetFrameText(_projectSource, _projectTarget, _verseReference); + Location = Properties.Settings.Default.WindowLocation; + WindowState = Properties.Settings.Default.DefaultWindowState; + if (MinimumSize.Height <= Properties.Settings.Default.WindowSize.Height && + MinimumSize.Width <= Properties.Settings.Default.WindowSize.Width) + { + Size = Properties.Settings.Default.WindowSize; + } + } + private void BackTranslationHelperForm_FormClosing(object sender, FormClosingEventArgs e) { // only allow Cancel or ReplaceEvery @@ -652,5 +770,43 @@ private void Unlock() temp.Dispose(); } } + + private void BackTranslationHelperForm_Deactivate(object sender, EventArgs e) + { + // if we lose focus, it's possible that the user switched to Ptx to make some edits, + // so purge the source and target tokens which would force us to requery them + _isNotInFocus = true; + + System.Diagnostics.Debug.WriteLine($"PtxBTH: BackTranslationHelperForm_Deactivate: _isNotInFocus = '{_isNotInFocus}', IsModified: {backTranslationHelperCtrl.IsModified}, _verseReference: {_verseReference}"); + + // if nothing's been changed, then no need to show it as needing to be requeried + // WRONG: if they edit something while deactivated, we won’t query it again if we don’t clear it + //if (!backTranslationHelperCtrl.IsModified) + // return; + } + + private void BackTranslationHelperForm_Activated(object sender, EventArgs e) + { + _isNotInFocus = false; + System.Diagnostics.Debug.WriteLine($"PtxBTH: BackTranslationHelperForm_Activated: _isNotInFocus = '{_isNotInFocus}', IsModified: {backTranslationHelperCtrl.IsModified}, _verseReference: {_verseReference}"); + +#if false + // THIS is now done in ScriptureDataChangedHandlerSource & ScriptureDataChangedHandlerTarget + // make the source and target data stale, and trigger a requery... + PurgeSourceData(_verseReference); + + var bookChapterKey = GetBookChapterKey(_verseReference); + if (UsfmTokensTarget.ContainsKey(bookChapterKey)) + { + UsfmTokensTarget.Remove(bookChapterKey); + } +#endif + + // unless we were editing it, and then force it to stay the same + if (backTranslationHelperCtrl.IsModified) + return; + + GetNewReference(_verseReference); + } } } diff --git a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.resx b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.resx index de129925..1af7de15 100644 --- a/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.resx +++ b/src/ParatextPluginBackTranslationHelper/BackTranslationHelperForm.resx @@ -117,20 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AAEAAAD/////AQAAAAAAAAAMAgAAAKcBQmFja1RyYW5zbGF0aW9uSGVscGVyLCBWZXJzaW9uPTEuMC4w - LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49ZjE0NDdiYWUxZTYzZjQ4NV1dLCBtc2Nv - cmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1 - YzU2MTkzNGUwODkMAwAAAFhCYWNrVHJhbnNsYXRpb25IZWxwZXIsIFZlcnNpb249MS4wLjAuMCwgQ3Vs - dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1mMTQ0N2JhZTFlNjNmNDg1BQEAAABHU3lzdGVtLkNv - bGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tCYWNrVHJhbnNsYXRpb25IZWxwZXIuVGFyZ2V0UG9zc2li - bGUDAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lvbgQAACZCYWNrVHJhbnNsYXRpb25IZWxwZXIuVGFyZ2V0 - UG9zc2libGVbXQMAAAAICAIAAAAJBAAAAAEAAAABAAAABwQAAAAAAQAAAAQAAAAEJEJhY2tUcmFuc2xh - dGlvbkhlbHBlci5UYXJnZXRQb3NzaWJsZQMAAAAJBQAAAA0DBQUAAAAkQmFja1RyYW5zbGF0aW9uSGVs - cGVyLlRhcmdldFBvc3NpYmxlAwAAAB48UG9zc2libGVJbmRleD5rX19CYWNraW5nRmllbGQfPFRyYW5z - bGF0b3JOYW1lPmtfX0JhY2tpbmdGaWVsZBs8VGFyZ2V0RGF0YT5rX19CYWNraW5nRmllbGQAAQEIAwAA - AAAAAAAKBgYAAAAACw== - - \ No newline at end of file diff --git a/src/ParatextPluginBackTranslationHelper/ParatextBackTranslationHelperPlugin.cs b/src/ParatextPluginBackTranslationHelper/ParatextBackTranslationHelperPlugin.cs index 60b0304c..114b6fd6 100644 --- a/src/ParatextPluginBackTranslationHelper/ParatextBackTranslationHelperPlugin.cs +++ b/src/ParatextPluginBackTranslationHelper/ParatextBackTranslationHelperPlugin.cs @@ -16,7 +16,7 @@ public class ParatextBackTranslationHelperPlugin : IParatextStandalonePlugin public const string PluginName = "Back Translation Helper"; public const string emailAddress = "silconverters_support@sil.org"; public string Name => PluginName; - public Version Version => new Version(1, 0); + public Version Version => new(1, 0); public string VersionString => Version.ToString(); public string Publisher => "SIL/UBS"; diff --git a/src/ParatextPluginBackTranslationHelper/ParatextPluginBackTranslationHelper.csproj b/src/ParatextPluginBackTranslationHelper/ParatextPluginBackTranslationHelper.csproj index 4892310d..7138e77b 100644 --- a/src/ParatextPluginBackTranslationHelper/ParatextPluginBackTranslationHelper.csproj +++ b/src/ParatextPluginBackTranslationHelper/ParatextPluginBackTranslationHelper.csproj @@ -1,6 +1,6 @@  - + Debug @@ -39,7 +39,7 @@ DEBUG;TRACE full x64 - 7.3 + latest prompt @@ -48,7 +48,7 @@ true pdbonly x64 - 7.3 + latest prompt @@ -57,7 +57,7 @@ DEBUG;TRACE full x86 - 7.3 + latest prompt @@ -66,7 +66,7 @@ true pdbonly x86 - 7.3 + latest prompt @@ -75,29 +75,20 @@ $(EcDistFilesPath)\win-$(Platform)\native\AIGuesserEC.dll - - $(EcDistFilesPath)\win-$(Platform)\native\EcTranslators.dll - - - $(EcDistFilesPath)\win-x86\native\EcTranslators.dll - - - $(EcDistFilesPath)\win-$(Platform)\native\BackTranslationHelper.dll - $(EcLibFilesPath)\net48\x86\ECInterfaces.dll $(EcLibFilesPath)\net48\x64\ECInterfaces.dll - - ..\..\packages\ParatextEmbeddedUiPluginInterfaces.2.0.21\lib\net48\EmbeddedUiPluginInterfaces.dll + + ..\..\packages\ParatextEmbeddedUiPluginInterfaces.2.0.23\lib\net48\EmbeddedUiPluginInterfaces.dll - ..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll + ..\..\packages\Newtonsoft.Json.13.0.2\lib\net45\Newtonsoft.Json.dll - - ..\..\packages\ParatextPluginInterfaces.2.0.21\lib\netstandard2.0\PluginInterfaces.dll + + ..\..\packages\ParatextPluginInterfaces.2.0.23\lib\netstandard2.0\PluginInterfaces.dll $(EcLibFilesPath)\net48\x86\SilEncConverters40.dll @@ -105,6 +96,15 @@ $(EcLibFilesPath)\net48\x64\SilEncConverters40.dll + + $(EcDistFilesPath)\win-$(Platform)\native\EcTranslators.dll + + + $(EcDistFilesPath)\win-x86\native\EcTranslators.dll + + + $(EcDistFilesPath)\win-$(Platform)\native\BackTranslationHelper.dll + ..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll @@ -176,6 +176,7 @@ BackTranslationHelperForm.cs + Designer ProjectListForm.cs @@ -183,6 +184,7 @@ ResXFileCodeGenerator Resources.Designer.cs + Designer SplashScreenForm.cs @@ -201,6 +203,8 @@ EcPlugins\Translators 4.0.0.0 Plugin Details.xml + + @@ -212,8 +216,7 @@ IF NOT EXIST "%25ParatextInstallDir%25\plugins\$(ProjectName)\$(ProjectName).ptx del "%25ParatextInstallDir%25\plugins\$(ProjectName)\$(ProjectName).ptxplg" :nodelete -@echo Copying files to '%25ParatextInstallDir%25\plugins\$(ProjectName) -' folder +@echo Copying files to '%25ParatextInstallDir%25\plugins\$(ProjectName)' folder xcopy "$(TargetDir)" "%25ParatextInstallDir%25\plugins\$(ProjectName)" /y /i ren "%25ParatextInstallDir%25\plugins\$(ProjectName)\$(TargetFileName)" "$(ProjectName).ptxplg" @@ -224,6 +227,6 @@ ren "%25ParatextInstallDir%25\plugins\$(ProjectName)\$(TargetFileName)" "$(Proje This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/ParatextPluginBackTranslationHelper/Properties/Resources.Designer.cs b/src/ParatextPluginBackTranslationHelper/Properties/Resources.Designer.cs index d56c8880..f0f46f97 100644 --- a/src/ParatextPluginBackTranslationHelper/Properties/Resources.Designer.cs +++ b/src/ParatextPluginBackTranslationHelper/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace SIL.ParatextBackTranslationHelperPlugin.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -60,6 +60,26 @@ internal Resources() { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pindown { + get { + object obj = ResourceManager.GetObject("pindown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pinup { + get { + object obj = ResourceManager.GetObject("pinup", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/src/ParatextPluginBackTranslationHelper/Properties/Resources.resx b/src/ParatextPluginBackTranslationHelper/Properties/Resources.resx index 18f5ace9..a5b18b56 100644 --- a/src/ParatextPluginBackTranslationHelper/Properties/Resources.resx +++ b/src/ParatextPluginBackTranslationHelper/Properties/Resources.resx @@ -118,7 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\pindown.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\pinup.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + - ..\Resources\Image1.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\SplashScreenImage.bmp;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/src/ParatextPluginBackTranslationHelper/Properties/Settings.Designer.cs b/src/ParatextPluginBackTranslationHelper/Properties/Settings.Designer.cs index b16208eb..e9592f50 100644 --- a/src/ParatextPluginBackTranslationHelper/Properties/Settings.Designer.cs +++ b/src/ParatextPluginBackTranslationHelper/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace SIL.ParatextBackTranslationHelperPlugin.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/src/ParatextPluginBackTranslationHelper/Resources/Image1.bmp b/src/ParatextPluginBackTranslationHelper/Resources/SplashScreenImage.bmp similarity index 100% rename from src/ParatextPluginBackTranslationHelper/Resources/Image1.bmp rename to src/ParatextPluginBackTranslationHelper/Resources/SplashScreenImage.bmp diff --git a/src/ParatextPluginBackTranslationHelper/Resources/pindown.bmp b/src/ParatextPluginBackTranslationHelper/Resources/pindown.bmp new file mode 100644 index 00000000..3b250237 Binary files /dev/null and b/src/ParatextPluginBackTranslationHelper/Resources/pindown.bmp differ diff --git a/src/ParatextPluginBackTranslationHelper/Resources/pinup.bmp b/src/ParatextPluginBackTranslationHelper/Resources/pinup.bmp new file mode 100644 index 00000000..d2c4db2f Binary files /dev/null and b/src/ParatextPluginBackTranslationHelper/Resources/pinup.bmp differ diff --git a/src/ParatextPluginBackTranslationHelper/app.config b/src/ParatextPluginBackTranslationHelper/app.config index 16eaa4c6..e8acb2dc 100644 --- a/src/ParatextPluginBackTranslationHelper/app.config +++ b/src/ParatextPluginBackTranslationHelper/app.config @@ -59,6 +59,22 @@ + + + + + + + + + + + + + + + + diff --git a/src/ParatextPluginBackTranslationHelper/packages.config b/src/ParatextPluginBackTranslationHelper/packages.config index 1c238f83..b05064df 100644 --- a/src/ParatextPluginBackTranslationHelper/packages.config +++ b/src/ParatextPluginBackTranslationHelper/packages.config @@ -1,7 +1,7 @@  - - - - + + + + \ No newline at end of file diff --git a/src/SILConvertersInstaller/SILConvertersInstaller.vbproj b/src/SILConvertersInstaller/SILConvertersInstaller.vbproj index 75d5f85f..5007b9ed 100644 --- a/src/SILConvertersInstaller/SILConvertersInstaller.vbproj +++ b/src/SILConvertersInstaller/SILConvertersInstaller.vbproj @@ -1,6 +1,6 @@  - + Local 9.0.30729 @@ -107,6 +107,8 @@ AllRules.ruleset + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -242,6 +244,6 @@ xcopy /s /y "$(EcDistFilesPath)\redist\*.*" "$(SolutionDir)output\$(PlatformName This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/SILConvertersInstaller/packages.config b/src/SILConvertersInstaller/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/SILConvertersInstaller/packages.config +++ b/src/SILConvertersInstaller/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/SILConvertersOffice/FindReplaceForm.Designer.cs b/src/SILConvertersOffice/FindReplaceForm.Designer.cs index 94141d68..7afab97d 100644 --- a/src/SILConvertersOffice/FindReplaceForm.Designer.cs +++ b/src/SILConvertersOffice/FindReplaceForm.Designer.cs @@ -82,7 +82,7 @@ private void InitializeComponent() this.buttonReplaceAll.TabIndex = 7; this.buttonReplaceAll.Text = "Replace &All"; this.buttonReplaceAll.UseVisualStyleBackColor = true; - this.buttonReplaceAll.Click += new System.EventHandler(this.buttonReplaceAll_Click); + this.buttonReplaceAll.Click += new System.EventHandler(this.ButtonReplaceAll_Click); // // buttonReplace // @@ -92,7 +92,7 @@ private void InitializeComponent() this.buttonReplace.TabIndex = 6; this.buttonReplace.Text = "&Replace"; this.buttonReplace.UseVisualStyleBackColor = true; - this.buttonReplace.Click += new System.EventHandler(this.buttonReplace_Click); + this.buttonReplace.Click += new System.EventHandler(this.ButtonReplace_Click); // // buttonFindNext // @@ -102,7 +102,7 @@ private void InitializeComponent() this.buttonFindNext.TabIndex = 5; this.buttonFindNext.Text = "&Find Next"; this.buttonFindNext.UseVisualStyleBackColor = true; - this.buttonFindNext.Click += new System.EventHandler(this.buttonFindNext_Click); + this.buttonFindNext.Click += new System.EventHandler(this.ButtonFindNext_Click); // // checkBoxMatchCase // @@ -114,7 +114,7 @@ private void InitializeComponent() this.checkBoxMatchCase.TabIndex = 8; this.checkBoxMatchCase.Text = "Matc&h case"; this.checkBoxMatchCase.UseVisualStyleBackColor = true; - this.checkBoxMatchCase.CheckedChanged += new System.EventHandler(this.checkBoxMatchCase_CheckedChanged); + this.checkBoxMatchCase.CheckedChanged += new System.EventHandler(this.CheckBoxMatchCase_CheckedChanged); // // comboBoxReplaceWith // @@ -127,7 +127,7 @@ private void InitializeComponent() this.comboBoxReplaceWith.Name = "comboBoxReplaceWith"; this.comboBoxReplaceWith.Size = new System.Drawing.Size(427, 29); this.comboBoxReplaceWith.TabIndex = 10; - this.comboBoxReplaceWith.SelectedIndexChanged += new System.EventHandler(this.comboBoxReplaceWith_SelectedIndexChanged); + this.comboBoxReplaceWith.SelectedIndexChanged += new System.EventHandler(this.ComboBoxReplaceWith_SelectedIndexChanged); // // labelReplaceWith // @@ -149,7 +149,7 @@ private void InitializeComponent() this.comboBoxFindWhat.Name = "comboBoxFindWhat"; this.comboBoxFindWhat.Size = new System.Drawing.Size(427, 29); this.comboBoxFindWhat.TabIndex = 9; - this.comboBoxFindWhat.SelectedIndexChanged += new System.EventHandler(this.comboBoxFindWhat_SelectedIndexChanged); + this.comboBoxFindWhat.SelectedIndexChanged += new System.EventHandler(this.ComboBoxFindWhat_SelectedIndexChanged); // // labelFindWhat // @@ -170,7 +170,7 @@ private void InitializeComponent() this.buttonExpressionBuilder.TabIndex = 4; this.buttonExpressionBuilder.Text = ">"; this.buttonExpressionBuilder.UseVisualStyleBackColor = true; - this.buttonExpressionBuilder.Click += new System.EventHandler(this.buttonExpressionBuilder_Click); + this.buttonExpressionBuilder.Click += new System.EventHandler(this.ButtonExpressionBuilder_Click); // // contextMenuStripExprBuilder // @@ -201,7 +201,7 @@ private void InitializeComponent() this.regularExpressionHelpToolStripMenuItem}); this.contextMenuStripExprBuilder.Name = "contextMenuStripExprBuilder"; this.contextMenuStripExprBuilder.Size = new System.Drawing.Size(351, 484); - this.contextMenuStripExprBuilder.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.contextMenuStripExprBuilder_ItemClicked); + this.contextMenuStripExprBuilder.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.ContextMenuStripExprBuilder_ItemClicked); // // MatchAnyCharacterToolStripMenuItem // @@ -343,7 +343,7 @@ private void InitializeComponent() this.regularExpressionHelpToolStripMenuItem.Name = "regularExpressionHelpToolStripMenuItem"; this.regularExpressionHelpToolStripMenuItem.Size = new System.Drawing.Size(350, 22); this.regularExpressionHelpToolStripMenuItem.Text = "Regular Expression &Help"; - this.regularExpressionHelpToolStripMenuItem.Click += new System.EventHandler(this.regularExpressionHelpToolStripMenuItem_Click); + this.regularExpressionHelpToolStripMenuItem.Click += new System.EventHandler(this.RegularExpressionHelpToolStripMenuItem_Click); // // buttonCancel // @@ -354,7 +354,7 @@ private void InitializeComponent() this.buttonCancel.TabIndex = 11; this.buttonCancel.Text = "&Close"; this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); // // ecTextBoxFindWhat // @@ -366,7 +366,7 @@ private void InitializeComponent() this.ecTextBoxFindWhat.Size = new System.Drawing.Size(408, 29); this.ecTextBoxFindWhat.TabIndex = 1; this.ecTextBoxFindWhat.WordWrap = false; - this.ecTextBoxFindWhat.TextChanged += new System.EventHandler(this.ecTextBox_TextChanged); + this.ecTextBoxFindWhat.TextChanged += new System.EventHandler(this.EcTextBox_TextChanged); // // ecTextBoxReplaceWith // @@ -378,7 +378,7 @@ private void InitializeComponent() this.ecTextBoxReplaceWith.Size = new System.Drawing.Size(408, 29); this.ecTextBoxReplaceWith.TabIndex = 3; this.ecTextBoxReplaceWith.WordWrap = false; - this.ecTextBoxReplaceWith.TextChanged += new System.EventHandler(this.ecTextBox_TextChanged); + this.ecTextBoxReplaceWith.TextChanged += new System.EventHandler(this.EcTextBox_TextChanged); // // progressBar // @@ -393,9 +393,9 @@ private void InitializeComponent() // this.backgroundWorker.WorkerReportsProgress = true; this.backgroundWorker.WorkerSupportsCancellation = true; - this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork); - this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted); - this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_ProgressChanged); + this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker_DoWork); + this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted); + this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.BackgroundWorker_ProgressChanged); // // FindReplaceForm // diff --git a/src/SILConvertersOffice/FindReplaceForm.cs b/src/SILConvertersOffice/FindReplaceForm.cs index 4fdba5ba..3bdb50d7 100644 --- a/src/SILConvertersOffice/FindReplaceForm.cs +++ b/src/SILConvertersOffice/FindReplaceForm.cs @@ -7,6 +7,18 @@ using ECInterfaces; using SilEncConverters40; using Word = Microsoft.Office.Interop.Word; +using System.Text.RegularExpressions; +using System.Text; +using System.Security.Policy; +#if BUILD_FOR_OFF11 +using SILConvertersOffice.Properties; +#elif BUILD_FOR_OFF12 +using SILConvertersOffice07.Properties; +#elif BUILD_FOR_OFF14 +using SILConvertersOffice10.Properties; +#elif BUILD_FOR_OFF15 +using SILConvertersOffice13.Properties; +#endif namespace SILConvertersOffice { @@ -21,8 +33,9 @@ internal partial class FindReplaceForm : Form { const string cstrClose = "&Close"; const string cstrStop = "&Stop"; + const string NetRegexHelpUrl = "https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference"; - private WordFindReplaceDocument m_doc; + private readonly WordFindReplaceDocument m_doc; FindWordProcessor m_aWordByWordProcessor = null; protected SearchAreaType m_eSearchAreaType = SearchAreaType.eUnknown; @@ -37,16 +50,16 @@ public FindReplaceForm(WordFindReplaceDocument doc) m_doc = doc; // make sure these exist so don't throw an error later when we try to add to them - if (Properties.Settings.Default.RecentFindWhat == null) - Properties.Settings.Default.RecentFindWhat = new System.Collections.Specialized.StringCollection(); + if (Settings.Default.RecentFindWhat == null) + Settings.Default.RecentFindWhat = new System.Collections.Specialized.StringCollection(); else - foreach (string str in Properties.Settings.Default.RecentFindWhat) + foreach (string str in Settings.Default.RecentFindWhat) comboBoxFindWhat.Items.Add(str); - if (Properties.Settings.Default.RecentReplaceWith == null) - Properties.Settings.Default.RecentReplaceWith = new System.Collections.Specialized.StringCollection(); + if (Settings.Default.RecentReplaceWith == null) + Settings.Default.RecentReplaceWith = new System.Collections.Specialized.StringCollection(); else - foreach (string str in Properties.Settings.Default.RecentReplaceWith) + foreach (string str in Settings.Default.RecentReplaceWith) comboBoxReplaceWith.Items.Add(str); #if BUILD_FOR_OFF15 @@ -61,7 +74,7 @@ public FindReplaceForm(WordFindReplaceDocument doc) helpProvider.SetHelpString(this, SILConvertersOffice07.Properties.Resources.FindReplaceFormHelpString); helpProvider.SetHelpString(ecTextBoxFindWhat, SILConvertersOffice07.Properties.Resources.ecTextBoxFindWhatHelpString); helpProvider.SetHelpString(ecTextBoxReplaceWith, SILConvertersOffice07.Properties.Resources.ecTextBoxReplaceWithHelpString); -#else +#elif BUILD_FOR_OFF11 helpProvider.SetHelpString(this, Properties.Resources.FindReplaceFormHelpString); helpProvider.SetHelpString(ecTextBoxFindWhat, Properties.Resources.ecTextBoxFindWhatHelpString); helpProvider.SetHelpString(ecTextBoxReplaceWith, Properties.Resources.ecTextBoxReplaceWithHelpString); @@ -92,11 +105,11 @@ protected void ProcessButtonEx(FormButtons eFormButton) // if there's no processor (e.g. initially, change of Find What or Replace With text)... if (m_aWordByWordProcessor == null) { - AddToComboBox(ecTextBoxFindWhat, comboBoxFindWhat, Properties.Settings.Default.RecentFindWhat); + AddToComboBox(ecTextBoxFindWhat, comboBoxFindWhat, Settings.Default.RecentFindWhat); // if the user clicked Find/Next, then don't give the Replace With text even if there is some m_aWordByWordProcessor = new FindWordProcessor(ecTextBoxFindWhat.Text, ecTextBoxReplaceWith.Text, - checkBoxMatchCase.Checked, ecTextBoxFindWhat.Font); + checkBoxMatchCase.Checked); } // update the button pressed information @@ -105,7 +118,7 @@ protected void ProcessButtonEx(FormButtons eFormButton) // if we're doing a replacement, then save the 'Replace with' string in our settings file if ((eFormButton == FormButtons.ReplaceOnce) || (eFormButton == FormButtons.ReplaceAll)) { - AddToComboBox(ecTextBoxReplaceWith, comboBoxReplaceWith, Properties.Settings.Default.RecentReplaceWith); + AddToComboBox(ecTextBoxReplaceWith, comboBoxReplaceWith, Settings.Default.RecentReplaceWith); // the user may have done 'Replace' when it was found, but then later clicked said ReplaceAll, // so update the value @@ -158,7 +171,7 @@ protected void DoWork(BackgroundWorker worker, WordFindReplaceDocument doc) doc.Search(worker); } - private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) + private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; DoWork(worker, e.Argument as WordFindReplaceDocument); @@ -166,22 +179,22 @@ private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) e.Cancel = true; } - private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) + private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // for us the "progress" is a new range of the document we're searching thru int nValue = (int)e.ProgressPercentage; - if (nValue > progressBar.Maximum) - { - progressBar.Maximum = nValue; - } progressBar.BeginInvoke( (MethodInvoker)delegate () { + if (nValue > progressBar.Maximum) + { + progressBar.Maximum = nValue; + } progressBar.Value = nValue; }); } - private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { bool bReplace = (m_aWordByWordProcessor.FormButton == FormButtons.ReplaceOnce) || (m_aWordByWordProcessor.FormButton == FormButtons.ReplaceAll); bool bContinue = false; // start again pessimistic @@ -299,7 +312,7 @@ private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerComplet base.Show(); } - private void contextMenuStripExprBuilder_ItemClicked(object sender, ToolStripItemClickedEventArgs e) + private void ContextMenuStripExprBuilder_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { string strItem = ((ToolStripItem)e.ClickedItem).Text; if (strItem != regularExpressionHelpToolStripMenuItem.Text) @@ -311,12 +324,8 @@ private void contextMenuStripExprBuilder_ItemClicked(object sender, ToolStripIte private void FindReplaceForm_FormClosing(object sender, FormClosingEventArgs e) { - // clear out the EncConverters object we created since we're probably done for a while (that - // is static so we don't have to keep buying it over and over again for simple changes in the - // expression). - FindWordProcessor.m_aECs = null; ResetBackgroundWorker(); - Properties.Settings.Default.Save(); // in case something was changed + Settings.Default.Save(); // in case something was changed e.Cancel = true; Hide(); } @@ -339,51 +348,50 @@ protected void AddToComboBox(EcTextBox tb, ComboBox cb, System.Collections.Speci } } - private void buttonFindNext_Click(object sender, EventArgs e) + private void ButtonFindNext_Click(object sender, EventArgs e) { ProcessButton(FormButtons.Next); } - private void buttonReplace_Click(object sender, EventArgs e) + private void ButtonReplace_Click(object sender, EventArgs e) { ProcessButton(FormButtons.ReplaceOnce); } - private void buttonReplaceAll_Click(object sender, EventArgs e) + private void ButtonReplaceAll_Click(object sender, EventArgs e) { ProcessButton(FormButtons.ReplaceAll); } - private void ecTextBox_TextChanged(object sender, EventArgs e) + private void EcTextBox_TextChanged(object sender, EventArgs e) { m_eSearchAreaType = SearchAreaType.eUnknown; m_aWordByWordProcessor = null; } - private void buttonExpressionBuilder_Click(object sender, EventArgs e) + private void ButtonExpressionBuilder_Click(object sender, EventArgs e) { ToolStripDropDownDirection dir = ToolStripDropDownDirection.BelowRight; this.buttonExpressionBuilder.ContextMenuStrip.Show(PointToScreen(buttonExpressionBuilder.Location), dir); } - private void comboBoxFindWhat_SelectedIndexChanged(object sender, EventArgs e) + private void ComboBoxFindWhat_SelectedIndexChanged(object sender, EventArgs e) { ecTextBoxFindWhat.Text = (string)comboBoxFindWhat.SelectedItem; } - private void comboBoxReplaceWith_SelectedIndexChanged(object sender, EventArgs e) + private void ComboBoxReplaceWith_SelectedIndexChanged(object sender, EventArgs e) { ecTextBoxReplaceWith.Text = (string)comboBoxReplaceWith.SelectedItem; } - private void regularExpressionHelpToolStripMenuItem_Click(object sender, EventArgs e) + private void RegularExpressionHelpToolStripMenuItem_Click(object sender, EventArgs e) { - // launch the ICU help - string strCommandLine = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + @"\SIL\Help\ICU Regular Expression Plug-in About box.htm"; - OfficeApp.LaunchProgram(strCommandLine, null); + // launch the .Net Regex help + System.Diagnostics.Process.Start(NetRegexHelpUrl); } - private void checkBoxMatchCase_CheckedChanged(object sender, EventArgs e) + private void CheckBoxMatchCase_CheckedChanged(object sender, EventArgs e) { m_aWordByWordProcessor = null; } @@ -394,7 +402,7 @@ private void ResetBackgroundWorker() this.backgroundWorker.CancelAsync(); } - private void buttonCancel_Click(object sender, EventArgs e) + private void ButtonCancel_Click(object sender, EventArgs e) { if (buttonCancel.Text == cstrStop) ResetBackgroundWorker(); @@ -411,26 +419,21 @@ internal class FindWordProcessor : OfficeDocumentProcessor protected char[] m_achDelimiter = new char[] { '\u001f' }; public int NumOfParagraphsToSearch = 1; public int NumOfReplacements = 0; - static public EncConverters m_aECs = null; - protected IEncConverter m_aECRegex = null; + protected Regex _netRegex = null; + protected string _replaceWith = null; protected string[] astrReplaceDoubleEscapeCodes = new string[] { @"\t", @"\r", @"\n", @"\a", @"\b", @"\f" }; protected string[] astrReplaceEscapeCodes = new string[] { "\t", "\r", "\n", "\a", "\b", "\f" }; - public FindWordProcessor(string strFindWhat, string strReplaceWith, bool bMatchCase, Font font) + public FindWordProcessor(string strFindWhat, string strReplaceWith, bool bMatchCase) { - if (m_aECs == null) - m_aECs = new EncConverters(true); + strReplaceWith = Regex.Unescape(strReplaceWith); - // for some reason, the text that goes to constructing the 'Find what' part of the CRegexMatcher is - // expecting doubly-escaped text (e.g. "\\r" for CR), but the text that goes for the 'Replace with' - // (i.e. the CRegex::ReplaceAll) is expecting singly-escaped text. Our text boxes, however, will always - // return these as doubly-escaped. So for the 'Replace with' stuff, we need to turn certain doubly- - // escaped codes into their single-escaped flavors). - int nNumEscapeCodes = astrReplaceDoubleEscapeCodes.Length; - for (int i = 0; i < nNumEscapeCodes; i++) - strReplaceWith = strReplaceWith.Replace(astrReplaceDoubleEscapeCodes[i], astrReplaceEscapeCodes[i]); + // use a dummy delimiter in the replaceWith string, so we can find the changed bit + // (hoping the person isn't looking for this delimiter) + _replaceWith = String.Format("{0}{1}{0}", m_achDelimiter[0], strReplaceWith); + + _netRegex = new(strFindWhat); - m_aECRegex = InitSearchFontConverter(strFindWhat, strReplaceWith, font, bMatchCase); AutoReplaceOnNextFind = false; // we'll take care of this as well // Normally, we search the text one paragraph at a time for the FindWhat string, but if the user @@ -448,48 +451,15 @@ public FindWordProcessor(string strFindWhat, string strReplaceWith, bool bMatchC } } - // initialize an EncConverter which will tell us when we've hit a match. Uses ICU RegEx (though, there's - // no reason this couldn't be .Net regex...) - protected IEncConverter InitSearchFontConverter(string strFindWhat, string strReplaceWith, Font font, bool bMatchCase) - { - // we're going to use a temporary ICU RegEx EncConverter to do our 'searching' for us. - // get a blank ICU Regex converter that we can program with our FindWhat string - // but, it may be null if ICU isn't installed - System.Diagnostics.Debug.Assert(m_aECs != null); - IEncConverter aIEC = null; - try - { - aIEC = m_aECs.NewEncConverterByImplementationType(EncConverters.strTypeSILicuRegex); - } - catch (Exception ex) - { - throw new ApplicationException("ICU doesn't appear to have been installed. This feature won't work without ICU.", ex); - } - - // we search for different things depending on whether it's "Find" (only) vs. "Find & Replace" - // delimit the replacement string with something we can detect, which we wouldn't otherwise expect - // to find in user text. - string strConverterSpec = String.Format("{0}->{2}{1}{2}{3}", strFindWhat, strReplaceWith, - m_achDelimiter[0], (bMatchCase) ? " /i" : null); - - // Give it a friendly name that isn't likely to conflict with anything 'real' the user might name it. - string strName = String.Format("{0} FindReplaceConverter", OfficeApp.cstrCaption); - ConvType eConvType = ConvType.Unicode_to_Unicode; - string strDummy = null; - int nProcType = (int)ProcessTypeFlags.ICURegularExpression; - - // initialize it so it's ready and put it in the current repository object (as a temporary converter) - aIEC.Initialize(strName, strConverterSpec, ref strDummy, ref strDummy, ref eConvType, - ref nProcType, 0, 0, true); - - return aIEC; - } - public void ReplaceText(WordRange aRunRange, string strNewText) { try { + // if you don't explicitly set the font after replacing the text, Word drops it + // in with some other default font... + var font = aRunRange.FontName; aRunRange.Text = strNewText; + aRunRange.FontName = font; } catch (Exception ex) { @@ -526,7 +496,7 @@ protected string[] GetFirstReplacementSplitArray(ref string strInput, ref string int nInputLength = strInput.Length; int nDiffLength = nInputLength; int nTempInputLength = nInputLength; - string strTempInput = null; + string strTempInput; do { // do a binary search until we get only one replacement @@ -537,7 +507,7 @@ protected string[] GetFirstReplacementSplitArray(ref string strInput, ref string nTempInputLength = Math.Min(nTempInputLength + nDiffLength, nInputLength); strTempInput = strInput.Substring(0, nTempInputLength); - strOutput = m_aECRegex.Convert(strTempInput); + strOutput = _netRegex.Replace(strTempInput, _replaceWith); astrSegments = strOutput.Split(m_achDelimiter); System.Diagnostics.Trace.WriteLine(String.Format("{0}: diff:{1} segments:{2}", nTempInputLength, nDiffLength, astrSegments.Length)); } while (astrSegments.Length != 3); @@ -554,16 +524,16 @@ public FindResult FindReplaceCompare(WordRange aRunRange, ref int SearchAreaStar { FindResult res = FindResult.eNothingFound; string strInput = aRunRange.Text; - if (String.IsNullOrEmpty(strInput) || (m_aECRegex == null)) + + if (String.IsNullOrEmpty(strInput) || (_netRegex == null)) return res; - // otherwise 'convert' it to see if the 'Find what' string is in it - string strOutput = m_aECRegex.Convert(strInput); + // otherwise do the replacement to see if the 'Find what' string is in it + string strOutput = _netRegex.Replace(strInput, _replaceWith); // if the input string is different from the output string, then the FindWhat string was found. if (strInput != strOutput) { -#if !DefineToNotUseSplitAndConvert // The way the convert works is that it will replace each instance of the input string that matches // the FindWhat syntax (i.e. there may be more than one replacement we have to deal with). // here's the problem: if there was more than one replacment, then I really can't tell what portion @@ -600,107 +570,6 @@ public FindResult FindReplaceCompare(WordRange aRunRange, ref int SearchAreaStar nEndOfFindWhatSelection = strInput.Length; else nEndOfFindWhatSelection = strInput.Length - strStuffFollowingMatch.Length; -#else - // this could probably be done more elegantly with Split rather than what I do in the #else case - string[] astrSegments = strOutput.Split(m_achDelimiter); - - // must be odd (before, ||: replace, following :||), where any or all can be null - int nTotalSegments = astrSegments.Length; - System.Diagnostics.Debug.Assert((nTotalSegments % 2) == 1); - - // get the index to the first character of the replacement (which is the same as the first character - // of the 'Find what' as well). - int nIndex = astrSegments[0].Length; - - // remember this so we pick up here later - SearchAreaStart += nIndex; - if (nIndex > 0) - aRunRange.Start = SearchAreaStart; - - // the replacement string is easy. It's just whatever's in the 1st element of the Split array. - // but we have to figure out what the 'Find what' text is so that we can select it (so we can replace - // it). This is not so easy, because it could be anything and not just a string of text like in a normal - // find. - string strReplacementString = astrSegments[1]; - - // Between the end of the first replacement and the beginning of the next (if multiple replacments) - // is a string which should match something in the original, which we can search for - string strStuffFollowingMatch = astrSegments[2]; // may be null - - int nEndOfFindWhatSelection; - if (String.IsNullOrEmpty(strStuffFollowingMatch)) - { - // If the 'Find what' is repeated twice in a row, then the stuff in-between the two instances of - // replacement text will be null. - // Detect this by looking at the length of the even number string array elements (2, 4, etc), - // which are the segments following the replacements. This tells us what we have to divide by - // to get the proportion for only one find. - int nNumReplacmentsInARow = 1; - int nNextReplacementIndex = 2; - nTotalSegments--; - while ((nNextReplacementIndex < nTotalSegments) && String.IsNullOrEmpty(astrSegments[nNextReplacementIndex])) - { - nNumReplacmentsInARow++; - nNextReplacementIndex += 2; - } - - if (nNextReplacementIndex < astrSegments.Length) - strStuffFollowingMatch = astrSegments[nNextReplacementIndex]; - - int numerator; - if (String.IsNullOrEmpty(strStuffFollowingMatch)) - numerator = strInput.Length; - else - numerator = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1); - nEndOfFindWhatSelection = ((numerator - nIndex) / nNumReplacmentsInARow) + nIndex; - } - else - nEndOfFindWhatSelection = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1); - - /* - int nIndex = strOutput.IndexOf(m_achDelimiter[0]); - System.Diagnostics.Debug.Assert(nIndex != -1); - SearchAreaStart += nIndex; - if (nIndex > 0) - aRunRange.Start = SearchAreaStart; - - int nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nIndex + 1); - System.Diagnostics.Debug.Assert(nEndOfReplacement != -1); - - // the replacement string is what's between these two - string strReplacementString = strOutput.Substring(nIndex + 1, (nEndOfReplacement - nIndex - 1)); - - // now the complicated part. Between the end of the first replacement and the next - // one is a string which should match something in the original. But if the replacement - // were null, then it could be the very next character... - // This also handles the situation where there may be several "found whats" - int nNumReplacmentsInARow = 1; - int nNextIndex = nEndOfReplacement + 1; - while ((nNextIndex < strOutput.Length) && (strOutput[nNextIndex] == m_achDelimiter[0])) - { - nNumReplacmentsInARow++; - nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nNextIndex + 1); - nNextIndex = nEndOfReplacement + 1; - } - - if (nNextIndex < strOutput.Length) - { - nEndOfReplacement = strOutput.IndexOf(m_achDelimiter[0], nNextIndex + 1); - if (nEndOfReplacement == -1) - nEndOfReplacement = strOutput.Length; - } - else if (nNextIndex == strOutput.Length) - nNextIndex--; - - string strStuffFollowingMatch = strOutput.Substring(nNextIndex, nEndOfReplacement - nNextIndex); - - nEndOfFindWhatSelection = ((strInput.Length - nIndex) / nNumReplacmentsInARow) + nIndex; - if (!String.IsNullOrEmpty(strStuffFollowingMatch)) - { - nEndOfFindWhatSelection = strInput.IndexOf(strStuffFollowingMatch, nIndex + 1) / nNumReplacmentsInARow; - } - */ -#endif // !UseSplitToFindReplacements FoundAreaLength = nEndOfFindWhatSelection - nIndex; aRunRange.End = SearchAreaStart + FoundAreaLength; @@ -889,10 +758,10 @@ public void ProcessParagraphsFindAndReplace(FindWordProcessor aWordProcessor, Wo WordRange aRunRange = GetStartingRange(theRangeToSearch); if (aRunRange == null) return; + object nOffsetParagraph = aWordProcessor.NumOfParagraphsToSearch - 1; // how many paragraphs ahead we have to look for a match - int nEndRangeToSearch = -1; // might change from loop to loop if we do replacements (so update inside loop) - object nOffsetParagraph = aWordProcessor.NumOfParagraphsToSearch - 1; + int nEndRangeToSearch; do { SearchAreaStart = aRunRange.Start; diff --git a/src/SILConvertersOffice/FontConvertersPicker.cs b/src/SILConvertersOffice/FontConvertersPicker.cs index 4176deeb..ad06e546 100644 --- a/src/SILConvertersOffice/FontConvertersPicker.cs +++ b/src/SILConvertersOffice/FontConvertersPicker.cs @@ -14,15 +14,26 @@ using System.Collections; using System.IO; // FileStream using System.Runtime.Serialization; // for SerializationException +using System.Xml.Linq; +using System.Linq; +#if BUILD_FOR_OFF11 +using SILConvertersOffice.Properties; +#elif BUILD_FOR_OFF12 +using SILConvertersOffice07.Properties; +#elif BUILD_FOR_OFF14 +using SILConvertersOffice10.Properties; +#elif BUILD_FOR_OFF15 +using SILConvertersOffice13.Properties; +#endif namespace SILConvertersOffice { internal partial class FontConvertersPicker : Form { - private OfficeDocument m_doc = null; - protected DirectableEncConverter m_aECForAll = null; - protected DirectableEncConverter m_aECLast = null; - protected Hashtable m_mapEncConverters = new Hashtable(); + private OfficeDocument m_doc; + protected DirectableEncConverter m_aECForAll; + protected DirectableEncConverter m_aECLast; + protected Hashtable m_mapEncConverters = new(); protected const int nMaxRecentFiles = 15; const int nColumnFontNames = 0; @@ -33,7 +44,7 @@ internal partial class FontConvertersPicker : Form protected const string cstrClickMsg = "Select a converter"; protected const string cstrFontClickMsg = "Select a font to apply"; protected const string cstrApplyECFormat = "Apply '{0}'?"; - protected string m_strApplyEC = null; + protected string m_strApplyEC; /// /// FontConvertersPicker: to choose the font you want to process in the Word document @@ -50,10 +61,10 @@ public FontConvertersPicker(OfficeDocument doc) protected void InsureSettings() { // make sure we have the collection around so we don't have to check it later - if (Properties.Settings.Default.ConverterMappingRecentFiles == null) + if (Settings.Default.ConverterMappingRecentFiles == null) { - Properties.Settings.Default.ConverterMappingRecentFiles = new System.Collections.Specialized.StringCollection(); - Properties.Settings.Default.Save(); + Settings.Default.ConverterMappingRecentFiles = new System.Collections.Specialized.StringCollection(); + Settings.Default.Save(); } } @@ -111,7 +122,7 @@ protected void PopulateGrid() ResetBackgroundWorker(); // just in case dataGridViewFontsConverters.Rows.Clear(); - + // check the check box state which says whether we do "all fonts" or just those in the document if (checkBoxFontsInUse.Checked) { @@ -120,9 +131,11 @@ protected void PopulateGrid() // Office 2007 (what I'm calling build 4518) doesn't allow background workers to run while a // modal dialog is visible. So do it inline. - if ( ((m_doc.GetType() != typeof(PubDocument)) && (m_doc.GetType() != typeof(PubStoryDocument))) - || ((PubDocument)m_doc).Document.Application.Version.Substring(0,2) == "11") + if (((m_doc.GetType() != typeof(PubDocument)) && (m_doc.GetType() != typeof(PubStoryDocument))) + || ((PubDocument)m_doc).Document.Application.Version.Substring(0, 2) == "11") + { backgroundWorker.RunWorkerAsync(m_doc); + } else { DoWork(backgroundWorker, m_doc); @@ -130,8 +143,20 @@ protected void PopulateGrid() } } else - foreach (FontFamily aFontFamily in new InstalledFontCollection().Families) - AddRow(aFontFamily.Name); + { + if (m_doc is WordDocument wordDoc) + { + var xdoc = wordDoc.XDocument; + var fonts = xdoc.Descendants().First(n => n.Name.LocalName == "fonts").Elements().Where(n => n.Name.LocalName == "font"); + var fontNames = fonts.Select(f => f.Attributes().First(a => a.Name.LocalName == "name").Value); + fontNames.Distinct().ToList().ForEach(fn => AddRow(fn)); + } + else + { + foreach (FontFamily aFontFamily in new InstalledFontCollection().Families) + AddRow(aFontFamily.Name); + } + } } protected bool IsTargetFontDefined(string strFontNameOutput) @@ -159,7 +184,7 @@ protected void InitConverterDetails(string strFontName, out string strConverterN if (aIEC != null) { - DirectableEncConverter aEC = new DirectableEncConverter(aIEC); + var aEC = new DirectableEncConverter(aIEC); m_mapEncConverters.Add(strFontName, aEC); } } @@ -168,7 +193,7 @@ protected void InitConverterDetails(string strFontName, out string strConverterN if (m_mapEncConverters.ContainsKey(strFontName)) { - DirectableEncConverter aEC = (DirectableEncConverter)m_mapEncConverters[strFontName]; + var aEC = (DirectableEncConverter)m_mapEncConverters[strFontName]; strConverterName = aEC.Name; strTooltip = aEC.ToString(); if (aEC.TargetFont != null) @@ -193,8 +218,7 @@ protected void InitConverterDetails(string strFontName, out string strConverterN protected void AddRow(string strFontName) { - string strConverterName, strTooltip, strFontNameOutput; - InitConverterDetails(strFontName, out strConverterName, out strTooltip, out strFontNameOutput); + InitConverterDetails(strFontName, out string strConverterName, out string strTooltip, out string strFontNameOutput); string[] row = { strFontName, strConverterName, strFontNameOutput }; int nIndex = dataGridViewFontsConverters.Rows.Add(row); @@ -206,19 +230,21 @@ public FontConverters SelectedFontConverters { get { - FontConverters aFCs = new FontConverters(); + FontConverters aFCs = new(); foreach (string strFontName in m_mapEncConverters.Keys) { DirectableEncConverter aIEC = (DirectableEncConverter)m_mapEncConverters[strFontName]; - FontConverter aFC = new FontConverter(strFontName, aIEC); - aFC.RhsFont = aIEC.TargetFont; + var aFC = new FontConverter(strFontName, aIEC) + { + RhsFont = aIEC.TargetFont + }; aFCs.Add(strFontName, aFC); } return aFCs; } } - private void buttonOK_Click(object sender, EventArgs e) + private void ButtonOK_Click(object sender, EventArgs e) { if (m_mapEncConverters.Count > 0) { @@ -229,7 +255,7 @@ private void buttonOK_Click(object sender, EventArgs e) MessageBox.Show("You must choose at least one converter (or click Cancel)", OfficeApp.cstrCaption); } - private void checkBoxFontsInUse_CheckedChanged(object sender, EventArgs e) + private void CheckBoxFontsInUse_CheckedChanged(object sender, EventArgs e) { PopulateGrid(); } @@ -245,7 +271,7 @@ private void ResetBackgroundWorker() this.backgroundWorker.CancelAsync(); } - private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) + private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { DoWork(sender as BackgroundWorker, e.Argument as OfficeDocument); } @@ -261,7 +287,7 @@ protected void DoWork(BackgroundWorker worker, OfficeDocument doc) nWordCount = 0; } */ - FontNamesInUseProcessor aDocumentProcess = new FontNamesInUseProcessor(nWordCount, worker); + var aDocumentProcess = new FontNamesInUseProcessor(nWordCount, worker); try { @@ -273,29 +299,28 @@ protected void DoWork(BackgroundWorker worker, OfficeDocument doc) } } - private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) + private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // for us the "progress" is a new font found (if not null) if (e.UserState != null) { - string[] aStrs = (string[])e.UserState; + var aStrs = (string[])e.UserState; System.Diagnostics.Debug.Assert(aStrs.Length == 2); - string strFontName = aStrs[0]; - string strWord = aStrs[1]; // in case we want to + var strFontName = aStrs[0]; AddRow(strFontName); } else progressBarFontsInUse.PerformStep(); } - private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) MessageBox.Show(e.Error.Message, OfficeApp.cstrCaption); progressBarFontsInUse.Visible = false; } - private void setDefaultConverterToolStripMenuItem_Click(object sender, EventArgs e) + private void SetDefaultConverterToolStripMenuItem_Click(object sender, EventArgs e) { EncConverters aECs = OfficeApp.GetEncConverters; if (aECs != null) @@ -303,7 +328,7 @@ private void setDefaultConverterToolStripMenuItem_Click(object sender, EventArgs IEncConverter aIEC = aECs.AutoSelectWithTitle(ConvType.Unknown, "Select Default Converter"); if (aIEC != null) { - DirectableEncConverter aEC = new DirectableEncConverter(aIEC.Name, aIEC.DirectionForward, aIEC.NormalizeOutput); + var aEC = new DirectableEncConverter(aIEC.Name, aIEC.DirectionForward, aIEC.NormalizeOutput); foreach (DataGridViewRow aRow in dataGridViewFontsConverters.Rows) { string strFontName = (string)aRow.Cells[nColumnFontNames].Value; @@ -327,8 +352,7 @@ private void UpdateConverterNames() foreach (DataGridViewRow aRow in dataGridViewFontsConverters.Rows) { string strFontname = (string)aRow.Cells[nColumnFontNames].Value; - string strConverterName, strTooltip, strFontNameOutput; - InitConverterDetails(strFontname, out strConverterName, out strTooltip, out strFontNameOutput); + InitConverterDetails(strFontname, out string strConverterName, out string strTooltip, out string strFontNameOutput); DataGridViewCell cell = aRow.Cells[nColumnConverterNames]; cell.Value = strConverterName; cell.ToolTipText = strTooltip; @@ -336,18 +360,20 @@ private void UpdateConverterNames() } } - private void newConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) + private void NewConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) { m_mapEncConverters.Clear(); UpdateConverterNames(); } - private void openConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) + private void OpenConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) { - OpenFileDialog dlgSettings = new OpenFileDialog(); - dlgSettings.DefaultExt = "fcm"; - dlgSettings.InitialDirectory = OfficeApp.GetAppDataDir; - dlgSettings.Filter = "Font Converter mapping files (*.fcm)|*.fcm|All files|*.*"; + var dlgSettings = new OpenFileDialog + { + DefaultExt = "fcm", + InitialDirectory = OfficeApp.GetAppDataDir, + Filter = "Font Converter mapping files (*.fcm)|*.fcm|All files|*.*" + }; if (dlgSettings.ShowDialog() == DialogResult.OK) { @@ -358,15 +384,17 @@ private void openConverterMappingToolStripMenuItem_Click(object sender, EventArg protected void LoadMappingFile(string strFilename) { m_mapEncConverters = null; - FileStream fs = new FileStream(strFilename, FileMode.Open); + var fs = new FileStream(strFilename, FileMode.Open); // Construct a SoapFormatter and use it // to serialize the data to the stream. try { - SoapFormatter formatter = new SoapFormatter(); - formatter.Binder = new DirectableEncConverterDeserializationBinder(); - formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; + SoapFormatter formatter = new() + { + Binder = new DirectableEncConverterDeserializationBinder(), + AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple + }; m_mapEncConverters = (Hashtable)formatter.Deserialize(fs); AddToConverterMappingRecentlyUsed(strFilename); } @@ -383,11 +411,13 @@ protected void LoadMappingFile(string strFilename) UpdateConverterNames(); } - private void saveConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) + private void SaveConverterMappingToolStripMenuItem_Click(object sender, EventArgs e) { - SaveFileDialog dlgSettings = new SaveFileDialog(); - dlgSettings.DefaultExt = "fcm"; - dlgSettings.FileName = "Font Converter mapping1.fcm"; + SaveFileDialog dlgSettings = new() + { + DefaultExt = "fcm", + FileName = "Font Converter mapping1.fcm" + }; if (!Directory.Exists(OfficeApp.GetAppDataDir)) Directory.CreateDirectory(OfficeApp.GetAppDataDir); dlgSettings.InitialDirectory = OfficeApp.GetAppDataDir; @@ -396,8 +426,8 @@ private void saveConverterMappingToolStripMenuItem_Click(object sender, EventArg { // Construct a SoapFormatter and use it // to serialize the data to the stream. - FileStream fs = new FileStream(dlgSettings.FileName, FileMode.Create); - SoapFormatter formatter = new SoapFormatter(); + var fs = new FileStream(dlgSettings.FileName, FileMode.Create); + var formatter = new SoapFormatter(); try { formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple; @@ -415,7 +445,7 @@ private void saveConverterMappingToolStripMenuItem_Click(object sender, EventArg } } - private void dataGridViewFontsConverters_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) + private void DataGridViewFontsConverters_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e) { int nColumnIndex = e.ColumnIndex; // if the user clicks on the header... that doesn't work @@ -515,16 +545,16 @@ public void AddToConverterMappingRecentlyUsed(string strFilename) System.Diagnostics.Debug.Assert(!String.IsNullOrEmpty(strFilename)); // add this filename to the list of recently used files - if (Properties.Settings.Default.ConverterMappingRecentFiles.Contains(strFilename)) - Properties.Settings.Default.ConverterMappingRecentFiles.Remove(strFilename); - else if (Properties.Settings.Default.ConverterMappingRecentFiles.Count > nMaxRecentFiles) - Properties.Settings.Default.ConverterMappingRecentFiles.RemoveAt(nMaxRecentFiles); + if (Settings.Default.ConverterMappingRecentFiles.Contains(strFilename)) + Settings.Default.ConverterMappingRecentFiles.Remove(strFilename); + else if (Settings.Default.ConverterMappingRecentFiles.Count > nMaxRecentFiles) + Settings.Default.ConverterMappingRecentFiles.RemoveAt(nMaxRecentFiles); - Properties.Settings.Default.ConverterMappingRecentFiles.Insert(0, strFilename); - Properties.Settings.Default.Save(); + Settings.Default.ConverterMappingRecentFiles.Insert(0, strFilename); + Settings.Default.Save(); } - private void recentFilesToolStripMenuItem_Click(object sender, EventArgs e) + private void RecentFilesToolStripMenuItem_Click(object sender, EventArgs e) { ToolStripDropDownItem aRecentFile = (ToolStripDropDownItem)sender; try @@ -536,12 +566,12 @@ private void recentFilesToolStripMenuItem_Click(object sender, EventArgs e) catch (Exception ex) { // probably means the file doesn't exist anymore, so remove it from the recent used list - Properties.Settings.Default.ConverterMappingRecentFiles.Remove(aRecentFile.Text); + Settings.Default.ConverterMappingRecentFiles.Remove(aRecentFile.Text); MessageBox.Show(ex.Message, OfficeApp.cstrCaption); } } - private void converterMappingToolStripMenuItem_DropDownOpening(object sender, EventArgs e) + private void ConverterMappingToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { bool bMappingsExist = (m_mapEncConverters.Count > 0); this.newConverterMappingToolStripMenuItem.Enabled = bMappingsExist; @@ -550,8 +580,8 @@ private void converterMappingToolStripMenuItem_DropDownOpening(object sender, Ev this.setDefaultConverterToolStripMenuItem.Enabled = bRowsExist; recentToolStripMenuItem.DropDownItems.Clear(); - foreach (string strRecentFile in Properties.Settings.Default.ConverterMappingRecentFiles) - recentToolStripMenuItem.DropDownItems.Add(strRecentFile, null, recentFilesToolStripMenuItem_Click); + foreach (string strRecentFile in Settings.Default.ConverterMappingRecentFiles) + recentToolStripMenuItem.DropDownItems.Add(strRecentFile, null, RecentFilesToolStripMenuItem_Click); recentToolStripMenuItem.Enabled = (recentToolStripMenuItem.DropDownItems.Count > 0); } } @@ -561,22 +591,22 @@ private void converterMappingToolStripMenuItem_DropDownOpening(object sender, Ev /// internal class FontNamesInUseProcessor : OfficeDocumentProcessor { - BackgroundWorker m_worker = null; // who we send updates to - List m_astrListFontNames = new List(); + readonly BackgroundWorker m_worker; // who we send updates to + readonly List m_astrListFontNames = new(); int m_nCount = 0; - int m_nModulo = 10; + readonly int m_nModulo = 10; const int cnNumSteps = 50; public FontNamesInUseProcessor(int nDocumentWordCount, BackgroundWorker worker) { - Process = myWordProcessor; + Process = MyWordProcessor; // get a rough estimate of the number of words in the document m_nModulo = (nDocumentWordCount == 0) ? 0 : Math.Max(nDocumentWordCount / cnNumSteps, 2); m_worker = worker; } - protected bool myWordProcessor(OfficeRange aWordRange, ref int nCharIndex) + protected bool MyWordProcessor(OfficeRange aWordRange, ref int nCharIndex) { if (m_worker.CancellationPending) return false; diff --git a/src/SILConvertersOffice/FontConvertersPicker.designer.cs b/src/SILConvertersOffice/FontConvertersPicker.designer.cs index 390b6a42..b62849c3 100644 --- a/src/SILConvertersOffice/FontConvertersPicker.designer.cs +++ b/src/SILConvertersOffice/FontConvertersPicker.designer.cs @@ -60,7 +60,7 @@ private void InitializeComponent() this.buttonOK.TabIndex = 1; this.buttonOK.Text = "OK"; this.buttonOK.UseVisualStyleBackColor = true; - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); // // buttonCancel // @@ -85,15 +85,15 @@ private void InitializeComponent() this.checkBoxFontsInUse.TabIndex = 3; this.checkBoxFontsInUse.Text = "&Limit to fonts in use"; this.checkBoxFontsInUse.UseVisualStyleBackColor = true; - this.checkBoxFontsInUse.CheckedChanged += new System.EventHandler(this.checkBoxFontsInUse_CheckedChanged); + this.checkBoxFontsInUse.CheckedChanged += new System.EventHandler(this.CheckBoxFontsInUse_CheckedChanged); // // backgroundWorker // this.backgroundWorker.WorkerReportsProgress = true; this.backgroundWorker.WorkerSupportsCancellation = true; - this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork); - this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted); - this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_ProgressChanged); + this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker_DoWork); + this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted); + this.backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.BackgroundWorker_ProgressChanged); // // dataGridViewFontsConverters // @@ -113,7 +113,7 @@ private void InitializeComponent() this.dataGridViewFontsConverters.RowHeadersVisible = false; this.dataGridViewFontsConverters.Size = new System.Drawing.Size(425, 319); this.dataGridViewFontsConverters.TabIndex = 4; - this.dataGridViewFontsConverters.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridViewFontsConverters_CellMouseClick); + this.dataGridViewFontsConverters.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DataGridViewFontsConverters_CellMouseClick); // // ColumnFontNames // @@ -164,7 +164,7 @@ private void InitializeComponent() this.converterMappingToolStripMenuItem.Name = "converterMappingToolStripMenuItem"; this.converterMappingToolStripMenuItem.Size = new System.Drawing.Size(116, 20); this.converterMappingToolStripMenuItem.Text = "&Converter Mappings"; - this.converterMappingToolStripMenuItem.DropDownOpening += new System.EventHandler(this.converterMappingToolStripMenuItem_DropDownOpening); + this.converterMappingToolStripMenuItem.DropDownOpening += new System.EventHandler(this.ConverterMappingToolStripMenuItem_DropDownOpening); // // setDefaultConverterToolStripMenuItem // @@ -172,7 +172,7 @@ private void InitializeComponent() this.setDefaultConverterToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.setDefaultConverterToolStripMenuItem.Text = "Set &Default Converter"; this.setDefaultConverterToolStripMenuItem.ToolTipText = "Select a converter to be applied to all fonts that aren\'t currently configured"; - this.setDefaultConverterToolStripMenuItem.Click += new System.EventHandler(this.setDefaultConverterToolStripMenuItem_Click); + this.setDefaultConverterToolStripMenuItem.Click += new System.EventHandler(this.SetDefaultConverterToolStripMenuItem_Click); // // toolStripSeparator1 // @@ -185,7 +185,7 @@ private void InitializeComponent() this.newConverterMappingToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.newConverterMappingToolStripMenuItem.Text = "&New"; this.newConverterMappingToolStripMenuItem.ToolTipText = "Click to reset the current mapping of font names to system converters"; - this.newConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.newConverterMappingToolStripMenuItem_Click); + this.newConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.NewConverterMappingToolStripMenuItem_Click); // // openConverterMappingToolStripMenuItem // @@ -193,7 +193,7 @@ private void InitializeComponent() this.openConverterMappingToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.openConverterMappingToolStripMenuItem.Text = "&Load"; this.openConverterMappingToolStripMenuItem.ToolTipText = "Click to load a previously saved mapping of font names to system converters"; - this.openConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.openConverterMappingToolStripMenuItem_Click); + this.openConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.OpenConverterMappingToolStripMenuItem_Click); // // recentToolStripMenuItem // @@ -207,7 +207,7 @@ private void InitializeComponent() this.saveConverterMappingToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.saveConverterMappingToolStripMenuItem.Text = "&Save"; this.saveConverterMappingToolStripMenuItem.ToolTipText = "Click to save the current mapping of font names to system converters"; - this.saveConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.saveConverterMappingToolStripMenuItem_Click); + this.saveConverterMappingToolStripMenuItem.Click += new System.EventHandler(this.SaveConverterMappingToolStripMenuItem_Click); // // progressBarFontsInUse // diff --git a/src/SILConvertersOffice/ManagedAggregator/SecOffice_ManagedAggregator03.csproj b/src/SILConvertersOffice/ManagedAggregator/SecOffice_ManagedAggregator03.csproj index ad3d215f..47eacf59 100644 --- a/src/SILConvertersOffice/ManagedAggregator/SecOffice_ManagedAggregator03.csproj +++ b/src/SILConvertersOffice/ManagedAggregator/SecOffice_ManagedAggregator03.csproj @@ -58,7 +58,7 @@ DEBUG;TRACE full x64 - 7.3 + latest prompt MinimumRecommendedRules.ruleset false @@ -69,7 +69,7 @@ true pdbonly x86 - 7.3 + latest prompt MinimumRecommendedRules.ruleset false diff --git a/src/SILConvertersOffice/OfficeApp.cs b/src/SILConvertersOffice/OfficeApp.cs index 8125f16a..b32dde1d 100644 --- a/src/SILConvertersOffice/OfficeApp.cs +++ b/src/SILConvertersOffice/OfficeApp.cs @@ -105,7 +105,7 @@ internal static void LaunchProgram(string strProgram, string strArguments) { try { - Process myProcess = new Process { StartInfo = { FileName = strProgram, Arguments = strArguments } }; + Process myProcess = new() { StartInfo = { FileName = strProgram, Arguments = strArguments } }; myProcess.Start(); } catch { } // we tried... @@ -145,7 +145,6 @@ internal static void ReleaseComObject(object obj) } finally { - obj = null; } } @@ -231,8 +230,7 @@ public virtual int EndIndex // not working for publisher public virtual void Select() { - if( m_typeRange != null ) - m_typeRange.InvokeMember("Select", BindingFlags.InvokeMethod, null, m_aRangeBasedOn, null); + m_typeRange?.InvokeMember("Select", BindingFlags.InvokeMethod, null, m_aRangeBasedOn, null); } public abstract string Text @@ -252,16 +250,14 @@ public virtual string FontName set { object font = GetProperty("Font"); - if( m_typeRange != null ) - m_typeRange.InvokeMember("Name", BindingFlags.SetProperty, null, font, new object[] { value }); + m_typeRange?.InvokeMember("Name", BindingFlags.SetProperty, null, font, new object[] { value }); } } protected void SetProperty(string strPropertyName, object value) { System.Diagnostics.Debug.Assert(m_aRangeBasedOn != null); - if( m_typeRange != null ) - m_typeRange.InvokeMember(strPropertyName, BindingFlags.SetProperty, null, m_aRangeBasedOn, new object[] { value }); + m_typeRange?.InvokeMember(strPropertyName, BindingFlags.SetProperty, null, m_aRangeBasedOn, new object[] { value }); } protected object GetProperty(string strPropertyName) @@ -487,7 +483,7 @@ internal class OfficeDocumentProcessor public delegate bool ProcessWord(OfficeRange aWordRange, ref int nCharIndex); private ProcessWord m_aWordProcessor = null; protected FontConverters m_mapFontsEncountered = null; - protected Dictionary m_mapCheckedInputStrings = new Dictionary(); + protected Dictionary m_mapCheckedInputStrings = new(); protected FontConverter m_aFC = null; protected FontConverters m_aFCs = null; protected IBaseConverterForm m_formDisplayValues = null; @@ -626,7 +622,7 @@ protected virtual FormButtons ConvertProcessing(OfficeRange aWordRange, FontConv public bool CompareInputOutputProcess(OfficeRange aWordRange, ref int nCharIndex) { - FormButtons res = FormButtons.None; + FormButtons res; do { string strInput = aWordRange.Text; @@ -658,8 +654,7 @@ public bool CompareInputOutputProcess(OfficeRange aWordRange, ref int nCharIndex } // see if we've already checked this word - string strReplace = null; - if (!m_mapCheckedInputStrings.TryGetValue(strInput, out strReplace)) + if (!m_mapCheckedInputStrings.TryGetValue(strInput, out string strReplace)) { res = ConvertProcessing(aWordRange, aThisFC, strInput, ref strReplace); @@ -695,7 +690,7 @@ public bool CompareInputOutputProcess(OfficeRange aWordRange, ref int nCharIndex protected virtual FontConverter QueryForFontConvert(string strFontName) { FontConverter aFC = null; - FontConvertersPicker aFontConverterPicker = new FontConvertersPicker(strFontName); + FontConvertersPicker aFontConverterPicker = new(strFontName); if (aFontConverterPicker.ShowDialog() == DialogResult.OK) aFC = aFontConverterPicker.SelectedFontConverters[strFontName]; return aFC; @@ -707,8 +702,7 @@ protected FontConverter QueryUserForFontScan(string strFontName) return null; // make sure our collection exists - if (m_mapFontsEncountered == null) - m_mapFontsEncountered = new FontConverters(); + m_mapFontsEncountered ??= new FontConverters(); if (!m_mapFontsEncountered.ContainsKey(strFontName)) { diff --git a/src/SILConvertersOffice/Properties/Settings.Designer.cs b/src/SILConvertersOffice/Properties/Settings.Designer.cs index c5906302..8bbc3893 100644 --- a/src/SILConvertersOffice/Properties/Settings.Designer.cs +++ b/src/SILConvertersOffice/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace SILConvertersOffice.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -55,5 +55,41 @@ public static Settings Default { this["ConverterMappingRecentFiles"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Normal")] + public global::System.Windows.Forms.FormWindowState DefaultWindowState { + get { + return ((global::System.Windows.Forms.FormWindowState)(this["DefaultWindowState"])); + } + set { + this["DefaultWindowState"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] + public global::System.Drawing.Point WindowLocation { + get { + return ((global::System.Drawing.Point)(this["WindowLocation"])); + } + set { + this["WindowLocation"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("800, 450")] + public global::System.Drawing.Size WindowSize { + get { + return ((global::System.Drawing.Size)(this["WindowSize"])); + } + set { + this["WindowSize"] = value; + } + } } } diff --git a/src/SILConvertersOffice/Properties/Settings.settings b/src/SILConvertersOffice/Properties/Settings.settings index 850ac784..8c9100ea 100644 --- a/src/SILConvertersOffice/Properties/Settings.settings +++ b/src/SILConvertersOffice/Properties/Settings.settings @@ -11,5 +11,14 @@ + + Normal + + + 0, 0 + + + 800, 450 + \ No newline at end of file diff --git a/src/SILConvertersOffice/PubApp.cs b/src/SILConvertersOffice/PubApp.cs index 5152ea87..577cd716 100644 --- a/src/SILConvertersOffice/PubApp.cs +++ b/src/SILConvertersOffice/PubApp.cs @@ -65,10 +65,6 @@ public override void LoadMenu() "Click this item to convert the selected text only", new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(SelectionConvert_Click)); - AddMenu(ref ResetMenuBtn, NewMenuBar, "&Reset", - "Reset the unfinished conversion processes", - new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(Reset_Click)); - AddMenu(ref ConvertParagraphsIsoFormatMenu, NewMenuBar, "Convert by ¶graph (iso formatted)", "Click this item to convert the document from the cursor on down, paragraph-by-paragraph, but in chunks that keep the formatting the same (which might ruin the Translation if using Bing or DeepL translators)", new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(ConvertParagraphs_Click)); @@ -76,6 +72,10 @@ public override void LoadMenu() AddMenu(ref ConvertParagraphsMenu, NewMenuBar, "Convert by paragraph", "Click this item to convert the document from the cursor on down, paragraph-by-paragraph, ignoring formatting (so formatting will be lost, but you'll get whole paragraphs translated as a unit)", new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(ConvertParagraphs_IgnoreStyle_Click)); + + AddMenu(ref ResetMenuBtn, NewMenuBar, "&Reset", + "Reset the unfinished conversion processes", + new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(Reset_Click)); } catch (Exception ex) { @@ -295,7 +295,7 @@ private void ParagraphByParagraph(OfficeTextDocument.ProcessingType eIsoFormatte return; PubRangeDocument doc = new PubRangeDocument(Application.ActiveDocument, eIsoFormattedRun); - OfficeDocumentProcessor aSelectionProcessor = GetDocumentProcessor((FontConverters)null, new SILConvertersOffice.TranslationHelperForm()); + OfficeDocumentProcessor aSelectionProcessor = GetDocumentProcessor((FontConverters)null, new SILConvertersOffice.TranslationHelperForms()); if (aSelectionProcessor != null) doc.ProcessWordByWord(aSelectionProcessor, OfficeTextDocument.ProcessingType.eIsoFormattedRun); diff --git a/src/SILConvertersOffice/SILConvertersOffice.csproj b/src/SILConvertersOffice/SILConvertersOffice.csproj index 47fc0f92..824a24d9 100644 --- a/src/SILConvertersOffice/SILConvertersOffice.csproj +++ b/src/SILConvertersOffice/SILConvertersOffice.csproj @@ -1,6 +1,6 @@  - + Debug x86 @@ -44,10 +44,11 @@ ..\..\output\x86\Release\ - TRACE + TRACE;BUILD_FOR_OFF11 true false x86 + latest true GlobalSuppressions.cs AllRules.ruleset @@ -56,9 +57,10 @@ true ..\..\output\x86\Debug\ - DEBUG;TRACE + TRACE;DEBUG;BUILD_FOR_OFF11 false x86 + latest true GlobalSuppressions.cs AllRules.ruleset @@ -66,18 +68,18 @@ ..\..\output\x64\Release\ - TRACE + TRACE;BUILD_FOR_OFF11 true x64 - 7.3 + latest AllRules.ruleset true ..\..\output\x64\Debug\ - DEBUG;TRACE + TRACE;DEBUG;BUILD_FOR_OFF11 x64 - 7.3 + latest AllRules.ruleset @@ -91,6 +93,8 @@ False DistFiles\DAO.DLL + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -144,6 +148,7 @@ System.XML.dll System.XML + @@ -186,9 +191,7 @@ - - Form - + TranslationHelperForm.cs @@ -313,6 +316,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/SILConvertersOffice/TranslationHelperForm.Designer.cs b/src/SILConvertersOffice/TranslationHelperForm.Designer.cs index 7081e6cb..2df444ef 100644 --- a/src/SILConvertersOffice/TranslationHelperForm.Designer.cs +++ b/src/SILConvertersOffice/TranslationHelperForm.Designer.cs @@ -1,4 +1,6 @@  +using System; + namespace SILConvertersOffice { partial class TranslationHelperForm @@ -38,12 +40,16 @@ private void InitializeComponent() this.backTranslationHelperCtrl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + // if you edit the form (e.g. to add a control), then the designer auto coding will change this "AutoSize = false" + // to (possibly true) and add an 'AutoSizeMode = GrowAndShrink'... but this will cause the embedded control to + // stop showing properly. It *must* be AutoSize = false. (keep this comment here too, so the next person sees it too) + // (I'm not sure if it's specifically necessary, but you might need to restore the PerformLayout at the bottom, + // which the editing of the form will remove too) this.backTranslationHelperCtrl.AutoSize = false; this.backTranslationHelperCtrl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.backTranslationHelperCtrl.Dock = System.Windows.Forms.DockStyle.Fill; this.backTranslationHelperCtrl.Location = new System.Drawing.Point(0, 0); this.backTranslationHelperCtrl.Name = "backTranslationHelperCtrl"; - this.backTranslationHelperCtrl.NewTargetTexts = ((System.Collections.Generic.List)(resources.GetObject("backTranslationHelperCtrl.NewTargetTexts"))); this.backTranslationHelperCtrl.Size = new System.Drawing.Size(790, 449); this.backTranslationHelperCtrl.TabIndex = 0; // @@ -56,6 +62,7 @@ private void InitializeComponent() this.Controls.Add(this.backTranslationHelperCtrl); this.Name = "TranslationHelperForm"; this.Text = "Back Translating from {0} - {1}"; + this.Load += new System.EventHandler(this.TranslationHelperForm_Load); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.TranslationHelperForm_FormClosing); this.ResumeLayout(false); this.PerformLayout(); diff --git a/src/SILConvertersOffice/TranslationHelperForm.cs b/src/SILConvertersOffice/TranslationHelperForm.cs index 7fe9c4b9..4d5a7902 100644 --- a/src/SILConvertersOffice/TranslationHelperForm.cs +++ b/src/SILConvertersOffice/TranslationHelperForm.cs @@ -6,10 +6,58 @@ using System.Drawing; using System.Linq; using System.Windows.Forms; +#if BUILD_FOR_OFF11 +using SILConvertersOffice.Properties; +#elif BUILD_FOR_OFF12 +using SILConvertersOffice07.Properties; +#elif BUILD_FOR_OFF14 +using SILConvertersOffice10.Properties; +#elif BUILD_FOR_OFF15 +using SILConvertersOffice13.Properties; +#endif namespace SILConvertersOffice { - internal partial class TranslationHelperForm : Form, IBaseConverterForm, IBackTranslationHelperDataSource + /// + /// each project (read: font and converter combination) needs its own TranslationHelperForm + /// so it can manage things like its own SpellFixer and set of EncConverters to use. So use + /// this class (w/ an 's') to triangulate between the different instances of it based on the + /// requested FontConverter + /// + internal class TranslationHelperForms : IBaseConverterForm + { + private static TranslationHelperForm _current; + private Dictionary Forms = new Dictionary(); + + bool IBaseConverterForm.SkipIdenticalValues => false; // this was a feature for checking round-tripping, which doesn't apply here + + string IBaseConverterForm.ForwardString + { + get + { + return _current?.ForwardString; + } + + set + { + _current.ForwardString = value; + } + } + + FormButtons IBaseConverterForm.Show(FontConverter aThisFC, string strInput, string strOutput) + { + if (!Forms.TryGetValue(aThisFC, out var form)) + { + form = new TranslationHelperForm(); + } + + _current = form; + + return _current.Show(aThisFC, strInput, strOutput); + } + } + + internal partial class TranslationHelperForm : Form, IBackTranslationHelperDataSource { protected FontConverter _theFontsAndEncConverter; protected BackTranslationHelperModel _model; @@ -21,14 +69,12 @@ public TranslationHelperForm() InitializeComponent(); } - bool IBaseConverterForm.SkipIdenticalValues => false; // this was a feature for checking round-tripping, which doesn't apply here - - string IBaseConverterForm.ForwardString + public string ForwardString { get { // TODO: fix this - return backTranslationHelperCtrl.NewTargetTexts.FirstOrDefault()?.TargetData; + return backTranslationHelperCtrl.GetNewTargetTexts().FirstOrDefault()?.TargetData; } set @@ -42,7 +88,7 @@ string IBaseConverterForm.ForwardString } } - FormButtons IBaseConverterForm.Show(FontConverter fontConverter, string sourceText, string targetText) + public FormButtons Show(FontConverter fontConverter, string sourceText, string targetText) { WordApp.SetCursorToWaiting(); ButtonPressed = FormButtons.Cancel; // reset and be pessimistic @@ -64,13 +110,17 @@ FormButtons IBaseConverterForm.Show(FontConverter fontConverter, string sourceTe }, }; - // this form is the implementation of the way to get get data + // this form is the implementation of the way to get data backTranslationHelperCtrl.BackTranslationHelperDataSource = this; if (!backTranslationHelperCtrl.TheTranslators.Any(t => t.Name == _theFontsAndEncConverter.DirectableEncConverter.GetEncConverter.Name)) backTranslationHelperCtrl.TheTranslators.Add(_theFontsAndEncConverter.DirectableEncConverter.GetEncConverter); backTranslationHelperCtrl.Initialize(displayExistingTargetTranslation: false); + // If Initialize sets the possible target boxes (more than the 1st one) to Visible, + // for some reason, it's not changing its state... Try this: + Application.DoEvents(); + // TODO: fix this backTranslationHelperCtrl.GetNewData(ref _model); _updateDataProc(_model); @@ -95,10 +145,11 @@ public void Log(string message) // TODO: } - public void WriteToTarget(string text) + public bool WriteToTarget(string text) { ButtonPressed = FormButtons.ReplaceEvery; Close(); + return true; } public void SetDataUpdateProc(Action updateDataProc) @@ -169,6 +220,17 @@ void IBackTranslationHelperDataSource.Cancel() Close(); } + private void TranslationHelperForm_Load(object sender, EventArgs e) + { + Location = Settings.Default.WindowLocation; + WindowState = Settings.Default.DefaultWindowState; + if (MinimumSize.Height <= Settings.Default.WindowSize.Height && + MinimumSize.Width <= Settings.Default.WindowSize.Width) + { + Size = Settings.Default.WindowSize; + } + } + private void TranslationHelperForm_FormClosing(object sender, FormClosingEventArgs e) { // only allow Cancel or ReplaceEvery @@ -177,6 +239,11 @@ private void TranslationHelperForm_FormClosing(object sender, FormClosingEventAr (ButtonPressed != FormButtons.Cancel) && (ButtonPressed != FormButtons.Next)) e.Cancel = true; + + Settings.Default.DefaultWindowState = WindowState; + Settings.Default.WindowLocation = Location; + Settings.Default.WindowSize = Size; + Settings.Default.Save(); } void IBackTranslationHelperDataSource.ButtonPressed(ButtonPressed button) @@ -188,10 +255,8 @@ void IBackTranslationHelperDataSource.ButtonPressed(ButtonPressed button) switch(button.ToString()) { case "MoveToNext": - ButtonPressed = FormButtons.Next; - break; case "WriteToTarget": - ButtonPressed = FormButtons.ReplaceOnce; + ButtonPressed = FormButtons.ReplaceOnce; // these both mean replace break; case "Cancel": ButtonPressed = FormButtons.Cancel; diff --git a/src/SILConvertersOffice/TranslationHelperForm.resx b/src/SILConvertersOffice/TranslationHelperForm.resx index de129925..1af7de15 100644 --- a/src/SILConvertersOffice/TranslationHelperForm.resx +++ b/src/SILConvertersOffice/TranslationHelperForm.resx @@ -117,20 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AAEAAAD/////AQAAAAAAAAAMAgAAAKcBQmFja1RyYW5zbGF0aW9uSGVscGVyLCBWZXJzaW9uPTEuMC4w - LjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49ZjE0NDdiYWUxZTYzZjQ4NV1dLCBtc2Nv - cmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1 - YzU2MTkzNGUwODkMAwAAAFhCYWNrVHJhbnNsYXRpb25IZWxwZXIsIFZlcnNpb249MS4wLjAuMCwgQ3Vs - dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1mMTQ0N2JhZTFlNjNmNDg1BQEAAABHU3lzdGVtLkNv - bGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tCYWNrVHJhbnNsYXRpb25IZWxwZXIuVGFyZ2V0UG9zc2li - bGUDAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lvbgQAACZCYWNrVHJhbnNsYXRpb25IZWxwZXIuVGFyZ2V0 - UG9zc2libGVbXQMAAAAICAIAAAAJBAAAAAEAAAABAAAABwQAAAAAAQAAAAQAAAAEJEJhY2tUcmFuc2xh - dGlvbkhlbHBlci5UYXJnZXRQb3NzaWJsZQMAAAAJBQAAAA0DBQUAAAAkQmFja1RyYW5zbGF0aW9uSGVs - cGVyLlRhcmdldFBvc3NpYmxlAwAAAB48UG9zc2libGVJbmRleD5rX19CYWNraW5nRmllbGQfPFRyYW5z - bGF0b3JOYW1lPmtfX0JhY2tpbmdGaWVsZBs8VGFyZ2V0RGF0YT5rX19CYWNraW5nRmllbGQAAQEIAwAA - AAAAAAAKBgYAAAAACw== - - \ No newline at end of file diff --git a/src/SILConvertersOffice/WordApp.cs b/src/SILConvertersOffice/WordApp.cs index 462cbd27..9804dec4 100644 --- a/src/SILConvertersOffice/WordApp.cs +++ b/src/SILConvertersOffice/WordApp.cs @@ -290,7 +290,7 @@ private void ParagraphByParagraph(OfficeTextDocument.ProcessingType processingTy // keep reusing the same doc processor (in case we're doing sub-paragraph selections and have already specified which cnvtr to use for a given font) // user must click the 'Reset' button, if they want to be requiried about which cnvtr to use if (m_officeDocumentProcessor == null) - m_officeDocumentProcessor = new OfficeDocumentProcessor((FontConverters)null, new SILConvertersOffice.TranslationHelperForm()); + m_officeDocumentProcessor = new OfficeDocumentProcessor((FontConverters)null, new SILConvertersOffice.TranslationHelperForms()); // start where the cursor is currently m_officeDocumentProcessor.LeftOvers = doc.SelectionRange; diff --git a/src/SILConvertersOffice/WordDocumentProcessor.cs b/src/SILConvertersOffice/WordDocumentProcessor.cs index 43e85f1f..097e8b8d 100644 --- a/src/SILConvertersOffice/WordDocumentProcessor.cs +++ b/src/SILConvertersOffice/WordDocumentProcessor.cs @@ -2,7 +2,9 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Windows.Forms; // for DialogResult +using System.Xml.Linq; using Word = Microsoft.Office.Interop.Word; /* #if !Csc30 @@ -25,6 +27,16 @@ public Word.Document Document get { return (Word.Document)m_baseDocument; } } + public XDocument XDocument + { + get + { + var xml = Document.Content.XML; + var doc = XDocument.Parse(xml); + return doc; + } + } + public override int WordCount { get { return Document.Words.Count; } @@ -372,7 +384,15 @@ public override bool ProcessWordByWord(OfficeDocumentProcessor aWordProcessor) { // if multiple paragraphs... int nCharIndex = 0; - WordParagraphs aParagraphRanges = new WordParagraphs(Document.Application.Selection); + var selection = Document.Application.Selection; + WordParagraphs aParagraphRanges = new WordParagraphs(selection); + + // if nothing was selected, then assume the user means 'whole document' + if (!aParagraphRanges.Any()) + { + aParagraphRanges = new WordParagraphs(Document.Paragraphs); + } + foreach (Word.Range aRange in aParagraphRanges) { WordRange aThisParagraph = new WordRange(aRange); diff --git a/src/SILConvertersOffice/WordRange.cs b/src/SILConvertersOffice/WordRange.cs index 13cad297..60600f60 100644 --- a/src/SILConvertersOffice/WordRange.cs +++ b/src/SILConvertersOffice/WordRange.cs @@ -3,6 +3,7 @@ using System.Text; using System.Drawing; using Word = Microsoft.Office.Interop.Word; +using Microsoft.Office.Interop.Word; namespace SILConvertersOffice { @@ -227,5 +228,19 @@ public WordParagraphs(Word.Selection aBasedOnSelection) aRange.End = aBasedOnSelection.End; } } + + public WordParagraphs(Paragraphs paragraphs) + { + int nParagraphCount = paragraphs.Count; + int i = 1; + Word.Range aRange = paragraphs[i].Range.Duplicate; + Add(aRange); + + while (i < nParagraphCount) + { + aRange = paragraphs[++i].Range.Duplicate; + Add(aRange); + } + } } } diff --git a/src/SILConvertersOffice/app.config b/src/SILConvertersOffice/app.config index cc4c784e..73978e04 100644 --- a/src/SILConvertersOffice/app.config +++ b/src/SILConvertersOffice/app.config @@ -1,7 +1,12 @@  - - + + +
+ + + + @@ -50,6 +55,35 @@ + + + + + + + + + + + + + + + + - + + + + + Normal + + + 0, 0 + + + 800, 450 + + + \ No newline at end of file diff --git a/src/SILConvertersOffice/packages.config b/src/SILConvertersOffice/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/SILConvertersOffice/packages.config +++ b/src/SILConvertersOffice/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/SILConvertersOffice07/Properties/Settings.Designer.cs b/src/SILConvertersOffice07/Properties/Settings.Designer.cs index e511f12a..76bdad5e 100644 --- a/src/SILConvertersOffice07/Properties/Settings.Designer.cs +++ b/src/SILConvertersOffice07/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace SILConvertersOffice07.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -55,5 +55,41 @@ public static Settings Default { this["ConverterMappingRecentFiles"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Normal")] + public global::System.Windows.Forms.FormWindowState DefaultWindowState { + get { + return ((global::System.Windows.Forms.FormWindowState)(this["DefaultWindowState"])); + } + set { + this["DefaultWindowState"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0, 0")] + public global::System.Drawing.Point WindowLocation { + get { + return ((global::System.Drawing.Point)(this["WindowLocation"])); + } + set { + this["WindowLocation"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("800, 450")] + public global::System.Drawing.Size WindowSize { + get { + return ((global::System.Drawing.Size)(this["WindowSize"])); + } + set { + this["WindowSize"] = value; + } + } } } diff --git a/src/SILConvertersOffice07/Properties/Settings.settings b/src/SILConvertersOffice07/Properties/Settings.settings index fdb4efbc..656226d5 100644 --- a/src/SILConvertersOffice07/Properties/Settings.settings +++ b/src/SILConvertersOffice07/Properties/Settings.settings @@ -1,5 +1,5 @@  - + @@ -11,5 +11,14 @@ + + Normal + + + 0, 0 + + + 800, 450 + \ No newline at end of file diff --git a/src/SILConvertersOffice07/RibbonWord.xml b/src/SILConvertersOffice07/RibbonWord.xml index 06b87b63..e10b93c6 100644 --- a/src/SILConvertersOffice07/RibbonWord.xml +++ b/src/SILConvertersOffice07/RibbonWord.xml @@ -12,12 +12,12 @@ size="large" onAction="Button_Clicked" screentip="Click this item to search the document using Regular Expression syntax" />
[ComVisible(false)] - internal class LoginSF : System.Windows.Forms.Form + internal partial class LoginSF : System.Windows.Forms.Form { - private System.Windows.Forms.CheckedListBox checkedListBoxProjects; - private System.Windows.Forms.Button buttonOK; - private System.Windows.Forms.Button buttonCancel; - private System.Windows.Forms.TextBox textBoxNewProjectName; - private System.Windows.Forms.Button buttonAddNewProject; - private System.Windows.Forms.CheckBox checkBoxUnicode; - private System.Windows.Forms.Label labelFont; - private System.Windows.Forms.ListBox listBoxFontSize; - private System.Windows.Forms.GroupBox groupBoxNewProject; - private System.Windows.Forms.Label labelName; - private System.Windows.Forms.ComboBox comboBoxFont; - private System.Windows.Forms.Label labelFontSize; - private System.Windows.Forms.ToolTip toolTips; - private System.Windows.Forms.MenuItem menuItemDelete; - private System.Windows.Forms.MenuItem menuItemClick; - private System.Windows.Forms.ContextMenu contextMenu; - private System.Windows.Forms.Label labelCP; - private System.Windows.Forms.TextBox textBoxCP; - private System.ComponentModel.IContainer components; - - private bool m_bLegacy; - private int m_cp = 1252; + private bool m_isRightToleft; private Font m_font; private string m_strConverterSpec; private string m_strEncConverterName; @@ -52,17 +31,11 @@ internal class LoginSF : System.Windows.Forms.Form public const string cstrAddNewProjectButtonToolTipText = "Click to add new project"; public const string cstrNewProjectGroupText = "New Project"; private const string cstrProjectMemoryKey = @"SOFTWARE\SIL\SilEncConverters40\SpellingFixerEC"; - private System.Windows.Forms.Label labelInstructions; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.TextBox textBoxWordBoundaryDelimiter; - private System.Windows.Forms.MenuItem menuItemEdit; - private System.Windows.Forms.MenuItem menuItemDeleteAll; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TextBox textBoxAddlPunctuation; private string m_strNonWordCharacters; - private string cstrProjectMostRecentProject = "MostRecentProject"; + private const string cstrProjectMostRecentProject = "MostRecentProject"; - public LoginSF() + + public LoginSF() { // // Required for Windows Form Designer support @@ -71,11 +44,8 @@ public LoginSF() this.checkedListBoxProjects.ContextMenu = this.contextMenu; - EncConverters aECs = new EncConverters(); - EncConverters myECs = aECs.FilterByProcessType(SpellingFixerEC.SFProcessType); - - // disable the list box (and the OK button) if there's nothing in it - this.buttonOK.Enabled = this.checkedListBoxProjects.Visible = (myECs.Count > 0); + var aECs = new EncConverters(); + var myECs = aECs.FilterByProcessType(SpellingFixerEC.SFProcessType); string strPartialName; foreach(IEncConverter aEC in myECs.Values) @@ -91,49 +61,20 @@ public LoginSF() } catch {} - // TODO: also, add a new ctor to allow choosing the project programmatically. - if( nIndex != -1 ) - checkedListBoxProjects.SetItemChecked(nIndex,true); - else - // if there are no items in the list, then make the "Add New Project" the default button - this.AcceptButton = this.buttonAddNewProject; - - // populate the font name combo box with all the fonts installed (but only if they - // do Regular style). That is, on my system, I choose the "Aharoni" (some sort of - // hebrew font) as a test and the creation of the "Font" object below failed, - // because I was using the ctor that takes only the name and size, but that font - // doesn't have a 'Regular' style (which is the default for that ctor). If I - // wanted to add a query for the font 'style' to this dialog box as well (c.f. - // Word's font dialog box), then this restriction could be removed, but... I'll - // wait until someone complains. - InstalledFontCollection installedFontCollection = new InstalledFontCollection(); - FontFamily[] fontFamilies = installedFontCollection.Families; - foreach(FontFamily fontFamily in fontFamilies) - if( fontFamily.IsStyleAvailable(FontStyle.Regular) ) - comboBoxFont.Items.Add(fontFamily.Name); - - // start with some defaults. - this.listBoxFontSize.SelectedItem = "14"; - this.textBoxCP.Text = "1252"; - this.textBoxWordBoundaryDelimiter.Text = SpellingFixerEC.cstrDefaultWordBoundaryDelimiter; - - // start out pessimmistic - DialogResult = DialogResult.Cancel; - } - - public Font FontToUse - { - get { return m_font; } + if (nIndex != -1) + { + checkedListBoxProjects.SetItemChecked(nIndex, true); + } } - public int CpToUse + public bool ProjectsExist { - get { return m_cp; } + get { return checkedListBoxProjects.Items.Count > 0; } } - public bool IsLegacy + public Font FontToUse { - get { return m_bLegacy; } + get { return m_font; } } public string ConverterSpec @@ -151,341 +92,15 @@ public string WordBoundaryDelimiter get { return m_strWordBoundaryDelimiter; } } - public string Punctuation + public bool IsRightToLeft { - get { return m_strNonWordCharacters; } + get { return m_isRightToleft; } } - /// - /// Clean up any resources being used. - /// - protected override void Dispose( bool disposing ) - { - if( disposing ) - { - if(components != null) - { - components.Dispose(); - } - } - base.Dispose( disposing ); - } - - #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(LoginSF)); - this.checkedListBoxProjects = new System.Windows.Forms.CheckedListBox(); - this.buttonOK = new System.Windows.Forms.Button(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.labelName = new System.Windows.Forms.Label(); - this.textBoxNewProjectName = new System.Windows.Forms.TextBox(); - this.checkBoxUnicode = new System.Windows.Forms.CheckBox(); - this.buttonAddNewProject = new System.Windows.Forms.Button(); - this.groupBoxNewProject = new System.Windows.Forms.GroupBox(); - this.textBoxAddlPunctuation = new System.Windows.Forms.TextBox(); - this.label2 = new System.Windows.Forms.Label(); - this.textBoxWordBoundaryDelimiter = new System.Windows.Forms.TextBox(); - this.label1 = new System.Windows.Forms.Label(); - this.labelFont = new System.Windows.Forms.Label(); - this.comboBoxFont = new System.Windows.Forms.ComboBox(); - this.labelFontSize = new System.Windows.Forms.Label(); - this.labelCP = new System.Windows.Forms.Label(); - this.textBoxCP = new System.Windows.Forms.TextBox(); - this.listBoxFontSize = new System.Windows.Forms.ListBox(); - this.toolTips = new System.Windows.Forms.ToolTip(this.components); - this.contextMenu = new System.Windows.Forms.ContextMenu(); - this.menuItemClick = new System.Windows.Forms.MenuItem(); - this.menuItemDelete = new System.Windows.Forms.MenuItem(); - this.menuItemDeleteAll = new System.Windows.Forms.MenuItem(); - this.menuItemEdit = new System.Windows.Forms.MenuItem(); - this.labelInstructions = new System.Windows.Forms.Label(); - this.groupBoxNewProject.SuspendLayout(); - this.SuspendLayout(); - // - // checkedListBoxProjects - // - this.checkedListBoxProjects.Cursor = System.Windows.Forms.Cursors.Hand; - this.checkedListBoxProjects.Location = new System.Drawing.Point(16, 16); - this.checkedListBoxProjects.Name = "checkedListBoxProjects"; - this.checkedListBoxProjects.Size = new System.Drawing.Size(360, 154); - this.checkedListBoxProjects.TabIndex = 0; - this.checkedListBoxProjects.ThreeDCheckBoxes = true; - this.toolTips.SetToolTip(this.checkedListBoxProjects, "List of existing projects"); - this.checkedListBoxProjects.DoubleClick += new System.EventHandler(this.checkedListBoxProjects_DoubleClick); - this.checkedListBoxProjects.SelectedIndexChanged += new System.EventHandler(this.checkedListBoxProjects_SelectedIndexChanged); - this.checkedListBoxProjects.MouseUp += new System.Windows.Forms.MouseEventHandler(this.checkedListBoxProjects_MouseUp); - // - // buttonOK - // - this.buttonOK.Location = new System.Drawing.Point(115, 464); - this.buttonOK.Name = "buttonOK"; - this.buttonOK.Size = new System.Drawing.Size(75, 24); - this.buttonOK.TabIndex = 11; - this.buttonOK.Text = "OK"; - this.toolTips.SetToolTip(this.buttonOK, "Click to use the checked project"); - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); - // - // buttonCancel - // - this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.buttonCancel.Location = new System.Drawing.Point(203, 464); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(75, 24); - this.buttonCancel.TabIndex = 12; - this.buttonCancel.Text = "Cancel"; - this.toolTips.SetToolTip(this.buttonCancel, "Click to cancel this operation"); - this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); - // - // labelName - // - this.labelName.Location = new System.Drawing.Point(32, 216); - this.labelName.Name = "labelName"; - this.labelName.Size = new System.Drawing.Size(56, 23); - this.labelName.TabIndex = 1; - this.labelName.Text = "&Name:"; - // - // textBoxNewProjectName - // - this.textBoxNewProjectName.Location = new System.Drawing.Point(88, 216); - this.textBoxNewProjectName.Name = "textBoxNewProjectName"; - this.textBoxNewProjectName.Size = new System.Drawing.Size(272, 20); - this.textBoxNewProjectName.TabIndex = 2; - this.textBoxNewProjectName.Text = ""; - this.toolTips.SetToolTip(this.textBoxNewProjectName, "Enter the name of a new projects (e.g. \'Hindi\')"); - this.textBoxNewProjectName.TextChanged += new System.EventHandler(this.textBoxNewProjectName_TextChanged); - // - // checkBoxUnicode - // - this.checkBoxUnicode.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; - this.checkBoxUnicode.Checked = true; - this.checkBoxUnicode.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxUnicode.Cursor = System.Windows.Forms.Cursors.Hand; - this.checkBoxUnicode.Location = new System.Drawing.Point(16, 120); - this.checkBoxUnicode.Name = "checkBoxUnicode"; - this.checkBoxUnicode.Size = new System.Drawing.Size(72, 24); - this.checkBoxUnicode.TabIndex = 7; - this.checkBoxUnicode.Text = "&Unicode:"; - this.toolTips.SetToolTip(this.checkBoxUnicode, "Check this if the data is Unicode-encoded (otherwise, it is Legacy-encoded)"); - this.checkBoxUnicode.CheckedChanged += new System.EventHandler(this.checkBoxUnicode_CheckedChanged); - // - // buttonAddNewProject - // - this.buttonAddNewProject.Location = new System.Drawing.Point(116, 224); - this.buttonAddNewProject.Name = "buttonAddNewProject"; - this.buttonAddNewProject.Size = new System.Drawing.Size(128, 23); - this.buttonAddNewProject.TabIndex = 10; - this.buttonAddNewProject.Text = "&Add New Project"; - this.toolTips.SetToolTip(this.buttonAddNewProject, "Click to add new project"); - this.buttonAddNewProject.Click += new System.EventHandler(this.buttonAddNewProject_Click); - // - // groupBoxNewProject - // - this.groupBoxNewProject.Controls.Add(this.textBoxAddlPunctuation); - this.groupBoxNewProject.Controls.Add(this.label2); - this.groupBoxNewProject.Controls.Add(this.textBoxWordBoundaryDelimiter); - this.groupBoxNewProject.Controls.Add(this.label1); - this.groupBoxNewProject.Controls.Add(this.labelFont); - this.groupBoxNewProject.Controls.Add(this.comboBoxFont); - this.groupBoxNewProject.Controls.Add(this.labelFontSize); - this.groupBoxNewProject.Controls.Add(this.checkBoxUnicode); - this.groupBoxNewProject.Controls.Add(this.labelCP); - this.groupBoxNewProject.Controls.Add(this.textBoxCP); - this.groupBoxNewProject.Controls.Add(this.listBoxFontSize); - this.groupBoxNewProject.Controls.Add(this.buttonAddNewProject); - this.groupBoxNewProject.Location = new System.Drawing.Point(16, 184); - this.groupBoxNewProject.Name = "groupBoxNewProject"; - this.groupBoxNewProject.Size = new System.Drawing.Size(360, 264); - this.groupBoxNewProject.TabIndex = 9; - this.groupBoxNewProject.TabStop = false; - this.groupBoxNewProject.Text = "New Project"; - // - // textBoxAddlPunctuation - // - this.textBoxAddlPunctuation.Location = new System.Drawing.Point(232, 184); - this.textBoxAddlPunctuation.Name = "textBoxAddlPunctuation"; - this.textBoxAddlPunctuation.Size = new System.Drawing.Size(112, 20); - this.textBoxAddlPunctuation.TabIndex = 14; - this.textBoxAddlPunctuation.Text = ""; - this.toolTips.SetToolTip(this.textBoxAddlPunctuation, "Enter any additional punctuation or whitespace characters needed for this languag" + - "e, separated by spaces"); - // - // label2 - // - this.label2.Location = new System.Drawing.Point(16, 184); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(208, 24); - this.label2.TabIndex = 13; - this.label2.Text = "Additional &punctuation and whitespace:"; - // - // textBoxWordBoundaryDelimiter - // - this.textBoxWordBoundaryDelimiter.Location = new System.Drawing.Point(232, 152); - this.textBoxWordBoundaryDelimiter.Name = "textBoxWordBoundaryDelimiter"; - this.textBoxWordBoundaryDelimiter.Size = new System.Drawing.Size(24, 20); - this.textBoxWordBoundaryDelimiter.TabIndex = 12; - this.textBoxWordBoundaryDelimiter.Text = SpellingFixerEC.cstrDefaultWordBoundaryDelimiter; - this.toolTips.SetToolTip(this.textBoxWordBoundaryDelimiter, "Enter the character(s) to use as a word boundary delimiter (e.g. with a delimiter" + - " of \"#\", you can enter the \"bad spelling\" words like: #car#, which will only mat" + - "ch if the search string is \"car\", but not \"cars\" or \"sportscar\")"); - this.textBoxWordBoundaryDelimiter.TextChanged += new System.EventHandler(this.textBoxWordBoundaryDelimiter_TextChanged); - // - // label1 - // - this.label1.Location = new System.Drawing.Point(16, 154); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(136, 16); - this.label1.TabIndex = 11; - this.label1.Text = "&Word boundary delimiter:"; - // - // labelFont - // - this.labelFont.Location = new System.Drawing.Point(16, 64); - this.labelFont.Name = "labelFont"; - this.labelFont.TabIndex = 3; - this.labelFont.Text = "&Font:"; - // - // comboBoxFont - // - this.comboBoxFont.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxFont.Location = new System.Drawing.Point(24, 88); - this.comboBoxFont.Name = "comboBoxFont"; - this.comboBoxFont.Size = new System.Drawing.Size(232, 21); - this.comboBoxFont.TabIndex = 4; - this.toolTips.SetToolTip(this.comboBoxFont, "Choose the font to be used for displaying the words whose spelling is to be corre" + - "cted (e.g. \'Arial Unicode MS\')"); - this.comboBoxFont.SelectedIndexChanged += new System.EventHandler(this.comboBoxFont_SelectedIndexChanged); - // - // labelFontSize - // - this.labelFontSize.Location = new System.Drawing.Point(264, 64); - this.labelFontSize.Name = "labelFontSize"; - this.labelFontSize.Size = new System.Drawing.Size(64, 23); - this.labelFontSize.TabIndex = 5; - this.labelFontSize.Text = "Font &Size:"; - // - // labelCP - // - this.labelCP.Location = new System.Drawing.Point(120, 120); - this.labelCP.Name = "labelCP"; - this.labelCP.Size = new System.Drawing.Size(80, 23); - this.labelCP.TabIndex = 8; - this.labelCP.Text = "&Code page:"; - this.labelCP.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - this.labelCP.Visible = false; - // - // textBoxCP - // - this.textBoxCP.Location = new System.Drawing.Point(200, 120); - this.textBoxCP.Name = "textBoxCP"; - this.textBoxCP.Size = new System.Drawing.Size(56, 20); - this.textBoxCP.TabIndex = 9; - this.textBoxCP.Text = ""; - this.toolTips.SetToolTip(this.textBoxCP, "Enter the code page used by this legacy font"); - this.textBoxCP.Visible = false; - this.textBoxCP.TextChanged += new System.EventHandler(this.textBoxCP_TextChanged); - // - // listBoxFontSize - // - this.listBoxFontSize.Items.AddRange(new object[] { - "8", - "9", - "10", - "10.5", - "11", - "12", - "14", - "16", - "18", - "20", - "22", - "24", - "26", - "28", - "36", - "48", - "72"}); - this.listBoxFontSize.Location = new System.Drawing.Point(272, 88); - this.listBoxFontSize.Name = "listBoxFontSize"; - this.listBoxFontSize.ScrollAlwaysVisible = true; - this.listBoxFontSize.Size = new System.Drawing.Size(72, 82); - this.listBoxFontSize.TabIndex = 6; - this.toolTips.SetToolTip(this.listBoxFontSize, "Choose the font size"); - this.listBoxFontSize.SelectedIndexChanged += new System.EventHandler(this.listBoxFontSize_SelectedIndexChanged); - // - // toolTips - // - this.toolTips.AutoPopDelay = 30000; - this.toolTips.InitialDelay = 500; - this.toolTips.ReshowDelay = 100; - // - // contextMenu - // - this.contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { - this.menuItemClick, - this.menuItemDelete, - this.menuItemDeleteAll, - this.menuItemEdit}); - // - // menuItemClick - // - this.menuItemClick.DefaultItem = true; - this.menuItemClick.Index = 0; - this.menuItemClick.Text = "&Click"; - this.menuItemClick.Click += new System.EventHandler(this.menuItemClick_Click); - // - // menuItemDelete - // - this.menuItemDelete.Index = 1; - this.menuItemDelete.Text = "&Delete"; - this.menuItemDelete.Click += new System.EventHandler(this.menuItemDelete_Click); - // - // menuItemDeleteAll - // - this.menuItemDeleteAll.Index = 2; - this.menuItemDeleteAll.Text = "Delete &All"; - this.menuItemDeleteAll.Click += new System.EventHandler(this.menuItemDeleteAll_Click); - // - // menuItemEdit - // - this.menuItemEdit.Index = 3; - this.menuItemEdit.Text = "&Edit"; - this.menuItemEdit.Click += new System.EventHandler(this.menuItemEdit_Click); - // - // labelInstructions - // - this.labelInstructions.Location = new System.Drawing.Point(32, 64); - this.labelInstructions.Name = "labelInstructions"; - this.labelInstructions.Size = new System.Drawing.Size(336, 64); - this.labelInstructions.TabIndex = 13; - this.labelInstructions.Text = "Fill in the details below and click the Add New Project button."; - // - // LoginSF - // - this.AcceptButton = this.buttonOK; - this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); - this.CancelButton = this.buttonCancel; - this.ClientSize = new System.Drawing.Size(392, 502); - this.Controls.Add(this.checkedListBoxProjects); - this.Controls.Add(this.labelName); - this.Controls.Add(this.textBoxNewProjectName); - this.Controls.Add(this.groupBoxNewProject); - this.Controls.Add(this.buttonOK); - this.Controls.Add(this.buttonCancel); - this.Controls.Add(this.labelInstructions); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "LoginSF"; - this.Text = "Choose or Add New Fix Spelling Project"; - this.groupBoxNewProject.ResumeLayout(false); - this.ResumeLayout(false); - + public string Punctuation + { + get { return m_strNonWordCharacters; } } - #endregion internal string FullName(string strProjName) { @@ -501,26 +116,29 @@ internal string PartialName(string strFullName) return null; } - internal static void CreateCCTable(string strCCTableSpec, string strEncConverterName, string strPunctuation, string strCustomCode, bool bUnicode) + internal static void CreateCCTable(string strCCTableSpec, string strEncConverterName, string strPunctuation) { - CreateCCTable(new FileStream(strCCTableSpec, FileMode.Create), strEncConverterName, strPunctuation, strCustomCode, bUnicode); + CreateCCTable(new FileStream(strCCTableSpec, FileMode.Create), strEncConverterName, strPunctuation); } - internal static void CreateCCTable(FileStream fs, string strEncConverterName, string strPunctuation, string strCustomCode, bool bUnicode) + internal static void CreateCCTable(FileStream fs, string strEncConverterName, string strPunctuation) { // write out the header lines. - StreamWriter sw = new StreamWriter(fs); - CreateCCTable(sw, strEncConverterName, strPunctuation, strCustomCode, bUnicode); + var sw = new StreamWriter(fs); + CreateCCTable(sw, strEncConverterName, strPunctuation); sw.Flush(); sw.Close(); } - internal static string cstrLastHeaderLine + internal static string CctableLastHeaderLine { get { return "c Last Header Line: DON'T modify the table beyond this point (or your changes may be overwritten)"; } } - internal static void CreateCCTable(StreamWriter sw, string strEncConverterName, string strPunctuation, string strCustomCode, bool bUnicode) + internal const string DummyRule = " d31 > d31 c dummy rule so that the table isn't empty (can be removed if you have rules below the Last Header Line below)"; + internal const string CustomRuleEndComment = "c +----------end custom changes----------+"; + + internal static void CreateCCTable(StreamWriter sw, string strEncConverterName, string strPunctuation, string strCustomCode = DummyRule, bool bUnicode = true) { // write out the header lines. string strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); @@ -537,14 +155,14 @@ internal static void CreateCCTable(StreamWriter sw, string strEncConverterName, sw.WriteLine("c +----------start custom changes----------+"); if (!String.IsNullOrEmpty(strCustomCode)) { - sw.Write(strCustomCode); + sw.WriteLine(strCustomCode); } - sw.WriteLine("c +----------end custom changes----------+"); + sw.WriteLine(CustomRuleEndComment); sw.WriteLine(""); - sw.WriteLine(cstrLastHeaderLine); + sw.WriteLine(CctableLastHeaderLine); } - internal static void ReWriteCCTableHeader(string strCCTableSpec, string strPunctuation, Encoding enc) + internal static void ReWriteCCTableHeader(string strCCTableSpec, string strPunctuation, Encoding enc, bool removeDummyRule) { // Open the CC table that has the mappings put them in a new file // while re-writing the first part of the header @@ -552,24 +170,39 @@ internal static void ReWriteCCTableHeader(string strCCTableSpec, string strPunct { const string strTempExt = ".new"; // get a stream writer for these encoding and append - StreamReader sr = new StreamReader(strCCTableSpec,enc); - StreamWriter sw = new StreamWriter(strCCTableSpec + strTempExt, false, enc); + var sr = new StreamReader(strCCTableSpec,enc); + var sw = new StreamWriter(strCCTableSpec + strTempExt, false, enc); // this is for version 1.2.0.0 string strVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + var copiedDummyRule = false; // copy the read stuff to the output and update the 'ws' store line for(string line = sr.ReadLine(); line != null; line = sr.ReadLine()) { - if( line.IndexOf("c This cc table was created by SpellingFixerEC.dll v") != -1 ) + if (line.Contains("c This cc table was created by SpellingFixerEC.dll v")) line = String.Format("c This cc table was created by SpellingFixerEC.dll v{0} on {1}.",strVersion, DateTime.Now.ToShortDateString()); - else if( line.IndexOf("store(ws)") != -1 ) + else if (line.Contains("store(ws)")) line = String.Format(" store(ws) {0} endstore", strPunctuation); + // if we're re-writing the cc table with this method, then if we're going to be adding + // actual rules (i.e. removeDummyRule is true), then we can get rid of the dummy rule. + if (line.Contains(DummyRule)) + { + if (removeDummyRule) + continue; + copiedDummyRule = true; + } + // otherwise, we need to put it back in + else if (line.Contains(CustomRuleEndComment) && !removeDummyRule && !copiedDummyRule) + { + sw.WriteLine(DummyRule); + } + sw.WriteLine(line); // stop when we get past the end of the header - if( line == cstrLastHeaderLine ) + if( line == CctableLastHeaderLine ) break; } @@ -585,121 +218,6 @@ internal static void ReWriteCCTableHeader(string strCCTableSpec, string strPunct } } - private void EnableAddNewProjectButton() - { - this.buttonAddNewProject.Enabled = ( - (this.textBoxNewProjectName.Text != "") - && ((this.comboBoxFont.SelectedItem != null) && (this.comboBoxFont.SelectedItem.ToString() != "")) - && ((this.listBoxFontSize.SelectedItem != null) && (this.listBoxFontSize.SelectedItem.ToString() != "")) - && ((this.checkBoxUnicode.Checked) || (this.textBoxCP.Text != "")) - && (!String.IsNullOrEmpty(this.textBoxWordBoundaryDelimiter.Text)) ); - } - - private bool m_bUserDefinePunctuation = false; - - private string DecodePunctuationForCC(string strPunctuation) - { - if( String.IsNullOrEmpty(strPunctuation) ) - return null; - - else - { - // initialize it so that *we* take care of delimiting the punctuation - m_bUserDefinePunctuation = false; - - // the first chunk of this should be the fixed punctuation - int nIndex = strPunctuation.IndexOf(SpellingFixerEC.GetDefaultPunctuation); - if ((nIndex == 0) && (strPunctuation.Length <= SpellingFixerEC.GetDefaultPunctuation.Length)) - { - // if this is all there is, then the 'decoded' string is nothing. - return null; - } - else - { - // pre-v3 - nIndex = strPunctuation.IndexOf(SpellingFixerEC.cstrDefaultPunctuationAndWhitespace); - if( nIndex == 0 ) - { - // if this is all there is, then the 'decoded' string is nothing. - int nLength = SpellingFixerEC.cstrDefaultPunctuationAndWhitespace.Length; - if (strPunctuation.Length <= nLength) - return null; - - // otherwise, process only the extra - strPunctuation = strPunctuation.Substring(nLength); - if (strPunctuation.IndexOf(SpellingFixerEC.cstrV3DefaultPunctuationAndWhitespaceAdds) == 0) - { - nLength = SpellingFixerEC.cstrV3DefaultPunctuationAndWhitespaceAdds.Length; - if (strPunctuation.Length <= nLength) - return null; - strPunctuation = strPunctuation.Substring(nLength + 1); - } - else - strPunctuation = strPunctuation.Substring(1); - } - else - { - m_bUserDefinePunctuation = true; - return strPunctuation; // in this case, the user is responsible for delimiting the string him/herself - } - } - } - - return DecodePunctuationForCCEx(strPunctuation); - } - - private string DecodePunctuationForCCEx(string strPunctuation) - { - string strRet = null; - string [] astrDelimitedChars = strPunctuation.Split(new char [] {' '}); - - // each string should be in the form 'X', where X is the punctuation - foreach(string strDelimitedChar in astrDelimitedChars) - { - if( (strDelimitedChar.IndexOfAny(new char [] {'\'', '\"' }) != -1) - && (strDelimitedChar.Length > 2) ) - strRet += strDelimitedChar.Substring(1,strDelimitedChar.Length - 2); - else - strRet += strDelimitedChar; - - strRet += ' '; - } - - if( !String.IsNullOrEmpty(strRet) ) - strRet = strRet.Substring(0,strRet.Length - 1); - - return strRet; - } - - private string EncodePunctuationForCC(string strPunctuation) - { - string strRet = null; - - if( m_bUserDefinePunctuation ) - return strPunctuation; - - else if( !String.IsNullOrEmpty(strPunctuation) ) - { - string [] astrChars = strPunctuation.Split(new char [] {' '}); - foreach(string strChar in astrChars) - { - if (SpellingFixerEC.GetDefaultPunctuation.IndexOf(strChar) != -1) - { - MessageBox.Show(String.Format("There's no need to add the {0} character as Additional Punctuation because it's there by default,\r\nas are these: {1}", - strChar, DecodePunctuationForCCEx(SpellingFixerEC.GetDefaultPunctuation)), SpellingFixerEC.cstrCaption); - return null; - } - strRet += '\'' + strChar + "\' "; - } - if( !String.IsNullOrEmpty(strRet) ) - strRet = strRet.Substring(0,strRet.Length - 1); - - return SpellingFixerEC.GetDefaultPunctuation + ' ' + strRet; - } - - return SpellingFixerEC.GetDefaultPunctuation; - } - internal static string GetMapTableFolderPath { get @@ -714,55 +232,64 @@ internal static string GetMapTableFolderPath } } - private void buttonAddNewProject_Click(object sender, System.EventArgs e) + private void MenuItemAddNewProject_Click(object sender, EventArgs e) { - // in case the Add New project button was default, change it to the OK button. - this.AcceptButton = this.buttonOK; + AddNewProject(); + } - // get the delimiter for word boundaries and disallow the /"/ character - m_strWordBoundaryDelimiter = this.textBoxWordBoundaryDelimiter.Text; - if( m_strWordBoundaryDelimiter.IndexOf('"') != -1 ) + private void AddNewProject() + { + using var dlg = new AddNewProjectForm(SpellingFixerEC.GetDefaultPunctuation) { - MessageBox.Show("Can't use the double-quote character for the word boundary delimiter",SpellingFixerEC.cstrCaption); + WordBoundaryDelimiter = SpellingFixerEC.cstrDefaultWordBoundaryDelimiter + }; + + var res = dlg.ShowDialog(); + if (res == DialogResult.Cancel) return; - } + + UpdateRepo(false, dlg); + } + + private void UpdateRepo(bool isEditing, AddNewProjectForm dlg) + { + // get the delimiter for word boundaries and disallow the /"/ character + m_strWordBoundaryDelimiter = dlg.WordBoundaryDelimiter; + m_isRightToleft = dlg.IsRightToLeft; bool bRewriteCCTable = false; - string strPunctuation = EncodePunctuationForCC(this.textBoxAddlPunctuation.Text); - if(strPunctuation == null ) + string strPunctuation = dlg.GetAddlPunctuation(true); + if (strPunctuation == null) + { return; // it had a bad character - - else if( strPunctuation != m_strNonWordCharacters ) + } + else if (strPunctuation != m_strNonWordCharacters) { // this means the file must be re-written bRewriteCCTable = true; m_strNonWordCharacters = strPunctuation; } - if( (!m_bLegacy) != this.checkBoxUnicode.Checked ) - { - m_bLegacy = !this.checkBoxUnicode.Checked; - bRewriteCCTable = true; - } - // check for existing EncConverter with this same project information string strCCTableSpec = null; - string strPartialName = this.textBoxNewProjectName.Text; - string strEncConverterName = FullName(strPartialName); - EncConverters aECs = new EncConverters(); + var strPartialName = dlg.NewProjectName; + var strEncConverterName = FullName(strPartialName); + var aECs = new EncConverters(); IEncConverter aEC = aECs[strEncConverterName]; - if( aEC != null ) + if (aEC != null) { // if we're *not* in edit mode - if( this.buttonAddNewProject.Text == cstrAddNewProjectButtonText ) + if (!isEditing) { - if( MessageBox.Show(String.Format("A project already exists by the name {0}. Click 'Yes' to overwrite", this.textBoxNewProjectName.Text),SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) + if (MessageBox.Show($"A project already exists by the name {strPartialName}. Click 'Yes' to overwrite", + SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNo) + == DialogResult.Yes) { // take it out of the check box list checkedListBoxProjects.Items.Remove(strPartialName); strCCTableSpec = aEC.ConverterIdentifier; - if( File.Exists(strCCTableSpec) ) + if (File.Exists(strCCTableSpec)) { File.Delete(strCCTableSpec); strCCTableSpec = null; @@ -770,14 +297,15 @@ private void buttonAddNewProject_Click(object sender, System.EventArgs e) // remove the existing one and we'll add a new one next aECs.Remove(aEC.Name); - aEC = null; } else return; } else // edit mode { - if( MessageBox.Show(String.Format("Do you want to update the '{0}' project?", this.textBoxNewProjectName.Text),SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) + if (MessageBox.Show($"Do you want to update the '{strPartialName}' project?", + SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNo) + == DialogResult.Yes) { // take it out of the check box list checkedListBoxProjects.Items.Remove(strPartialName); @@ -787,44 +315,33 @@ private void buttonAddNewProject_Click(object sender, System.EventArgs e) // the remove the converter since we'll add it back again next aECs.Remove(aEC.Name); - aEC = null; } else { - // reset this in case we were just editing it. - ResetNewProjectLook(); return; } } } // if we're aren't using the old cc table, then... - if( strCCTableSpec == null ) + if (String.IsNullOrEmpty(strCCTableSpec)) { // now add it (put it in the normal 'MapsTables' folder in \pf\cf\sil\...) string strMapsTableDir = GetMapTableFolderPath; strCCTableSpec = strMapsTableDir + @"\" + strEncConverterName + ".cct"; - if( File.Exists(strCCTableSpec) ) + if (File.Exists(strCCTableSpec)) { // the converter doesn't exist, but a file with the name we would have // given it does... ask the user if they want to overwrite it. // TODO: this doesn't allow for complete flexibility. It might be nicer to // allow for any arbitrary name, but not if noone complains. - if( MessageBox.Show(String.Format("A file exists by the name {0}. Click 'Yes' to overwrite", strCCTableSpec),SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) + if (MessageBox.Show($"A file exists by the name {strCCTableSpec}. Click 'Yes' to overwrite", + SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNo) + == DialogResult.Yes) { File.Delete(strCCTableSpec); -#if WriteOnAdd -// if the user goes to add the first record, it'd be better if the file didn't exist because now we do some -// preliminary testing whether the CC table already changes a word before adding a new one, but this causes -// a non-trapable error if there are no rules in the file. So just create it when it is actually needed - CreateCCTable(strCCTableSpec,strEncConverterName,m_strNonWordCharacters, !this.m_bLegacy); -#endif } } -#if WriteOnAdd - else - CreateCCTable(strCCTableSpec,strEncConverterName,m_strNonWordCharacters, !this.m_bLegacy); -#endif bRewriteCCTable = false; } @@ -832,86 +349,35 @@ private void buttonAddNewProject_Click(object sender, System.EventArgs e) // TODO: EncConverters needs a new interface to get the defining encodingID from // a FontName (so we can use it in this call) just like we can 'try' to get the // code page given a font name (see 'CodePage' below) - ConvType eConvType = (m_bLegacy) - ? ConvType.Legacy_to_Legacy : ConvType.Unicode_to_Unicode; + var eConvType = ConvType.Unicode_to_Unicode; - aECs.Add(strEncConverterName,strCCTableSpec,eConvType,null,null,SpellingFixerEC.SFProcessType); - - Font font = null; - try - { - font = new Font(comboBoxFont.SelectedItem.ToString(),Convert.ToSingle(listBoxFontSize.SelectedItem)); - } - catch - { - MessageBox.Show("Couldn't create the selected font. Contact support"); - return; - } + aECs.Add(strEncConverterName, strCCTableSpec, eConvType, null, null, SpellingFixerEC.SFProcessType); + + Font font = dlg.SelectedFont; // add this 'displaying font' information to the converter as properties/attributes - ECAttributes aECAttrs = aECs.Attributes(strEncConverterName,AttributeType.Converter); - aECAttrs.Add(SpellingFixerEC.cstrAttributeFontToUse,font.Name); + ECAttributes aECAttrs = aECs.Attributes(strEncConverterName, AttributeType.Converter); + aECAttrs.Add(SpellingFixerEC.cstrAttributeFontToUse, font.Name); + aECAttrs.Add(SpellingFixerEC.cstrAttributeFontRightToLeft, m_isRightToleft); aECAttrs.Add(SpellingFixerEC.cstrAttributeFontSizeToUse, font.Size); aECAttrs.Add(SpellingFixerEC.cstrAttributeWordBoundaryDelimiter, m_strWordBoundaryDelimiter); aECAttrs.Add(SpellingFixerEC.cstrAttributeNonWordChars, m_strNonWordCharacters); - // if it's not Unicode, then we need a code page in order to convert from wide to - // narrow (when writing to the file). - int cp = 0; - if( m_bLegacy ) - { - // try to get the code page from EncConverters - try - { - cp = aECs.CodePage(font.Name); - } - catch - { - // if it fails, it means we don't have a mapping, so add one here. - // TODO: it would be nice to have an encoding, but I'm loath to query - // the user for it here since it isn't extremely relevant to this app. - cp = Convert.ToInt32(this.textBoxCP.Text); - aECs.AddFont(font.Name,cp,null); - } - } - - if(bRewriteCCTable) // we are going to continue using the old file... so we must re-write it. + if (bRewriteCCTable) // we are going to continue using the old file... so we must re-write it. { // if it was legacy encoded, then we need to convert the data to narrow using // the code page the user specified (or we got out of the repository) - Encoding enc = null; - if( m_bLegacy ) - { - if (cp == EncConverters.cnSymbolFontCodePage) - cp = EncConverters.cnIso8859_1CodePage; - enc = Encoding.GetEncoding(cp); - } - else - enc = new UTF8Encoding(); + var enc = new UTF8Encoding(); - DataTable myTable; - if( SpellingFixerEC.InitializeDataTableFromCCTable(strCCTableSpec, enc, m_strWordBoundaryDelimiter, out myTable) ) + if (SpellingFixerEC.InitializeDataTableFromCCTable(strCCTableSpec, enc, m_strWordBoundaryDelimiter, out DataTable myTable)) { - ReWriteCCTableHeader(strCCTableSpec,m_strNonWordCharacters,enc); SpellingFixerEC.AppendCCTableFromDataTable(strCCTableSpec, enc, m_strWordBoundaryDelimiter, m_strNonWordCharacters, myTable); } } // finally, add the new project to the now-visible checkbox list - this.buttonOK.Enabled = checkedListBoxProjects.Visible = true; ClearClickedItems(); - checkedListBoxProjects.Items.Add(strPartialName,CheckState.Checked); - - // reset this in case we were just editing it. - ResetNewProjectLook(); - } - - private void ResetNewProjectLook() - { - this.groupBoxNewProject.Text = cstrNewProjectGroupText; - this.buttonAddNewProject.Text = cstrAddNewProjectButtonText; - this.toolTips.SetToolTip(this.buttonAddNewProject, cstrAddNewProjectButtonToolTipText); - this.textBoxNewProjectName.ReadOnly = false; + checkedListBoxProjects.Items.Add(strPartialName, CheckState.Checked); } private void ClearClickedItems() @@ -920,7 +386,7 @@ private void ClearClickedItems() checkedListBoxProjects.SetItemCheckState(indexChecked,CheckState.Unchecked); } - private void buttonOK_Click(object sender, System.EventArgs e) + private void ButtonOK_Click(object sender, System.EventArgs e) { // When the OK button is clicked, it means the user is choosing the project in // the project checkbox list. So use *that* information only to fill in the @@ -928,16 +394,14 @@ private void buttonOK_Click(object sender, System.EventArgs e) // necessarily true that we added a project during this instantiation, so don't // depend on the internal variables (e.g. m_font, etc.) having something // meaningful) - Debug.Assert( checkedListBoxProjects.Visible ); - CheckedListBox.CheckedItemCollection aCheckedItems = checkedListBoxProjects.CheckedItems; + var aCheckedItems = checkedListBoxProjects.CheckedItems; // should only be once checked item - Debug.Assert(aCheckedItems.Count == 1); if( aCheckedItems.Count != 1 ) return; string strEncConverterName = aCheckedItems[0].ToString(); - if( LoadProject(strEncConverterName) ) + if (LoadProject(strEncConverterName)) { DialogResult = DialogResult.OK; this.Close(); @@ -946,113 +410,79 @@ private void buttonOK_Click(object sender, System.EventArgs e) internal bool LoadProject(string strProjectName) { + if (String.IsNullOrEmpty(strProjectName)) + return false; + // get the EncConverter that should have been added above by 'AddNewProject' button - EncConverters aECs = new EncConverters(); - IEncConverter aEC = aECs[FullName(strProjectName)]; - if( aEC != null ) + var aECs = new EncConverters(); + var converterName = strProjectName; + if (strProjectName.StartsWith(SpellingFixerEC.cstrSFConverterPrefix)) + { + strProjectName = strProjectName.Substring(SpellingFixerEC.cstrSFConverterPrefix.Length); + } + else + { + converterName = FullName(strProjectName); + } + + IEncConverter aEC = aECs[converterName]; + if (aEC != null) { m_strEncConverterName = aEC.Name; m_strConverterSpec = aEC.ConverterIdentifier; - ECAttributes aECAttrs = aECs.Attributes(aEC.Name,AttributeType.Converter); + ECAttributes aECAttrs = aECs.Attributes(aEC.Name, AttributeType.Converter); string strFontName = aECAttrs[SpellingFixerEC.cstrAttributeFontToUse]; string sFontSize = aECAttrs[SpellingFixerEC.cstrAttributeFontSizeToUse]; + m_isRightToleft = aECAttrs.ContainsKey(SpellingFixerEC.cstrAttributeFontRightToLeft) && (aECAttrs[SpellingFixerEC.cstrAttributeFontRightToLeft] == "true"); m_strWordBoundaryDelimiter = aECAttrs[SpellingFixerEC.cstrAttributeWordBoundaryDelimiter]; m_strNonWordCharacters = aECAttrs[SpellingFixerEC.cstrAttributeNonWordChars]; // new in 1.2 (so it might not exist) - if( m_strNonWordCharacters == null ) - m_strNonWordCharacters = SpellingFixerEC.GetDefaultPunctuation; - - // if this was added (without having been made on this system), then - // these properties doesn't get added automatically. Must go to edit mode! - if((strFontName == null) - || (sFontSize == null) - || (m_strWordBoundaryDelimiter == null) ) - { - MessageBox.Show("It looks like this project was added to the repository incorrectly because it's missing some important properties. You'll need to edit it again to set the font, and other values."); - DoEdit(aECs, aEC, strProjectName, strFontName, sFontSize); - - // make the "Update" button the default button - this.AcceptButton = this.buttonAddNewProject; - return false; - } + m_strNonWordCharacters ??= SpellingFixerEC.GetDefaultPunctuation; - float fFontSize = (float)0.0; - try + // if this was added (without having been made on this computer), then + // these properties don't get added automatically. Must go to edit mode! + if (String.IsNullOrEmpty(strFontName) + || String.IsNullOrEmpty(sFontSize) + || String.IsNullOrEmpty(m_strWordBoundaryDelimiter)) { - fFontSize = (float)Convert.ToSingle(sFontSize); + MessageBox.Show("This converter is missing some important properties. You'll need to edit it again to set the font, and other values."); + DoEdit(strProjectName, strFontName, sFontSize); + return false; } - catch {} - if( (strFontName != "") && (fFontSize != 0.0) ) - m_font = new Font(strFontName,fFontSize); + var fFontSize = GetFloatFontSize(sFontSize); - m_bLegacy = (aEC.ConversionType == ConvType.Legacy_to_Legacy); - if( m_bLegacy ) - m_cp = aECs.CodePage(strFontName); + if (!String.IsNullOrEmpty(strFontName) && (fFontSize != 0.0)) + m_font = new Font(strFontName, fFontSize); RegistryKey keyLastSFProject = Registry.CurrentUser.CreateSubKey(cstrProjectMemoryKey); - keyLastSFProject.SetValue(cstrProjectMostRecentProject,strProjectName); + keyLastSFProject.SetValue(cstrProjectMostRecentProject, strProjectName); return true; } return false; } - private void buttonCancel_Click(object sender, System.EventArgs e) - { - DialogResult = DialogResult.Cancel; - this.Close(); - } - - private void textBoxNewProjectName_TextChanged(object sender, System.EventArgs e) - { - // check to see if the Add button should be enable. - EnableAddNewProjectButton(); - } - - private void comboBoxFont_SelectedIndexChanged(object sender, System.EventArgs e) - { - // check to see if the Add button should be enable. - EnableAddNewProjectButton(); - } - - private void listBoxFontSize_SelectedIndexChanged(object sender, System.EventArgs e) + private static float GetFloatFontSize(string sFontSize) { - // check to see if the Add button should be enable. - EnableAddNewProjectButton(); - } - - private void checkBoxUnicode_CheckedChanged(object sender, System.EventArgs e) - { - // check to see if the Add button should be enable. - EnableAddNewProjectButton(); - bool bIsLegacy = !this.checkBoxUnicode.Checked; - this.labelCP.Visible = this.textBoxCP.Visible = bIsLegacy; - - // if it's a legacy encoding, then see if the repository already has a cp for - // this font - if( bIsLegacy ) + var fFontSize = (float)0.0; + try { - EncConverters aECs = new EncConverters(); - int cp = (this.textBoxCP.Text != "") ? Convert.ToInt32(this.textBoxCP.Text) : 1252; - try - { - if( (comboBoxFont.SelectedItem != null) && (comboBoxFont.SelectedItem.ToString() != "") ) - cp = aECs.CodePage(comboBoxFont.SelectedItem.ToString()); - } - catch {} - this.textBoxCP.Text = cp.ToString(); + fFontSize = (float)Convert.ToSingle(sFontSize); } + catch { } + + return fFontSize; } - private void textBoxCP_TextChanged(object sender, System.EventArgs e) + private void ButtonCancel_Click(object sender, System.EventArgs e) { - // check to see if the Add button should be enable. - EnableAddNewProjectButton(); + DialogResult = DialogResult.Cancel; + this.Close(); } - private void checkedListBoxProjects_SelectedIndexChanged(object sender, System.EventArgs e) + private void CheckedListBoxProjects_SelectedIndexChanged(object sender, System.EventArgs e) { int nIndex = checkedListBoxProjects.SelectedIndex; ClearClickedItems(); @@ -1063,13 +493,13 @@ private void checkedListBoxProjects_SelectedIndexChanged(object sender, System.E // get the point at which the right mouse button was clicked (for subsequent pop-up // menu processing) private Point m_ptRightClicked; - private void checkedListBoxProjects_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) + private void CheckedListBoxProjects_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) { // don't want now that I support double-click if( e.Button == MouseButtons.Right ) m_ptRightClicked = new Point(e.X,e.Y); } - private void menuItemClick_Click(object sender, System.EventArgs e) + private void MenuItemClick_Click(object sender, System.EventArgs e) { int nIndex = checkedListBoxProjects.IndexFromPoint(m_ptRightClicked); if( nIndex >= 0 ) @@ -1079,7 +509,7 @@ private void menuItemClick_Click(object sender, System.EventArgs e) } } - private void menuItemDelete_Click(object sender, System.EventArgs e) + private void MenuItemDelete_Click(object sender, System.EventArgs e) { int nIndex = checkedListBoxProjects.IndexFromPoint(m_ptRightClicked); if( nIndex >= 0 ) @@ -1087,7 +517,7 @@ private void menuItemDelete_Click(object sender, System.EventArgs e) string strProjectName = checkedListBoxProjects.Items[nIndex].ToString(); if( MessageBox.Show(String.Format("Are you sure you want to delete the '{0}' project?",strProjectName), SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) { - EncConverters aECs = new EncConverters(); + var aECs = new EncConverters(); IEncConverter aEC = aECs[FullName(strProjectName)]; if( aEC != null ) { @@ -1105,15 +535,11 @@ private void menuItemDelete_Click(object sender, System.EventArgs e) } checkedListBoxProjects.Items.Remove(strProjectName); - - if( this.checkedListBoxProjects.Items.Count == 0 ) - this.AcceptButton = this.buttonAddNewProject; - EnableAddNewProjectButton(); } } } - private void menuItemEdit_Click(object sender, System.EventArgs e) + private void MenuItemEdit_Click(object sender, System.EventArgs e) { // Provide a way to edit the info (in case the user wants to change the // font, size, or delimter. @@ -1121,7 +547,7 @@ private void menuItemEdit_Click(object sender, System.EventArgs e) if( nIndex >= 0 ) { string strProjectName = checkedListBoxProjects.Items[nIndex].ToString(); - EncConverters aECs = new EncConverters(); + var aECs = new EncConverters(); IEncConverter aEC = aECs[FullName(strProjectName)]; if( aEC != null ) { @@ -1131,54 +557,44 @@ private void menuItemEdit_Click(object sender, System.EventArgs e) string strFontName = aECAttrs[SpellingFixerEC.cstrAttributeFontToUse]; string sFontSize = aECAttrs[SpellingFixerEC.cstrAttributeFontSizeToUse]; + m_isRightToleft = aECAttrs.ContainsKey(SpellingFixerEC.cstrAttributeFontRightToLeft) && (aECAttrs[SpellingFixerEC.cstrAttributeFontRightToLeft] == "true"); m_strWordBoundaryDelimiter = aECAttrs[SpellingFixerEC.cstrAttributeWordBoundaryDelimiter]; m_strNonWordCharacters = aECAttrs[SpellingFixerEC.cstrAttributeNonWordChars]; - DoEdit(aECs, aEC, strProjectName, strFontName, sFontSize); + DoEdit(strProjectName, strFontName, sFontSize); } - - // make the "Update" button the default button - this.AcceptButton = this.buttonAddNewProject; } } - private void DoEdit(EncConverters aECs, IEncConverter aEC, string strProjectName, string strFontName, string sFontSize) + private void DoEdit(string strProjectName, string strFontName, string sFontSize) { - this.textBoxNewProjectName.Text = strProjectName; - this.textBoxWordBoundaryDelimiter.Text = m_strWordBoundaryDelimiter; - - // new in 1.2 (so it might not exist) - this.textBoxAddlPunctuation.Text = this.DecodePunctuationForCC(m_strNonWordCharacters); - - this.listBoxFontSize.SelectedItem = sFontSize; - this.comboBoxFont.SelectedItem = strFontName; + m_font = new Font(strFontName, GetFloatFontSize(sFontSize)); - m_bLegacy = (aEC.ConversionType == ConvType.Legacy_to_Legacy); - this.checkBoxUnicode.Checked = !m_bLegacy; - if( m_bLegacy ) + using var dlg = new AddNewProjectForm(m_strNonWordCharacters) { - this.labelCP.Visible = this.textBoxCP.Visible = true; - this.textBoxCP.Text = aECs.CodePage(strFontName).ToString(); - } + NewProjectName = strProjectName, + WordBoundaryDelimiter = m_strWordBoundaryDelimiter, + SelectedFont = m_font, + IsRightToLeft = m_isRightToleft, + }; + + var res = dlg.ShowDialog(); + if (res == DialogResult.Cancel) + return; - // update the "Add New Project" button to say "Update Project" - this.groupBoxNewProject.Text = "Edit Project Settings"; - this.buttonAddNewProject.Text = "Update &Project"; - this.toolTips.SetToolTip(this.buttonAddNewProject, "Click to update the project information"); - this.textBoxNewProjectName.ReadOnly = true; - EnableAddNewProjectButton(); + UpdateRepo(true, dlg); } - private void menuItemDeleteAll_Click(object sender, System.EventArgs e) + private void MenuItemDeleteAll_Click(object sender, System.EventArgs e) { // verify first! if( MessageBox.Show("Are you sure you want to delete all the existing projects?", SpellingFixerEC.cstrCaption, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) { - EncConverters aECs = new EncConverters(); + var aECs = new EncConverters(); foreach(string strProjectName in checkedListBoxProjects.Items) { IEncConverter aEC = aECs[FullName(strProjectName)]; - if( aEC != null ) + if (aEC != null) { // if they do this, then don't bother querying about saving the files. if( File.Exists(aEC.ConverterIdentifier) ) @@ -1192,21 +608,21 @@ private void menuItemDeleteAll_Click(object sender, System.EventArgs e) // now remove them from the checkbox list while( checkedListBoxProjects.Items.Count > 0 ) checkedListBoxProjects.Items.RemoveAt(0); - - this.buttonOK.Enabled = this.checkedListBoxProjects.Visible = false; - this.AcceptButton = this.buttonAddNewProject; } } // double click means edit - private void checkedListBoxProjects_DoubleClick(object sender, EventArgs e) + private void CheckedListBoxProjects_DoubleClick(object sender, EventArgs e) { - this.menuItemEdit_Click(sender,e); + this.MenuItemEdit_Click(sender,e); } - private void textBoxWordBoundaryDelimiter_TextChanged(object sender, EventArgs e) + private void LoginSF_Shown(object sender, EventArgs e) { - EnableAddNewProjectButton(); + if (!ProjectsExist) + { + AddNewProject(); + } } } } \ No newline at end of file diff --git a/src/SpellingFixerEC/LoginSF.resx b/src/SpellingFixerEC/LoginSF.resx index 1fb7e94a..6c2177b8 100644 --- a/src/SpellingFixerEC/LoginSF.resx +++ b/src/SpellingFixerEC/LoginSF.resx @@ -3,7 +3,7 @@ + + + + + + + + + + + + + + + + + + - + + @@ -89,267 +109,22 @@ text/microsoft-resx - 1.3 + 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - Private - - - False - - - Private - - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - Private - - - 8, 8 - - - True - - - False - - - True - - - Private - - - Private - - - False - - - Private - - - False - - - Private - - - Private - - - Private - - - Private - - - False - - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - Private - - - Private - - - False - - - False - - - Private - - - Private - - - False - - - Private - - - Private - - - Private - - - False - - - Private - - - False - - - Private - - - Private - - - Private - - + 17, 17 - - - Private - - - Private - - + + 107, 17 - - - Private - - - Private - - - Private - - - Private - - - Private - - - Private - - - Private - - - Private - - - Private - - - False - - - Private - - - Private - - - False - - - (Default) - - - False - - - False - - - 8, 8 - - - LoginSF - - - True - - - 80 - - - True - - - Private - - + + + AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIAC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/ diff --git a/src/SpellingFixerEC/QueryFindReplaceDialog.Designer.cs b/src/SpellingFixerEC/QueryFindReplaceDialog.Designer.cs new file mode 100644 index 00000000..91080157 --- /dev/null +++ b/src/SpellingFixerEC/QueryFindReplaceDialog.Designer.cs @@ -0,0 +1,301 @@ +namespace SpellingFixerEC +{ + partial class QueryFindReplaceDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QueryFindReplaceDialog)); + this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this.labelFind = new System.Windows.Forms.Label(); + this.textBoxFindWord = new SilEncConverters40.EcTextBox(); + this.labelReplace = new System.Windows.Forms.Label(); + this.textBoxReplaceWord = new SilEncConverters40.EcTextBox(); + this.groupBoxWordBoundaries = new System.Windows.Forms.GroupBox(); + this.checkBoxWordFinal = new System.Windows.Forms.CheckBox(); + this.checkBoxWordInitial = new System.Windows.Forms.CheckBox(); + this.labelUnicodeCodes = new System.Windows.Forms.Label(); + this.labelAddedFromOriginalWord = new System.Windows.Forms.Label(); + this.textBoxOriginalWord = new System.Windows.Forms.TextBox(); + this.buttonDelete = new System.Windows.Forms.Button(); + this.buttonOk = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.textBoxWordBoundaryFindText = new System.Windows.Forms.TextBox(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.tableLayoutPanel.SuspendLayout(); + this.groupBoxWordBoundaries.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel + // + this.tableLayoutPanel.ColumnCount = 5; + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel.Controls.Add(this.labelFind, 0, 0); + this.tableLayoutPanel.Controls.Add(this.textBoxFindWord, 1, 0); + this.tableLayoutPanel.Controls.Add(this.labelReplace, 0, 1); + this.tableLayoutPanel.Controls.Add(this.textBoxReplaceWord, 1, 1); + this.tableLayoutPanel.Controls.Add(this.groupBoxWordBoundaries, 0, 2); + this.tableLayoutPanel.Controls.Add(this.labelUnicodeCodes, 0, 3); + this.tableLayoutPanel.Controls.Add(this.labelAddedFromOriginalWord, 0, 4); + this.tableLayoutPanel.Controls.Add(this.textBoxOriginalWord, 2, 4); + this.tableLayoutPanel.Controls.Add(this.buttonDelete, 0, 5); + this.tableLayoutPanel.Controls.Add(this.buttonOk, 3, 5); + this.tableLayoutPanel.Controls.Add(this.buttonCancel, 4, 5); + this.tableLayoutPanel.Controls.Add(this.textBoxWordBoundaryFindText, 2, 2); + this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.tableLayoutPanel.Name = "tableLayoutPanel"; + this.tableLayoutPanel.Padding = new System.Windows.Forms.Padding(12, 13, 12, 13); + this.tableLayoutPanel.RowCount = 6; + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel.Size = new System.Drawing.Size(496, 311); + this.tableLayoutPanel.TabIndex = 0; + // + // labelFind + // + this.labelFind.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.labelFind.AutoSize = true; + this.labelFind.Location = new System.Drawing.Point(47, 18); + this.labelFind.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.labelFind.Name = "labelFind"; + this.labelFind.Size = new System.Drawing.Size(30, 13); + this.labelFind.TabIndex = 0; + this.labelFind.Text = "Find:"; + // + // textBoxFindWord + // + this.tableLayoutPanel.SetColumnSpan(this.textBoxFindWord, 4); + this.textBoxFindWord.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxFindWord.Location = new System.Drawing.Point(81, 15); + this.textBoxFindWord.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.textBoxFindWord.Name = "textBoxFindWord"; + this.textBoxFindWord.Size = new System.Drawing.Size(401, 20); + this.textBoxFindWord.TabIndex = 2; + this.toolTip.SetToolTip(this.textBoxFindWord, "The word (or part of a word) to replace"); + this.textBoxFindWord.TextChanged += new System.EventHandler(this.TextBoxFindWord_TextChanged); + this.textBoxFindWord.Enter += new System.EventHandler(this.TextBoxFindWord_Enter); + // + // labelReplace + // + this.labelReplace.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.labelReplace.AutoSize = true; + this.labelReplace.Location = new System.Drawing.Point(27, 42); + this.labelReplace.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.labelReplace.Name = "labelReplace"; + this.labelReplace.Size = new System.Drawing.Size(50, 13); + this.labelReplace.TabIndex = 1; + this.labelReplace.Text = "Replace:"; + // + // textBoxReplaceWord + // + this.tableLayoutPanel.SetColumnSpan(this.textBoxReplaceWord, 4); + this.textBoxReplaceWord.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxReplaceWord.Location = new System.Drawing.Point(81, 39); + this.textBoxReplaceWord.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.textBoxReplaceWord.Name = "textBoxReplaceWord"; + this.textBoxReplaceWord.Size = new System.Drawing.Size(401, 20); + this.textBoxReplaceWord.TabIndex = 1; + this.toolTip.SetToolTip(this.textBoxReplaceWord, "The replacement word"); + this.textBoxReplaceWord.TextChanged += new System.EventHandler(this.TextBoxReplaceWord_TextChanged); + this.textBoxReplaceWord.Enter += new System.EventHandler(this.TextBoxReplaceWord_Enter); + // + // groupBoxWordBoundaries + // + this.tableLayoutPanel.SetColumnSpan(this.groupBoxWordBoundaries, 2); + this.groupBoxWordBoundaries.Controls.Add(this.checkBoxWordFinal); + this.groupBoxWordBoundaries.Controls.Add(this.checkBoxWordInitial); + this.groupBoxWordBoundaries.Location = new System.Drawing.Point(14, 63); + this.groupBoxWordBoundaries.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.groupBoxWordBoundaries.Name = "groupBoxWordBoundaries"; + this.groupBoxWordBoundaries.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.groupBoxWordBoundaries.Size = new System.Drawing.Size(150, 53); + this.groupBoxWordBoundaries.TabIndex = 3; + this.groupBoxWordBoundaries.TabStop = false; + this.groupBoxWordBoundaries.Text = "Word Boundaries"; + // + // checkBoxWordFinal + // + this.checkBoxWordFinal.AutoSize = true; + this.checkBoxWordFinal.Location = new System.Drawing.Point(94, 19); + this.checkBoxWordFinal.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.checkBoxWordFinal.Name = "checkBoxWordFinal"; + this.checkBoxWordFinal.Size = new System.Drawing.Size(45, 17); + this.checkBoxWordFinal.TabIndex = 5; + this.checkBoxWordFinal.Text = "End"; + this.checkBoxWordFinal.UseVisualStyleBackColor = true; + this.checkBoxWordFinal.CheckedChanged += new System.EventHandler(this.CheckBoxWordBoundary_CheckedChanged); + // + // checkBoxWordInitial + // + this.checkBoxWordInitial.AutoSize = true; + this.checkBoxWordInitial.Location = new System.Drawing.Point(14, 19); + this.checkBoxWordInitial.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.checkBoxWordInitial.Name = "checkBoxWordInitial"; + this.checkBoxWordInitial.Size = new System.Drawing.Size(73, 17); + this.checkBoxWordInitial.TabIndex = 4; + this.checkBoxWordInitial.Text = "Beginning"; + this.toolTip.SetToolTip(this.checkBoxWordInitial, "Click to force the find to use use an initial "); + this.checkBoxWordInitial.UseVisualStyleBackColor = true; + this.checkBoxWordInitial.CheckedChanged += new System.EventHandler(this.CheckBoxWordBoundary_CheckedChanged); + // + // labelUnicodeCodes + // + this.labelUnicodeCodes.AutoSize = true; + this.labelUnicodeCodes.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; + this.tableLayoutPanel.SetColumnSpan(this.labelUnicodeCodes, 5); + this.labelUnicodeCodes.Dock = System.Windows.Forms.DockStyle.Fill; + this.labelUnicodeCodes.Location = new System.Drawing.Point(14, 118); + this.labelUnicodeCodes.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.labelUnicodeCodes.Name = "labelUnicodeCodes"; + this.labelUnicodeCodes.Padding = new System.Windows.Forms.Padding(5, 5, 5, 5); + this.labelUnicodeCodes.Size = new System.Drawing.Size(468, 128); + this.labelUnicodeCodes.TabIndex = 9; + this.labelUnicodeCodes.Text = "labelUnicodeCodes"; + this.toolTip.SetToolTip(this.labelUnicodeCodes, "This area shows the Unicode code point values for the characters in the box above" + + " which has focus. You can use this to see hidden characters (e.g. zero width joi" + + "ner)."); + // + // labelAddedFromOriginalWord + // + this.labelAddedFromOriginalWord.AutoSize = true; + this.tableLayoutPanel.SetColumnSpan(this.labelAddedFromOriginalWord, 2); + this.labelAddedFromOriginalWord.Location = new System.Drawing.Point(14, 246); + this.labelAddedFromOriginalWord.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.labelAddedFromOriginalWord.Name = "labelAddedFromOriginalWord"; + this.labelAddedFromOriginalWord.Size = new System.Drawing.Size(136, 13); + this.labelAddedFromOriginalWord.TabIndex = 10; + this.labelAddedFromOriginalWord.Text = "Added while Clipboard had:"; + this.toolTip.SetToolTip(this.labelAddedFromOriginalWord, "This word was on the clipboard when the dialog opened."); + this.labelAddedFromOriginalWord.Visible = false; + // + // textBoxOriginalWord + // + this.tableLayoutPanel.SetColumnSpan(this.textBoxOriginalWord, 3); + this.textBoxOriginalWord.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBoxOriginalWord.Location = new System.Drawing.Point(168, 248); + this.textBoxOriginalWord.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.textBoxOriginalWord.Name = "textBoxOriginalWord"; + this.textBoxOriginalWord.ReadOnly = true; + this.textBoxOriginalWord.Size = new System.Drawing.Size(314, 20); + this.textBoxOriginalWord.TabIndex = 11; + this.toolTip.SetToolTip(this.textBoxOriginalWord, "Word originally on the Clipboard when this dialog opened."); + this.textBoxOriginalWord.Visible = false; + // + // buttonDelete + // + this.buttonDelete.DialogResult = System.Windows.Forms.DialogResult.Abort; + this.buttonDelete.Location = new System.Drawing.Point(14, 272); + this.buttonDelete.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.buttonDelete.Name = "buttonDelete"; + this.buttonDelete.Size = new System.Drawing.Size(63, 24); + this.buttonDelete.TabIndex = 8; + this.buttonDelete.Text = "Delete"; + this.buttonDelete.UseVisualStyleBackColor = true; + this.buttonDelete.Click += new System.EventHandler(this.ButtonDelete_Click); + // + // buttonOk + // + this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK; + this.buttonOk.Location = new System.Drawing.Point(354, 272); + this.buttonOk.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.buttonOk.Name = "buttonOk"; + this.buttonOk.Size = new System.Drawing.Size(62, 24); + this.buttonOk.TabIndex = 6; + this.buttonOk.Text = "OK"; + this.buttonOk.UseVisualStyleBackColor = true; + // + // buttonCancel + // + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(420, 272); + this.buttonCancel.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(62, 24); + this.buttonCancel.TabIndex = 7; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + // + // textBoxWordBoundaryFindText + // + this.textBoxWordBoundaryFindText.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.tableLayoutPanel.SetColumnSpan(this.textBoxWordBoundaryFindText, 3); + this.textBoxWordBoundaryFindText.Location = new System.Drawing.Point(168, 79); + this.textBoxWordBoundaryFindText.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.textBoxWordBoundaryFindText.Name = "textBoxWordBoundaryFindText"; + this.textBoxWordBoundaryFindText.ReadOnly = true; + this.textBoxWordBoundaryFindText.Size = new System.Drawing.Size(314, 20); + this.textBoxWordBoundaryFindText.TabIndex = 8; + // + // QueryFindReplaceDialog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(496, 311); + this.Controls.Add(this.tableLayoutPanel); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.Name = "QueryFindReplaceDialog"; + this.Text = "Find & Replace (CC)"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.QueryFindReplaceDialog_FormClosing); + this.tableLayoutPanel.ResumeLayout(false); + this.tableLayoutPanel.PerformLayout(); + this.groupBoxWordBoundaries.ResumeLayout(false); + this.groupBoxWordBoundaries.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; + private System.Windows.Forms.Label labelFind; + private System.Windows.Forms.Label labelReplace; + private System.Windows.Forms.Button buttonDelete; + private SilEncConverters40.EcTextBox textBoxFindWord; + private System.Windows.Forms.ToolTip toolTip; + private SilEncConverters40.EcTextBox textBoxReplaceWord; + private System.Windows.Forms.Label labelUnicodeCodes; + private System.Windows.Forms.Label labelAddedFromOriginalWord; + private System.Windows.Forms.TextBox textBoxOriginalWord; + private System.Windows.Forms.Button buttonOk; + private System.Windows.Forms.Button buttonCancel; + private System.Windows.Forms.CheckBox checkBoxWordInitial; + private System.Windows.Forms.CheckBox checkBoxWordFinal; + private System.Windows.Forms.GroupBox groupBoxWordBoundaries; + private System.Windows.Forms.TextBox textBoxWordBoundaryFindText; + } +} \ No newline at end of file diff --git a/src/SpellingFixerEC/QueryFindReplaceDialog.cs b/src/SpellingFixerEC/QueryFindReplaceDialog.cs new file mode 100644 index 00000000..3b30b2c5 --- /dev/null +++ b/src/SpellingFixerEC/QueryFindReplaceDialog.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SpellingFixerEC +{ + public partial class QueryFindReplaceDialog : Form + { + private string _findWhat; + public string FindWhat + { + get + { + return $"{BoundaryInitial}{_findWhat}{BoundaryFinal}"; + } + set + { + _findWhat = value; + } + } + public string ReplaceWith { get; set; } + public string BoundaryCharacter { get; set; } + + private String BoundaryInitial + { + get + { + return (IsBoundaryInitial) ? BoundaryCharacter : String.Empty; + } + } + + private String BoundaryFinal + { + get + { + return (IsBoundaryFinal) ? BoundaryCharacter : String.Empty; + } + } + + public QueryFindReplaceDialog(Font font) + { + InitializeComponent(); + + textBoxFindWord.Font = + textBoxOriginalWord.Font = + textBoxWordBoundaryFindText.Font = + textBoxReplaceWord.Font = font; + } + + public DialogResult ShowDialog(string findWhat, string replaceWith, string originalWord, + bool isRightToLeft, string boundaryCharacter, bool isShowDelete) + { + if (findWhat?.StartsWith(boundaryCharacter) ?? false) + { + IsBoundaryInitial = checkBoxWordInitial.Checked = true; + findWhat = findWhat.Substring(1); + } + + if (findWhat?.EndsWith(boundaryCharacter) ?? false) + { + IsBoundaryFinal = checkBoxWordFinal.Checked = true; + findWhat = findWhat.Substring(0, findWhat.Length - 1); + } + + if (originalWord?.StartsWith(boundaryCharacter) ?? false) + { + originalWord = originalWord.Substring(1); + } + + if (originalWord?.EndsWith(boundaryCharacter) ?? false) + { + originalWord = originalWord.Substring(0, originalWord.Length - 1); + } + + FindWhat = textBoxFindWord.Text = findWhat; + textBoxReplaceWord.Text = replaceWith; + textBoxOriginalWord.Text = originalWord; + BoundaryCharacter = boundaryCharacter; + + if (isRightToLeft) + { + textBoxFindWord.RightToLeft = RightToLeft.Yes; + textBoxReplaceWord.RightToLeft = RightToLeft.Yes; + textBoxOriginalWord.RightToLeft = RightToLeft.Yes; + textBoxWordBoundaryFindText.RightToLeft = RightToLeft.Yes; + } + + buttonDelete.Visible = isShowDelete; + + if (findWhat != replaceWith) + { + this.Text = "Existing Replacement Rule"; + if (!String.IsNullOrEmpty(originalWord)) + { + labelAddedFromOriginalWord.Visible = + textBoxOriginalWord.Visible = true; + this.textBoxOriginalWord.Text = originalWord; + } + } + + UpdateFindWhatDisplay(); + var res = base.ShowDialog(); + return res; + } + + private void UpdateUniCodes(string strInputString) + { + string strWhole = null; + foreach (char ch in strInputString) + { + string strPiece; + if (ch == 0) // sometimes it's null (esp. for utf32) + { + strPiece = "nul (u0000) "; + } + else + { + var strUPiece = String.Format("{0:X}", (int)ch); + + // left pad with 0's (there may be a better way to do this, but + // I don't know what it is) + while (strUPiece.Length < 4) strUPiece = "0" + strUPiece; + + strPiece = String.Format("{0:#} (u{1,4}) ", ch, strUPiece); + } + strWhole += strPiece; + } + + labelUnicodeCodes.Text = strWhole; + } + + private void CheckBoxWordBoundary_CheckedChanged(object sender, EventArgs e) + { + UpdateFindWhatDisplay(); + } + + private void TextBoxFindWord_TextChanged(object sender, EventArgs e) + { + FindWhat = textBoxFindWord.Text; + UpdateFindWhatDisplay(); + UpdateUniCodes(textBoxFindWord.Text); + } + + private void TextBoxReplaceWord_TextChanged(object sender, EventArgs e) + { + UpdateUniCodes(textBoxReplaceWord.Text); + ReplaceWith = textBoxReplaceWord.Text; + } + + private void TextBoxFindWord_Enter(object sender, EventArgs e) + { + UpdateUniCodes(textBoxFindWord.Text); + } + + private void TextBoxReplaceWord_Enter(object sender, EventArgs e) + { + UpdateUniCodes(textBoxReplaceWord.Text); + } + + private bool IsBoundaryInitial { get; set; } + private bool IsBoundaryFinal { get; set; } + + private void UpdateFindWhatDisplay() + { + IsBoundaryInitial = checkBoxWordInitial.Checked; + IsBoundaryFinal = checkBoxWordFinal.Checked; + + textBoxWordBoundaryFindText.Text = FindWhat; + } + + private void QueryFindReplaceDialog_FormClosing(object sender, FormClosingEventArgs e) + { + if (String.IsNullOrEmpty(FindWhat) && (DialogResult == DialogResult.OK)) + { + MessageBox.Show("You can't have an empty value for the \"Find What\" text. Click Cancel if you didn't mean to add a rule.", SpellingFixerEC.cstrCaption); + e.Cancel = true; + } + } + + private void ButtonDelete_Click(object sender, EventArgs e) + { + Close(); // button has DialogResult.Abort associated w/ it, which triggers the caller to delete + } + } +} diff --git a/src/SpellingFixerEC/QueryGoodSpelling.resx b/src/SpellingFixerEC/QueryFindReplaceDialog.resx similarity index 92% rename from src/SpellingFixerEC/QueryGoodSpelling.resx rename to src/SpellingFixerEC/QueryFindReplaceDialog.resx index 42f91293..dc496dc4 100644 --- a/src/SpellingFixerEC/QueryGoodSpelling.resx +++ b/src/SpellingFixerEC/QueryFindReplaceDialog.resx @@ -1,149 +1,146 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 130, 17 - - - - - AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/ - AAAA//8A/wAAAP8A/wD//wAA////AHd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3 - d3f3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3 - d3d3d//////3d3d3d3d3d3d3d3f//////3d3d3d3d3d3d3d3//////d3d3d3d3d3d3d3d3d3f/93d3d3 - d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d393d3d3d3d3d3d3d3d3d3d3d3 - d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7d3e7u7u3d3u7u7t3e7u7u3d3u7u7t3d7u7u7d3u7d3d3d3d3 - d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3f3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3 - d3d3d3//d3d3d3d3d3d3d3d3d3f/93d3d3d3d3d3d3d3d3d//////3d3d3d3d3d3d3d3//////93d3d3 - d3d3d3d3d3//////d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d3//d3 - d3d3d3d3d3d3d3d3d393d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAoAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA - AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AHd3d3d3d3d3d3d3d/d3 - d3d3d3d3f3d3d3d3d///93d3d3d3d393d3d3d3d393d3d3d3d3d3d3d3u7t3u7t3u7u7u3e7u3e7u3d3 - d3d3d3d3d3d3f3d3d3d3d3f3d3d3d3d3f///d3d3d3d393d3d3d3d3d/d3d3d3d3d3d3d3d3AAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAIAICAQAAAAAADoAgAAJgAAABAQEAAAAAAAKAEAAA4DAAAoAAAAIAAAAEAAAAABAAQAAAAAAIAC + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/ + AAAA//8A/wAAAP8A/wD//wAA////AHd3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3 + d3f3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3 + d3d3d//////3d3d3d3d3d3d3d3f//////3d3d3d3d3d3d3d3//////d3d3d3d3d3d3d3d3d3f/93d3d3 + d3d3d3d3d3d3d//3d3d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d393d3d3d3d3d3d3d3d3d3d3d3 + d3d3d3d3d3d3d3d3d3d3d3d3d3d3d7u7d3e7u7u3d3u7u7t3e7u7u3d3u7u7t3d7u7u7d3u7d3d3d3d3 + d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3f3d3d3d3d3d3d3d3d3d3d//3d3d3d3d3d3d3 + d3d3d3//d3d3d3d3d3d3d3d3d3f/93d3d3d3d3d3d3d3d3d//////3d3d3d3d3d3d3d3//////93d3d3 + d3d3d3d3d3//////d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d3//d3d3d3d3d3d3d3d3d3d3//d3 + d3d3d3d3d3d3d3d3d393d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAoAAAAEAAAACAAAAABAAQAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA + AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AHd3d3d3d3d3d3d3d/d3 + d3d3d3d3f3d3d3d3d///93d3d3d3d393d3d3d3d393d3d3d3d3d3d3d3u7t3u7t3u7u7u3e7u3e7u3d3 + d3d3d3d3d3d3f3d3d3d3d3f3d3d3d3d3f///d3d3d3d393d3d3d3d3d/d3d3d3d3d3d3d3d3AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + \ No newline at end of file diff --git a/src/SpellingFixerEC/QueryGoodSpelling.cs b/src/SpellingFixerEC/QueryGoodSpelling.cs deleted file mode 100644 index bcfa84ef..00000000 --- a/src/SpellingFixerEC/QueryGoodSpelling.cs +++ /dev/null @@ -1,367 +0,0 @@ -using System; -using System.Drawing; -using System.Collections; -using System.ComponentModel; -using System.Windows.Forms; -using System.Runtime.InteropServices; // for ComVisible -using SilEncConverters40; - -namespace SpellingFixerEC -{ - /// - /// Summary description for QueryGoodSpelling. - /// - internal class QueryGoodSpelling : System.Windows.Forms.Form - { - private IContainer components; - private System.Windows.Forms.Label label1 = null; - private EcTextBox textBoxBadWord = null; - private System.Windows.Forms.Label label2 = null; - private EcTextBox textBoxReplacement = null; - private System.Windows.Forms.Button buttonOK = null; - private System.Windows.Forms.Button buttonCancel = null; - private string m_strGoodWord; - private System.Windows.Forms.Label labelUniCodes; - private System.Windows.Forms.Button buttonDelete; - private System.Windows.Forms.TextBox labelOriginalReason; - private System.Windows.Forms.Label labelOrigReasonLabel; - private TableLayoutPanel tableLayoutPanel; - private HelpProvider helpProvider; - private ToolTip toolTip; - private string m_strBadWord; // in case we change it - - public QueryGoodSpelling(Font font) - { - // - // Required for Windows Form Designer support - // - InitializeComponent(); - - textBoxBadWord.Font = font; - textBoxReplacement.Font = font; - labelOriginalReason.Font = font; - - helpProvider.SetHelpString(this.textBoxBadWord, Properties.Resources.textBoxBadWordHelp); - helpProvider.SetHelpString(this.textBoxReplacement, Properties.Resources.textBoxReplacementHelp); - } - - public DialogResult ShowDialog(string strBadWord, string strReplacement, string strOriginalWord, bool bShowDelete) - { - textBoxBadWord.Text = strBadWord; - textBoxReplacement.Text = strReplacement; - - textBoxReplacement.Focus(); - textBoxReplacement.SelectAll(); - - this.buttonDelete.Visible = bShowDelete; - - if (strBadWord != strReplacement) - { - this.Text = "Existing Replacement Rule"; - if (!String.IsNullOrEmpty(strOriginalWord)) - { - this.labelOrigReasonLabel.Visible = true; - this.labelOriginalReason.Visible = true; - this.labelOriginalReason.Text = strOriginalWord; - } - } - - return base.ShowDialog(); - } - - public string GoodSpelling - { - get { return m_strGoodWord; } - } - - public string BadSpelling - { - get { return m_strBadWord; } - } - - /// - /// Clean up any resources being used. - /// - protected override void Dispose( bool disposing ) - { - if( disposing ) - { - if(components != null) - { - components.Dispose(); - } - } - base.Dispose( disposing ); - } - - #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QueryGoodSpelling)); - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.buttonOK = new System.Windows.Forms.Button(); - this.buttonCancel = new System.Windows.Forms.Button(); - this.labelUniCodes = new System.Windows.Forms.Label(); - this.buttonDelete = new System.Windows.Forms.Button(); - this.labelOriginalReason = new System.Windows.Forms.TextBox(); - this.labelOrigReasonLabel = new System.Windows.Forms.Label(); - this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); - this.textBoxBadWord = new EcTextBox(); - this.textBoxReplacement = new EcTextBox(); - this.helpProvider = new System.Windows.Forms.HelpProvider(); - this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.tableLayoutPanel.SuspendLayout(); - this.SuspendLayout(); - // - // label1 - // - this.label1.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(28, 6); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(69, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Bad Spelling:"; - // - // label2 - // - this.label2.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(24, 32); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(73, 13); - this.label2.TabIndex = 2; - this.label2.Text = "Replacement:"; - // - // buttonOK - // - this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonOK.Location = new System.Drawing.Point(237, 244); - this.buttonOK.Name = "buttonOK"; - this.buttonOK.Size = new System.Drawing.Size(61, 23); - this.buttonOK.TabIndex = 3; - this.buttonOK.Text = "OK"; - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); - // - // buttonCancel - // - this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.buttonCancel.Location = new System.Drawing.Point(304, 244); - this.buttonCancel.Name = "buttonCancel"; - this.buttonCancel.Size = new System.Drawing.Size(61, 23); - this.buttonCancel.TabIndex = 4; - this.buttonCancel.Text = "Cancel"; - this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); - // - // labelUniCodes - // - this.labelUniCodes.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.tableLayoutPanel.SetColumnSpan(this.labelUniCodes, 4); - this.labelUniCodes.Dock = System.Windows.Forms.DockStyle.Fill; - this.helpProvider.SetHelpString(this.labelUniCodes, "This area shows the Unicode code point values for the characters in the box above" + - " which has focus. You can use this to see hidden characters (e.g. zero width joi" + - "ner)."); - this.labelUniCodes.Location = new System.Drawing.Point(3, 55); - this.labelUniCodes.Margin = new System.Windows.Forms.Padding(3); - this.labelUniCodes.Name = "labelUniCodes"; - this.labelUniCodes.Padding = new System.Windows.Forms.Padding(3); - this.helpProvider.SetShowHelp(this.labelUniCodes, true); - this.labelUniCodes.Size = new System.Drawing.Size(362, 157); - this.labelUniCodes.TabIndex = 5; - this.labelUniCodes.Text = "labelUniCodes"; - // - // buttonDelete - // - this.buttonDelete.DialogResult = System.Windows.Forms.DialogResult.Abort; - this.buttonDelete.Location = new System.Drawing.Point(3, 244); - this.buttonDelete.Name = "buttonDelete"; - this.buttonDelete.Size = new System.Drawing.Size(67, 23); - this.buttonDelete.TabIndex = 6; - this.buttonDelete.Text = "Delete"; - this.buttonDelete.Visible = false; - this.buttonDelete.Click += new System.EventHandler(this.buttonDelete_Click); - // - // labelOriginalReason - // - this.tableLayoutPanel.SetColumnSpan(this.labelOriginalReason, 3); - this.labelOriginalReason.Dock = System.Windows.Forms.DockStyle.Fill; - this.labelOriginalReason.Location = new System.Drawing.Point(103, 218); - this.labelOriginalReason.Name = "labelOriginalReason"; - this.labelOriginalReason.ReadOnly = true; - this.labelOriginalReason.Size = new System.Drawing.Size(262, 20); - this.labelOriginalReason.TabIndex = 7; - this.labelOriginalReason.Visible = false; - // - // labelOrigReasonLabel - // - this.labelOrigReasonLabel.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.labelOrigReasonLabel.AutoSize = true; - this.labelOrigReasonLabel.Location = new System.Drawing.Point(3, 221); - this.labelOrigReasonLabel.Name = "labelOrigReasonLabel"; - this.labelOrigReasonLabel.Size = new System.Drawing.Size(94, 13); - this.labelOrigReasonLabel.TabIndex = 8; - this.labelOrigReasonLabel.Text = "added while fixing:"; - this.labelOrigReasonLabel.Visible = false; - // - // tableLayoutPanel - // - this.tableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.tableLayoutPanel.ColumnCount = 4; - this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel.Controls.Add(this.labelOriginalReason, 1, 3); - this.tableLayoutPanel.Controls.Add(this.textBoxBadWord, 1, 0); - this.tableLayoutPanel.Controls.Add(this.label2, 0, 1); - this.tableLayoutPanel.Controls.Add(this.labelUniCodes, 0, 2); - this.tableLayoutPanel.Controls.Add(this.buttonDelete, 0, 4); - this.tableLayoutPanel.Controls.Add(this.textBoxReplacement, 1, 1); - this.tableLayoutPanel.Controls.Add(this.buttonOK, 2, 4); - this.tableLayoutPanel.Controls.Add(this.label1, 0, 0); - this.tableLayoutPanel.Controls.Add(this.labelOrigReasonLabel, 0, 3); - this.tableLayoutPanel.Controls.Add(this.buttonCancel, 3, 4); - this.tableLayoutPanel.Location = new System.Drawing.Point(12, 12); - this.tableLayoutPanel.Name = "tableLayoutPanel"; - this.tableLayoutPanel.RowCount = 5; - this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel.Size = new System.Drawing.Size(368, 270); - this.tableLayoutPanel.TabIndex = 9; - // - // textBoxBadWord - // - this.tableLayoutPanel.SetColumnSpan(this.textBoxBadWord, 3); - this.textBoxBadWord.Dock = System.Windows.Forms.DockStyle.Fill; - this.helpProvider.SetHelpString(this.textBoxBadWord, ""); - this.textBoxBadWord.Location = new System.Drawing.Point(103, 3); - this.textBoxBadWord.Name = "textBoxBadWord"; - this.helpProvider.SetShowHelp(this.textBoxBadWord, true); - this.textBoxBadWord.Size = new System.Drawing.Size(262, 20); - this.textBoxBadWord.TabIndex = 1; - this.textBoxBadWord.Text = "textBoxBadWord"; - this.toolTip.SetToolTip(this.textBoxBadWord, "Contains the bad spelling form"); - this.textBoxBadWord.GotFocus += new System.EventHandler(this.textBoxBadWord_GotFocus); - this.textBoxBadWord.TextChanged += new System.EventHandler(this.textBoxBadWord_TextChanged); - // - // textBoxReplacement - // - this.tableLayoutPanel.SetColumnSpan(this.textBoxReplacement, 3); - this.textBoxReplacement.Dock = System.Windows.Forms.DockStyle.Fill; - this.helpProvider.SetHelpString(this.textBoxReplacement, ""); - this.textBoxReplacement.Location = new System.Drawing.Point(103, 29); - this.textBoxReplacement.Name = "textBoxReplacement"; - this.helpProvider.SetShowHelp(this.textBoxReplacement, true); - this.textBoxReplacement.Size = new System.Drawing.Size(262, 20); - this.textBoxReplacement.TabIndex = 1; - this.textBoxReplacement.Text = "textBoxReplacement"; - this.toolTip.SetToolTip(this.textBoxReplacement, "Contains the good spelling form (i.e. the replacment for when the bad spelling fo" + - "rm occurs)"); - this.textBoxReplacement.GotFocus += new System.EventHandler(this.textBoxReplacement_GotFocus); - this.textBoxReplacement.TextChanged += new System.EventHandler(this.textBoxReplacement_TextChanged); - // - // QueryGoodSpelling - // - this.AcceptButton = this.buttonOK; - this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); - this.ClientSize = new System.Drawing.Size(392, 294); - this.Controls.Add(this.tableLayoutPanel); - this.HelpButton = true; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "QueryGoodSpelling"; - this.Text = "Fix Spelling"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.QueryGoodSpelling_FormClosing); - this.tableLayoutPanel.ResumeLayout(false); - this.tableLayoutPanel.PerformLayout(); - this.ResumeLayout(false); - - } - #endregion - - private void buttonOK_Click(object sender, System.EventArgs e) - { - m_strGoodWord = this.textBoxReplacement.Text; - m_strBadWord = this.textBoxBadWord.Text; - this.Close(); - } - - private void QueryGoodSpelling_FormClosing(object sender, FormClosingEventArgs e) - { - if (String.IsNullOrEmpty(m_strBadWord) && (DialogResult == DialogResult.OK)) - { - MessageBox.Show("You can't have an empty Bad Spelling form. Click Cancel if you didn't mean to add a rule.", SpellingFixerEC.cstrCaption); - e.Cancel = true; - } - } - - private void buttonCancel_Click(object sender, System.EventArgs e) - { - // this.DialogResult = DialogResult.Cancel; - this.Close(); - } - - private void textBoxBadWord_GotFocus(object sender, EventArgs e) - { - UpdateUniCodes(this.textBoxBadWord.Text); - } - - private void textBoxReplacement_GotFocus(object sender, EventArgs e) - { - UpdateUniCodes(this.textBoxReplacement.Text); - } - - private void UpdateUniCodes(string strInputString) - { - int nLenString = strInputString.Length; - - string strWhole = null, strPiece = null, strUPiece = null; - foreach(char ch in strInputString) - { - if( ch == 0 ) // sometimes it's null (esp. for utf32) - strPiece = "nul (u0000) "; - else - { - strUPiece = String.Format("{0:X}", (int)ch); - - // left pad with 0's (there may be a better way to do this, but - // I don't know what it is) - while(strUPiece.Length < 4) strUPiece = "0" + strUPiece; - - strPiece = String.Format("{0:#} (u{1,4}) ", ch, strUPiece); - } - strWhole += strPiece; - } - - this.labelUniCodes.Text = strWhole; - } - - private void textBoxBadWord_TextChanged(object sender, EventArgs e) - { - UpdateUniCodes(this.textBoxBadWord.Text); - } - - private void textBoxReplacement_TextChanged(object sender, EventArgs e) - { - UpdateUniCodes(this.textBoxReplacement.Text); - } - - private void buttonDelete_Click(object sender, System.EventArgs e) - { - this.Close(); - } - } -} diff --git a/src/SpellingFixerEC/SpellingFixerEC.cs b/src/SpellingFixerEC/SpellingFixerEC.cs index 0b767ca5..055f59ed 100644 --- a/src/SpellingFixerEC/SpellingFixerEC.cs +++ b/src/SpellingFixerEC/SpellingFixerEC.cs @@ -25,6 +25,7 @@ public class SpellingFixerEC { public const string cstrAttributeFontToUse = "SpellingFixer Display Font"; public const string cstrAttributeFontSizeToUse = "SpellingFixer Display Font Size"; + public const string cstrAttributeFontRightToLeft = "SpellingFixer Display Right to Left"; public const string cstrAttributeWordBoundaryDelimiter = "SpellingFixer Word Boundary Delimiter"; public const string cstrAttributeNonWordChars = "SpellingFixer punctuation and whitespace characters"; public const string cstrDefaultPunctuationAndWhitespace = "' ' tab nl '.' ',' '!' ':' ';' '-' \"'\" '\"' '' '' '' '' '(' ')' '[' ']' '{' '}'"; @@ -45,8 +46,7 @@ public class SpellingFixerEC private string m_strNonWordChars; private string m_strConverterSpec; private string m_strEncConverterName; - private bool m_bLegacy; - private int m_cp = 1252; + private bool m_isRightToLeft; // leave a default constructor which *doesn't* automatically log-in to a project for // COM clients that want to use CscProject via SelectProject below. @@ -60,13 +60,11 @@ public SpellingFixerEC() ///
public void LoginProject() { - LoginSF login = new LoginSF(); + var login = new LoginSF(); if (login.ShowDialog() == DialogResult.OK) { m_font = login.FontToUse; - m_bLegacy = login.IsLegacy; - if (m_bLegacy) - m_cp = login.CpToUse; + m_isRightToLeft = login.IsRightToLeft; m_strConverterSpec = login.ConverterSpec; SpellFixerEncConverterName = login.EncConverterName; WordBoundaryDelimiter = login.WordBoundaryDelimiter; @@ -78,13 +76,11 @@ public void LoginProject() public SpellingFixerEC(string strProjectName) { - LoginSF login = new LoginSF(); + var login = new LoginSF(); if (login.LoadProject(strProjectName)) { m_font = login.FontToUse; - m_bLegacy = login.IsLegacy; - if (m_bLegacy) - m_cp = login.CpToUse; + m_isRightToLeft = login.IsRightToLeft; m_strConverterSpec = login.ConverterSpec; SpellFixerEncConverterName = login.EncConverterName; WordBoundaryDelimiter = login.WordBoundaryDelimiter; @@ -97,12 +93,11 @@ public SpellingFixerEC(string strProjectName) public SpellingFixerEC(string strProjectName, Font font, string strConverterSpec, string strEncConverterName, [Optional, DefaultParameterValue(SpellingFixerEC.cstrDefaultWordBoundaryDelimiter)] string strWordBoundaryDelimiter, [Optional, DefaultParameterValue(cstrDefaultPunctuationAndWhitespace)] string strPunctuationAndWhiteSpace, - [Optional, DefaultParameterValue(false)] bool bLegacy, [Optional, DefaultParameterValue(1252)] int cp) + [Optional, DefaultParameterValue(false)] bool bLegacy, [Optional, DefaultParameterValue(1252)] int cp, + [Optional, DefaultParameterValue(false)] bool bRightToLeft) { m_font = font; - m_bLegacy = bLegacy; - if (m_bLegacy) - m_cp = cp; + m_isRightToLeft = bRightToLeft; m_strConverterSpec = strConverterSpec; SpellFixerEncConverterName = strEncConverterName; WordBoundaryDelimiter = strWordBoundaryDelimiter; @@ -143,8 +138,8 @@ public IEncConverter SpellFixerEncConverter if (m_strEncConverterName == null) return null; - EncConverters aECs = new EncConverters(); - IEncConverter aEC = null; + var aECs = new EncConverters(); + IEncConverter aEC; if (aECs.ContainsKey(m_strEncConverterName)) aEC = aECs[m_strEncConverterName]; else @@ -152,9 +147,9 @@ public IEncConverter SpellFixerEncConverter aEC = new CcEncConverter(); string strDummy = null; int nProcType = 0; - ConvType eConvType = (m_bLegacy) ? ConvType.Legacy_to_Legacy : ConvType.Unicode_to_Unicode; + var eConvType = ConvType.Unicode_to_Unicode; aEC.Initialize(m_strEncConverterName, m_strConverterSpec, ref strDummy, ref strDummy, - ref eConvType, ref nProcType, m_cp, m_cp, true); + ref eConvType, ref nProcType, 0, 0, true); } return aEC; @@ -167,6 +162,12 @@ private string WordBoundaryDelimiter set { m_strWordBoundaryDelimiter = value; } } + private bool IsRightToLeft + { + get { return m_isRightToLeft; } + set { m_isRightToLeft = value; } + } + private string PunctuationAndWhiteSpace { get { return m_strNonWordChars; } @@ -183,9 +184,8 @@ public void QueryForSpellingCorrectionIfTableEmpty(string strBadWord) // even if the file exists, it might have no rules, so double-check if (File.Exists(m_strConverterSpec)) { - DataTable myTable; Encoding enc = GetEncoding; - if ( !InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out myTable) + if ( !InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out DataTable myTable) || (myTable.Rows.Count > 0)) { return; // don't query for a record if there are already spelling corrections in the file @@ -193,7 +193,7 @@ public void QueryForSpellingCorrectionIfTableEmpty(string strBadWord) } else { - LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace, null, !this.m_bLegacy); + LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace); } QueryAndAppend(strBadWord); @@ -201,16 +201,20 @@ public void QueryForSpellingCorrectionIfTableEmpty(string strBadWord) protected void QueryAndAppend(string strBadWord) { +#if !OldDialogs + var aQuery = new QueryFindReplaceDialog(m_font); +#else QueryGoodSpelling aQuery = new QueryGoodSpelling(m_font); - if (aQuery.ShowDialog(strBadWord, strBadWord, strBadWord, false) == DialogResult.OK) +#endif + if (aQuery.ShowDialog(strBadWord, strBadWord, strBadWord, IsRightToLeft, WordBoundaryDelimiter, false) == DialogResult.OK) { // if it was legacy encoded, then we need to convert the data to narrow using // the code page the user specified (or we got out of the repository) Encoding enc = GetEncoding; // get a stream writer for these encoding and append - StreamWriter sw = new StreamWriter(m_strConverterSpec, true, enc); - sw.WriteLine(FormatSubstitutionRule(aQuery.BadSpelling, aQuery.GoodSpelling, WordBoundaryDelimiter, strBadWord)); + var sw = new StreamWriter(m_strConverterSpec, true, enc); + sw.WriteLine(FormatSubstitutionRule(aQuery.FindWhat, aQuery.ReplaceWith, WordBoundaryDelimiter, strBadWord)); sw.Flush(); sw.Close(); } @@ -242,7 +246,7 @@ public void AssignCorrectSpelling(string strBadWord) } else { - LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace, null, !this.m_bLegacy); + LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace); } QueryAndAppend(strBadWord); @@ -271,7 +275,7 @@ public void AssignCorrectSpelling(string strBadWord, string strReplacement) } else { - LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace, null, !this.m_bLegacy); + LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace); } // if it was legacy encoded, then we need to convert the data to narrow using @@ -279,7 +283,7 @@ public void AssignCorrectSpelling(string strBadWord, string strReplacement) Encoding enc = GetEncoding; // get a stream writer for this encoding and append - StreamWriter sw = new StreamWriter(m_strConverterSpec, true, enc); + var sw = new StreamWriter(m_strConverterSpec, true, enc); sw.WriteLine(FormatSubstitutionRule(strBadWord, strReplacement, WordBoundaryDelimiter, strBadWord)); sw.Flush(); sw.Close(); @@ -294,9 +298,8 @@ public void FindReplacementRule(string strWord) CleanWord(ref strWord); // Open the CC table that has the mappings and put them in a DataTable. - DataTable myTable; Encoding enc = GetEncoding; - if (InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out myTable)) + if (InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out DataTable myTable)) { // temporary filename for temporary CC tables (to check portions of the file at a time) string strTempName = Path.GetTempFileName(); @@ -365,8 +368,12 @@ public void FindReplacementRule(string strWord) else if ((nFoundIndex >= 0) && (nFoundIndex < myTable.Rows.Count)) { DataRow row = myTable.Rows[nFoundIndex]; +#if !OldDialogs + var aQuery = new QueryFindReplaceDialog(m_font); +#else QueryGoodSpelling aQuery = new QueryGoodSpelling(m_font); - DialogResult res = aQuery.ShowDialog((string)row[strColumnLhs], (string)row[strColumnRhs], GetComment(row), true); +#endif + DialogResult res = aQuery.ShowDialog((string)row[strColumnLhs], (string)row[strColumnRhs], GetComment(row), IsRightToLeft, WordBoundaryDelimiter, true); bool bRewrite = false; if (res == DialogResult.Abort) { @@ -377,14 +384,14 @@ public void FindReplacementRule(string strWord) // if the user clicks OK and has made a change... if ((res == DialogResult.OK) - && (((string)row[strColumnLhs] != aQuery.BadSpelling) - || ((string)row[strColumnRhs] != aQuery.GoodSpelling) + && (((string)row[strColumnLhs] != aQuery.FindWhat) + || ((string)row[strColumnRhs] != aQuery.ReplaceWith) ) ) { // update the table and rewrite - row[strColumnLhs] = aQuery.BadSpelling; - row[strColumnRhs] = aQuery.GoodSpelling; + row[strColumnLhs] = aQuery.FindWhat; + row[strColumnRhs] = aQuery.ReplaceWith; row[strColumnCmt] = strWord; bRewrite = true; } @@ -392,7 +399,6 @@ public void FindReplacementRule(string strWord) if (bRewrite) { // write the newly updated DataTable - LoginSF.ReWriteCCTableHeader(m_strConverterSpec, PunctuationAndWhiteSpace, enc); AppendCCTableFromDataTable(m_strConverterSpec, enc, WordBoundaryDelimiter, PunctuationAndWhiteSpace, myTable); } } @@ -408,20 +414,19 @@ public void EditSpellingFixes() // Open the CC table that has the mappings and put them in a DataTable. if (!File.Exists(m_strConverterSpec)) { - LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace, null, !this.m_bLegacy); + LoginSF.CreateCCTable(m_strConverterSpec, SpellFixerEncConverterName, PunctuationAndWhiteSpace); } // if it was legacy encoded, then we need to convert the data to narrow using // the code page the user specified (or we got out of the repository) Encoding enc = GetEncoding; - DataTable myTable; - if (InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out myTable)) + if (InitializeDataTableFromCCTable(m_strConverterSpec, enc, WordBoundaryDelimiter, out DataTable myTable)) { // now put up an editable grid with this data. DialogResult res = DialogResult.Cancel; try { - ViewBadGoodPairsDlg dlg = new ViewBadGoodPairsDlg(myTable, m_font); + var dlg = new ViewBadGoodPairsDlg(myTable, m_font, WordBoundaryDelimiter, IsRightToLeft); res = dlg.ShowDialog(); } #if DEBUG @@ -435,7 +440,6 @@ public void EditSpellingFixes() if (res == DialogResult.OK) { - LoginSF.ReWriteCCTableHeader(m_strConverterSpec, PunctuationAndWhiteSpace, enc); AppendCCTableFromDataTable(m_strConverterSpec, enc, WordBoundaryDelimiter, PunctuationAndWhiteSpace, myTable); } } @@ -446,19 +450,7 @@ protected Encoding GetEncoding { get { - // if it was legacy encoded, then we need to convert the data to narrow using - // the code page the user specified (or we got out of the repository) - Encoding enc = null; - if (m_bLegacy) - { - int cp = m_cp; - if (m_cp == EncConverters.cnSymbolFontCodePage) - cp = EncConverters.cnIso8859_1CodePage; - enc = Encoding.GetEncoding(cp); - } - else - enc = new UTF8Encoding(); - + var enc = new UTF8Encoding(); return enc; } } @@ -467,7 +459,7 @@ protected static DataTable GetDataTable { get { - DataTable myTable = new DataTable("SpellingFixesList"); + var myTable = new DataTable("SpellingFixesList"); myTable.Columns.Add(new DataColumn(strColumnLhs, typeof(string))); myTable.Columns.Add(new DataColumn(strColumnRhs, typeof(string))); myTable.Columns.Add(new DataColumn(strColumnCmt, typeof(string))); @@ -481,8 +473,8 @@ private static void CleanWord(ref string str) // then strip off invalid chars (that sometimes come in from Word) if (str != null) { - int nIndexBadChar = 0; char[] aBadChars = new char[] { '\r', '\n' }; + int nIndexBadChar; while ((nIndexBadChar = str.IndexOfAny(aBadChars)) != -1) str = str.Remove(nIndexBadChar, 1); } @@ -506,7 +498,7 @@ private bool ChaChaChaChaChanges(IEncConverter aEC, string strFileName, string s { string strDummy = null; int lProcessType = (int)SpellingFixerEC.SFProcessType; - ConvType eConvType = (m_bLegacy) ? ConvType.Legacy_to_Legacy : ConvType.Unicode_to_Unicode; + var eConvType = ConvType.Unicode_to_Unicode; aEC.Initialize("dummyname", strFileName, ref strDummy, ref strDummy, ref eConvType, ref lProcessType, 0, 0, true); return (aEC.Convert(strWord) != strWord); } @@ -517,20 +509,6 @@ private bool ChaChaChaChaChanges(IEncConverter aEC, string strFileName, Encoding return ChaChaChaChaChanges(aEC, strFileName, strWord); } - private void GetPortionOfTable(DataTable myTable, int nIndex, int nLength, ref DataTable tblTestingRules) - { - tblTestingRules.Clear(); - for (int i = nIndex; (nLength-- > 0); nIndex++) - { - DataRow row = myTable.Rows[nIndex]; - DataRow newRow = tblTestingRules.NewRow(); - newRow[strColumnLhs] = row[strColumnLhs]; - newRow[strColumnRhs] = row[strColumnRhs]; - newRow[strColumnCmt] = row[strColumnCmt]; - tblTestingRules.Rows.Add(newRow); - } - } - internal static string FormatSubstitutionRule(string strBad, string strGood, string strWordBoundaryDelimiter, string strCommentWord) { // if the user indicated a word boundary condition (i.e. #pete, ete#, or #pete#) @@ -582,14 +560,18 @@ internal static void AppendCCTableFromDataTable string strConverterSpec, Encoding enc, string strWordBoundaryDelimiter, - string strPunctuationAndWhiteSpace, + string strNonWordCharacters, DataTable myTable ) { + int rowCount = myTable.Rows.Count; + + LoginSF.ReWriteCCTableHeader(strConverterSpec, strNonWordCharacters, enc, rowCount > 0); + // get a stream writer to write the new pairs - StreamWriter sw = new StreamWriter(strConverterSpec, true, enc); + var sw = new StreamWriter(strConverterSpec, true, enc); - AppendCCTableFromDataTable(sw, strWordBoundaryDelimiter, strPunctuationAndWhiteSpace, myTable, 0, myTable.Rows.Count); + AppendCCTableFromDataTable(sw, strWordBoundaryDelimiter, myTable, 0, rowCount); sw.Flush(); sw.Close(); @@ -600,9 +582,9 @@ internal void WriteCCTableFromDataTable(string strFilename, Encoding enc, DataTa if (File.Exists(strFilename)) File.Delete(strFilename); - StreamWriter sw = new StreamWriter(strFilename, false, enc); - LoginSF.CreateCCTable(sw, SpellFixerEncConverterName, PunctuationAndWhiteSpace, null, !m_bLegacy); - AppendCCTableFromDataTable(sw, WordBoundaryDelimiter, PunctuationAndWhiteSpace, tbl, nTableIndex, nNumRows); + var sw = new StreamWriter(strFilename, false, enc); + LoginSF.CreateCCTable(sw, SpellFixerEncConverterName, PunctuationAndWhiteSpace); + AppendCCTableFromDataTable(sw, WordBoundaryDelimiter, tbl, nTableIndex, nNumRows); sw.Flush(); sw.Close(); } @@ -611,7 +593,6 @@ internal static void AppendCCTableFromDataTable ( StreamWriter sw, string strWordBoundaryDelimiter, - string strPunctuationAndWhiteSpace, DataTable myTable, int nTableIndex, int nNumRows @@ -638,10 +619,10 @@ int nNumRows internal static StreamReader InitReaderPastHeader(string strConverterSpec, Encoding enc) { // get a stream writer for these encoding and append - StreamReader sr = new StreamReader(strConverterSpec, enc); + var sr = new StreamReader(strConverterSpec, enc); // skip past the header lines - string line = null; + string line; do { line = sr.ReadLine(); @@ -649,7 +630,7 @@ internal static StreamReader InitReaderPastHeader(string strConverterSpec, Encod if (line == null) throw new ExternalException(String.Format("The substitution mapping file (i.e. '{0}') appears to be from a previous version of SpellFixer. Create a new project and manually copy over the spelling substitutions from the existing mapping file to the new project mapping file using a text editor like Notepad", strConverterSpec)); - } while (line != LoginSF.cstrLastHeaderLine); + } while (line != LoginSF.CctableLastHeaderLine); return sr; } @@ -666,7 +647,7 @@ out DataTable myTable StreamReader sr = InitReaderPastHeader(strConverterSpec, enc); myTable = GetDataTable; - string line = null; + string line; while ((line = sr.ReadLine()) != null) { string strLhs = null; diff --git a/src/SpellingFixerEC/SpellingFixerEC.csproj b/src/SpellingFixerEC/SpellingFixerEC.csproj index e86f8a1f..a58d6bf2 100644 --- a/src/SpellingFixerEC/SpellingFixerEC.csproj +++ b/src/SpellingFixerEC/SpellingFixerEC.csproj @@ -1,6 +1,6 @@  - + Local 9.0.30729 @@ -60,6 +60,7 @@ x86 true GlobalSuppressions.cs + latest prompt AllRules.ruleset false @@ -74,6 +75,7 @@ x86 true GlobalSuppressions.cs + latest prompt AllRules.ruleset false @@ -101,11 +103,14 @@ latest prompt AllRules.ruleset + false $(EcDistFilesPath)\win-$(Platform)\native\CcEC.dll + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -138,20 +143,32 @@ + + Form + + + AddNewProjectForm.cs + Code Form + + LoginSF.cs + True True Resources.resx - + Form + + QueryFindReplaceDialog.cs + @@ -160,6 +177,10 @@ ViewBadGoodPairsDlg.cs + + AddNewProjectForm.cs + Designer + LoginSF.cs Designer @@ -169,9 +190,8 @@ ResXFileCodeGenerator Resources.Designer.cs - - QueryGoodSpelling.cs - Designer + + QueryFindReplaceDialog.cs ViewBadGoodPairsDlg.cs @@ -230,6 +250,6 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/SpellingFixerEC/ViewBadGoodPairsDlg.cs b/src/SpellingFixerEC/ViewBadGoodPairsDlg.cs index b44de844..6245e0ae 100644 --- a/src/SpellingFixerEC/ViewBadGoodPairsDlg.cs +++ b/src/SpellingFixerEC/ViewBadGoodPairsDlg.cs @@ -22,11 +22,16 @@ internal partial class ViewBadGoodPairsDlg : Form const int cnBadSpelling = 0; const int cnGoodSpelling = 1; + private readonly string _wordBoundaryDelimiter; + private readonly bool _isRightToLeft; - internal ViewBadGoodPairsDlg(DataTable myTable, Font font) + internal ViewBadGoodPairsDlg(DataTable myTable, Font font, string wordBoundaryDelimiter, bool isRightToLeft) { InitializeComponent(); + _wordBoundaryDelimiter = wordBoundaryDelimiter; + _isRightToLeft = isRightToLeft; + // for this ctor, the columns from the datatable this.dataGridView.Columns.Clear(); @@ -94,24 +99,24 @@ protected bool EditingCscBad2GoodList } #endif - private void buttonOK_Click(object sender, EventArgs e) + private void ButtonOK_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK; this.Close(); } - private void buttonCancel_Click(object sender, EventArgs e) + private void ButtonCancel_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel; this.Close(); } - private void dataGridView_UserAddedRow(object sender, DataGridViewRowEventArgs e) + private void DataGridView_UserAddedRow(object sender, DataGridViewRowEventArgs e) { buttonOK.Enabled = true; } - private void dataGridView_UserDeletedRow(object sender, DataGridViewRowEventArgs e) + private void DataGridView_UserDeletedRow(object sender, DataGridViewRowEventArgs e) { DeletingRow(e.Row); } @@ -153,7 +158,7 @@ protected bool DeletingRow(DataGridViewRow theRow) protected string m_strBadForm = null; protected string m_strGoodForm = null; protected string m_strWordBeingEdited = null; - private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) + private void DataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e) { DataGridViewRow theRow = dataGridView.Rows[e.RowIndex]; if (theRow.IsNewRow) @@ -167,7 +172,7 @@ private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEve m_strWordBeingEdited = (e.ColumnIndex == cnBadSpelling) ? m_strBadForm : m_strGoodForm; } - private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) + private void DataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) { DataGridViewRow theRow = dataGridView.Rows[e.RowIndex]; string strWordEdited = (string)theRow.Cells[e.ColumnIndex].Value; @@ -175,218 +180,12 @@ private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e return; buttonOK.Enabled = true; - -#if !TurnOffSF30 - // the word was changed... if we're editing the dictionary... - if (EditingDictionary) - { - // if this is a new record... - if (String.IsNullOrEmpty(m_strWordBeingEdited)) - if (!AddToWhiteList(strWordEdited)) // (i.e. so add) - { - // means we didn't add it (because it was already there) - System.Diagnostics.Debug.Assert(m_mapWhiteList.ContainsKey(strWordEdited)); - - // in that case, don't add this new value, but just select and display the existing value. - theRow.Cells[cnGoodSpelling].Value = null; - } - - // ... then we also have to update any entries in the bad2good list that had - // the original good word in them. - DialogResult res = RetaskBad2GoodList(m_strWordBeingEdited, strWordEdited); - - // either if they said 'Yes' or there weren't others... - if (res != DialogResult.Cancel) - { - // update the current value in the known good list with the new value - RetaskWhiteListSfw(m_strWordBeingEdited, strWordEdited); - } - - // if it happened to have been 'No', then we have to have the old value as well - if (res == DialogResult.No) - { - if (AddToWhiteList(m_strWordBeingEdited)) // (i.e. so add) - dataGridView.Rows.Add(new object[] { null, m_strWordBeingEdited }); - } - - // the update to the WordsToCheck will happen by the caller after we're totally done - } - else if (EditingCscBad2GoodList) - { - DataGridViewCell theBadCell = theRow.Cells[cnBadSpelling]; - if (e.ColumnIndex == cnGoodSpelling) - { - string strBadValue = (string)theBadCell.Value; - if (String.IsNullOrEmpty(strBadValue)) - theRow.Cells[cnGoodSpelling].Value = strWordEdited; - else - { - // if this is newly edited (i.e. word being edited is null), then pretend the bad value is - // new too (or it looks like it's already there) - GoodValueEdited(theRow, strBadValue, strBadValue, m_strWordBeingEdited, strWordEdited); - } - } - else // edited the bad spelling cell - { - System.Diagnostics.Debug.Assert(e.ColumnIndex == cnBadSpelling); - if (String.IsNullOrEmpty(m_strWordBeingEdited) && (theRow.Cells[cnGoodSpelling].Value == null)) - // means that this is the new row, so with only a bad value, we have nothing - theRow.Cells[cnBadSpelling].Value = strWordEdited; - else - BadValueOnlyEdited(theBadCell, m_strWordBeingEdited, strWordEdited, (string)theRow.Cells[cnGoodSpelling].Value); - } - } -#endif - } - - private void UpdateGridGoodValues(string strOldValue, string strNewValue) - { - foreach (DataGridViewRow aRow in dataGridView.Rows) - { - DataGridViewCell theGoodCell = aRow.Cells[cnGoodSpelling]; - if (strOldValue == (string)theGoodCell.Value) - theGoodCell.Value = strNewValue; - } - } - -#if !TurnOffSF30 - private DialogResult RetaskBad2GoodList(string strOldValue, string strNewValue) - { - // ... then we also have to update any entries in the bad2good list that had - // the original good word in them. - DialogResult res = DialogResult.None; - if (m_mapBad2Good.ContainsValue(strOldValue)) - { - bool bDeleting = String.IsNullOrEmpty(strNewValue); - string strMsg = String.Format("The word you just {1}, '{2}', is in other records in the bad-to-good list.{0}Would you like to have those record(s) {1} as well?", - Environment.NewLine, (bDeleting) ? "deleted" : "changed", strOldValue); - - if (!bDeleting) - strMsg += String.Format(" (i.e. to '{0}')", strNewValue); - - res = MessageBox.Show(strMsg, CscProject.cstrCaption, MessageBoxButtons.YesNoCancel); - - if (res == DialogResult.Yes) - { - while (m_mapBad2Good.ContainsValue(strOldValue)) - { - foreach (KeyValuePair kvp in m_mapBad2Good) - { - if (strOldValue == kvp.Value) - { - m_mapBad2Good.Remove(kvp.Key); - if (!bDeleting) - m_mapBad2Good.Add(kvp.Key, strNewValue); - break; // can't modify the collection without restarting the enumerator - } - } - } - } - } - - return res; - } - - private void RetaskWhiteListSfw(string strKey, string strNewValue) - { - SpellFixerWord sfw = m_mapWhiteList[strKey]; - m_mapWhiteList.Remove(strKey); - if (!m_mapWhiteList.ContainsKey(strNewValue)) - { - sfw.Value = strNewValue; - sfw.InitializeNonStaticData(m_project); - m_mapWhiteList.Add(sfw); - } - } - - private bool AddToWhiteList(string strValue) - { - if (!m_mapWhiteList.ContainsKey(strValue)) - { - SpellFixerWord sfw = m_project.GetNewSpellFixerWord(strValue, null); - m_mapWhiteList.Add(sfw); - return true; - } - return false; - } - - protected void GoodValueEdited(DataGridViewRow theRow, string strBadValue, string strNewBadValue, - string strGoodValue, string strNewGoodValue) - { - // if the new record is already in there, then just select and display the existing value - if (strBadValue != strNewBadValue) - foreach (DataGridViewRow aRow in dataGridView.Rows) - if (strNewBadValue == (string)aRow.Cells[cnBadSpelling].Value) - { - aRow.Selected = true; - dataGridView.FirstDisplayedScrollingRowIndex = aRow.Index; - System.Diagnostics.Debug.Assert(m_mapBad2Good.ContainsKey(strNewBadValue) && m_mapBad2Good[strNewBadValue] == strNewGoodValue); - return; - } - - // remove the one we're editing (so we don't find it below causing us to query the user - // about *that* one) - if (!String.IsNullOrEmpty(strBadValue)) - m_mapBad2Good.Remove(strBadValue); - - // then see if any other records have the same 'good form' and ask the user if they'd like us - // to change those also - DialogResult res = RetaskBad2GoodList(strGoodValue, strNewGoodValue); - if (res == DialogResult.Yes) - UpdateGridGoodValues(strGoodValue, strNewGoodValue); - - // now update the row being edited with the new data - theRow.Cells[cnGoodSpelling].Value = strNewGoodValue; - if (strNewBadValue != strBadValue) - theRow.Cells[cnBadSpelling].Value = strNewBadValue; - - // now add the new data to the collection - m_mapBad2Good.Add(strNewBadValue, strNewGoodValue); - - // also update the known good list with the new good form (if we're changing them all) - System.Diagnostics.Debug.Assert(String.IsNullOrEmpty(strGoodValue) || m_mapWhiteList.ContainsKey(strGoodValue)); - if (!String.IsNullOrEmpty(strGoodValue) - && m_mapWhiteList.ContainsKey(strGoodValue) - && (res != DialogResult.No)) // this means the original good form is still there for other records - { - RetaskWhiteListSfw(strGoodValue, strNewGoodValue); - } - else if (!m_mapWhiteList.ContainsKey(strNewGoodValue)) - AddToWhiteList(strNewGoodValue); - - buttonOK.Enabled = true; - // the update to the WordsToCheck will happen by the caller after we're totally done - } - - protected void BadValueOnlyEdited(DataGridViewCell theBadCell, string strBadValue, string strNewBadValue, - string strNewGoodValue) - { - // update the row value - theBadCell.Value = strNewBadValue; - - // and update the collection - if (!String.IsNullOrEmpty(strBadValue)) - m_mapBad2Good.Remove(strBadValue); - - m_mapBad2Good.Add(strNewBadValue, strNewGoodValue); - - // since we know this can't be a good word (or it wouldn't be the 'bad' form), remove it from the white list if present - if (m_mapWhiteList.ContainsKey(strNewBadValue)) - m_mapWhiteList.Remove(strNewBadValue); - - buttonOK.Enabled = true; } -#else // not in SF30 -#endif - - private void dataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) + private void DataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) { if ((e.RowIndex < 0) || (e.RowIndex >= dataGridView.Rows.Count) || (e.ColumnIndex < 0) || (e.ColumnIndex >= dataGridView.Columns.Count) -#if !TurnOffSF30 - || (EditingDictionary) -#endif || (e.Button != MouseButtons.Right)) return; @@ -413,8 +212,13 @@ protected void ProcessEditRow(DataGridViewRow theRow) string strBadValue = (string)theBadCell.Value; string strGoodValue = (string)theGoodCell.Value; +#if !OldDialogs + var aQuery = new QueryFindReplaceDialog(dataGridView.RowsDefaultCellStyle.Font); +#else QueryGoodSpelling aQuery = new QueryGoodSpelling(dataGridView.RowsDefaultCellStyle.Font); - DialogResult res = aQuery.ShowDialog(strBadValue, strGoodValue, strBadValue, (strBadValue != null)); +#endif + DialogResult res = aQuery.ShowDialog(strBadValue, strGoodValue, strBadValue, + _isRightToLeft, _wordBoundaryDelimiter, (strBadValue != null)); if (res == DialogResult.Abort) { // this means delete @@ -439,10 +243,10 @@ protected void ProcessEditRow(DataGridViewRow theRow) // o both columns were non-null and now the 'bad' value (only) is changed // -> change the bad value in the row // -> change the bad value in the bad2good list - if (String.IsNullOrEmpty(aQuery.BadSpelling) || String.IsNullOrEmpty(aQuery.GoodSpelling)) + if (String.IsNullOrEmpty(aQuery.FindWhat) || String.IsNullOrEmpty(aQuery.ReplaceWith)) { // if either of them are null... - throw new ApplicationException("The 'Bad' and 'Good' forms are not allowed to be nothing!"); + throw new ApplicationException("The 'Find What' and 'Replace With' values are not allowed to be nothing!"); } #if !TurnOffSF30 /* I don't recall what I was thinking about this one. Sometimes having the good and bad spelling @@ -460,8 +264,8 @@ protected void ProcessEditRow(DataGridViewRow theRow) #endif { // Legacy SpellFixer - theBadCell.Value = aQuery.BadSpelling; - theGoodCell.Value = aQuery.GoodSpelling; + theBadCell.Value = aQuery.FindWhat; + theGoodCell.Value = aQuery.ReplaceWith; } #if !TurnOffSF30 else if (String.IsNullOrEmpty(strBadValue) && m_mapBad2Good.ContainsKey(aQuery.BadSpelling)) @@ -506,7 +310,7 @@ protected void ProcessEditRow(DataGridViewRow theRow) } } - private void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) + private void DataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { System.Diagnostics.Trace.WriteLine(String.Format("PreviewKeyDown: sender: {3}, KeyValue: {0}, KeyCode: {1}, KeyData: {2}", e.KeyValue, e.KeyCode, e.KeyData, sender.ToString())); @@ -528,7 +332,7 @@ private void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs } } - private void buttonAddCorrection_Click(object sender, EventArgs e) + private void ButtonAddCorrection_Click(object sender, EventArgs e) { DataTable myTable = (DataTable)dataGridView.DataSource; myTable.Rows.Add(new object[] { "incorect", "incorrect" }); diff --git a/src/SpellingFixerEC/ViewBadGoodPairsDlg.designer.cs b/src/SpellingFixerEC/ViewBadGoodPairsDlg.designer.cs index dd730121..76c9d7c3 100644 --- a/src/SpellingFixerEC/ViewBadGoodPairsDlg.designer.cs +++ b/src/SpellingFixerEC/ViewBadGoodPairsDlg.designer.cs @@ -32,12 +32,12 @@ private void InitializeComponent() { this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); this.dataGridView = new System.Windows.Forms.DataGridView(); - this.ColumnBadSpelling = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.ColumnGoodSpelling = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.buttonOK = new System.Windows.Forms.Button(); this.buttonCancel = new System.Windows.Forms.Button(); - this.helpProvider = new System.Windows.Forms.HelpProvider(); this.buttonAddCorrection = new System.Windows.Forms.Button(); + this.helpProvider = new System.Windows.Forms.HelpProvider(); + this.ColumnBadSpelling = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.ColumnGoodSpelling = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.tableLayoutPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.SuspendLayout(); @@ -76,55 +76,55 @@ private void InitializeComponent() this.dataGridView.RowHeadersWidth = 26; this.dataGridView.Size = new System.Drawing.Size(375, 293); this.dataGridView.TabIndex = 0; - this.dataGridView.UserAddedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView_UserAddedRow); - this.dataGridView.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.dataGridView_CellBeginEdit); - this.dataGridView.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.dataGridView_PreviewKeyDown); - this.dataGridView.CellMouseUp += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView_CellMouseUp); - this.dataGridView.UserDeletedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView_UserDeletedRow); - this.dataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView_CellEndEdit); - // - // ColumnBadSpelling - // - this.ColumnBadSpelling.HeaderText = "Bad Form"; - this.ColumnBadSpelling.Name = "ColumnBadSpelling"; - // - // ColumnGoodSpelling - // - this.ColumnGoodSpelling.HeaderText = "Good Form"; - this.ColumnGoodSpelling.Name = "ColumnGoodSpelling"; + this.dataGridView.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.DataGridView_CellBeginEdit); + this.dataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellEndEdit); + this.dataGridView.CellMouseUp += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.DataGridView_CellMouseUp); + this.dataGridView.UserAddedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.DataGridView_UserAddedRow); + this.dataGridView.UserDeletedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.DataGridView_UserDeletedRow); + this.dataGridView.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.DataGridView_PreviewKeyDown); // // buttonOK // this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonOK.Location = new System.Drawing.Point(48, 302); + this.buttonOK.Location = new System.Drawing.Point(49, 302); this.buttonOK.Name = "buttonOK"; this.buttonOK.Size = new System.Drawing.Size(75, 23); this.buttonOK.TabIndex = 1; this.buttonOK.Text = "OK"; this.buttonOK.UseVisualStyleBackColor = true; - this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click); // // buttonCancel // this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.buttonCancel.Location = new System.Drawing.Point(129, 302); + this.buttonCancel.Location = new System.Drawing.Point(130, 302); this.buttonCancel.Name = "buttonCancel"; this.buttonCancel.Size = new System.Drawing.Size(75, 23); this.buttonCancel.TabIndex = 2; this.buttonCancel.Text = "Cancel"; this.buttonCancel.UseVisualStyleBackColor = true; - this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click); // // buttonAddCorrection // - this.buttonAddCorrection.Location = new System.Drawing.Point(255, 302); + this.buttonAddCorrection.Location = new System.Drawing.Point(257, 302); this.buttonAddCorrection.Name = "buttonAddCorrection"; this.buttonAddCorrection.Size = new System.Drawing.Size(114, 23); this.buttonAddCorrection.TabIndex = 3; - this.buttonAddCorrection.Text = "&Add Correction"; + this.buttonAddCorrection.Text = "&Add Substitution"; this.buttonAddCorrection.UseVisualStyleBackColor = true; - this.buttonAddCorrection.Click += new System.EventHandler(this.buttonAddCorrection_Click); + this.buttonAddCorrection.Click += new System.EventHandler(this.ButtonAddCorrection_Click); + // + // ColumnBadSpelling + // + this.ColumnBadSpelling.HeaderText = "Find What"; + this.ColumnBadSpelling.Name = "ColumnBadSpelling"; + // + // ColumnGoodSpelling + // + this.ColumnGoodSpelling.HeaderText = "Replace With"; + this.ColumnGoodSpelling.Name = "ColumnGoodSpelling"; // // ViewBadGoodPairsDlg // @@ -138,7 +138,7 @@ private void InitializeComponent() this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "ViewBadGoodPairsDlg"; - this.Text = "Edit Bad-Good Pairs"; + this.Text = "Edit Find-Replace Pairs"; this.tableLayoutPanel.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit(); this.ResumeLayout(false); @@ -149,11 +149,11 @@ private void InitializeComponent() private System.Windows.Forms.TableLayoutPanel tableLayoutPanel; private System.Windows.Forms.DataGridView dataGridView; - private System.Windows.Forms.DataGridViewTextBoxColumn ColumnBadSpelling; - private System.Windows.Forms.DataGridViewTextBoxColumn ColumnGoodSpelling; private System.Windows.Forms.Button buttonOK; private System.Windows.Forms.Button buttonCancel; private System.Windows.Forms.HelpProvider helpProvider; private System.Windows.Forms.Button buttonAddCorrection; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnBadSpelling; + private System.Windows.Forms.DataGridViewTextBoxColumn ColumnGoodSpelling; } } \ No newline at end of file diff --git a/src/SpellingFixerEC/ViewBadGoodPairsDlg.resx b/src/SpellingFixerEC/ViewBadGoodPairsDlg.resx index 615b2736..b780aad6 100644 --- a/src/SpellingFixerEC/ViewBadGoodPairsDlg.resx +++ b/src/SpellingFixerEC/ViewBadGoodPairsDlg.resx @@ -112,24 +112,18 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + True - + True - - True - - - True - - + 17, 17 \ No newline at end of file diff --git a/src/SpellingFixerEC/packages.config b/src/SpellingFixerEC/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/SpellingFixerEC/packages.config +++ b/src/SpellingFixerEC/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/TECkit Mapping Editor/TECkit Mapping Editor.csproj b/src/TECkit Mapping Editor/TECkit Mapping Editor.csproj index 0d173fc2..9f8b1b65 100644 --- a/src/TECkit Mapping Editor/TECkit Mapping Editor.csproj +++ b/src/TECkit Mapping Editor/TECkit Mapping Editor.csproj @@ -1,6 +1,6 @@  - + Debug x86 @@ -88,6 +88,8 @@ AllRules.ruleset + $(EcLibFilesPath)\net48\x86\ECInterfaces.dll @@ -237,6 +239,6 @@ xcopy /y "$(ProjectDir)UnicodeRanges.xml" "$(SolutionDir)output\$(PlatformName)\ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/TECkit Mapping Editor/packages.config b/src/TECkit Mapping Editor/packages.config index 59d699ac..e0a2de1e 100644 --- a/src/TECkit Mapping Editor/packages.config +++ b/src/TECkit Mapping Editor/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file