Compare commits

...

26 Commits

Author SHA1 Message Date
Simon Rozman
78ccf1b2cf Version set to 2.0-beta 2016-05-13 18:54:11 +02:00
Simon Rozman
c921d533a9 Issue with non included term trailing in sub-word index fixed 2016-05-13 18:47:12 +02:00
Simon Rozman
e4fb91e305 Settings moved from menu(s) to configuration dialog
(closes #21)
2016-05-13 16:22:51 +02:00
Simon Rozman
a81dd7e250 Character request feature added
(closes #13)
2016-05-13 13:36:25 +02:00
Simon Rozman
a4fe4b6a26 Current character category display added to character selector 2016-05-13 13:24:18 +02:00
Simon Rozman
1198579963 Character category index fixed 2016-05-13 13:22:17 +02:00
Simon Rozman
5d732522fe wxZRColaCharGrid memory leak fixed
(fixes #23)
2016-05-13 13:21:39 +02:00
Simon Rozman
155fb03c5a Character search moved to separate thread for smoother experience 2016-05-13 12:11:38 +02:00
Simon Rozman
710937f8df Language ID type redeclaration for easier and safer work 2016-05-13 10:16:29 +02:00
Simon Rozman
4e435b044c Additional operators 2016-05-13 10:16:23 +02:00
Simon Rozman
4ec7dc3ca5 Search optimizations 2016-05-13 09:32:36 +02:00
Simon Rozman
9c3c1585d5 Character Select finished
(closes #11)
2016-05-13 03:44:28 +02:00
Simon Rozman
53ce3a2411 COMDAT Folding disabled for debug builds 2016-05-12 17:15:04 +02:00
Simon Rozman
643a8dcb82 Sub-module update 2016-05-12 14:12:09 +02:00
Simon Rozman
9337b660d2 Database update 2016-05-12 10:56:07 +02:00
Simon Rozman
44f2ef1ae1 Work on character selector continues 2016-05-11 14:39:57 +02:00
Simon Rozman
4aa0d9183e Support for Unicode character database added 2016-05-11 14:39:20 +02:00
Simon Rozman
e3c6a01722 ZRCola::index::compare_sort() reverts to compare() by default now 2016-05-11 12:40:14 +02:00
Simon Rozman
0d30a89d22 Character selector merged back to continue work
# Conflicts:
#	ZRCola/ZRCola.fbp
#	ZRCola/ZRCola.vcxproj
#	ZRCola/ZRCola.vcxproj.filters
#	ZRCola/locale/sl_SI.po
#	ZRCola/zrcolafrm.cpp
#	ZRCola/zrcolafrm.h
#	ZRCola/zrcolagui.cpp
#	ZRCola/zrcolagui.h
2016-05-11 09:00:59 +02:00
Simon Rozman
23ba447283 ZRCola now minimizes to system tray.
(closes #20)
2016-05-10 13:10:37 +02:00
Simon Rozman
a27f7f470d (De)Composition moved to idle processing & other optimizations
(fixes #19)
2016-05-10 09:41:35 +02:00
Simon Rozman
50790ad01d ZRCola no longer responds to Ctrl+Alt shortcuts when invoked with AltGr 2016-05-09 16:48:54 +02:00
Simon Rozman
ae3344d5eb Aesthetic modifications 2016-05-09 11:57:19 +02:00
Simon Rozman
79ae4855e3 Additional "text updated" event generation added to fix premature event receiving on EM_REPLACESEL
(fixes #19)
2016-05-09 11:57:02 +02:00
Simon Rozman
349bc34fa8 libZRColaUI extended to use wxWidgets and ZRColaApp::GetKeySequenceAsText() moved back to ZRCola::keyseq_db::GetSequenceAsText() for general accessibility 2016-05-09 11:05:21 +02:00
Simon Rozman
b7533d4b27 Character selector feature skeleton added 2016-04-26 16:05:42 +02:00
56 changed files with 8608 additions and 1341 deletions

View File

@@ -130,6 +130,7 @@ featZRCola comp00_ZRCola_Re.ttf
!IF "$(LANG)" == "Sl"
featZRCola compZRCola.mo.sl_SI
featZRCola compZRCola.zrcdb.mo.sl_SI
featZRCola complibZRColaUI.mo.sl_SI
featZRCola compwxExtend.mo.sl_SI
featZRCola compwxstd.mo.sl_SI
!ENDIF

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -83,20 +83,24 @@
<ClCompile Include="zrcolaapp.cpp" />
<ClCompile Include="zrcolachrcatpnl.cpp" />
<ClCompile Include="zrcolachrgrid.cpp" />
<ClCompile Include="zrcolachrslct.cpp" />
<ClCompile Include="zrcolacomppnl.cpp" />
<ClCompile Include="zrcolafrm.cpp" />
<ClCompile Include="zrcolagui.cpp" />
<ClCompile Include="zrcolakeyhndlr.cpp" />
<ClCompile Include="zrcolasettings.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="zrcolaapp.h" />
<ClInclude Include="zrcolachrcatpnl.h" />
<ClInclude Include="zrcolachrgrid.h" />
<ClInclude Include="zrcolachrslct.h" />
<ClInclude Include="zrcolacomppnl.h" />
<ClInclude Include="zrcolafrm.h" />
<ClInclude Include="zrcolagui.h" />
<ClInclude Include="zrcolakeyhndlr.h" />
<ClInclude Include="zrcolasettings.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\lib\libZRColaUI\build\libZRColaUI.vcxproj">
@@ -110,6 +114,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="res\char_select.ico" />
<None Include="res\edit_copy.ico" />
<None Include="res\edit_cut.ico" />
<None Include="res\edit_paste.ico" />

View File

@@ -43,6 +43,12 @@
<ClCompile Include="zrcolachrcatpnl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="zrcolachrslct.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="zrcolasettings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -69,6 +75,12 @@
<ClInclude Include="zrcolachrcatpnl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="zrcolachrslct.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="zrcolasettings.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="res\zrcola.ico">
@@ -95,6 +107,9 @@
<None Include="ZRCola.fbp">
<Filter>Resource Files</Filter>
</None>
<None Include="res\char_select.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRCola.rc">

View File

@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRCola\n"
"POT-Creation-Date: 2016-05-06 14:24+0200\n"
"PO-Revision-Date: 2016-05-06 14:24+0200\n"
"POT-Creation-Date: 2016-05-13 15:52+0200\n"
"PO-Revision-Date: 2016-05-13 15:52+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: sl_SI\n"
@@ -17,156 +17,14 @@ msgstr ""
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: zrcolaapp.cpp:155
msgid "Esc"
msgstr "Esc"
#: zrcolafrm.cpp:90 zrcolagui.h:98 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4
msgid "ZRCola"
msgstr "ZRCola"
#: zrcolaapp.cpp:157
msgid "F1"
msgstr "F1"
#: zrcolaapp.cpp:158
msgid "F2"
msgstr "F2"
#: zrcolaapp.cpp:159
msgid "F3"
msgstr "F3"
#: zrcolaapp.cpp:160
msgid "F4"
msgstr "F4"
#: zrcolaapp.cpp:161
msgid "F5"
msgstr "F5"
#: zrcolaapp.cpp:162
msgid "F6"
msgstr "F6"
#: zrcolaapp.cpp:163
msgid "F7"
msgstr "F7"
#: zrcolaapp.cpp:164
msgid "F8"
msgstr "F8"
#: zrcolaapp.cpp:165
msgid "F9"
msgstr "F9"
#: zrcolaapp.cpp:166
msgid "F10"
msgstr "F10"
#: zrcolaapp.cpp:167
msgid "F11"
msgstr "F11"
#: zrcolaapp.cpp:168
msgid "F12"
msgstr "F12"
#: zrcolaapp.cpp:170
msgid "Print Screen"
msgstr "Print Screen"
#: zrcolaapp.cpp:171
msgid "Scroll Lock"
msgstr "Scroll Lock"
#: zrcolaapp.cpp:172
msgid "Pause"
msgstr "Pause"
#: zrcolaapp.cpp:174
msgid "Backspace"
msgstr "Backspace"
#: zrcolaapp.cpp:175
msgid "Tab"
msgstr "Tab"
#: zrcolaapp.cpp:176
msgid "Caps Lock"
msgstr "Caps Lock"
#: zrcolaapp.cpp:177
msgid "Return"
msgstr "Return"
#: zrcolaapp.cpp:178
msgid "Space"
msgstr "preslednica"
#: zrcolaapp.cpp:180
msgid "Shift"
msgstr "Shift"
#: zrcolaapp.cpp:181
msgid "Alt"
msgstr "Alt"
#: zrcolaapp.cpp:182
msgid "Ctrl"
msgstr "Ctrl"
#: zrcolaapp.cpp:183
msgid "Menu"
msgstr "Menu"
#: zrcolaapp.cpp:185
msgid "Insert"
msgstr "Insert"
#: zrcolaapp.cpp:186
msgid "Delete"
msgstr "Delete"
#: zrcolaapp.cpp:187
msgid "Page Up"
msgstr "Page Up"
#: zrcolaapp.cpp:188
msgid "Page Down"
msgstr "Page Down"
#: zrcolaapp.cpp:189
msgid "Home"
msgstr "Home"
#: zrcolaapp.cpp:190
msgid "End"
msgstr "End"
#: zrcolaapp.cpp:192
msgid "Left"
msgstr "Left"
#: zrcolaapp.cpp:193
msgid "Up"
msgstr "Up"
#: zrcolaapp.cpp:194
msgid "Right"
msgstr "Right"
#: zrcolaapp.cpp:195
msgid "Down"
msgstr "Down"
#: zrcolaapp.cpp:197
msgid "Num Lock"
msgstr "Num Lock"
#: zrcolafrm.cpp:91
#, c-format
msgid "Select %s language for decomposition"
msgstr "Izberi jezik %s za razstavljanje"
#: zrcolafrm.cpp:110
#: zrcolafrm.cpp:108
msgid ""
"ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality "
"will not be available."
@@ -174,11 +32,11 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F5 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:110 zrcolafrm.cpp:112
#: zrcolafrm.cpp:108 zrcolafrm.cpp:110
msgid "Warning"
msgstr "Opozorilo"
#: zrcolafrm.cpp:112
#: zrcolafrm.cpp:110
msgid ""
"ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality "
"will not be available."
@@ -186,11 +44,11 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F6 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:187
msgid "Start ZRCola automatically on logon"
msgstr "Samodejno zaženi ZRColo ob prijavi"
#: zrcolafrm.cpp:336
msgid "http://zrcola-2.amebis.si/en/contact/"
msgstr "http://zrcola-2.amebis.si/contact/"
#: zrcolafrm.cpp:399
#: zrcolafrm.cpp:342
#, c-format
msgid ""
"ZRCola v%s\n"
@@ -199,174 +57,242 @@ msgstr ""
"ZRCola v%s\n"
"Vse pravice pridržane 2015-%s Amebis"
#: zrcolafrm.cpp:399
#: zrcolafrm.cpp:342
msgid "About ZRCola"
msgstr "O ZRColi"
#: zrcolagui.cpp:36
msgid "&Start on Logon"
msgstr "Z&aženi ob prijavi"
#: zrcolagui.cpp:36
msgid "Start this program automatically on logon"
msgstr "Samodejno zaženi ta program ob prijavi"
#: zrcolagui.cpp:42
msgid "E&xit"
msgstr "I&zhod"
#: zrcolagui.cpp:42
#: zrcolagui.cpp:36
msgid "Quit this program"
msgstr "Zapri ta program"
#: zrcolagui.cpp:45
#: zrcolagui.cpp:39
msgid "&Program"
msgstr "&Program"
#: zrcolagui.cpp:78
#: zrcolagui.cpp:72
msgid "Select &All"
msgstr "Izberi &vse"
#: zrcolagui.cpp:78
#: zrcolagui.cpp:72
msgid "Select all text"
msgstr "Izberi celotno besedilo"
#: zrcolagui.cpp:84
#: zrcolagui.cpp:78
msgid "C&haracter Selector..."
msgstr "Izbirnik &znaka ..."
#: zrcolagui.cpp:78 zrcolagui.cpp:166
msgid "Display character selector to select character to insert into text"
msgstr "Prikaži izbirnik znaka za izbor znaka za vstavljanje v besedilo"
#: zrcolagui.cpp:89
msgid "&Send Composed"
msgstr "Pošlji &sestavljeno"
#: zrcolagui.cpp:84 zrcolagui.cpp:159
#: zrcolagui.cpp:89 zrcolagui.cpp:168
msgid "Send composed text to source window"
msgstr "Pošlji sestavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:93
#: zrcolagui.cpp:98
msgid "Send &Decomposed"
msgstr "Pošlji &razstavljeno"
#: zrcolagui.cpp:93 zrcolagui.cpp:161
#: zrcolagui.cpp:98 zrcolagui.cpp:170
msgid "Send decomposed text to source window"
msgstr "Pošlji razstavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:102
#: zrcolagui.cpp:107
msgid "Abort (De)composition"
msgstr "Prekini raz/sestavljanje"
#: zrcolagui.cpp:102
#: zrcolagui.cpp:107
msgid "Abort composition and return focus to source window"
msgstr "Prekini sestavljanje in vrni fokus nazaj izvornemu oknu"
#: zrcolagui.cpp:111
msgid "&Language"
msgstr "&Jezik"
#: zrcolagui.cpp:118
msgid "&Settings..."
msgstr "Na&stavitve ..."
#: zrcolagui.cpp:113
msgid "&Automatic"
msgstr "S&amodejno"
#: zrcolagui.cpp:118
msgid "Open program configuration dialog"
msgstr "Odpri nastavitveni dialog programa"
#: zrcolagui.cpp:113
msgid "Set language according to keyboard layout automatically"
msgstr "Samodejno nastavi jezik glede na izbrano tipkovnico"
#: zrcolagui.cpp:120
#: zrcolagui.cpp:121
msgid "&Edit"
msgstr "Ur&edi"
#: zrcolagui.cpp:124
#: zrcolagui.cpp:125
msgid "&Edit Toolbar"
msgstr "Orodna vrstica za ur&ejanje"
#: zrcolagui.cpp:124
#: zrcolagui.cpp:125
msgid "Toggle edit toolbar"
msgstr "Prikaži/skrij orodno vrstico za urejanje"
#: zrcolagui.cpp:128
#: zrcolagui.cpp:129
msgid "&Compose Toolbar"
msgstr "Orodna vrsti&ca za sestavljanje"
#: zrcolagui.cpp:128
#: zrcolagui.cpp:129
msgid "Toggle compose toolbar"
msgstr "Prikaži/skrij orodno vrstico za sestavljanje"
#: zrcolagui.cpp:134
#: zrcolagui.cpp:135
msgid "Character Catalo&g"
msgstr "Katalo&g znakov"
#: zrcolagui.cpp:134
#: zrcolagui.cpp:135
msgid "Toggle character catalog panel"
msgstr "Prikaži/skrij katalog znakov"
#: zrcolagui.cpp:137
#: zrcolagui.cpp:138
msgid "&View"
msgstr "Po&gled"
#: zrcolagui.cpp:144
#: zrcolagui.cpp:142
msgid "&Request a new character..."
msgstr "&Zahtevaj nov znak ..."
#: zrcolagui.cpp:142
msgid "Submit a request to ZRC to add a new character"
msgstr "Oddaj prošnjo ZRC-u za dodajanje novega znaka"
#: zrcolagui.cpp:151
msgid "&Help"
msgstr "Po&moč"
#: zrcolagui.cpp:149
#: zrcolagui.cpp:156
msgid "Cut"
msgstr "Izreži"
#: zrcolagui.cpp:149
#: zrcolagui.cpp:156
msgid "Cut selection"
msgstr "Izreži izbor"
#: zrcolagui.cpp:151
#: zrcolagui.cpp:158
msgid "Copy"
msgstr "Kopiraj"
#: zrcolagui.cpp:151
#: zrcolagui.cpp:158
msgid "Copy selection"
msgstr "Kopiraj izbor"
#: zrcolagui.cpp:153
#: zrcolagui.cpp:160
msgid "Paste"
msgstr "Prilepi"
#: zrcolagui.cpp:153
#: zrcolagui.cpp:160
msgid "Paste selection"
msgstr "Prilepi izbor"
#: zrcolagui.cpp:156
#: zrcolagui.cpp:163
msgid "Edit"
msgstr "Urejanje"
#: zrcolagui.cpp:159
#: zrcolagui.cpp:166 zrcolagui.h:222
msgid "Character Selector"
msgstr "Izbirnik znaka"
#: zrcolagui.cpp:168
msgid "Send Composed"
msgstr "Pošlji sestavljeno"
#: zrcolagui.cpp:161
#: zrcolagui.cpp:170
msgid "Send Decomposed"
msgstr "Pošlji razstavljeno"
#: zrcolagui.cpp:170
#: zrcolagui.cpp:173
msgid "Compose"
msgstr "Sestavljanje"
#: zrcolagui.cpp:174
#: zrcolagui.cpp:177
msgid "Character Catalog"
msgstr "Katalog znakov"
#: zrcolagui.cpp:178
#: zrcolagui.cpp:181
msgid "(De)Composer"
msgstr "Raz/Sestavljalnik"
#: zrcolagui.cpp:213
#: zrcolagui.cpp:218
msgid "Decomposed Text"
msgstr "Razstavljeno besedilo"
#: zrcolagui.cpp:233
#: zrcolagui.cpp:238
msgid "Decomposed Unicode Dump"
msgstr "Unicode razstavljenega"
#: zrcolagui.cpp:260
#: zrcolagui.cpp:265
msgid "Composed Text"
msgstr "Sestavljeno besedilo"
#: zrcolagui.cpp:280
#: zrcolagui.cpp:285
msgid "Composed Unicode Dump"
msgstr "Unicode sestavljenega"
#: zrcolagui.cpp:405
msgid "&Browse"
msgstr "Pre&brskaj"
#: zrcolagui.cpp:453
msgid "Re&cently Used"
msgstr "Nedavno &uporabljeni"
#: zrcolagui.cpp:494
msgid "Preview"
msgstr "Predogled"
#: zrcolagui.cpp:499
msgid "U+"
msgstr "U+"
#: zrcolagui.cpp:550
msgid "Re&lated"
msgstr "&Sorodni"
#: zrcolagui.cpp:650
msgid ""
"Some character native to specific language you are working with should not "
"decompose to primitives.\n"
"For optimal decomposition you should set the language correctly."
msgstr ""
"Nekateri znaki iz posameznih jezikov, s katerimi delate, se ne smejo "
"razstaviti v dele.\n"
"Za optimalno razstavljanje izberite pravilni jezik."
#: zrcolagui.cpp:654
msgid "Select language &automatically according to selected keyboard"
msgstr "S&amodejno izberi jezik glede na izbrano tipkovnico"
#: zrcolagui.cpp:657
msgid "&Manually select the language from the list below:"
msgstr "Ročno izberi jezik na spodnje&m spisku:"
#: zrcolagui.cpp:669
msgid "Text Language"
msgstr "Jezik besedila"
#: zrcolagui.cpp:674
msgid ""
"ZRCola can be launched every time you log in to your computer.\n"
"It will be available on the system tray and via registered shortcuts Win+F5 "
"and Win+F6."
msgstr ""
"ZRCola se lahko zažene ob vsaki prijavi v vaš računalnik.\n"
"Na voljo bo na vrstici za sistemska obvestila ter preko registriranih "
"bližnjic Win+F5 in Win+F6."
#: zrcolagui.cpp:678
msgid "Start ZRCola &automatically on logon"
msgstr "S&amodejno zaženi ZRColo ob prijavi"
#: zrcolagui.cpp:685
msgid "Startup"
msgstr "Zagon"
#: zrcolakeyhndlr.cpp:44
msgid ""
"INS key is pressed. Type the Unicode code of desired character now (up to "
@@ -375,37 +301,161 @@ msgstr ""
"Pritisnjena tipka INS. Zdaj vtpikajte kodo Unicode želenega znaka (do štiri "
"šestnajstiške števke: 0-9, A-F), nato izpustite INS."
#: zrcolagui.h:86 MSIBuild/En.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/En.Win32.Debug.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Debug.Feature-2.idtx:4
#: MSIBuild/En.x64.Debug.Shortcut-2.idtx:4
msgid "ZRCola"
msgstr "ZRCola"
#: zrcolasettings.cpp:116
msgid "Start ZRCola automatically on logon"
msgstr "Samodejno zaženi ZRColo ob prijavi"
#: zrcolagui.h:258
msgid "Settings"
msgstr "Nastavitve"
# Windows charset for this language (decimal)
#: MSIBuild/En.Win32.Debug.Feature-2.idtx:3
#: MSIBuild/En.Win32.Debug.Shortcut-2.idtx:3
#: MSIBuild/En.x64.Debug.Feature-2.idtx:3
#: MSIBuild/En.x64.Debug.Shortcut-2.idtx:3
#: MSIBuild/En.Win32.Release.Feature-2.idtx:3
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:3
#: MSIBuild/En.x64.Release.Feature-2.idtx:3
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:3
msgid "1252"
msgstr "1250"
#: MSIBuild/En.Win32.Debug.Feature-2.idtx:4
#: MSIBuild/En.Win32.Debug.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Debug.Feature-2.idtx:4
#: MSIBuild/En.x64.Debug.Shortcut-2.idtx:4
#: MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4
#: MSIBuild/En.x64.Release.Feature-2.idtx:4
#: MSIBuild/En.x64.Release.Shortcut-2.idtx:4
msgid "Input system for linguistic use"
msgstr "Vnašalni sistem za jezikoslovno rabo"
#~ msgid "Auto Start"
#~ msgstr "Samodejni zagon"
#~ msgid "Select %s language for decomposition"
#~ msgstr "Izberi jezik %s za razstavljanje"
#~ msgid "&Start on Logon"
#~ msgstr "Z&aženi ob prijavi"
#~ msgid "Start this program automatically on logon"
#~ msgstr "Samodejno zaženi ta program ob prijavi"
#~ msgid "Set language according to keyboard layout automatically"
#~ msgstr "Samodejno nastavi jezik glede na izbrano tipkovnico"
#~ msgid "&Unicode"
#~ msgstr "&Unicode"
#~ msgid "Esc"
#~ msgstr "Esc"
#~ msgid "F1"
#~ msgstr "F1"
#~ msgid "F2"
#~ msgstr "F2"
#~ msgid "F3"
#~ msgstr "F3"
#~ msgid "F4"
#~ msgstr "F4"
#~ msgid "F5"
#~ msgstr "F5"
#~ msgid "F6"
#~ msgstr "F6"
#~ msgid "F7"
#~ msgstr "F7"
#~ msgid "F8"
#~ msgstr "F8"
#~ msgid "F9"
#~ msgstr "F9"
#~ msgid "F10"
#~ msgstr "F10"
#~ msgid "F11"
#~ msgstr "F11"
#~ msgid "F12"
#~ msgstr "F12"
#~ msgid "Print Screen"
#~ msgstr "Print Screen"
#~ msgid "Scroll Lock"
#~ msgstr "Scroll Lock"
#~ msgid "Pause"
#~ msgstr "Pause"
#~ msgid "Backspace"
#~ msgstr "Backspace"
#~ msgid "Tab"
#~ msgstr "Tab"
#~ msgid "Caps Lock"
#~ msgstr "Caps Lock"
#~ msgid "Return"
#~ msgstr "Return"
#~ msgid "Space"
#~ msgstr "preslednica"
#~ msgid "Shift"
#~ msgstr "Shift"
#~ msgid "Alt"
#~ msgstr "Alt"
#~ msgid "Ctrl"
#~ msgstr "Ctrl"
#~ msgid "Menu"
#~ msgstr "Menu"
#~ msgid "Insert"
#~ msgstr "Insert"
#~ msgid "Delete"
#~ msgstr "Delete"
#~ msgid "Page Up"
#~ msgstr "Page Up"
#~ msgid "Page Down"
#~ msgstr "Page Down"
#~ msgid "Home"
#~ msgstr "Home"
#~ msgid "End"
#~ msgstr "End"
#~ msgid "Left"
#~ msgstr "Left"
#~ msgid "Up"
#~ msgstr "Up"
#~ msgid "Right"
#~ msgstr "Right"
#~ msgid "Down"
#~ msgstr "Down"
#~ msgid "Num Lock"
#~ msgstr "Num Lock"
#~ msgid "`"
#~ msgstr "`"
#~ msgid "-"
#~ msgstr "-"
#~ msgid "+"
#~ msgstr "+"
#~ msgid "["
#~ msgstr "["

BIN
ZRCola/res/char_select.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

1794
ZRCola/res/char_select.pdf Normal file

File diff suppressed because one or more lines are too long

View File

@@ -23,11 +23,14 @@
#include <wx/msgdlg.h>
#include <wx/persist.h>
#include <wx/persist/toplevel.h>
#include <wx/utils.h>
#include <wx/valtext.h>
#include <wxex/common.h>
#include <wxex/persist/auimanager.h>
#include <fstream>
#include <string>
#include <utility>
#include <vector>
#include <stdex/idrec.h>
@@ -45,3 +48,4 @@
#include "zrcolacomppnl.h"
#include "zrcolafrm.h"
#include "zrcolakeyhndlr.h"
#include "zrcolasettings.h"

View File

@@ -60,7 +60,8 @@ bool ZRColaApp::OnInit()
if (wxConfigBase::Get()->Read(wxT("LocalizationRepositoryPath"), &sPath))
m_locale.AddCatalogLookupPathPrefix(sPath);
wxVERIFY(m_locale.Init(language));
wxVERIFY(m_locale.AddCatalog(wxT("wxExtend")));
wxVERIFY(m_locale.AddCatalog(wxT("wxExtend") wxT(wxExtendVersion)));
wxVERIFY(m_locale.AddCatalog(wxT("libZRColaUI")));
wxVERIFY(m_locale.AddCatalog(wxT("ZRCola")));
wxVERIFY(m_locale.AddCatalog(wxT("ZRCola-zrcdb")));
}
@@ -112,7 +113,23 @@ bool ZRColaApp::OnInit()
m_ks_db.idxKey.clear();
m_ks_db.data .clear();
}
}
} else if (id == ZRCola::character_rec::id) {
dat >> ZRCola::character_rec(m_chr_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading character data from ZRCola.zrcdb."));
m_chr_db.idxChr.clear();
m_chr_db.data .clear();
}
} else if (id == ZRCola::chrcat_rec::id) {
dat >> ZRCola::chrcat_rec(m_cc_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading character category data from ZRCola.zrcdb."));
m_cc_db.idxChrCat.clear();
m_cc_db.idxRnk .clear();
m_cc_db.data .clear();
}
} else
stdex::idrec::ignore<ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dat);
}
if (!has_translation_data)
@@ -128,81 +145,3 @@ bool ZRColaApp::OnInit()
return true;
}
bool ZRColaApp::GetKeySequenceAsText(_In_count_(seq_len) const ZRCola::keyseq_db::keyseq::key_t *seq, _In_ size_t seq_len, _Out_ wxString& str)
{
assert(seq || !seq_len);
str.Clear();
for (size_t i = 0; i < seq_len; i++) {
if (i) str += L", ";
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::CTRL ) str += L"Ctrl+";
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::ALT ) str += L"Alt+";
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::SHIFT) str += L"Shift+";
wchar_t k = seq[i].key;
#if defined(__WXMSW__)
// Translate from U.S. Keyboard to scan code.
static const HKL s_hkl = ::LoadKeyboardLayout(_T("00000409"), 0);
k = ::MapVirtualKeyEx(k, MAPVK_VK_TO_VSC, s_hkl);
// Translate from scan code to local keyboard.
k = ::MapVirtualKey(k, MAPVK_VSC_TO_VK);
#endif
switch (k) {
case 0 : return false;
case WXK_ESCAPE : str += _("Esc" ); break;
case WXK_F1 : str += _("F1" ); break;
case WXK_F2 : str += _("F2" ); break;
case WXK_F3 : str += _("F3" ); break;
case WXK_F4 : str += _("F4" ); break;
case WXK_F5 : str += _("F5" ); break;
case WXK_F6 : str += _("F6" ); break;
case WXK_F7 : str += _("F7" ); break;
case WXK_F8 : str += _("F8" ); break;
case WXK_F9 : str += _("F9" ); break;
case WXK_F10 : str += _("F10" ); break;
case WXK_F11 : str += _("F11" ); break;
case WXK_F12 : str += _("F12" ); break;
case WXK_PRINT : str += _("Print Screen"); break;
case WXK_SCROLL : str += _("Scroll Lock" ); break;
case WXK_PAUSE : str += _("Pause" ); break;
case WXK_BACK : str += _("Backspace" ); break;
case WXK_TAB : str += _("Tab" ); break;
case WXK_CAPITAL : str += _("Caps Lock" ); break;
case WXK_RETURN : str += _("Return" ); break;
case WXK_SPACE : str += _("Space" ); break;
case WXK_SHIFT : str += _("Shift" ); break;
case WXK_ALT : str += _("Alt" ); break;
case WXK_CONTROL : str += _("Ctrl" ); break;
case WXK_MENU : str += _("Menu" ); break;
case WXK_INSERT : str += _("Insert" ); break;
case WXK_DELETE : str += _("Delete" ); break;
case WXK_PAGEUP : str += _("Page Up" ); break;
case WXK_PAGEDOWN : str += _("Page Down" ); break;
case WXK_HOME : str += _("Home" ); break;
case WXK_END : str += _("End" ); break;
case WXK_LEFT : str += _("Left" ); break;
case WXK_UP : str += _("Up" ); break;
case WXK_RIGHT : str += _("Right" ); break;
case WXK_DOWN : str += _("Down" ); break;
case WXK_NUMLOCK : str += _("Num Lock" ); break;
default:
#if defined(__WXMSW__)
k = ::MapVirtualKey(k, MAPVK_VK_TO_CHAR);
#endif
str += k;
}
}
return true;
}

View File

@@ -29,6 +29,7 @@ class ZRColaApp;
#include <wx/app.h>
#include <wx/config.h>
#include <wx/intl.h>
#include <zrcola/character.h>
#include <zrcola/language.h>
#include <zrcola/translate.h>
#include <zrcolaui/keyboard.h>
@@ -57,44 +58,18 @@ public:
///
inline wxString GetDatabasePath() const;
///
/// Get text representation of a given key sequence
///
/// \param[in] seq Key sequence
/// \param[in] seq_len Number of elements in \p seq
/// \param[out] str Text representation of a \p seq key sequence
///
/// \returns
/// - \c true if conversion succeeded
/// - \c false otherwise
///
static bool GetKeySequenceAsText(_In_count_(seq_len) const ZRCola::keyseq_db::keyseq::key_t *seq, _In_ size_t seq_len, _Out_ wxString& str);
///
/// Get text representation of a given key sequence
///
/// \param[in] seq Key sequence
/// \param[in] seq_len Number of elements in \p seq
///
/// \returns Text representation of a \p seq key sequence
///
static inline wxString GetKeySequenceAsText(_In_count_(seq_len) const ZRCola::keyseq_db::keyseq::key_t *seq, _In_ size_t seq_len)
{
wxString str;
return GetKeySequenceAsText(seq, seq_len, str) ? str : wxEmptyString;
}
public:
ZRCola::translation_db m_t_db; ///< Translation database
ZRCola::langchar_db m_lc_db; ///< Language character database
ZRCola::language_db m_lang_db; ///< Language database
ZRCola::keyseq_db m_ks_db; ///< Key sequence database
ZRCola::character_db m_chr_db; ///< Character database
ZRCola::chrcat_db m_cc_db; ///< Characted category database
wxZRColaFrame *m_mainWnd; ///< Main window
protected:
wxLocale m_locale; ///< Current locale
wxLocale m_locale; ///< Current locale
};

View File

@@ -112,7 +112,9 @@ void wxZRColaCharacterCatalogPanel::OnGridClick(wxGridEvent& event)
void wxZRColaCharacterCatalogPanel::OnGridKeyDown(wxKeyEvent& event)
{
if (event.GetKeyCode() == WXK_RETURN) {
switch (event.GetKeyCode()) {
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
ZRColaApp *app = (ZRColaApp*)wxTheApp;
if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(m_grid->GetCursorRow(), m_grid->GetCursorColumn()));

View File

@@ -44,7 +44,7 @@ wxZRColaCharGrid::wxZRColaCharGrid(wxWindow *parent, wxWindowID id, const wxPoin
SetDefaultRowSize(wxZRColaCharacterGridRowHeight);
// Create timer for saving the state.
m_toolTipTimer = new wxTimer(this, wxID_TOOLTIP_TIMER);
m_timerToolTip.SetOwner(this, wxID_TOOLTIP_TIMER);
// wxEVT_MOTION event must be connected to the wxGridWindow, not wxGrid itself.
wxWindow *gridWnd = GetGridWindow();
@@ -56,32 +56,26 @@ wxZRColaCharGrid::~wxZRColaCharGrid()
{
wxWindow *gridWnd = GetGridWindow();
gridWnd->Disconnect(gridWnd->GetId(), wxEVT_MOTION, wxMouseEventHandler(wxZRColaCharGrid::OnMotion), NULL, this);
if (m_toolTipTimer)
delete m_toolTipTimer;
}
void wxZRColaCharGrid::Init()
{
m_isResizing = false;
m_toolTipTimer = NULL;
m_toolTipIdx = (size_t)-1;
m_regenerate = false;
m_isResizing = false;
m_toolTipIdx = (size_t)-1;
}
void wxZRColaCharGrid::SetCharacters(const wxString &chars)
{
m_chars = chars;
m_chars = chars;
m_regenerate = true;
// Build and set new grid data.
size_t char_len = m_chars.Length();
int rows = std::max<int>((char_len + m_numCols - 1) / m_numCols, 1);
wxGridStringTable *table = new wxGridStringTable(rows, m_numCols);
for (int r = 0, i = 0; r < rows; r++)
for (int c = 0; c < m_numCols; c++, i++)
table->SetValue(r, c, i < char_len ? wxString(1, m_chars[i]) : wxEmptyString);
SetTable(table, true);
// Invoke OnSize(), which will populate the grid.
wxSizeEvent e(GetSize(), m_windowId);
e.SetEventObject(this);
HandleWindowEvent(e);
}
@@ -92,18 +86,16 @@ wxString wxZRColaCharGrid::GetToolTipText(int idx)
ZRColaApp *app = (ZRColaApp*)wxTheApp;
// See if this character has a key sequence registered.
ZRCola::keyseq_db::indexKey::size_type start, end;
ZRCola::keyseq_db::indexKey::size_type start;
bool found;
ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq)];
ks->chr = m_chars[idx];
ks->seq_len = 0;
found = app->m_ks_db.idxChr.find(*ks, start, end);
delete ks;
char ks[sizeof(ZRCola::keyseq_db::keyseq)] = {};
((ZRCola::keyseq_db::keyseq*)ks)->chr = m_chars[idx];
found = app->m_ks_db.idxChr.find(*(ZRCola::keyseq_db::keyseq*)ks, start);
if (found) {
ZRCola::keyseq_db::keyseq &seq = app->m_ks_db.idxChr[start];
wxString ks_str;
if (ZRColaApp::GetKeySequenceAsText(seq.seq, seq.seq_len, ks_str))
if (ZRCola::keyseq_db::GetSequenceAsText(seq.seq, seq.seq_len, ks_str))
return wxString::Format(wxT("U+%04X (%s)"), (int)m_chars[idx], ks_str.c_str());
}
@@ -138,21 +130,25 @@ void wxZRColaCharGrid::OnSize(wxSizeEvent& event)
BeginBatch();
if (cols != m_numCols) {
if (m_regenerate || cols != m_numCols) {
// Build and set new grid data.
wxGridStringTable *table = new wxGridStringTable(rows, cols);
for (int r = 0, i = 0; r < rows; r++)
for (int c = 0; c < cols; c++, i++)
table->SetValue(r, c, i < char_len ? wxString(1, m_chars[i]) : wxEmptyString);
SetTable(table, true);
m_regenerate = false;
}
// Set column widths to stretch to full width.
for (int c = 0, x_l = 0; c < cols; c++) {
int x_r = (c + 1)*width/cols;
SetColSize(c, x_r - x_l);
x_l = x_r;
}
for (int c = 0; c < cols; c++)
SetColSize(c, wxZRColaCharacterGridColumnWidth);
//// Set column widths to stretch to full width.
//for (int c = 0, x_l = 0; c < cols; c++) {
// int x_r = (c + 1)*width/cols;
// SetColSize(c, x_r - x_l);
// x_l = x_r;
//}
EndBatch();
m_isResizing = false;
@@ -193,7 +189,7 @@ void wxZRColaCharGrid::OnMotion(wxMouseEvent& event)
if (toolTipIdx >= m_chars.Length()) {
// Index out of range.
m_toolTipIdx = (size_t)-1;
m_toolTipTimer->Stop();
m_timerToolTip.Stop();
return;
} else if (toolTipIdx != m_toolTipIdx) {
// Cell changed.
@@ -204,7 +200,7 @@ void wxZRColaCharGrid::OnMotion(wxMouseEvent& event)
gridWnd->SetToolTip(GetToolTipText(m_toolTipIdx));
} else {
// This must be our initial entry. Schedule tooltip display after 1s.
m_toolTipTimer->Start(1000, true);
m_timerToolTip.Start(1000, true);
}
}
}

View File

@@ -58,6 +58,16 @@ public:
///
void SetCharacters(const wxString &chars);
///
/// Returns displayed characters
///
/// \returns The string containing displayed characters
///
inline wxString GetCharacters() const
{
return m_chars;
}
protected:
virtual wxString GetToolTipText(int idx);
@@ -74,7 +84,8 @@ protected:
wxString m_chars; ///< Array of Unicode characters to display in the grid
private:
bool m_regenerate; ///< Force regenerate grid table
bool m_isResizing; ///< Prevents nesting of OnSize() method.
wxTimer *m_toolTipTimer;///< Timer for displaying tooltip
wxTimer m_timerToolTip; ///< Timer for displaying tooltip
size_t m_toolTipIdx; ///< Index of cell for tooltip display
};

416
ZRCola/zrcolachrslct.cpp Normal file
View File

@@ -0,0 +1,416 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
//////////////////////////////////////////////////////////////////////////
// wxZRColaCharSelect
//////////////////////////////////////////////////////////////////////////
wxDEFINE_EVENT(wxEVT_SEARCH_COMPLETE, wxThreadEvent);
wxZRColaCharSelect::wxZRColaCharSelect(wxWindow* parent) :
m_searchChanged(false),
m_unicodeChanged(false),
m_char(0),
m_searchThread(NULL),
wxZRColaCharSelectBase(parent)
{
Connect(wxID_ANY, wxEVT_SEARCH_COMPLETE, wxThreadEventHandler(wxZRColaCharSelect::OnSearchComplete), NULL, this);
m_unicode->SetValidator(wxHexValidator<wchar_t>(&m_char));
// Fill categories.
ZRColaApp *app = (ZRColaApp*)wxTheApp;
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrcat_db::chrcat &cc = app->m_cc_db.idxRnk[i];
int idx = m_categories->Insert(wxGetTranslation(wxString(cc.name, cc.name_len), wxT("ZRCola-zrcdb")), i);
m_categories->Check(idx);
m_ccOrder.insert(std::make_pair(cc.id, idx));
}
ResetResults();
}
wxZRColaCharSelect::~wxZRColaCharSelect()
{
if (m_searchThread)
m_searchThread->Delete();
Disconnect(wxID_ANY, wxEVT_SEARCH_COMPLETE, wxThreadEventHandler(wxZRColaCharSelect::OnSearchComplete), NULL, this);
}
void wxZRColaCharSelect::OnIdle(wxIdleEvent& event)
{
event.Skip();
if (m_unicodeChanged) {
if (m_unicode->GetValidator()->TransferFromWindow()) {
ZRColaApp *app = (ZRColaApp*)wxTheApp;
m_gridPreview->SetCellValue(wxString(1, m_char), 0, 0);
{
char chr[sizeof(ZRCola::character_db::character)] = {};
((ZRCola::character_db::character*)chr)->chr = m_char;
size_t start;
if (app->m_chr_db.idxChr.find(*(ZRCola::character_db::character*)chr, start)) {
const ZRCola::character_db::character &chr = app->m_chr_db.idxChr[start];
m_description->SetValue(wxString(chr.data, chr.desc_len));
{
char cc[sizeof(ZRCola::chrcat_db::chrcat)] = {};
((ZRCola::chrcat_db::chrcat*)cc)->id = chr.cat;
size_t start;
if (app->m_cc_db.idxChrCat.find(*((ZRCola::chrcat_db::chrcat*)cc), start)) {
const ZRCola::chrcat_db::chrcat &cat = app->m_cc_db.idxChrCat[start];
m_category->SetValue(wxGetTranslation(wxString(cat.name, cat.name_len), wxT("ZRCola-zrcdb")));
} else
m_category->SetValue(wxEmptyString);
}
m_gridRelated->SetCharacters(wxString(chr.data + chr.desc_len, chr.rel_len));
} else {
m_description->SetValue(wxEmptyString);
m_category->SetValue(wxEmptyString);
m_gridRelated->ClearGrid();
}
m_gridRelated->Scroll(0, 0);
}
}
m_unicodeChanged = false;
} else if (m_searchChanged) {
if (m_searchThread)
m_searchThread->Delete();
wxString val(m_search->GetValue());
if (!val.IsEmpty()) {
ZRColaApp *app = (ZRColaApp*)wxTheApp;
m_searchThread = new SearchThread(this);
m_searchThread->m_search.assign(val.c_str(), val.Length());
// Select categories.
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrcat_db::chrcat &cc = app->m_cc_db.idxRnk[i];
if (m_categories->IsChecked(i))
m_searchThread->m_cats.insert(cc.id);
}
if (m_searchThread->Run() != wxTHREAD_NO_ERROR) {
wxFAIL_MSG("Can't create the thread!");
delete m_searchThread;
m_searchThread = NULL;
}
} else
ResetResults();
m_searchChanged = false;
}
}
void wxZRColaCharSelect::OnSearchText(wxCommandEvent& event)
{
event.Skip();
m_searchChanged = true;
}
void wxZRColaCharSelect::OnCategoriesToggle(wxCommandEvent& event)
{
event.Skip();
m_searchChanged = true;
}
void wxZRColaCharSelect::OnSearchComplete(wxThreadEvent& event)
{
event.Skip();
if (m_searchThread) {
// Display results.
wxString chars;
chars.reserve(m_searchThread->m_hits.size());
for (std::vector< std::pair<unsigned long, wchar_t> >::const_iterator i = m_searchThread->m_hits.cbegin(), i_end = m_searchThread->m_hits.cend(); i != i_end; ++i)
chars += i->second;
m_gridResults->SetCharacters(chars);
m_searchThread->Delete();
m_searchThread = NULL;
m_gridResults->Scroll(0, 0);
}
}
void wxZRColaCharSelect::OnResultSelectCell(wxGridEvent& event)
{
wxString val(m_gridResults->GetCellValue(event.GetRow(), event.GetCol()));
m_char = val.IsEmpty() ? 0 : val[0];
m_unicode->GetValidator()->TransferToWindow();
}
void wxZRColaCharSelect::OnResultCellDClick(wxGridEvent& event)
{
event.Skip();
wxString val(m_gridResults->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty()) {
m_char = val[0];
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
}
}
void wxZRColaCharSelect::OnResultsKeyDown(wxKeyEvent& event)
{
switch (event.GetKeyCode()) {
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
wxString val(m_gridResults->GetCellValue(m_gridResults->GetCursorRow(), m_gridResults->GetCursorColumn()));
if (!val.IsEmpty()) {
m_char = val[0];
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
event.StopPropagation();
return;
}
}
event.Skip();
}
void wxZRColaCharSelect::OnRecentSelectCell(wxGridEvent& event)
{
wxString val(m_gridRecent->GetCellValue(event.GetRow(), event.GetCol()));
m_char = val.IsEmpty() ? 0 : val[0];
m_unicode->GetValidator()->TransferToWindow();
}
void wxZRColaCharSelect::OnRecentCellDClick(wxGridEvent& event)
{
event.Skip();
wxString val(m_gridRecent->GetCellValue(event.GetRow(), event.GetCol()));
if (!val.IsEmpty()) {
m_char = val[0];
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
}
}
void wxZRColaCharSelect::OnRecentKeyDown(wxKeyEvent& event)
{
switch (event.GetKeyCode()) {
case WXK_RETURN:
case WXK_NUMPAD_ENTER:
wxString val(m_gridRecent->GetCellValue(m_gridRecent->GetCursorRow(), m_gridRecent->GetCursorColumn()));
if (!val.IsEmpty()) {
m_char = val[0];
wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK);
m_sdbSizerButtonsOK->GetEventHandler()->ProcessEvent(e);
event.StopPropagation();
return;
}
}
event.Skip();
}
void wxZRColaCharSelect::OnRelatedSelectCell(wxGridEvent& event)
{
wxString val(m_gridRelated->GetCellValue(event.GetRow(), event.GetCol()));
m_char = val.IsEmpty() ? 0 : val[0];
m_unicode->GetValidator()->TransferToWindow();
}
void wxZRColaCharSelect::OnUnicodeText(wxCommandEvent& event)
{
event.Skip();
m_unicodeChanged = true;
}
void wxZRColaCharSelect::OnOKButtonClick(wxCommandEvent& event)
{
event.Skip();
wxString
recent(m_gridRecent->GetCharacters()),
val(1, m_char);
for (size_t i = 0, n = recent.Length(); i < n; i++) {
const wxStringCharType c = recent[i];
if (c != m_char)
val += c;
}
m_gridRecent->SetCharacters(val);
}
void wxZRColaCharSelect::ResetResults()
{
// Fill the results.
ZRColaApp *app = (ZRColaApp*)wxTheApp;
size_t i, n = app->m_chr_db.idxChr.size();
wxString val;
val.reserve(n);
for (i = 0; i < n; i++) {
const ZRCola::character_db::character &chr = app->m_chr_db.idxChr[i];
std::map<ZRCola::chrcatid_t, int>::const_iterator idx = m_ccOrder.find(chr.cat);
if (idx == m_ccOrder.end() || m_categories->IsChecked(idx->second))
val += chr.chr;
}
m_gridResults->SetCharacters(val);
}
wxZRColaCharSelect::SearchThread::SearchThread(wxZRColaCharSelect *parent) :
m_parent(parent),
wxThread(wxTHREAD_JOINABLE)
{
//// This is a worker thread. Set priority between minimal and normal.
//SetPriority((wxPRIORITY_MIN + wxPRIORITY_DEFAULT) / 2);
}
wxThread::ExitCode wxZRColaCharSelect::SearchThread::Entry()
{
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::map<wchar_t, unsigned long> hits;
if (TestDestroy()) return (wxThread::ExitCode)1;
{
// Search by indexes and merge results.
std::map<wchar_t, unsigned long> hits_sub;
if (!app->m_chr_db.Search(m_search.c_str(), m_cats, hits, hits_sub, TestDestroyS, this)) return (wxThread::ExitCode)1;
for (std::map<wchar_t, unsigned long>::const_iterator i = hits_sub.cbegin(), i_end = hits_sub.cend(); i != i_end; ++i) {
if (TestDestroy()) return (wxThread::ExitCode)1;
std::map<wchar_t, unsigned long>::iterator idx = hits.find(i->first);
if (idx == hits.end())
hits.insert(std::make_pair(i->first, i->second / 4));
else
idx->second += i->second / 4;
}
}
// Now sort the characters by rank.
m_hits.reserve(hits.size());
for (std::map<wchar_t, unsigned long>::const_iterator i = hits.cbegin(), i_end = hits.cend(); i != i_end; ++i) {
if (TestDestroy()) return (wxThread::ExitCode)1;
m_hits.push_back(std::make_pair(i->second, i->first));
}
std::qsort(m_hits.data(), m_hits.size(), sizeof(std::pair<unsigned long, wchar_t>), CompareHits);
// Signal the event handler that this thread is going to be destroyed.
// NOTE: here we assume that using the m_parent pointer is safe,
// (in this case this is assured by the wxZRColaCharSelect destructor)
wxQueueEvent(m_parent, new wxThreadEvent(wxEVT_SEARCH_COMPLETE));
return 0;
}
int __cdecl wxZRColaCharSelect::SearchThread::CompareHits(const void *a, const void *b)
{
const std::pair<unsigned long, wchar_t> *_a = (const std::pair<unsigned long, wchar_t>*)a;
const std::pair<unsigned long, wchar_t> *_b = (const std::pair<unsigned long, wchar_t>*)b;
if (_a->first > _b->first) return -1;
else if (_a->first < _b->first) return 1;
if (_a->second < _b->second) return -1;
else if (_a->second > _b->second) return 1;
return 0;
}
bool __cdecl wxZRColaCharSelect::SearchThread::TestDestroyS(void *cookie)
{
return static_cast<wxZRColaCharSelect::SearchThread*>(cookie)->TestDestroy();
}
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaCharSelect
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaCharSelect::wxPersistentZRColaCharSelect(wxZRColaCharSelect *wnd) : wxPersistentDialog(wnd)
{
}
void wxPersistentZRColaCharSelect::Save() const
{
wxPersistentDialog::Save();
const wxZRColaCharSelect * const wnd = static_cast<const wxZRColaCharSelect*>(GetWindow());
SaveValue(wxT("recentChars"), wnd->m_gridRecent->GetCharacters());
ZRColaApp *app = (ZRColaApp*)wxTheApp;
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrcat_db::chrcat &cc = app->m_cc_db.idxRnk[i];
wxString name(wxT("category"));
name.Append(cc.id.data, _countof(cc.id.data));
SaveValue(name, wnd->m_categories->IsChecked(i));
}
}
bool wxPersistentZRColaCharSelect::Restore()
{
wxZRColaCharSelect * const wnd = static_cast<wxZRColaCharSelect*>(GetWindow());
wxString recent;
if (RestoreValue(wxT("recentChars"), &recent))
wnd->m_gridRecent->SetCharacters(recent);
ZRColaApp *app = (ZRColaApp*)wxTheApp;
for (size_t i = 0, n = app->m_cc_db.idxRnk.size(); i < n; i++) {
const ZRCola::chrcat_db::chrcat &cc = app->m_cc_db.idxRnk[i];
wxString name(wxT("category"));
name.Append(cc.id.data, _countof(cc.id.data));
bool val;
if (RestoreValue(name, &val))
wnd->m_categories->Check(i, val);
}
wnd->ResetResults();
return wxPersistentDialog::Restore();
}

120
ZRCola/zrcolachrslct.h Normal file
View File

@@ -0,0 +1,120 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
///
/// Forward declarations
///
class wxZRColaCharSelect;
class wxPersistentZRColaCharSelect;
#pragma once
#include "zrcolagui.h"
#include <zrcola/character.h>
#include <wxex/valhex.h>
#include <wxex/persist/dialog.h>
#include <wx/event.h>
#include <wx/thread.h>
#include <map>
wxDECLARE_EVENT(wxEVT_SEARCH_COMPLETE, wxThreadEvent);
///
/// ZRCola character select dialog
///
class wxZRColaCharSelect : public wxZRColaCharSelectBase
{
public:
wxZRColaCharSelect(wxWindow* parent);
virtual ~wxZRColaCharSelect();
friend class wxPersistentZRColaCharSelect; // Allow saving/restoring window state.
friend class SearchThread; // For search thread back-notifications
protected:
virtual void OnIdle(wxIdleEvent& event);
virtual void OnSearchText(wxCommandEvent& event);
virtual void OnCategoriesToggle(wxCommandEvent& event);
void OnSearchComplete(wxThreadEvent& event);
virtual void OnResultSelectCell(wxGridEvent& event);
virtual void OnResultCellDClick(wxGridEvent& event);
virtual void OnResultsKeyDown(wxKeyEvent& event);
virtual void OnRecentSelectCell(wxGridEvent& event);
virtual void OnRecentCellDClick(wxGridEvent& event);
virtual void OnRecentKeyDown(wxKeyEvent& event);
virtual void OnRelatedSelectCell(wxGridEvent& event);
virtual void OnUnicodeText(wxCommandEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
void ResetResults();
public:
wchar_t m_char; ///< Currently selected character (0 when none)
protected:
bool m_searchChanged; ///< Did Search field or category selection change?
std::map<ZRCola::chrcatid_t, int> m_ccOrder; ///< Character category order
bool m_unicodeChanged; ///< Did Unicode field change?
///
/// Search worker thread
///
class SearchThread : public wxThread
{
public:
SearchThread(wxZRColaCharSelect *parent);
protected:
virtual ExitCode Entry();
static int __cdecl CompareHits(const void *a, const void *b);
static bool __cdecl TestDestroyS(void *cookie);
public:
std::wstring m_search; ///< Search phrase
std::set<ZRCola::chrcatid_t> m_cats; ///< Search categories
std::vector< std::pair<unsigned long, wchar_t> > m_hits; ///< Search results
protected:
wxZRColaCharSelect *m_parent; ///< Thread owner
} *m_searchThread; ///< Search thread
};
///
/// Supports saving/restoring wxZRColaCharSelect state
///
class wxPersistentZRColaCharSelect : public wxPersistentDialog
{
public:
wxPersistentZRColaCharSelect(wxZRColaCharSelect *wnd);
virtual void Save() const;
virtual bool Restore();
};
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaCharSelect *wnd)
{
return new wxPersistentZRColaCharSelect(wnd);
}

View File

@@ -24,22 +24,15 @@
// wxZRColaComposerPanel
//////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(wxZRColaComposerPanel, wxZRColaComposerPanelBase)
EVT_TIMER(wxZRColaComposerPanel::wxID_CHECKPOINT_TIMER, wxZRColaComposerPanel::OnTimerTimeout)
END_EVENT_TABLE()
wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_progress(false),
m_decomposedChanged(false),
m_composedChanged(false),
m_selDecomposed(0, 0),
m_selComposed(0, 0),
wxZRColaComposerPanelBase(parent)
{
m_decomposed->PushEventHandler(&m_keyhandler);
// Create timer for saving the state.
m_timer = new wxTimer(this, wxID_CHECKPOINT_TIMER);
// Restore the previously saved state (if exists).
wxString fileName(GetStateFileName());
if (wxFileExists(fileName)) {
@@ -59,10 +52,15 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
file.Read(wxStringBuffer(composed, n), sizeof(wchar_t)*n);
if (!file.Error()) {
// Restore state.
m_progress = true;
m_decomposed->SetValue(decomposed);
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, decomposed.GetData(), decomposed.Length(), m_selDecomposed.first, m_selDecomposed.second);
m_decomposedChanged = false;
m_composed->SetValue(composed);
m_progress = false;
m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, composed.GetData(), composed.Length(), m_selComposed.first, m_selComposed.second);
m_composedChanged = false;
}
}
}
@@ -74,9 +72,6 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
wxZRColaComposerPanel::~wxZRColaComposerPanel()
{
if (m_timer)
delete m_timer;
m_decomposed->PopEventHandler();
// This is a controlled exit. Purge saved state.
@@ -86,6 +81,73 @@ wxZRColaComposerPanel::~wxZRColaComposerPanel()
}
void wxZRColaComposerPanel::SynchronizePanels()
{
if (m_decomposedChanged) {
m_timerSave.Stop();
wxString src;
size_t len = GetValue(m_decomposed, src);
std::wstring norm;
((ZRColaApp*)wxTheApp)->m_t_db.Decompose(src.data(), len, norm, &m_mapping1);
std::wstring dst;
((ZRColaApp*)wxTheApp)->m_t_db.Compose(norm.data(), norm.size(), dst, &m_mapping2);
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
// Update decomposed HEX dump.
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, src.data(), len, m_selDecomposed.first, m_selDecomposed.second);
// Update composed text, and its HEX dump.
m_composed->SetValue(dst);
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, dst.data(), dst.length(), m_selComposed.first, m_selComposed.second);
// Schedule state save after 3s.
m_timerSave.Start(3000, true);
} else if (m_composedChanged) {
m_timerSave.Stop();
wxString src;
size_t len = GetValue(m_composed, src);
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::wstring dst;
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), len, &app->m_lc_db, mainWnd->m_settings->m_lang, dst, &m_mapping2);
else
app->m_t_db.Decompose(src.data(), len, dst, &m_mapping2);
m_mapping1.clear();
m_mapping2.invert();
m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
// Update composed HEX dump.
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, src.data(), len, m_selComposed.first, m_selComposed.second);
// Update decomposed text, and its HEX dump.
m_decomposed->SetValue(dst);
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, dst.data(), dst.length(), m_selDecomposed.first, m_selDecomposed.second);
// Schedule state save after 3s.
m_timerSave.Start(3000, true);
}
m_decomposedChanged = false;
m_composedChanged = false;
}
void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
{
event.Skip();
@@ -97,9 +159,18 @@ void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selDecomposed.first = from;
m_selDecomposed.second = to;
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
m_composed->SetSelection(from = m_mapping2.to_dst(m_mapping1.to_dst(from)), to = m_mapping2.to_dst(m_mapping1.to_dst(to)));
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(from),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(from)),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(to )));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
}
}
@@ -115,63 +186,28 @@ void wxZRColaComposerPanel::OnDecomposedHexPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selDecomposedHex.first = from;
m_selDecomposedHex.second = to;
m_decomposed->SetSelection(from = m_mappingDecomposedHex.to_src(from), to = m_mappingDecomposedHex.to_src(to));
m_composed->SetSelection(from = m_mapping2.to_dst(m_mapping1.to_dst(from)), to = m_mapping2.to_dst(m_mapping1.to_dst(to)));
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mappingDecomposedHex.to_src(from),
m_selDecomposed.second = m_mappingDecomposedHex.to_src(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
}
}
void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
{
if (m_progress) {
// We are being updated by wxZRColaComposerPanel::OnComposedText()
event.Skip();
} else {
m_timer->Stop();
event.Skip();
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_decomposed->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> src(len + 1);
::GetWindowTextW(hWnd, src.data(), src.size());
#else
wxString src(m_decomposed->GetValue());
size_t len = src.Length();
#endif
std::wstring norm;
((ZRColaApp*)wxTheApp)->m_t_db.Decompose(src.data(), len, norm, &m_mapping1);
std::wstring dst;
((ZRColaApp*)wxTheApp)->m_t_db.Compose(norm.data(), norm.size(), dst, &m_mapping2);
long from, to;
m_decomposed->GetSelection(&from, &to);
// Update decomposed HEX dump.
wxString hex;
GetHex(hex, m_mappingDecomposedHex, src.data(), len);
m_decomposedHex->SetValue(hex);
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
// Update composed text.
m_progress = true;
m_composed->SetValue(dst);
m_composed->SetSelection(from = m_mapping2.to_dst(m_mapping1.to_dst(from)), to = m_mapping2.to_dst(m_mapping1.to_dst(to)));
// Update composed HEX dump.
GetHex(hex, m_mappingComposedHex, dst.data(), dst.length());
m_composedHex->SetValue(hex);
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
event.Skip();
m_progress = false;
// Schedule state save after 3s.
m_timer->Start(3000, true);
}
// Set the flag the decomposed text changed to trigger idle-time composition.
m_decomposedChanged = true;
}
@@ -186,9 +222,18 @@ void wxZRColaComposerPanel::OnComposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selComposed.first = from;
m_selComposed.second = to;
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
m_decomposed->SetSelection(from = m_mapping1.to_src(m_mapping2.to_src(from)), to = m_mapping1.to_src(m_mapping2.to_src(to)));
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(from),
m_selComposedHex.second = m_mappingComposedHex.to_dst(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(from)),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(to )));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
}
}
@@ -204,107 +249,48 @@ void wxZRColaComposerPanel::OnComposedHexPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selComposedHex.first = from;
m_selComposedHex.second = to;
m_composed->SetSelection(from = m_mappingComposedHex.to_src(from), to = m_mappingComposedHex.to_src(to));
m_decomposed->SetSelection(from = m_mapping1.to_src(m_mapping2.to_src(from)), to = m_mapping1.to_src(m_mapping2.to_src(to)));
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
m_composed->SetSelection(
m_selComposed.first = m_mappingComposedHex.to_src(from),
m_selComposed.second = m_mappingComposedHex.to_src(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
}
}
void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
{
if (m_progress) {
// We are being updated by wxZRColaComposerPanel::OnDecomposedText()
event.Skip();
} else {
m_timer->Stop();
event.Skip();
#ifdef __WINDOWS__
// Use Windows GetWindowTextLength() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_composed->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> src(len + 1);
::GetWindowTextW(hWnd, src.data(), src.size());
#else
wxString src(m_composed->GetValue());
size_t len = src.Length();
#endif
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::wstring dst;
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), len, &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping2);
else
app->m_t_db.Decompose(src.data(), len, dst, &m_mapping2);
m_mapping1.clear();
m_mapping2.invert();
long from, to;
m_composed->GetSelection(&from, &to);
// Update composed HEX dump.
wxString hex;
GetHex(hex, m_mappingComposedHex, src.data(), len);
m_composedHex->SetValue(hex);
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
// Update decomposed text.
m_progress = true;
m_decomposed->SetValue(dst);
m_decomposed->SetSelection(from = m_mapping1.to_src(m_mapping2.to_src(from)), to = m_mapping1.to_src(m_mapping2.to_src(to)));
// Update decomposed HEX dump.
GetHex(hex, m_mappingDecomposedHex, dst.data(), dst.length());
m_decomposedHex->SetValue(hex);
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
event.Skip();
m_progress = false;
// Schedule state save after 3s.
m_timer->Start(3000, true);
}
// Set the flag the composed text changed to trigger idle-time decomposition.
m_composedChanged = true;
}
void wxZRColaComposerPanel::OnTimerTimeout(wxTimerEvent& event)
void wxZRColaComposerPanel::OnSaveTimer(wxTimerEvent& event)
{
wxString fileName(GetStateFileName());
wxFFile file(fileName, wxT("wb"));
if (file.IsOpened()) {
wxString text;
size_t len;
// Save decomposed text.
{
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_decomposed->GetHWND();
unsigned __int64 len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> text(len + 1);
::GetWindowTextW(hWnd, text.data(), text.size());
#else
wxString text(m_decomposed->GetValue());
unsigned __int64 len = text.Length();
#endif
file.Write(&len, sizeof(len));
file.Write(text.data(), sizeof(wchar_t)*len);
}
len = GetValue(m_decomposed, text);
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
// Save composed text.
{
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_composed->GetHWND();
unsigned __int64 len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> text(len + 1);
::GetWindowTextW(hWnd, text.data(), text.size());
#else
wxString text(m_composed->GetValue());
unsigned __int64 len = text.Length();
#endif
file.Write(&len, sizeof(len));
file.Write(text.data(), sizeof(wchar_t)*len);
}
len = GetValue(m_composed, text);
file.Write(&len, sizeof(len));
file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
}
event.Skip();
@@ -329,10 +315,36 @@ wxString wxZRColaComposerPanel::GetStateFileName()
}
void wxZRColaComposerPanel::GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len)
size_t wxZRColaComposerPanel::GetValue(wxTextCtrl *wnd, wxString &text)
{
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = wnd->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
if (len < 0x100) {
WCHAR buf[0x100];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
} else {
LPWSTR buf = new WCHAR[len + 1];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
delete [] buf;
}
return len;
#else
text = wnd->GetValue();
return text.Length();
#endif
}
void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to)
{
wxString hex;
bool first = true;
hex.clear();
mapping.clear();
for (size_t i = 0; i < len && src[i]; i++) {
wchar_t c = src[i];
@@ -345,6 +357,11 @@ void wxZRColaComposerPanel::GetHex(wxString &hex, ZRCola::mapping_vector &mappin
first = false;
}
}
wnd->SetValue(hex);
wnd->SetSelection(
range.first = mapping.to_dst(from),
range.second = mapping.to_dst(to ));
}

View File

@@ -38,14 +38,11 @@ class wxZRColaComposerPanel;
class wxZRColaComposerPanel : public wxZRColaComposerPanelBase
{
public:
enum
{
wxID_CHECKPOINT_TIMER = 2000,
};
wxZRColaComposerPanel(wxWindow* parent);
virtual ~wxZRColaComposerPanel();
void SynchronizePanels();
friend class wxPersistentZRColaComposerPanel; // Allow saving/restoring window state.
protected:
@@ -55,14 +52,15 @@ protected:
virtual void OnComposedPaint(wxPaintEvent& event);
virtual void OnComposedHexPaint(wxPaintEvent& event);
virtual void OnComposedText(wxCommandEvent& event);
virtual void OnTimerTimeout(wxTimerEvent& event);
DECLARE_EVENT_TABLE()
virtual void OnSaveTimer(wxTimerEvent& event);
static wxString GetStateFileName();
static void GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len);
static size_t GetValue(wxTextCtrl *wnd, wxString &text);
static void SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to);
protected:
bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls
bool m_decomposedChanged; ///< Boolean flag to mark decomposed text "dirty" to trigger composition
bool m_composedChanged; ///< Boolean flag to mark composed text "dirty" to trigger decomposition
ZRCola::mapping_vector m_mapping1; ///< Character index mapping vector between decomposed and normalized text
ZRCola::mapping_vector m_mapping2; ///< Character index mapping vector between normalized and composed text
std::pair<long, long>
@@ -71,7 +69,6 @@ protected:
m_selComposed, ///< Character index of selected text in composed text control
m_selComposedHex; ///< Character index of selected text in composed HEX dump text control
wxZRColaKeyHandler m_keyhandler; ///< Key handler for decomposed window
wxTimer *m_timer; ///< Timer to trigger the state save
ZRCola::mapping_vector m_mappingDecomposedHex; ///< Character index mapping vector between decomposed text and its HEX dump
ZRCola::mapping_vector m_mappingComposedHex; ///< Character index mapping vector between composed text and its HEX dump
};

View File

@@ -25,40 +25,40 @@
//////////////////////////////////////////////////////////////////////////
wxBEGIN_EVENT_TABLE(wxZRColaFrame, wxZRColaFrameBase)
EVT_UPDATE_UI (wxID_AUTOSTART , wxZRColaFrame::OnAutostartUpdate )
EVT_MENU (wxID_AUTOSTART , wxZRColaFrame::OnAutostart )
EVT_MENU (wxID_EXIT , wxZRColaFrame::OnExit )
EVT_MENU (wxID_EXIT , wxZRColaFrame::OnExit )
EVT_UPDATE_UI_RANGE(wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU_RANGE (wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI (wxID_SELECTALL , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU (wxID_SELECTALL , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI_RANGE(wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU_RANGE (wxID_CUT , wxID_CLEAR , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI (wxID_SELECTALL , wxZRColaFrame::OnForwardEventUpdate )
EVT_MENU (wxID_SELECTALL , wxZRColaFrame::OnForwardEvent )
EVT_UPDATE_UI_RANGE(wxID_SEND_COMPOSED , wxID_SEND_ABORT , wxZRColaFrame::OnSendUpdate )
EVT_MENU (wxID_SEND_COMPOSED , wxZRColaFrame::OnSendComposed )
EVT_MENU (wxID_SEND_DECOMPOSED , wxZRColaFrame::OnSendDecomposed )
EVT_MENU (wxID_SEND_ABORT , wxZRColaFrame::OnSendAbort )
EVT_MENU (wxID_CHARACTER_SELECTOR , wxZRColaFrame::OnInsertCharacter )
EVT_UPDATE_UI (wxID_DECOMP_LANG_AUTO , wxZRColaFrame::OnDecomposedLanguageAutoUpdate)
EVT_MENU (wxID_DECOMP_LANG_AUTO , wxZRColaFrame::OnDecomposedLanguageAuto )
EVT_UPDATE_UI_RANGE(wxID_DECOMP_LANGUAGE_START, wxID_DECOMP_LANGUAGE_END, wxZRColaFrame::OnDecomposedLanguageUpdate )
EVT_MENU_RANGE (wxID_DECOMP_LANGUAGE_START, wxID_DECOMP_LANGUAGE_END, wxZRColaFrame::OnDecomposedLanguage )
EVT_UPDATE_UI_RANGE(wxID_SEND_COMPOSED , wxID_SEND_ABORT, wxZRColaFrame::OnSendUpdate )
EVT_MENU (wxID_SEND_COMPOSED , wxZRColaFrame::OnSendComposed )
EVT_MENU (wxID_SEND_DECOMPOSED , wxZRColaFrame::OnSendDecomposed )
EVT_MENU (wxID_SEND_ABORT , wxZRColaFrame::OnSendAbort )
EVT_UPDATE_UI (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEditUpdate )
EVT_MENU (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEdit )
EVT_UPDATE_UI (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarComposeUpdate )
EVT_MENU (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarCompose )
EVT_UPDATE_UI (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalogUpdate )
EVT_MENU (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalog )
EVT_MENU (wxID_FOCUS_CHARACTER_CATALOG , wxZRColaFrame::OnPanelCharacterCatalogFocus )
EVT_MENU (wxID_SETTINGS , wxZRColaFrame::OnSettings )
EVT_MENU (wxID_ABOUT , wxZRColaFrame::OnAbout )
EVT_UPDATE_UI (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEditUpdate )
EVT_MENU (wxID_TOOLBAR_EDIT , wxZRColaFrame::OnToolbarEdit )
EVT_UPDATE_UI (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarComposeUpdate )
EVT_MENU (wxID_TOOLBAR_COMPOSE , wxZRColaFrame::OnToolbarCompose )
EVT_UPDATE_UI (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalogUpdate)
EVT_MENU (wxID_PANEL_CHRGRPS , wxZRColaFrame::OnPanelCharacterCatalog )
EVT_MENU (wxID_FOCUS_CHARACTER_CATALOG , wxZRColaFrame::OnPanelCharacterCatalogFocus )
EVT_MENU (wxID_HELP_REQCHAR , wxZRColaFrame::OnHelpReqChar )
EVT_MENU (wxID_ABOUT , wxZRColaFrame::OnAbout )
wxEND_EVENT_TABLE()
wxZRColaFrame::wxZRColaFrame() :
m_lang_auto(true),
m_hWndSource(NULL),
m_chrSelect(NULL),
m_settings(NULL),
wxZRColaFrameBase(NULL)
{
{
@@ -75,33 +75,31 @@ wxZRColaFrame::wxZRColaFrame() :
// Load main window icons.
#ifdef __WINDOWS__
wxIcon icon_small(wxT("00_zrcola.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));
wxIconBundle icons;
icons.AddIcon(wxIcon(wxT("00_zrcola.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON)));
icons.AddIcon(icon_small);
icons.AddIcon(wxIcon(wxT("00_zrcola.ico"), wxBITMAP_TYPE_ICO_RESOURCE, ::GetSystemMetrics(SM_CXICON ), ::GetSystemMetrics(SM_CYICON )));
SetIcons(icons);
#else
SetIcon(wxICON(00_zrcola.ico));
wxIcon icon_small(wxICON(00_zrcola.ico));
SetIcon(icon_small);
#endif
{
// Populate language lists.
memcpy(m_lang, ZRCOLA_LANG_VOID, sizeof(m_lang));
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
m_toolDecompLanguage->Clear();
wxString label1_tran(_("Select %s language for decomposition"));
for (size_t i = 0, n = app->m_lang_db.idxLng.size(); i < n; i++) {
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
wxString
label(lang.name, lang.name_len),
label_tran2(wxGetTranslation(label, wxT("ZRCola-zrcdb")));
if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1)
m_menuDecompLanguage->AppendRadioItem(wxID_DECOMP_LANGUAGE_START + i, label_tran2, wxString::Format(label1_tran, (const wxStringCharType*)label_tran2));
m_toolDecompLanguage->Insert(label_tran2, i);
if (memcmp(m_lang, lang.id, sizeof(m_lang)) == 0)
m_toolDecompLanguage->Select(i);
}
m_taskBarIcon = new wxTaskBarIcon();
if (m_taskBarIcon->IsOk()) {
m_taskBarIcon->SetIcon(icon_small, _("ZRCola"));
m_taskBarIcon->Connect(wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler(wxZRColaFrame::OnTaskbarIconClick), NULL, this);
} else {
// Taskbar icon creation failed. Not the end of the world. No taskbar icon then.
delete m_taskBarIcon;
}
m_settings = new wxZRColaSettings(this);
wxPersistentRegisterAndRestore<wxZRColaSettings>(m_settings);
m_chrSelect = new wxZRColaCharSelect(this);
wxPersistentRegisterAndRestore<wxZRColaCharSelect>(m_chrSelect);
// Set focus.
m_panel->m_decomposed->SetFocus();
@@ -153,57 +151,23 @@ wxZRColaFrame::~wxZRColaFrame()
UnregisterHotKey(wxZRColaHKID_INVOKE_DECOMPOSE);
UnregisterHotKey(wxZRColaHKID_INVOKE_COMPOSE);
if (m_chrSelect)
delete m_chrSelect;
if (m_settings)
delete m_settings;
if (m_taskBarIcon) {
m_taskBarIcon->Disconnect(wxEVT_TASKBAR_LEFT_DOWN, wxTaskBarIconEventHandler(wxZRColaFrame::OnTaskbarIconClick), NULL, this);
delete m_taskBarIcon;
}
// Save wxAuiManager's state before return to parent's destructor.
// Since the later calls m_mgr.UnInit() the regular persistence mechanism is useless to save wxAuiManager's state.
wxPersistentAuiManager((wxAuiManager*)&m_mgr).Save();
}
void wxZRColaFrame::OnAutostartUpdate(wxUpdateUIEvent& event)
{
#if defined(__WXMSW__)
wxString linkName(wxExpandEnvVars("%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\ZRCola.lnk"));
event.Check(wxFileExists(linkName));
#else
event.Enable(false);
#endif
}
void wxZRColaFrame::OnAutostart(wxCommandEvent& event)
{
#if defined(__WXMSW__)
wxString linkName(wxExpandEnvVars("%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\ZRCola.lnk"));
if (wxFileExists(linkName)) {
// The shortcut already exists. Remove it.
wxRemoveFile(linkName);
} else {
// Create the shortcut.
IShellLink *sl;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&sl);
if (SUCCEEDED(hr)) {
// Setup ZRCola shortcut.
sl->SetPath(wxTheApp->argv[0]);
sl->SetDescription(_("Start ZRCola automatically on logon"));
sl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
IPersistFile *pf;
hr = sl->QueryInterface(IID_IPersistFile, (LPVOID*)&pf);
if (SUCCEEDED(hr)) {
// Save the link by calling IPersistFile::Save.
hr = pf->Save(linkName, TRUE);
pf->Release();
}
sl->Release();
}
}
#endif
}
void wxZRColaFrame::OnExit(wxCommandEvent& event)
{
Close();
@@ -230,6 +194,15 @@ void wxZRColaFrame::OnForwardEvent(wxCommandEvent& event)
}
void wxZRColaFrame::OnInsertCharacter(wxCommandEvent& event)
{
if (m_chrSelect->ShowModal() == wxID_OK && m_chrSelect->m_char) {
m_panel->m_decomposed->WriteText(m_chrSelect->m_char);
m_panel->m_decomposed->SetFocus();
}
}
void wxZRColaFrame::OnSendUpdate(wxUpdateUIEvent& event)
{
event.Enable(m_hWndSource ? true : false);
@@ -271,72 +244,36 @@ void wxZRColaFrame::OnSendAbort(wxCommandEvent& event)
}
void wxZRColaFrame::OnDecomposedLanguageAutoUpdate(wxUpdateUIEvent& event)
void wxZRColaFrame::OnSettings(wxCommandEvent& event)
{
#if defined(__WXMSW__)
event.Check(m_lang_auto);
#else
event.Enable(false);
#endif
m_settings->ShowModal();
}
void wxZRColaFrame::OnDecomposedLanguageAuto(wxCommandEvent& event)
void wxZRColaFrame::OnIdle(wxIdleEvent& event)
{
// Toggle auto language flag.
m_lang_auto = !m_lang_auto;
m_panel->SynchronizePanels();
if (m_lang_auto) {
#if defined(__WXMSW__)
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), m_lang);
UpdateDecomposedLanguage();
#endif
}
event.Skip();
}
void wxZRColaFrame::OnDecomposedLanguageUpdate(wxUpdateUIEvent& event)
void wxZRColaFrame::OnTaskbarIconClick(wxTaskBarIconEvent& event)
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[event.GetId() - wxID_DECOMP_LANGUAGE_START];
event.Check(memcmp(m_lang, lang.id, sizeof(m_lang)) == 0);
Iconize(false);
Show(true);
Raise();
event.Skip();
}
void wxZRColaFrame::OnDecomposedLanguage(wxCommandEvent& event)
void wxZRColaFrame::OnIconize(wxIconizeEvent& event)
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
size_t i = event.GetId() - wxID_DECOMP_LANGUAGE_START;
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
if (m_taskBarIcon)
Show(!event.IsIconized());
if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) {
memcpy(m_lang, lang.id, sizeof(m_lang));
m_toolDecompLanguage->Select(i);
// Notify composed text something changed and should re-decompose.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
m_panel->m_composed->ProcessWindowEvent(event2);
m_lang_auto = false;
}
}
void wxZRColaFrame::OnDecompLanguageChoice(wxCommandEvent& event)
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
size_t i = event.GetSelection();
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) {
memcpy(m_lang, lang.id, sizeof(m_lang));
// Notify composed text something changed and should re-decompose.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
m_panel->m_composed->ProcessWindowEvent(event2);
m_lang_auto = false;
}
event.Skip();
}
@@ -394,6 +331,12 @@ void wxZRColaFrame::OnPanelCharacterCatalogFocus(wxCommandEvent& event)
}
void wxZRColaFrame::OnHelpReqChar(wxCommandEvent& event)
{
wxLaunchDefaultBrowser(_("http://zrcola-2.amebis.si/en/contact/"));
}
void wxZRColaFrame::OnAbout(wxCommandEvent& event)
{
wxMessageBox(wxString::Format(_("ZRCola v%s\nCopyright 2015-%s Amebis"), wxT(ZRCOLA_VERSION_STR), wxT(ZRCOLA_BUILD_YEAR_STR)), _("About ZRCola"), wxOK | wxICON_INFORMATION);
@@ -411,11 +354,10 @@ HRESULT STDMETHODCALLTYPE wxZRColaFrame::OnLanguageChange(LANGID langid, __RPC__
HRESULT STDMETHODCALLTYPE wxZRColaFrame::OnLanguageChanged()
{
if (m_lang_auto) {
if (m_settings->m_lang_auto) {
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), m_lang);
UpdateDecomposedLanguage();
ZRCola::LangConvert(LOWORD(hkl), m_settings->m_lang);
}
return S_OK;
@@ -494,20 +436,6 @@ void wxZRColaFrame::DoSend(const wxString& str)
}
void wxZRColaFrame::UpdateDecomposedLanguage()
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
// Find language on the language list.
ZRCola::language_db::language *l = new ZRCola::language_db::language;
memcpy(l->id, m_lang, sizeof(l->id));
l->name_len = 0;
ZRCola::language_db::indexLang::size_type start, end;
m_toolDecompLanguage->SetSelection(app->m_lang_db.idxLng.find(*l, start, end) ? start : -1);
delete l;
}
#ifdef __WXMSW__
WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
@@ -575,8 +503,6 @@ void wxPersistentZRColaFrame::Save() const
wxPersistentZRColaComposerPanel(wnd->m_panel).Save();
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Save();
SaveValue(wxT("langAuto" ), wnd->m_lang_auto);
SaveValue(wxT("lang" ), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang)));
wxPersistentTLW::Save();
}
@@ -587,27 +513,6 @@ bool wxPersistentZRColaFrame::Restore()
wxZRColaFrame * const wnd = static_cast<wxZRColaFrame*>(GetWindow());
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
wxString lang;
// Restore automatic language detection setting first.
RestoreValue(wxT("langAuto"), &(wnd->m_lang_auto));
if (wnd->m_lang_auto) {
#if defined(__WXMSW__)
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), wnd->m_lang);
#endif
} else if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
// The language was read from configuration.
memcpy(wnd->m_lang, (const char*)lang.c_str(), sizeof(wnd->m_lang));
} else if (!app->m_lang_db.idxLng.empty()) {
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[0];
memcpy(wnd->m_lang, lang.id, sizeof(wnd->m_lang));
} else
memcpy(wnd->m_lang, ZRCOLA_LANG_VOID, sizeof(wnd->m_lang));
wnd->UpdateDecomposedLanguage();
wxPersistentZRColaCharacterCatalogPanel(wnd->m_panelChrCat).Restore();
wxPersistentZRColaComposerPanel(wnd->m_panel).Restore();

View File

@@ -26,7 +26,10 @@ class wxZRColaFrame;
#pragma once
#include "zrcolagui.h"
#include "zrcolachrslct.h"
#include "zrcolasettings.h"
#include <zrcola/language.h>
#include <wx/taskbar.h>
#include <wx/persist/toplevel.h>
#if defined(__WXMSW__)
#include <msctf.h>
@@ -52,9 +55,7 @@ class wxZRColaFrame :
public:
enum
{
wxID_DECOMP_LANGUAGE_START = 6000,
wxID_DECOMP_LANGUAGE_END = 6099,
wxID_FOCUS_CHARACTER_CATALOG,
wxID_FOCUS_CHARACTER_CATALOG = 2000,
};
wxZRColaFrame();
@@ -64,20 +65,18 @@ public:
friend class wxZRColaComposerPanel;
protected:
void OnAutostartUpdate(wxUpdateUIEvent& event);
void OnAutostart(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnForwardEventUpdate(wxUpdateUIEvent& event);
void OnForwardEvent(wxCommandEvent& event);
void OnInsertCharacter(wxCommandEvent& event);
void OnSendUpdate(wxUpdateUIEvent& event);
void OnSendComposed(wxCommandEvent& event);
void OnSendDecomposed(wxCommandEvent& event);
void OnSendAbort(wxCommandEvent& event);
void OnDecomposedLanguageAutoUpdate(wxUpdateUIEvent& event);
void OnDecomposedLanguageAuto(wxCommandEvent& event);
void OnDecomposedLanguageUpdate(wxUpdateUIEvent& event);
void OnDecomposedLanguage(wxCommandEvent& event);
virtual void OnDecompLanguageChoice(wxCommandEvent& event);
void OnSettings(wxCommandEvent& event);
virtual void OnIdle(wxIdleEvent& event);
void OnTaskbarIconClick(wxTaskBarIconEvent& event);
virtual void OnIconize(wxIconizeEvent& event);
void OnToolbarEditUpdate(wxUpdateUIEvent& event);
void OnToolbarEdit(wxCommandEvent& event);
void OnToolbarComposeUpdate(wxUpdateUIEvent& event);
@@ -85,6 +84,7 @@ protected:
void OnPanelCharacterCatalogUpdate(wxUpdateUIEvent& event);
void OnPanelCharacterCatalog(wxCommandEvent& event);
void OnPanelCharacterCatalogFocus(wxCommandEvent& event);
void OnHelpReqChar(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
@@ -106,7 +106,6 @@ protected:
private:
void DoSend(const wxString& str);
void UpdateDecomposedLanguage();
protected:
#ifdef __WXMSW__
@@ -114,9 +113,10 @@ protected:
#endif
protected:
bool m_lang_auto; ///< Automatic language selection according to keyboard layout
ZRCola::langid_t m_lang; ///< Language for decomposing
WXHWND m_hWndSource; ///< handle of the active window, when the ZRCola hotkey was pressed
WXHWND m_hWndSource; ///< Handle of the active window, when the ZRCola hotkey was pressed
wxTaskBarIcon *m_taskBarIcon; ///< Taskbar icon
wxZRColaCharSelect *m_chrSelect; ///< Character selection dialog
wxZRColaSettings *m_settings; ///< Configuration dialog
};

View File

@@ -32,12 +32,6 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menubar = new wxMenuBar( 0 );
m_menuProgram = new wxMenu();
wxMenuItem* m_menuItemAutoStart;
m_menuItemAutoStart = new wxMenuItem( m_menuProgram, wxID_AUTOSTART, wxString( _("&Start on Logon") ) , _("Start this program automatically on logon"), wxITEM_CHECK );
m_menuProgram->Append( m_menuItemAutoStart );
m_menuProgram->AppendSeparator();
wxMenuItem* m_menuItemExit;
m_menuItemExit = new wxMenuItem( m_menuProgram, wxID_EXIT, wxString( _("E&xit") ) + wxT('\t') + wxT("Alt+F4"), _("Quit this program"), wxITEM_NORMAL );
m_menuProgram->Append( m_menuItemExit );
@@ -80,6 +74,17 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->AppendSeparator();
wxMenuItem* m_menuCharSelect;
m_menuCharSelect = new wxMenuItem( m_menuEdit, wxID_CHARACTER_SELECTOR, wxString( _("C&haracter Selector...") ) + wxT('\t') + wxT("F8"), _("Display character selector to select character to insert into text"), wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuCharSelect->SetBitmaps( wxIcon( wxT("char_select.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
m_menuCharSelect->SetBitmap( wxIcon( wxT("char_select.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#endif
m_menuEdit->Append( m_menuCharSelect );
m_menuEdit->AppendSeparator();
wxMenuItem* m_menuItemSendComposed;
m_menuItemSendComposed = new wxMenuItem( m_menuEdit, wxID_SEND_COMPOSED, wxString( _("&Send Composed") ) + wxT('\t') + wxT("F5"), _("Send composed text to source window"), wxITEM_NORMAL );
#ifdef __WXMSW__
@@ -107,15 +112,11 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
#endif
m_menuEdit->Append( m_menuItemSendAbort );
m_menuDecompLanguage = new wxMenu();
wxMenuItem* m_menuDecompLanguageItem = new wxMenuItem( m_menuEdit, wxID_ANY, _("&Language"), wxEmptyString, wxITEM_NORMAL, m_menuDecompLanguage );
wxMenuItem* m_menuDecompLanguageAuto;
m_menuDecompLanguageAuto = new wxMenuItem( m_menuDecompLanguage, wxID_DECOMP_LANG_AUTO, wxString( _("&Automatic") ) , _("Set language according to keyboard layout automatically"), wxITEM_CHECK );
m_menuDecompLanguage->Append( m_menuDecompLanguageAuto );
m_menuEdit->AppendSeparator();
m_menuDecompLanguage->AppendSeparator();
m_menuEdit->Append( m_menuDecompLanguageItem );
wxMenuItem* m_menuSettings;
m_menuSettings = new wxMenuItem( m_menuEdit, wxID_SETTINGS, wxString( _("&Settings...") ) , _("Open program configuration dialog"), wxITEM_NORMAL );
m_menuEdit->Append( m_menuSettings );
m_menubar->Append( m_menuEdit, _("&Edit") );
@@ -137,9 +138,15 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menubar->Append( m_menuView, _("&View") );
m_menuHelp = new wxMenu();
wxMenuItem* m_menuItemAbout;
m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
m_menuHelp->Append( m_menuItemAbout );
wxMenuItem* m_menuHelpReqChar;
m_menuHelpReqChar = new wxMenuItem( m_menuHelp, wxID_HELP_REQCHAR, wxString( _("&Request a new character...") ) , _("Submit a request to ZRC to add a new character"), wxITEM_NORMAL );
m_menuHelp->Append( m_menuHelpReqChar );
m_menuHelp->AppendSeparator();
wxMenuItem* m_menuHelpAbout;
m_menuHelpAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
m_menuHelp->Append( m_menuHelpAbout );
m_menubar->Append( m_menuHelp, _("&Help") );
@@ -156,16 +163,12 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_mgr.AddPane( m_toolbarEdit, wxAuiPaneInfo().Name( wxT("toolbarEdit") ).Top().Caption( _("Edit") ).PinButton( true ).Dock().Resizable().FloatingSize( wxSize( -1,-1 ) ).LeftDockable( false ).RightDockable( false ).Row( 0 ).Layer( 1 ).ToolbarPane() );
m_toolbarCompose = new wxAuiToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_LAYOUT );
m_toolCharSelect = m_toolbarCompose->AddTool( wxID_CHARACTER_SELECTOR, _("Character Selector"), wxIcon( wxT("char_select.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Character Selector"), _("Display character selector to select character to insert into text"), NULL );
m_toolSendComposed = m_toolbarCompose->AddTool( wxID_SEND_COMPOSED, _("Send Composed"), wxIcon( wxT("send_composed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Send Composed"), _("Send composed text to source window"), NULL );
m_toolSendDecomposed = m_toolbarCompose->AddTool( wxID_SEND_DECOMPOSED, _("Send Decomposed"), wxIcon( wxT("send_decomposed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Send Decomposed"), _("Send decomposed text to source window"), NULL );
m_toolbarCompose->AddSeparator();
wxArrayString m_toolDecompLanguageChoices;
m_toolDecompLanguage = new wxChoice( m_toolbarCompose, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_toolDecompLanguageChoices, 0 );
m_toolDecompLanguage->SetSelection( 0 );
m_toolbarCompose->AddControl( m_toolDecompLanguage );
m_toolbarCompose->Realize();
m_mgr.AddPane( m_toolbarCompose, wxAuiPaneInfo().Name( wxT("toolbarCompose") ).Top().Caption( _("Compose") ).PinButton( true ).Dock().Resizable().FloatingSize( wxSize( -1,-1 ) ).LeftDockable( false ).RightDockable( false ).Row( 0 ).Layer( 1 ).ToolbarPane() );
@@ -183,13 +186,15 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
this->Centre( wxBOTH );
// Connect Events
m_toolDecompLanguage->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
this->Connect( wxEVT_ICONIZE, wxIconizeEventHandler( wxZRColaFrameBase::OnIconize ) );
this->Connect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaFrameBase::OnIdle ) );
}
wxZRColaFrameBase::~wxZRColaFrameBase()
{
// Disconnect Events
m_toolDecompLanguage->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
this->Disconnect( wxEVT_ICONIZE, wxIconizeEventHandler( wxZRColaFrameBase::OnIconize ) );
this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaFrameBase::OnIdle ) );
m_mgr.UnInit();
@@ -298,6 +303,7 @@ wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindow
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
m_timerSave.SetOwner( this, wxID_TIMER_SAVE );
// Connect Events
m_decomposed->Connect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnDecomposedPaint ), NULL, this );
@@ -306,6 +312,7 @@ wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindow
m_composed->Connect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnComposedPaint ), NULL, this );
m_composed->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaComposerPanelBase::OnComposedText ), NULL, this );
m_composedHex->Connect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnComposedHexPaint ), NULL, this );
this->Connect( wxID_TIMER_SAVE, wxEVT_TIMER, wxTimerEventHandler( wxZRColaComposerPanelBase::OnSaveTimer ) );
}
wxZRColaComposerPanelBase::~wxZRColaComposerPanelBase()
@@ -317,6 +324,7 @@ wxZRColaComposerPanelBase::~wxZRColaComposerPanelBase()
m_composed->Disconnect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnComposedPaint ), NULL, this );
m_composed->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaComposerPanelBase::OnComposedText ), NULL, this );
m_composedHex->Disconnect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnComposedHexPaint ), NULL, this );
this->Disconnect( wxID_TIMER_SAVE, wxEVT_TIMER, wxTimerEventHandler( wxZRColaComposerPanelBase::OnSaveTimer ) );
}
@@ -379,3 +387,350 @@ wxZRColaCharacterCatalogPanelBase::~wxZRColaCharacterCatalogPanelBase()
m_grid->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( wxZRColaCharacterCatalogPanelBase::OnGridKeyDown ), NULL, this );
}
wxZRColaCharSelectBase::wxZRColaCharSelectBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxDialog( parent, id, title, pos, size, style, name )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizerContent;
bSizerContent = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerColumns;
bSizerColumns = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeft;
bSizerLeft = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizerBrowse;
sbSizerBrowse = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("&Browse") ), wxVERTICAL );
m_search = new wxSearchCtrl( sbSizerBrowse->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
#ifndef __WXMAC__
m_search->ShowSearchButton( true );
#endif
m_search->ShowCancelButton( true );
sbSizerBrowse->Add( m_search, 0, wxALL|wxEXPAND, 5 );
wxArrayString m_categoriesChoices;
m_categories = new wxCheckListBox( sbSizerBrowse->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,60 ), m_categoriesChoices, 0 );
sbSizerBrowse->Add( m_categories, 0, wxALL|wxEXPAND, 5 );
m_gridResults = new wxZRColaCharGrid( sbSizerBrowse->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxSTATIC_BORDER );
// Grid
m_gridResults->CreateGrid( 0, 0 );
m_gridResults->EnableEditing( false );
m_gridResults->EnableGridLines( false );
m_gridResults->EnableDragGridSize( false );
m_gridResults->SetMargins( 0, 0 );
// Columns
m_gridResults->EnableDragColMove( false );
m_gridResults->EnableDragColSize( false );
m_gridResults->SetColLabelSize( 0 );
m_gridResults->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridResults->EnableDragRowSize( false );
m_gridResults->SetRowLabelSize( 0 );
m_gridResults->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridResults->SetDefaultCellFont( wxFont( 20, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_gridResults->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
m_gridResults->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
m_gridResults->SetMinSize( wxSize( 560,35 ) );
m_gridResults->SetMaxSize( wxSize( 560,-1 ) );
sbSizerBrowse->Add( m_gridResults, 1, wxALL|wxEXPAND, 5 );
bSizerLeft->Add( sbSizerBrowse, 1, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerRecent;
sbSizerRecent = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Re&cently Used") ), wxVERTICAL );
m_gridRecent = new wxZRColaCharGrid( sbSizerRecent->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,35 ), wxSTATIC_BORDER );
// Grid
m_gridRecent->CreateGrid( 0, 0 );
m_gridRecent->EnableEditing( false );
m_gridRecent->EnableGridLines( false );
m_gridRecent->EnableDragGridSize( false );
m_gridRecent->SetMargins( 0, 0 );
// Columns
m_gridRecent->EnableDragColMove( false );
m_gridRecent->EnableDragColSize( false );
m_gridRecent->SetColLabelSize( 0 );
m_gridRecent->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridRecent->EnableDragRowSize( false );
m_gridRecent->SetRowLabelSize( 0 );
m_gridRecent->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridRecent->SetDefaultCellFont( wxFont( 20, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_gridRecent->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
m_gridRecent->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 90, false, wxEmptyString ) );
sbSizerRecent->Add( m_gridRecent, 0, wxALL|wxEXPAND, 5 );
bSizerLeft->Add( sbSizerRecent, 0, wxALL|wxEXPAND, 5 );
bSizerColumns->Add( bSizerLeft, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerRight;
bSizerRight = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizerPreview;
sbSizerPreview = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Preview") ), wxVERTICAL );
wxBoxSizer* bSizerUnicode;
bSizerUnicode = new wxBoxSizer( wxHORIZONTAL );
m_labelUnicode = new wxStaticText( sbSizerPreview->GetStaticBox(), wxID_ANY, _("U+"), wxDefaultPosition, wxDefaultSize, 0 );
m_labelUnicode->Wrap( -1 );
bSizerUnicode->Add( m_labelUnicode, 0, wxALIGN_CENTER, 5 );
m_unicode = new wxTextCtrl( sbSizerPreview->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 50,-1 ), 0 );
bSizerUnicode->Add( m_unicode, 0, wxALIGN_CENTER, 5 );
sbSizerPreview->Add( bSizerUnicode, 0, wxALIGN_CENTER|wxALL, 5 );
m_gridPreview = new wxGrid( sbSizerPreview->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSTATIC_BORDER );
// Grid
m_gridPreview->CreateGrid( 1, 1 );
m_gridPreview->EnableEditing( false );
m_gridPreview->EnableGridLines( false );
m_gridPreview->EnableDragGridSize( false );
m_gridPreview->SetMargins( 0, 0 );
// Columns
m_gridPreview->SetColSize( 0, 200 );
m_gridPreview->EnableDragColMove( false );
m_gridPreview->EnableDragColSize( false );
m_gridPreview->SetColLabelSize( 0 );
m_gridPreview->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridPreview->SetRowSize( 0, 200 );
m_gridPreview->EnableDragRowSize( false );
m_gridPreview->SetRowLabelSize( 0 );
m_gridPreview->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridPreview->SetDefaultCellFont( wxFont( 120, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_gridPreview->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
m_gridPreview->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
sbSizerPreview->Add( m_gridPreview, 0, wxALL|wxEXPAND, 5 );
m_description = new wxTextCtrl( sbSizerPreview->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE|wxTE_READONLY );
sbSizerPreview->Add( m_description, 1, wxALL|wxEXPAND, 5 );
m_category = new wxTextCtrl( sbSizerPreview->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_READONLY );
sbSizerPreview->Add( m_category, 0, wxALL|wxEXPAND, 5 );
bSizerRight->Add( sbSizerPreview, 70, wxALL|wxEXPAND, 5 );
wxStaticBoxSizer* sbSizerRelated;
sbSizerRelated = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Re&lated") ), wxVERTICAL );
m_gridRelated = new wxZRColaCharGrid( sbSizerRelated->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( -1,-1 ), wxSTATIC_BORDER );
// Grid
m_gridRelated->CreateGrid( 0, 0 );
m_gridRelated->EnableEditing( false );
m_gridRelated->EnableGridLines( false );
m_gridRelated->EnableDragGridSize( false );
m_gridRelated->SetMargins( 0, 0 );
// Columns
m_gridRelated->EnableDragColMove( false );
m_gridRelated->EnableDragColSize( false );
m_gridRelated->SetColLabelSize( 0 );
m_gridRelated->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridRelated->EnableDragRowSize( false );
m_gridRelated->SetRowLabelSize( 0 );
m_gridRelated->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridRelated->SetDefaultCellFont( wxFont( 20, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_gridRelated->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
sbSizerRelated->Add( m_gridRelated, 1, wxALL|wxEXPAND, 5 );
bSizerRight->Add( sbSizerRelated, 30, wxALL|wxEXPAND, 5 );
bSizerColumns->Add( bSizerRight, 0, wxEXPAND, 5 );
bSizerContent->Add( bSizerColumns, 1, wxEXPAND, 5 );
bSizerContent->Add( 5, 5, 0, wxALL|wxEXPAND, 5 );
m_sdbSizerButtons = new wxStdDialogButtonSizer();
m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
m_sdbSizerButtons->Realize();
bSizerContent->Add( m_sdbSizerButtons, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerContent );
this->Layout();
bSizerContent->Fit( this );
// Connect Events
this->Connect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaCharSelectBase::OnIdle ) );
m_search->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaCharSelectBase::OnSearchText ), NULL, this );
m_categories->Connect( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEventHandler( wxZRColaCharSelectBase::OnCategoriesToggle ), NULL, this );
m_gridResults->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( wxZRColaCharSelectBase::OnResultCellDClick ), NULL, this );
m_gridResults->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnResultSelectCell ), NULL, this );
m_gridResults->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( wxZRColaCharSelectBase::OnResultsKeyDown ), NULL, this );
m_gridRecent->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( wxZRColaCharSelectBase::OnRecentCellDClick ), NULL, this );
m_gridRecent->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnRecentSelectCell ), NULL, this );
m_gridRecent->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( wxZRColaCharSelectBase::OnRecentKeyDown ), NULL, this );
m_unicode->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaCharSelectBase::OnUnicodeText ), NULL, this );
m_gridRelated->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnRelatedSelectCell ), NULL, this );
m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaCharSelectBase::OnOKButtonClick ), NULL, this );
}
wxZRColaCharSelectBase::~wxZRColaCharSelectBase()
{
// Disconnect Events
this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaCharSelectBase::OnIdle ) );
m_search->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaCharSelectBase::OnSearchText ), NULL, this );
m_categories->Disconnect( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEventHandler( wxZRColaCharSelectBase::OnCategoriesToggle ), NULL, this );
m_gridResults->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( wxZRColaCharSelectBase::OnResultCellDClick ), NULL, this );
m_gridResults->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnResultSelectCell ), NULL, this );
m_gridResults->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( wxZRColaCharSelectBase::OnResultsKeyDown ), NULL, this );
m_gridRecent->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( wxZRColaCharSelectBase::OnRecentCellDClick ), NULL, this );
m_gridRecent->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnRecentSelectCell ), NULL, this );
m_gridRecent->Disconnect( wxEVT_KEY_DOWN, wxKeyEventHandler( wxZRColaCharSelectBase::OnRecentKeyDown ), NULL, this );
m_unicode->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaCharSelectBase::OnUnicodeText ), NULL, this );
m_gridRelated->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( wxZRColaCharSelectBase::OnRelatedSelectCell ), NULL, this );
m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaCharSelectBase::OnOKButtonClick ), NULL, this );
}
wxZRColaSettingsBase::wxZRColaSettingsBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxDialog( parent, id, title, pos, size, style, name )
{
this->SetSizeHints( wxDefaultSize, wxSize( -1,-1 ) );
wxBoxSizer* bSizerContent;
bSizerContent = new wxBoxSizer( wxVERTICAL );
m_listbook = new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLB_DEFAULT );
m_panelLanguage = new wxPanel( m_listbook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerLanguage;
bSizerLanguage = new wxBoxSizer( wxVERTICAL );
m_langLabel = new wxStaticText( m_panelLanguage, wxID_ANY, _("Some character native to specific language you are working with should not decompose to primitives.\nFor optimal decomposition you should set the language correctly."), wxDefaultPosition, wxDefaultSize, 0 );
m_langLabel->Wrap( -1 );
bSizerLanguage->Add( m_langLabel, 0, wxALL|wxEXPAND, 5 );
m_langAuto = new wxRadioButton( m_panelLanguage, wxID_ANY, _("Select language &automatically according to selected keyboard"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
bSizerLanguage->Add( m_langAuto, 0, wxALL|wxEXPAND, 5 );
m_langManual = new wxRadioButton( m_panelLanguage, wxID_ANY, _("&Manually select the language from the list below:"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerLanguage->Add( m_langManual, 0, wxALL|wxEXPAND, 5 );
m_languages = new wxListBox( m_panelLanguage, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
m_languages->SetMinSize( wxSize( -1,150 ) );
bSizerLanguage->Add( m_languages, 1, wxALL|wxEXPAND, 5 );
m_panelLanguage->SetSizer( bSizerLanguage );
m_panelLanguage->Layout();
bSizerLanguage->Fit( m_panelLanguage );
m_listbook->AddPage( m_panelLanguage, _("Text Language"), true );
m_panelAutoStart = new wxPanel( m_listbook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerAutoStart;
bSizerAutoStart = new wxBoxSizer( wxVERTICAL );
m_autoStartLabel = new wxStaticText( m_panelAutoStart, wxID_ANY, _("ZRCola can be launched every time you log in to your computer.\nIt will be available on the system tray and via registered shortcuts Win+F5 and Win+F6."), wxDefaultPosition, wxDefaultSize, 0 );
m_autoStartLabel->Wrap( -1 );
bSizerAutoStart->Add( m_autoStartLabel, 0, wxALL|wxEXPAND, 5 );
m_autoStart = new wxCheckBox( m_panelAutoStart, wxID_ANY, _("Start ZRCola &automatically on logon"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerAutoStart->Add( m_autoStart, 0, wxALL|wxEXPAND, 5 );
m_panelAutoStart->SetSizer( bSizerAutoStart );
m_panelAutoStart->Layout();
bSizerAutoStart->Fit( m_panelAutoStart );
m_listbook->AddPage( m_panelAutoStart, _("Startup"), false );
#ifdef __WXGTK__ // Small icon style not supported in GTK
wxListView* m_listbookListView = m_listbook->GetListView();
long m_listbookFlags = m_listbookListView->GetWindowStyleFlag();
if( m_listbookFlags & wxLC_SMALL_ICON )
{
m_listbookFlags = ( m_listbookFlags & ~wxLC_SMALL_ICON ) | wxLC_ICON;
}
m_listbookListView->SetWindowStyleFlag( m_listbookFlags );
#endif
bSizerContent->Add( m_listbook, 1, wxEXPAND | wxALL, 5 );
bSizerContent->Add( 0, 0, 0, wxALL|wxEXPAND, 5 );
m_sdbSizerButtons = new wxStdDialogButtonSizer();
m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
m_sdbSizerButtonsApply = new wxButton( this, wxID_APPLY );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsApply );
m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
m_sdbSizerButtons->Realize();
bSizerContent->Add( m_sdbSizerButtons, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerContent );
this->Layout();
bSizerContent->Fit( this );
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxZRColaSettingsBase::OnInitDialog ) );
m_langAuto->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxZRColaSettingsBase::OnLangAuto ), NULL, this );
m_langManual->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxZRColaSettingsBase::OnLangManual ), NULL, this );
m_sdbSizerButtonsApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaSettingsBase::OnApplyButtonClick ), NULL, this );
m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaSettingsBase::OnOKButtonClick ), NULL, this );
}
wxZRColaSettingsBase::~wxZRColaSettingsBase()
{
// Disconnect Events
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( wxZRColaSettingsBase::OnInitDialog ) );
m_langAuto->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxZRColaSettingsBase::OnLangAuto ), NULL, this );
m_langManual->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( wxZRColaSettingsBase::OnLangManual ), NULL, this );
m_sdbSizerButtonsApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaSettingsBase::OnApplyButtonClick ), NULL, this );
m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( wxZRColaSettingsBase::OnOKButtonClick ), NULL, this );
}

View File

@@ -25,7 +25,6 @@ class wxZRColaCharGrid;
#include <wx/settings.h>
#include <wx/aui/aui.h>
#include <wx/aui/auibar.h>
#include <wx/choice.h>
class wxZRColaCharacterCatalogPanel;
class wxZRColaComposerPanel;
#include <wx/statusbr.h>
@@ -35,7 +34,19 @@ class wxZRColaComposerPanel;
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
#include <wx/timer.h>
#include <wx/choice.h>
#include <wx/grid.h>
#include <wx/srchctrl.h>
#include <wx/checklst.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/radiobut.h>
#include <wx/listbox.h>
#include <wx/checkbox.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
///////////////////////////////////////////////////////////////////////////
@@ -49,20 +60,20 @@ class wxZRColaFrameBase : public wxFrame
protected:
enum
{
wxID_AUTOSTART = 1000,
wxID_CHARACTER_SELECTOR = 1000,
wxID_SEND_COMPOSED,
wxID_SEND_DECOMPOSED,
wxID_SEND_ABORT,
wxID_DECOMP_LANG_AUTO,
wxID_SETTINGS,
wxID_TOOLBAR_EDIT,
wxID_TOOLBAR_COMPOSE,
wxID_PANEL_CHRGRPS
wxID_PANEL_CHRGRPS,
wxID_HELP_REQCHAR
};
wxMenuBar* m_menubar;
wxMenu* m_menuProgram;
wxMenu* m_menuEdit;
wxMenu* m_menuDecompLanguage;
wxMenu* m_menuView;
wxMenu* m_menuHelp;
wxAuiToolBar* m_toolbarEdit;
@@ -70,14 +81,15 @@ class wxZRColaFrameBase : public wxFrame
wxAuiToolBarItem* m_toolEditCopy;
wxAuiToolBarItem* m_toolEditPaste;
wxAuiToolBar* m_toolbarCompose;
wxAuiToolBarItem* m_toolCharSelect;
wxAuiToolBarItem* m_toolSendComposed;
wxAuiToolBarItem* m_toolSendDecomposed;
wxChoice* m_toolDecompLanguage;
wxZRColaCharacterCatalogPanel* m_panelChrCat;
wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnDecompLanguageChoice( wxCommandEvent& event ) { event.Skip(); }
virtual void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
public:
@@ -98,6 +110,11 @@ class wxZRColaComposerPanelBase : public wxPanel
private:
protected:
enum
{
wxID_TIMER_SAVE = 1000
};
wxSplitterWindow* m_splitterDecomposed;
wxPanel* m_panelDecomposedEdit;
wxPanel* m_panelDecomposedHex;
@@ -106,6 +123,7 @@ class wxZRColaComposerPanelBase : public wxPanel
wxPanel* m_panelComposedEdit;
wxPanel* m_panelComposedHex;
wxTextCtrl* m_composedHex;
wxTimer m_timerSave;
// Virtual event handlers, overide them in your derived class
virtual void OnDecomposedPaint( wxPaintEvent& event ) { event.Skip(); }
@@ -114,6 +132,7 @@ class wxZRColaComposerPanelBase : public wxPanel
virtual void OnComposedPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnComposedText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnComposedHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnSaveTimer( wxTimerEvent& event ) { event.Skip(); }
public:
@@ -161,4 +180,85 @@ class wxZRColaCharacterCatalogPanelBase : public wxPanel
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaCharSelectBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaCharSelectBase : public wxDialog
{
private:
protected:
wxSearchCtrl* m_search;
wxCheckListBox* m_categories;
wxZRColaCharGrid* m_gridResults;
wxZRColaCharGrid* m_gridRecent;
wxStaticText* m_labelUnicode;
wxTextCtrl* m_unicode;
wxGrid* m_gridPreview;
wxTextCtrl* m_description;
wxTextCtrl* m_category;
wxZRColaCharGrid* m_gridRelated;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnSearchText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCategoriesToggle( wxCommandEvent& event ) { event.Skip(); }
virtual void OnResultCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnResultsKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnRecentCellDClick( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnRecentKeyDown( wxKeyEvent& event ) { event.Skip(); }
virtual void OnUnicodeText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRelatedSelectCell( wxGridEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaCharSelectBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Character Selector"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaCharSelect") );
~wxZRColaCharSelectBase();
};
///////////////////////////////////////////////////////////////////////////////
/// Class wxZRColaSettingsBase
///////////////////////////////////////////////////////////////////////////////
class wxZRColaSettingsBase : public wxDialog
{
private:
protected:
wxListbook* m_listbook;
wxPanel* m_panelLanguage;
wxStaticText* m_langLabel;
wxRadioButton* m_langAuto;
wxRadioButton* m_langManual;
wxListBox* m_languages;
wxPanel* m_panelAutoStart;
wxStaticText* m_autoStartLabel;
wxCheckBox* m_autoStart;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsApply;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnLangAuto( wxCommandEvent& event ) { event.Skip(); }
virtual void OnLangManual( wxCommandEvent& event ) { event.Skip(); }
virtual void OnApplyButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
wxZRColaSettingsBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Settings"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE, const wxString& name = wxT("ZRColaSettings") );
~wxZRColaSettingsBase();
};
#endif //__ZRCOLAGUI_H__

View File

@@ -62,9 +62,14 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(wxEmptyString);
}
} else if (e.GetUnicodeKey() || !e.HasAnyModifiers()) {
} else if ((e.GetUnicodeKey() || !e.HasAnyModifiers())
#if defined(__WXMSW__)
&& ::GetKeyState(VK_RMENU) >= 0
#endif
)
{
ZRColaApp *app = (ZRColaApp*)wxTheApp;
ZRCola::keyseq_db::indexKey::size_type start, end;
ZRCola::keyseq_db::indexKey::size_type start;
bool found;
wxFrame *pFrame = wxDynamicCast(app->m_mainWnd, wxFrame);
@@ -91,7 +96,7 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
ks->chr = 0;
ks->seq_len = n;
memcpy(ks->seq, m_seq.data(), sizeof(ZRCola::keyseq_db::keyseq::key_t)*n);
found = app->m_ks_db.idxKey.find(*ks, start, end);
found = app->m_ks_db.idxKey.find(*ks, start);
delete ks;
}
@@ -117,7 +122,7 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
{
// The sequence is a partial match. Continue watching.
if (pFrame && pFrame->GetStatusBar())
pFrame->SetStatusText(ZRColaApp::GetKeySequenceAsText(m_seq.data(), m_seq.size()));
pFrame->SetStatusText(ZRCola::keyseq_db::GetSequenceAsText(m_seq.data(), m_seq.size()));
event.StopPropagation();
return true;
@@ -131,7 +136,7 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
}
} else if (event.GetEventType() == wxEVT_KEY_UP) {
wxKeyEvent &e = (wxKeyEvent&)event;
if (e.GetKeyCode() == WXK_INSERT && m_is_insert) {
if (m_is_insert && e.GetKeyCode() == WXK_INSERT) {
// Insert key has been depressed.
wxFrame *pFrame = wxDynamicCast(((ZRColaApp*)wxTheApp)->m_mainWnd, wxFrame);
if (pFrame && pFrame->GetStatusBar())

190
ZRCola/zrcolasettings.cpp Normal file
View File

@@ -0,0 +1,190 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
//////////////////////////////////////////////////////////////////////////
// wxZRColaSettings
//////////////////////////////////////////////////////////////////////////
wxZRColaSettings::wxZRColaSettings(wxWindow* parent) :
m_lang_auto(true),
m_lang(ZRCola::langid_t_blank),
wxZRColaSettingsBase(parent)
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
m_languages->Clear();
for (size_t i = 0, n = app->m_lang_db.idxLng.size(); i < n; i++) {
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i];
wxString
label(lang.name, lang.name_len),
label_tran(wxGetTranslation(label, wxT("ZRCola-zrcdb")));
m_languages->Insert(label_tran, i);
}
}
void wxZRColaSettings::OnInitDialog(wxInitDialogEvent& event)
{
event.Skip();
// Set state of auto-start according to Startup folder shortcut presence.
#if defined(__WXMSW__)
wxString linkName(wxExpandEnvVars("%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\ZRCola.lnk"));
m_autoStart->SetValue(wxFileExists(linkName));
#else
m_autoStart->SetValue(false);
m_panelAutoStart->Enable(false);
#endif
m_languages->Enable(!m_lang_auto);
(m_lang_auto ? m_langAuto : m_langManual)->SetValue(true);
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
char l[sizeof(ZRCola::language_db::language)] = {};
((ZRCola::language_db::language*)l)->id = m_lang;
ZRCola::language_db::indexLang::size_type start;
m_languages->Select(app->m_lang_db.idxLng.find(*(ZRCola::language_db::language*)l, start) ? start : -1);
}
void wxZRColaSettings::OnLangAuto(wxCommandEvent& event)
{
m_languages->Enable(!event.IsChecked());
}
void wxZRColaSettings::OnLangManual(wxCommandEvent& event)
{
m_languages->Enable(event.IsChecked());
}
void wxZRColaSettings::OnApplyButtonClick(wxCommandEvent& event)
{
event.Skip();
#if defined(__WXMSW__)
wxString linkName(wxExpandEnvVars("%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\ZRCola.lnk"));
if (m_autoStart->IsChecked()) {
// Create the shortcut.
IShellLink *sl;
HRESULT hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&sl);
if (SUCCEEDED(hr)) {
// Setup ZRCola shortcut.
sl->SetPath(wxTheApp->argv[0]);
sl->SetDescription(_("Start ZRCola automatically on logon"));
sl->SetShowCmd(SW_SHOWMINNOACTIVE);
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
IPersistFile *pf;
hr = sl->QueryInterface(IID_IPersistFile, (LPVOID*)&pf);
if (SUCCEEDED(hr)) {
// Save the link by calling IPersistFile::Save.
hr = pf->Save(linkName, TRUE);
pf->Release();
}
sl->Release();
}
} else if (wxFileExists(linkName)) {
// The shortcut already exists. Remove it.
wxRemoveFile(linkName);
}
#endif
if (m_langAuto->GetValue()) {
m_lang_auto = true;
#if defined(__WXMSW__)
// Set update keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), m_lang);
#endif
} else {
m_lang_auto = false;
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[m_languages->GetSelection()];
if (m_lang != lang.id) {
m_lang = lang.id;
// Notify composed text something changed and should re-decompose.
wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED);
app->m_mainWnd->m_panel->m_composed->ProcessWindowEvent(event2);
}
}
}
void wxZRColaSettings::OnOKButtonClick(wxCommandEvent& event)
{
wxZRColaSettings::OnApplyButtonClick(event);
}
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaSettings
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaSettings::wxPersistentZRColaSettings(wxZRColaSettings *wnd) : wxPersistentDialog(wnd)
{
}
void wxPersistentZRColaSettings::Save() const
{
wxPersistentDialog::Save();
const wxZRColaSettings * const wnd = static_cast<const wxZRColaSettings*>(GetWindow());
SaveValue(wxT("langAuto"), wnd->m_lang_auto);
SaveValue(wxT("lang" ), wxString::FromAscii(wnd->m_lang.data, _countof(wnd->m_lang.data)));
}
bool wxPersistentZRColaSettings::Restore()
{
wxZRColaSettings * const wnd = static_cast<wxZRColaSettings*>(GetWindow());
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
wxString lang;
// Restore automatic language detection setting first.
RestoreValue(wxT("langAuto"), &(wnd->m_lang_auto));
if (wnd->m_lang_auto) {
#if defined(__WXMSW__)
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), wnd->m_lang);
#endif
} else if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
// The language was read from configuration.
wnd->m_lang = lang.c_str();
} else if (!app->m_lang_db.idxLng.empty()) {
const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[0];
wnd->m_lang = lang.id;
} else
wnd->m_lang = ZRCola::langid_t_blank;
return wxPersistentDialog::Restore();
}

72
ZRCola/zrcolasettings.h Normal file
View File

@@ -0,0 +1,72 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
///
/// Forward declarations
///
class wxZRColaSettings;
class wxPersistentZRColaSettings;
#pragma once
#include "zrcolagui.h"
#include <wxex/persist/dialog.h>
///
/// Configuration dialog
///
class wxZRColaSettings : public wxZRColaSettingsBase
{
public:
wxZRColaSettings(wxWindow* parent);
friend class wxPersistentZRColaSettings; // Allow saving/restoring window state.
protected:
virtual void OnInitDialog(wxInitDialogEvent& event);
virtual void OnLangAuto(wxCommandEvent& event);
virtual void OnLangManual(wxCommandEvent& event);
virtual void OnApplyButtonClick(wxCommandEvent& event);
virtual void OnOKButtonClick(wxCommandEvent& event);
public:
bool m_lang_auto; ///< Is language for decomposing resolved using currently selected keyboard
ZRCola::langid_t m_lang; ///< Language for decomposing
};
///
/// Supports saving/restoring wxZRColaSettings state
///
class wxPersistentZRColaSettings : public wxPersistentDialog
{
public:
wxPersistentZRColaSettings(wxZRColaSettings *wnd);
virtual void Save() const;
virtual bool Restore();
};
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaSettings *wnd)
{
return new wxPersistentZRColaSettings(wnd);
}

View File

@@ -20,6 +20,94 @@
#include "stdafx.h"
bool ZRCola::DBSource::character_desc_idx::add_keywords(const wchar_t *str, wchar_t chr, size_t sub)
{
wxASSERT_MSG(str, wxT("string is NULL"));
while (*str) {
// Skip white space.
for (;;) {
if (*str == 0)
return true;
else if (!iswspace(*str))
break;
else
str++;
}
// Get term.
std::wstring term;
if (*str == L'"') {
const wchar_t *str_end = ++str;
for (;;) {
if (*str_end == 0) {
term.assign(str, str_end);
break;
} else if (*str_end == L'"') {
term.assign(str, str_end);
str_end++;
break;
} else
str_end++;
}
str = str_end;
} else {
const wchar_t *str_end = str + 1;
for (; *str_end && !iswspace(*str_end); str_end++);
term.assign(str, str_end);
str = str_end;
}
if (!term.empty()) {
std::transform(term.begin(), term.end(), term.begin(), std::towlower);
if (sub) {
std::wstring::size_type j_end = term.size();
if (j_end >= sub) {
// Insert all keyword substrings "sub" or more characters long.
for (std::wstring::size_type i = 0, i_end = j_end - sub; i <= i_end; ++i) {
for (std::wstring::size_type j = i + sub; j <= j_end; ++j)
add_keyword(term.substr(i, j - i), chr);
}
}
} else {
// Insert exact keyword only.
add_keyword(term, chr);
}
}
}
return true;
}
void ZRCola::DBSource::character_desc_idx::save(ZRCola::textindex<wchar_t, wchar_t, unsigned __int32> &idx) const
{
idx .clear();
idx.keys .clear();
idx.values.clear();
// Pre-allocate memory.
std::vector<wchar_t>::size_type size_keys = 0;
std::vector<wchar_t>::size_type size_values = 0;
for (const_iterator i = cbegin(), i_end = cend(); i != i_end; ++i) {
size_keys += i->first.size();
size_values += i->second.size();
}
idx .reserve(size() );
idx.keys .reserve(size_keys );
idx.values.reserve(size_values);
// Convert the index.
for (const_iterator i = cbegin(), i_end = cend(); i != i_end; ++i) {
ZRCola::mappair_t<unsigned __int32> p = { idx.keys.size(), idx.values.size() };
idx.push_back(p);
idx.keys.insert(idx.keys.end(), i->first.cbegin(), i->first.cend());
idx.values.insert(idx.values.end(), i->second.cbegin(), i->second.cend());
}
}
ZRCola::DBSource::DBSource()
{
}
@@ -156,10 +244,13 @@ bool ZRCola::DBSource::GetValue(const ATL::CComPtr<ADOField>& f, std::wstring& v
ATL::CComVariant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
val.reserve(::SysStringLen(V_BSTR(&v)));
val = V_BSTR(&v);
val.reserve(::SysStringLen(V_BSTR(&v)));
val = V_BSTR(&v);
} else
val.empty();
return true;
}
@@ -171,26 +262,29 @@ bool ZRCola::DBSource::GetUnicodeCharacter(const ATL::CComPtr<ADOField>& f, wcha
ATL::CComVariant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
// Parse the field. Must be exactly one Unicode code.
UINT i = 0, n = ::SysStringLen(V_BSTR(&v));
chr = 0;
for (; i < n && V_BSTR(&v)[i]; i++) {
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') chr = chr*0x10 + (V_BSTR(&v)[i] - L'0');
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') chr = chr*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') chr = chr*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
else break;
}
if (i <= 0 && 4 < i) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0030: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
} else if (i != n) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0031: Syntax error in \"%.*ls\" field (\"%.*ls\"). Extra trailing characters.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
// Parse the field. Must be exactly one Unicode code.
UINT i = 0, n = ::SysStringLen(V_BSTR(&v));
chr = 0;
for (; i < n && V_BSTR(&v)[i]; i++) {
if (L'0' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'9') chr = chr*0x10 + (V_BSTR(&v)[i] - L'0');
else if (L'A' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'F') chr = chr*0x10 + (V_BSTR(&v)[i] - L'A' + 10);
else if (L'a' <= V_BSTR(&v)[i] && V_BSTR(&v)[i] <= L'f') chr = chr*0x10 + (V_BSTR(&v)[i] - L'a' + 10);
else break;
}
if (i <= 0 && 4 < i) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0030: Syntax error in \"%.*ls\" field (\"%.*ls\"). Unicode code must be one to four hexadecimal characters long.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
} else if (i != n) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0031: Syntax error in \"%.*ls\" field (\"%.*ls\"). Extra trailing characters.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
} else
chr = 0;
return true;
}
@@ -306,9 +400,9 @@ bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADOField>& f, ZRCola::lang
_ftprintf(stderr, wxT("%s: error ZCC0081: Syntax error in \"%.*ls\" field (\"%.*ls\"). Language ID must contain ASCII characters only.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
lang[i] = (char)c;
lang.data[i] = (char)c;
} else
lang[i] = 0;
lang.data[i] = 0;
} else
break;
}
@@ -317,6 +411,43 @@ bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADOField>& f, ZRCola::lang
}
bool ZRCola::DBSource::GetChrCat(const ATL::CComPtr<ADOField>& f, chrcatid_t& cc) const
{
wxASSERT_MSG(f, wxT("field is empty"));
ATL::CComVariant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
if (V_VT(&v) != VT_NULL) {
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
// Parse the field.
size_t n = wcsnlen(V_BSTR(&v), ::SysStringLen(V_BSTR(&v)));
if (n < 1 || 2 < n) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0110: Syntax error in \"%.*ls\" field (\"%.*ls\"). Character category ID must be one (1) or two (2) characters long.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
for (size_t i = 0;; i++) {
if (i < sizeof(cc)) {
if (i < n) {
wchar_t c = V_BSTR(&v)[i];
if ((unsigned short)c > 0x7f) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0111: Syntax error in \"%.*ls\" field (\"%.*ls\"). Character category ID must contain ASCII characters only.\n"), m_filename.c_str(), fieldname.Length(), (BSTR)fieldname, n, V_BSTR(&v));
return false;
}
cc.data[i] = (char)c;
} else
cc.data[i] = 0;
} else
break;
}
} else
memset(cc.data, 0, sizeof(cc));
return true;
}
bool ZRCola::DBSource::SelectTranslations(ATL::CComPtr<ADORecordset> &rs) const
{
@@ -610,3 +741,128 @@ bool ZRCola::DBSource::GetCharacterGroup(const ATL::CComPtr<ADORecordset>& rs, c
return true;
}
bool ZRCola::DBSource::SelectCharacters(ATL::CComPtr<ADORecordset>& rs) const
{
// Create a new recordset.
if (rs) rs.Release();
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT DISTINCT [znak], [opis_en], [klj_bes_en], [kat], [znak_v], [znak_m] "
L"FROM [VRS_CharList] "
L"ORDER BY [znak]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0120: Error loading characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::GetCharacter(const ATL::CComPtr<ADORecordset>& rs, character& chr) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
ATL::CComPtr<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
wchar_t c;
chr.rel.clear();
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, chr.chr), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"znak_v"), &f)));
wxCHECK(GetUnicodeCharacter(f, c), false);
if (c && c != chr.chr)
chr.rel += c;
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"znak_m"), &f)));
wxCHECK(GetUnicodeCharacter(f, c), false);
if (c && c != chr.chr)
chr.rel += c;
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"opis_en"), &f)));
wxCHECK(GetValue(f, chr.desc), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"klj_bes_en"), &f)));
wxCHECK(GetValue(f, chr.keywords), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"kat"), &f)));
wxCHECK(GetChrCat(f, chr.cat), false);
}
return true;
}
bool ZRCola::DBSource::SelectCharacterCategories(ATL::CComPtr<ADORecordset>& rs) const
{
// Create a new recordset.
if (rs) rs.Release();
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT DISTINCT [kat], [opis_en], [Rang] "
L"FROM [VRS_CharCategory] "
L"ORDER BY [Rang], [opis_en]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0130: Error loading character categories from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::GetCharacterCategory(const ATL::CComPtr<ADORecordset>& rs, chrcat& cc) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
ATL::CComPtr<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
std::wstring id;
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"kat"), &f)));
wxCHECK(GetChrCat(f, cc.id), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"Rang"), &f)));
wxCHECK(GetValue(f, cc.rank), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"opis_en"), &f)));
wxCHECK(GetValue(f, cc.name), false);
}
return true;
}

View File

@@ -19,10 +19,12 @@
#pragma once
#include <zrcola/character.h>
#include <zrcola/common.h>
#include <atlbase.h>
#include <adoint.h>
#include <map>
#include <string>
#include <vector>
@@ -98,6 +100,85 @@ namespace ZRCola {
};
///
/// Character
///
class character {
public:
wchar_t chr; ///< Character
ZRCola::chrcatid_t cat; ///> Category ID
std::wstring desc; ///< Character description
std::wstring keywords; ///< Additional keywords
std::wstring rel; ///< Related characters
};
///
/// Character description index key comparator
///
struct character_desc_idx_less : public std::binary_function<std::wstring, std::wstring, bool>
{
inline bool operator()(const std::wstring& _Left, const std::wstring& _Right) const
{
size_t
_Left_len = _Left .size(),
_Right_len = _Right.size();
int r = _wcsncoll(_Left.c_str(), _Right.c_str(), std::min<size_t>(_Left_len, _Right_len));
if (r != 0 ) return r < 0;
else if (_Left_len < _Right_len) return true;
return false;
}
};
///
/// Character description index
///
class character_desc_idx : public std::map<std::wstring, std::vector<wchar_t>, character_desc_idx_less>
{
public:
bool add_keywords(const wchar_t *str, wchar_t chr, size_t sub = 0);
void save(ZRCola::textindex<wchar_t, wchar_t, unsigned __int32> &idx) const;
protected:
inline void add_keyword(const std::wstring &term, wchar_t chr)
{
iterator idx = find(term);
if (idx == end()) {
// New keyword.
insert(std::make_pair(term, std::vector<wchar_t>(1, chr)));
} else {
// Append to existing keyword.
std::vector<wchar_t> &val = idx->second;
for (std::vector<wchar_t>::iterator i = val.begin(), i_end = val.end(); ; ++i) {
if (i == i_end) {
// End-of-values reached. Append character.
val.push_back(chr);
break;
} else if (*i == chr) {
// Character already among the values.
break;
}
}
}
}
};
///
/// Character category
///
class chrcat {
public:
ZRCola::chrcatid_t id; ///> Category ID
int rank; ///< Character category rank
std::wstring name; ///< Character category name
};
public:
DBSource();
virtual ~DBSource();
@@ -151,6 +232,19 @@ namespace ZRCola {
}
///
/// Splits string to individual keywords
///
/// \param[in ] str String
/// \param[out] keywords Array of keywords
///
/// \returns
/// - true when successful
/// - false otherwise
///
static bool GetKeywords(const wchar_t *str, std::vector< std::wstring > &keywords);
///
/// Gets boolean from ZRCola.zrc database
///
@@ -242,6 +336,19 @@ namespace ZRCola {
bool GetLanguage(const ATL::CComPtr<ADOField>& f, langid_t& lang) const;
///
/// Gets character category ID from ZRCola.zrc database
///
/// \param[in] f Data field
/// \param[out] cc Character category
///
/// \returns
/// - true when successful
/// - false otherwise
///
bool GetChrCat(const ATL::CComPtr<ADOField>& f, chrcatid_t& cc) const;
///
/// Returns character translations
///
@@ -366,6 +473,54 @@ namespace ZRCola {
///
bool GetCharacterGroup(const ATL::CComPtr<ADORecordset>& rs, chrgrp& cg) const;
///
/// Returns characters
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectCharacters(ATL::CComPtr<ADORecordset>& rs) const;
///
/// Returns character data
///
/// \param[in] rs Recordset with results
/// \param[out] chr Character
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetCharacter(const ATL::CComPtr<ADORecordset>& rs, character& chr) const;
///
/// Returns character categories
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectCharacterCategories(ATL::CComPtr<ADORecordset>& rs) const;
///
/// Returns character category data
///
/// \param[in] rs Recordset with results
/// \param[out] cc Character category
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetCharacterCategory(const ATL::CComPtr<ADORecordset>& rs, chrcat& cc) const;
protected:
std::basic_string<TCHAR> m_filename; ///< Database filename
ATL::CComPtr<ADOConnection> m_db; ///< Database

View File

@@ -20,279 +20,6 @@
#include "stdafx.h"
///
/// Writes translation database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Translation database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::translation_db &db)
{
assert(db.idxComp.size() == db.idxDecomp.size());
unsigned __int32 count;
// Write index count.
ZRCola::translation_db::indexComp::size_type trans_count = db.idxComp.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (trans_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)trans_count;
stream.write((const char*)&count, sizeof(count));
// Write composition index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxComp.data(), sizeof(unsigned __int32)*count);
// Write decomposition index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxDecomp.data(), sizeof(unsigned __int32)*count);
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Writes key sequence database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Key sequence database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::keyseq_db &db)
{
assert(db.idxChr.size() == db.idxKey.size());
unsigned __int32 count;
// Write index count.
ZRCola::keyseq_db::indexChr::size_type ks_count = db.idxChr.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (ks_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)ks_count;
stream.write((const char*)&count, sizeof(count));
// Write character index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
// Write key index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxKey.data(), sizeof(unsigned __int32)*count);
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Writes language database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Language database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::language_db &db)
{
unsigned __int32 count;
// Write index count.
ZRCola::language_db::indexLang::size_type lang_count = db.idxLng.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (lang_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)lang_count;
stream.write((const char*)&count, sizeof(count));
// Write language index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxLng.data(), sizeof(unsigned __int32)*count);
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Writes language character database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Language character database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::langchar_db &db)
{
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
assert(db.idxChr.size() == db.idxLng.size());
#endif
unsigned __int32 count;
// Write index count.
ZRCola::langchar_db::indexChar::size_type lc_count = db.idxChr.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (lc_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)lc_count;
stream.write((const char*)&count, sizeof(count));
// Write character index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
// Write language index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxLng.data(), sizeof(unsigned __int32)*count);
#endif
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Writes character group database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Character group database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(std::ostream& stream, const ZRCola::chrgrp_db &db)
{
unsigned __int32 count;
// Write index count.
ZRCola::keyseq_db::indexChr::size_type ks_count = db.idxRnk.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (ks_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)ks_count;
stream.write((const char*)&count, sizeof(count));
// Write rank index.
if (stream.fail()) return stream;
stream.write((const char*)db.idxRnk.data(), sizeof(unsigned __int32)*count);
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Main function
///
@@ -478,7 +205,7 @@ int _tmain(int argc, _TCHAR *argv[])
&ks2 = db.idxKey[i ];
if (ZRCola::keyseq_db::keyseq::CompareSequence(ks1.seq, ks1.seq_len, ks2.seq, ks2.seq_len) == 0) {
std::wstring seq_str;
wxString seq_str;
ZRCola::keyseq_db::GetSequenceAsText(ks1.seq, ks1.seq_len, seq_str);
_ftprintf(stderr, wxT("%s: warning ZCC0007: Duplicate key sequence (%ls => %04X or %04X). The keyboard behaviour will be unpredictable.\n"), (LPCTSTR)filenameIn.c_str(), seq_str.c_str(), ks1.chr, ks2.chr);
}
@@ -516,7 +243,7 @@ int _tmain(int argc, _TCHAR *argv[])
// Add language to index and data.
unsigned __int32 idx = db.data.size();
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lang.id)[i]);
db.data.push_back(((const unsigned __int16*)lang.id.data)[i]);
std::wstring::size_type n = lang.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("language name too long"));
db.data.push_back((unsigned __int16)n);
@@ -570,7 +297,7 @@ int _tmain(int argc, _TCHAR *argv[])
unsigned __int32 idx = db.data.size();
db.data.push_back(lc.chr);
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::langid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)lc.lang)[i]);
db.data.push_back(((const unsigned __int16*)lc.lang.data)[i]);
db.idxChr.push_back(idx);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.push_back(idx);
@@ -656,6 +383,126 @@ int _tmain(int argc, _TCHAR *argv[])
}
}
{
// Get characters.
ATL::CComPtr<ADORecordset> rs;
if (src.SelectCharacters(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
ZRCola::DBSource::character chr;
ZRCola::character_db db;
ZRCola::DBSource::character_desc_idx idxChrDsc, idxChrDscSub;
// Preallocate memory.
db.idxChr.reserve(count);
db.data .reserve(count*4);
// Parse characters and build index and data.
while (!ZRCola::DBSource::IsEOF(rs)) {
// Read character from the database.
if (src.GetCharacter(rs, chr)) {
// Add character to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back((unsigned __int16)chr.chr);
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::chrcatid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)chr.cat.data)[i]);
std::wstring::size_type n_desc = chr.desc.length();
wxASSERT_MSG(n_desc <= 0xffff, wxT("character description too long"));
db.data.push_back((unsigned __int16)n_desc);
std::wstring::size_type n_rel = chr.rel.length();
wxASSERT_MSG(n_rel <= 0xffff, wxT("too many related characters"));
db.data.push_back((unsigned __int16)n_rel);
for (std::wstring::size_type i = 0; i < n_desc; i++)
db.data.push_back(chr.desc[i]);
for (std::wstring::size_type i = 0; i < n_rel; i++)
db.data.push_back(chr.rel[i]);
db.idxChr.push_back(idx);
// Add description (and keywords) to index.
idxChrDsc .add_keywords(chr.desc .c_str(), chr.chr, 0);
idxChrDsc .add_keywords(chr.keywords.c_str(), chr.chr, 0);
idxChrDscSub.add_keywords(chr.desc .c_str(), chr.chr, 3);
idxChrDscSub.add_keywords(chr.keywords.c_str(), chr.chr, 3);
} else
has_errors = true;
wxVERIFY(SUCCEEDED(rs->MoveNext()));
}
// Sort indices.
db.idxChr.sort();
// Save text indices.
idxChrDsc .save(db.idxDsc );
idxChrDscSub.save(db.idxDscSub);
// Write characters to file.
dst << ZRCola::character_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0017: Error getting character count from database or too many characters.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0016: Error getting characters from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
{
// Get character categories.
ATL::CComPtr<ADORecordset> rs;
if (src.SelectCharacterCategories(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
ZRCola::DBSource::chrcat cc;
ZRCola::chrcat_db db;
// Preallocate memory.
db.idxChrCat.reserve(count);
db.idxRnk .reserve(count);
db.data .reserve(count*4);
// Parse character categories and build index and data.
while (!ZRCola::DBSource::IsEOF(rs)) {
// Read character category from the database.
if (src.GetCharacterCategory(rs, cc)) {
// Add character category to index and data.
unsigned __int32 idx = db.data.size();
for (std::wstring::size_type i = 0; i < sizeof(ZRCola::chrcatid_t)/sizeof(unsigned __int16); i++)
db.data.push_back(((const unsigned __int16*)cc.id.data)[i]);
wxASSERT_MSG((int)0xffff8000 <= cc.rank && cc.rank <= (int)0x00007fff, wxT("character category rank out of bounds"));
db.data.push_back((unsigned __int16)cc.rank);
std::wstring::size_type n_name = cc.name.length();
wxASSERT_MSG(n_name <= 0xffff, wxT("character category name too long"));
db.data.push_back((unsigned __int16)n_name);
for (std::wstring::size_type i = 0; i < n_name; i++)
db.data.push_back(cc.name[i]);
db.idxChrCat.push_back(idx);
db.idxRnk .push_back(idx);
if (build_pot)
pot.insert(cc.name);
} else
has_errors = true;
wxVERIFY(SUCCEEDED(rs->MoveNext()));
}
// Sort indices.
db.idxChrCat.sort();
db.idxRnk .sort();
// Write character categories to file.
dst << ZRCola::chrcat_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0019: Error getting character category count from database or too many character categories.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0018: Error getting character categories from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
stdex::idrec::close<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dst, dst_start);
if (dst.fail()) {

View File

@@ -48,6 +48,8 @@
#include <stdlib.h>
#include <algorithm>
#include <codecvt>
#include <cwctype>
#include <fstream>
#include <set>

View File

@@ -34,6 +34,9 @@
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
<Target Name="Sign" Condition="'$(ManifestCertificateThumbprint)' != '' and ('$(ConfigurationType)' == 'Application' or '$(ConfigurationType)' == 'DynamicLibrary')" AfterTargets="_Manifest" BeforeTargets="RegisterOutput" Inputs="$(OutDir)$(TargetName)$(TargetExt)" Outputs="$(IntDir)$(TargetName).sign">

View File

@@ -23,7 +23,7 @@
// Product version as a single DWORD
// Note: Used for version comparison within C/C++ code.
//
#define ZRCOLA_VERSION 0x01ff0700
#define ZRCOLA_VERSION 0x01ff0800
//
// Product version by components
@@ -33,26 +33,26 @@
//
#define ZRCOLA_VERSION_MAJ 1
#define ZRCOLA_VERSION_MIN 255
#define ZRCOLA_VERSION_REV 7
#define ZRCOLA_VERSION_REV 8
#define ZRCOLA_VERSION_BUILD 0
//
// Human readable product version and build year for UI
//
#define ZRCOLA_VERSION_STR "2.0-alpha7"
#define ZRCOLA_VERSION_STR "2.0-beta"
#define ZRCOLA_BUILD_YEAR_STR "2016"
//
// Numerical version presentation for ProductVersion propery in
// MSI packages (syntax: N.N[.N[.N]])
//
#define ZRCOLA_VERSION_INST "1.255.7"
#define ZRCOLA_VERSION_INST "1.255.8"
//
// The product code for ProductCode property in MSI packages
// Replace with new on every version change, regardless how minor it is.
//
#define ZRCOLA_VERSION_GUID "{E83CDC77-6348-4C0B-8BD5-0BD812FEA52E}"
#define ZRCOLA_VERSION_GUID "{9ABAB2D1-7A6B-4D99-B362-D98D53930367}"
//
// The product vendor and application name for configuration keeping.

View File

@@ -19,6 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\character.cpp" />
<ClCompile Include="..\src\language.cpp" />
<ClCompile Include="..\src\mapping.cpp" />
<ClCompile Include="..\src\normalize.cpp" />
@@ -31,6 +32,7 @@
<ClCompile Include="..\src\translate.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\zrcola\character.h" />
<ClInclude Include="..\include\zrcola\common.h" />
<ClInclude Include="..\include\zrcola\language.h" />
<ClInclude Include="..\include\zrcola\normalize.h" />

View File

@@ -30,6 +30,9 @@
<ClCompile Include="..\src\language.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\character.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\stdafx.h">
@@ -47,6 +50,9 @@
<ClInclude Include="..\include\zrcola\language.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\include\zrcola\character.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\res\libZRCola.rc">

View File

@@ -0,0 +1,542 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common.h"
#include <stdex/idrec.h>
#include <istream>
#include <map>
#include <ostream>
#include <vector>
#include <set>
#include <string>
#pragma warning(push)
#pragma warning(disable: 4200)
#pragma warning(disable: 4251)
#pragma warning(disable: 4512)
namespace ZRCola {
///
/// Character category ID type
/// Two letter abbreviation, non-terminated
///
struct chrcatid_t {
char data[2];
inline chrcatid_t& operator=(const chrcatid_t &src)
{
data[0] = src.data[0];
data[1] = src.data[1];
return *this;
}
inline chrcatid_t& operator=(const char *src)
{
data[1] = (data[0] = src[0]) != 0 ? src[1] : 0;
return *this;
}
};
///
/// Blank character category
///
const chrcatid_t chrcatid_t_blank = {};
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a == \p b
/// - false otherwise
///
inline bool operator==(const chrcatid_t &a, const chrcatid_t & b)
{
return
a.data[0] == b.data[0] &&
(a.data[0] == 0 || a.data[1] == b.data[1]);
}
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a != \p b
/// - false otherwise
///
inline bool operator!=(const chrcatid_t &a, const chrcatid_t & b)
{
return !operator==(a, b);
}
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a < \p b
/// - false otherwise
///
inline bool operator<(const chrcatid_t& a, const chrcatid_t& b)
{
if (a.data[0] < b.data[0]) return true;
else if (a.data[0] > b.data[0]) return false;
else if (a.data[1] < b.data[1]) return true;
else return false;
}
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a > \p b
/// - false otherwise
///
inline bool operator>(const chrcatid_t& a, const chrcatid_t& b)
{
return operator<(b, a);
}
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a <= \p b
/// - false otherwise
///
inline bool operator<=(const chrcatid_t &a, const chrcatid_t & b)
{
return !operator>(a, b);
}
///
/// Compares two character category IDs
///
/// \param[in] a First character category ID
/// \param[in] b Second character category ID
///
/// \returns
/// - true when \p a >= \p b
/// - false otherwise
///
inline bool operator>=(const chrcatid_t &a, const chrcatid_t & b)
{
return !operator<(a, b);
}
///
/// Character Database
///
class ZRCOLA_API character_db {
public:
#pragma pack(push)
#pragma pack(2)
///
/// Character data
///
struct character {
wchar_t chr; ///> Character
chrcatid_t cat; ///> Category ID
unsigned __int16 desc_len; ///< Character description length in \c data
unsigned __int16 rel_len; ///< Related character count in \c data
wchar_t data[]; ///< Character description and list of related characters
};
#pragma pack(pop)
///
/// Character index
///
class indexChar : public index<unsigned __int16, unsigned __int32, character>
{
public:
///
/// Constructs the index
///
/// \param[in] h Reference to vector holding the data
///
indexChar(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, character>(h) {}
///
/// Compares two characters by ID (for searching)
///
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare(_In_ const character &a, _In_ const character &b) const
{
if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return 1;
return 0;
}
} idxChr; ///< Character index
textindex<wchar_t, wchar_t, unsigned __int32> idxDsc; ///< Description index
textindex<wchar_t, wchar_t, unsigned __int32> idxDscSub; ///< Description index (sub-terms)
std::vector<unsigned __int16> data; ///< Character data
public:
///
/// Constructs the database
///
inline character_db() : idxChr(data) {}
///
/// Search for characters by description in given categories
///
/// \param[in ] str Search string
/// \param[in ] cats Set of categories, character must be a part of
/// \param[inout] hits (character, count) map to append full-word hits to
/// \param[inout] hits_sub (character, count) map to append partial-word hits to
/// \param[in] fn_abort Pointer to function to periodically test for search cancellation
/// \param[in] cookie Cookie for \p fn_abort call
///
bool Search(_In_z_ const wchar_t *str, _In_ const std::set<chrcatid_t> &cats, _Inout_ std::map<wchar_t, unsigned long> &hits, _Inout_ std::map<wchar_t, unsigned long> &hits_sub, _In_opt_ bool (__cdecl *fn_abort)(void *cookie) = NULL, _In_opt_ void *cookie = NULL) const;
///
/// Get character category
///
/// \param[in] c Character
///
/// \returns
/// - Character category if character found
/// - `ZRCola::chrcatid_t_blank` otherwise
///
inline chrcatid_t GetCharCat(wchar_t c) const
{
char _chr[sizeof(character)];
((character *)_chr)->chr = c;
indexChar::size_type start;
return idxChr.find(*((character *)_chr), start) ? idxChr[start].cat : chrcatid_t_blank;
}
};
typedef ZRCOLA_API stdex::idrec::record<character_db, recordid_t, recordsize_t, ZRCOLA_RECORD_ALIGN> character_rec;
///
/// Character category database
///
class ZRCOLA_API chrcat_db {
public:
#pragma pack(push)
#pragma pack(2)
///
/// Character category data
///
struct chrcat {
chrcatid_t id; ///< Character category ID
unsigned __int16 rank; ///< Character category rank
unsigned __int16 name_len; ///< \c name length (in characters)
wchar_t name[]; ///< Character category name
};
#pragma pack(pop)
///
/// Character category index
///
class indexChrCat : public index<unsigned __int16, unsigned __int32, chrcat>
{
public:
///
/// Constructs the index
///
/// \param[in] h Reference to vector holding the data
///
indexChrCat(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, chrcat>(h) {}
///
/// Compares two character categories by ID (for searching)
///
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare(_In_ const chrcat &a, _In_ const chrcat &b) const
{
if (a.id < b.id) return -1;
else if (a.id > b.id) return 1;
else return 0;
}
} idxChrCat; ///< Character category index
///
/// Rank index
///
class indexRank : public index<unsigned __int16, unsigned __int32, chrcat>
{
public:
///
/// Constructs the index
///
/// \param[in] h Reference to vector holding the data
///
indexRank(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, chrcat>(h) {}
///
/// Compares two character categories by ID (for searching)
///
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare(_In_ const chrcat &a, _In_ const chrcat &b) const
{
if (a.rank < b.rank) return -1;
else if (a.rank > b.rank) return +1;
return 0;
}
///
/// Compares two character categories by rank (for sorting)
///
/// \param[in] a Pointer to character category
/// \param[in] b Pointer to second character category
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare_sort(_In_ const chrcat &a, _In_ const chrcat &b) const
{
if (a.rank < b.rank) return -1;
else if (a.rank > b.rank) return +1;
int r = _wcsncoll(a.name, b.name, std::min<unsigned __int16>(a.name_len, b.name_len));
if (r != 0) return r;
if (a.name_len < b.name_len) return -1;
else if (a.name_len > b.name_len) return +1;
return 0;
}
} idxRnk; ///< Rank index
std::vector<unsigned __int16> data; ///< Character category data
public:
///
/// Constructs the database
///
inline chrcat_db() : idxChrCat(data), idxRnk(data) {}
};
typedef ZRCOLA_API stdex::idrec::record<chrcat_db, recordid_t, recordsize_t, ZRCOLA_RECORD_ALIGN> chrcat_rec;
};
const ZRCola::recordid_t stdex::idrec::record<ZRCola::character_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"CHR";
const ZRCola::recordid_t stdex::idrec::record<ZRCola::chrcat_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"CCT";
///
/// Reads character database from a stream
///
/// \param[in ] stream Input stream
/// \param[out] db Character database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::character_db &db)
{
// Read character index.
stream >> db.idxChr;
if (!stream.good()) return stream;
// Read description index.
stream >> db.idxDsc;
if (!stream.good()) return stream;
// Read sub-term description index.
stream >> db.idxDscSub;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}
///
/// Writes character database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Character database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::character_db &db)
{
// Write character index.
if (stream.fail()) return stream;
stream << db.idxChr;
// Write description index.
if (!stream.good()) return stream;
stream << db.idxDsc;
// Write sub-term description index.
if (!stream.good()) return stream;
stream << db.idxDscSub;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Writes character category database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Character category database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::chrcat_db &db)
{
// Write character category index.
if (stream.fail()) return stream;
stream << db.idxChrCat;
// Write rank index.
if (stream.fail()) return stream;
stream << db.idxRnk;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Reads character category database from a stream
///
/// \param[in ] stream Input stream
/// \param[out] db Character category database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::chrcat_db &db)
{
// Read character category index.
stream >> db.idxChrCat;
if (!stream.good()) return stream;
// Read rank index.
stream >> db.idxRnk;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}
#pragma warning(pop)

View File

@@ -19,6 +19,9 @@
#pragma once
#include <istream>
#include <ostream>
#include <utility>
#include <vector>
#ifdef _WIN32
#include <Windows.h>
@@ -49,22 +52,167 @@
///
#define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC")
///
/// Unknown language ID
///
#define ZRCOLA_LANG_VOID " "
namespace ZRCola {
typedef unsigned __int32 recordid_t;
typedef unsigned __int32 recordsize_t;
///
/// Key-value index pair for mappings
///
#pragma pack(push)
#pragma pack(2)
template <class T>
struct mappair_t
{
T idx_key; ///< Index of key
T idx_val; ///< Index of value
};
#pragma pack(pop)
///
/// Language ID type
/// Three letter abbreviation, zero terminated
///
typedef char langid_t[4];
struct langid_t {
char data[4];
inline langid_t& operator=(const langid_t &src)
{
data[0] = src.data[0];
data[1] = src.data[1];
data[2] = src.data[2];
data[3] = src.data[3];
return *this;
}
inline langid_t& operator=(const char *src)
{
data[3] = (
data[2] = (
data[1] = (
data[0] = src[0] ) != 0 ?
src[1] : 0) != 0 ?
src[2] : 0) != 0 ?
src[3] : 0;
return *this;
}
};
///
/// Blank language ID
///
const langid_t langid_t_blank = {};
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a == \p b
/// - false otherwise
///
inline bool operator==(const langid_t &a, const langid_t & b)
{
return
a.data[0] == b.data[0] &&
(a.data[0] == 0 || (a.data[1] == b.data[1] &&
(a.data[1] == 0 || (a.data[2] == b.data[2] &&
(a.data[2] == 0 || a.data[3] == b.data[3])))));
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a != \p b
/// - false otherwise
///
inline bool operator!=(const langid_t &a, const langid_t & b)
{
return !operator==(a, b);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a < \p b
/// - false otherwise
///
inline bool operator<(const langid_t& a, const langid_t& b)
{
if (a.data[0] < b.data[0]) return true;
else if (a.data[0] > b.data[0]) return false;
else if (a.data[1] < b.data[1]) return true;
else if (a.data[1] > b.data[1]) return false;
else if (a.data[2] < b.data[2]) return true;
else if (a.data[2] > b.data[2]) return false;
else if (a.data[3] < b.data[3]) return true;
else return false;
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a > \p b
/// - false otherwise
///
inline bool operator>(const langid_t& a, const langid_t& b)
{
return operator<(b, a);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a <= \p b
/// - false otherwise
///
inline bool operator<=(const langid_t &a, const langid_t & b)
{
return !operator>(a, b);
}
///
/// Compares two language IDs
///
/// \param[in] a First language ID
/// \param[in] b Second language ID
///
/// \returns
/// - true when \p a >= \p b
/// - false otherwise
///
inline bool operator>=(const langid_t &a, const langid_t & b)
{
return !operator<(a, b);
}
#ifdef _WIN32
@@ -182,7 +330,11 @@ namespace ZRCola {
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare_sort(_In_ const T_data &a, _In_ const T_data &b) const = 0;
virtual int compare_sort(_In_ const T_data &a, _In_ const T_data &b) const
{
// Revert to `compare()` by default.
return compare(a, b);
}
///
@@ -203,7 +355,7 @@ namespace ZRCola {
for (start = 0, end = size(); start < end; ) {
size_type m = (start + end) / 2;
int r = compare(el, at(m));
if (r < 0) end = m;
if (r < 0) end = m;
else if (r > 0) start = m + 1;
else {
// Narrow the search area on the left to start at the first element in the run.
@@ -227,6 +379,40 @@ namespace ZRCola {
return false;
}
///
/// Search for the first element in the index
///
/// \param[in] el Element we are looking for (needle)
/// \param[out] start Index of the first matching element found
///
/// \returns
/// - \c true if found
/// - \c false otherwise
///
bool find(_In_ const T_data &el, _Out_ size_type &start) const
{
// Start with the full search area.
size_t end;
for (start = 0, end = size(); start < end; ) {
size_type m = (start + end) / 2;
int r = compare(el, at(m));
if (r < 0) end = m;
else if (r > 0) start = m + 1;
else {
// Narrow the search area on the left to start at the first element in the run.
for (size_type end2 = m; start < end2;) {
size_type m = (start + end2) / 2;
int r = compare(el, at(m));
if (r <= 0) end2 = m; else start = m + 1;
}
return true;
}
}
return false;
}
private:
static int __cdecl compare_s(void *p, const void *a, const void *b)
{
@@ -236,6 +422,75 @@ namespace ZRCola {
};
///
/// Memory text index
///
template <class T_key, class T_val, class T_idx = unsigned __int32>
class textindex : public std::vector< mappair_t<T_idx> >
{
public:
typedef std::vector< mappair_t<T_idx> > base_t;
std::vector<T_key> keys; ///< Key data
std::vector<T_val> values; ///< Index values
public:
///
/// Constructs the index
///
textindex() {}
///
/// Finds data for given key
///
/// \param[in ] key Pointer to key
/// \param[in ] key_len Count of \p key elements
/// \param[out] val Pointer to receive pointer to key's values
/// \param[out] val_len Pointer to receive count of \p val elements
///
/// \returns
/// - \c true if found
/// - \c false otherwise
///
bool find(_In_count_(key_len) const T_key *key, _In_ size_t key_len, _Out_ const T_val **val, _Out_ size_t *val_len) const
{
for (size_type start = 0, end = size(); start < end; ) {
size_type m = (start + end) / 2;
int r = compare(key, key_len, m);
if (r < 0) end = m;
else if (r > 0) start = m + 1;
else {
// Get values at position m.
size_t start = base_t::at(m ).idx_val;
*val_len = (m < size() ? base_t::at(m + 1).idx_val : values.size()) - start;
*val = &values.at(start);
return true;
}
}
return false;
}
protected:
inline int compare(_In_count_(key_len) const T_key *key, _In_ size_t key_len, size_type pos) const
{
// Get key at position pos.
size_t
start = base_t::at(pos ).idx_key,
key2_len = (pos < size() ? base_t::at(pos + 1).idx_key : keys.size()) - start;
std::vector<T_key>::const_pointer key2 = &keys.at(start);
// Compare keys.
int r = memcmp(key, key2, sizeof(T_key)*std::min<size_t>(key_len, key2_len));
if (r != 0 ) return r;
else if (key_len < key2_len) return -1;
else if (key_len > key2_len) return 1;
return 0;
}
};
///
/// Source-destination index transformation mapping
///
@@ -288,4 +543,184 @@ namespace ZRCola {
};
};
///
/// Writes index to a stream
///
/// \param[in] stream Output stream
/// \param[in] idx Index
///
/// \returns The stream \p stream
///
template <class T, class T_idx, class T_data>
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::index<T, T_idx, T_data> &idx)
{
// Write index count.
ZRCola::index<T, T_idx, T_data>::size_type idx_count = idx.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (idx_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)idx_count;
stream.write((const char*)&count, sizeof(count));
// Write index data.
if (stream.fail()) return stream;
stream.write((const char*)idx.data(), sizeof(T_idx)*count);
return stream;
}
///
/// Reads index from a stream
///
/// \param[in] stream Input stream
/// \param[out] idx Index
///
/// \returns The stream \p stream
///
template <class T, class T_idx, class T_data>
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::index<T, T_idx, T_data> &idx)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read index data.
idx.resize(count);
stream.read((char*)idx.data(), sizeof(T_idx)*count);
} else
idx.clear();
return stream;
}
///
/// Writes text index to a stream
///
/// \param[in] stream Output stream
/// \param[in] idx Text index
///
/// \returns The stream \p stream
///
template <class T_key, class T_val, class T_idx>
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::textindex<T_key, T_val, T_idx> &idx)
{
unsigned __int32 count;
// Write index count.
ZRCola::textindex<T_key, T_val, T_idx>::size_type idx_count = idx.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (idx_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)idx_count;
stream.write((const char*)&count, sizeof(count));
// Write index data.
if (stream.fail()) return stream;
stream.write((const char*)idx.data(), sizeof(ZRCola::textindex<T_key, T_val, T_idx>::value_type)*count);
// Write key count.
std::vector<T_key>::size_type key_count = idx.keys.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (idx_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)key_count;
stream.write((const char*)&count, sizeof(count));
// Write key data.
if (stream.fail()) return stream;
stream.write((const char*)idx.keys.data(), sizeof(std::vector<T_key>::value_type)*count);
// Write value count.
std::vector<T_val>::size_type value_count = idx.values.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (idx_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
count = (unsigned __int32)value_count;
stream.write((const char*)&count, sizeof(count));
// Write value data.
if (stream.fail()) return stream;
stream.write((const char*)idx.values.data(), sizeof(std::vector<T_val>::value_type)*count);
return stream;
}
///
/// Reads text index from a stream
///
/// \param[in] stream Input stream
/// \param[out] idx Text index
///
/// \returns The stream \p stream
///
template <class T_key, class T_val, class T_idx>
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::textindex<T_key, T_val, T_idx> &idx)
{
unsigned __int32 count;
// Read text index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read text index.
idx.resize(count);
stream.read((char*)idx.data(), sizeof(ZRCola::textindex<T_key, T_val, T_idx>::value_type)*count);
if (!stream.good()) return stream;
} else
idx.clear();
// Read keys count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read keys.
idx.keys.resize(count);
stream.read((char*)idx.keys.data(), sizeof(std::vector<T_key>::value_type)*count);
if (!stream.good()) return stream;
} else
idx.keys.clear();
// Read value count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
if (count) {
// Read values.
idx.values.resize(count);
stream.read((char*)idx.values.data(), sizeof(std::vector<T_val>::value_type)*count);
} else
idx.values.clear();
return stream;
}
#pragma warning(pop)

View File

@@ -23,6 +23,7 @@
#include <stdex/idrec.h>
#include <istream>
#include <ostream>
#include <vector>
#include <string>
@@ -97,8 +98,8 @@ namespace ZRCola {
if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return 1;
int r = memcmp(a.lang, b.lang, sizeof(langid_t));
if (r != 0) return r;
if (a.lang < b.lang) return -1;
else if (a.lang > b.lang) return 1;
return 0;
}
@@ -233,29 +234,8 @@ namespace ZRCola {
///
virtual int compare(_In_ const language &a, _In_ const language &b) const
{
int r = memcmp(a.id, b.id, sizeof(langid_t));
if (r != 0) return r;
return 0;
}
///
/// Compares two languages by ID (for sorting)
///
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
/// - =0 when a == b
/// - >0 when a > b
///
virtual int compare_sort(_In_ const language &a, _In_ const language &b) const
{
int r = memcmp(a.id, b.id, sizeof(langid_t));
if (r != 0) return r;
// As the language ID must not duplicate, further comparison is pointless.
if (a.id < b.id) return -1;
else if (a.id > b.id) return 1;
return 0;
}
@@ -279,41 +259,113 @@ const ZRCola::recordid_t stdex::idrec::record<ZRCola::langchar_db, ZRCola::recor
const ZRCola::recordid_t stdex::idrec::record<ZRCola::language_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"LNG";
///
/// Writes language character database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Language character database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::langchar_db &db)
{
// Write character index.
if (stream.fail()) return stream;
stream << db.idxChr;
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
// Write language index.
if (stream.fail()) return stream;
stream << db.idxLng;
#endif
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Reads language character database from a stream
///
/// \param[in] stream Input stream
/// \param[in ] stream Input stream
/// \param[out] db Language character database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::langchar_db &db)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read character index.
db.idxChr.resize(count);
stream.read((char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
stream >> db.idxChr;
if (!stream.good()) return stream;
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
// Read language index.
db.idxLng.resize(count);
stream.read((char*)db.idxLng.data(), sizeof(unsigned __int32)*count);
stream >> db.idxLng;
if (!stream.good()) return stream;
#endif
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}
///
/// Writes language database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Language database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::language_db &db)
{
// Write language index.
if (stream.fail()) return stream;
stream << db.idxLng;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
@@ -322,31 +374,28 @@ inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::langch
///
/// Reads language database from a stream
///
/// \param[in] stream Input stream
/// \param[in ] stream Input stream
/// \param[out] db Language database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::language_db &db)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read language index.
db.idxLng.resize(count);
stream.read((char*)db.idxLng.data(), sizeof(unsigned __int32)*count);
stream >> db.idxLng;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}

View File

@@ -24,6 +24,7 @@
#include <stdex/idrec.h>
#include <istream>
#include <ostream>
#include <vector>
#include <string>
@@ -223,7 +224,7 @@ namespace ZRCola {
///
inline void Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map = NULL) const
{
Decompose(input, inputMax, NULL, ZRCOLA_LANG_VOID, output, map);
Decompose(input, inputMax, NULL, langid_t_blank, output, map);
}
///
@@ -247,39 +248,74 @@ namespace ZRCola {
const ZRCola::recordid_t stdex::idrec::record<ZRCola::translation_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"TRN";
///
/// Writes translation database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Translation database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::translation_db &db)
{
// Write composition index.
if (stream.fail()) return stream;
stream << db.idxComp;
// Write decomposition index.
if (stream.fail()) return stream;
stream << db.idxDecomp;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Reads translation database from a stream
///
/// \param[in] stream Input stream
/// \param[in ] stream Input stream
/// \param[out] db Translation database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::translation_db &db)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read composition index.
db.idxComp.resize(count);
stream.read((char*)db.idxComp.data(), sizeof(unsigned __int32)*count);
stream >> db.idxComp;
if (!stream.good()) return stream;
// Read decomposition index.
db.idxDecomp.resize(count);
stream.read((char*)db.idxDecomp.data(), sizeof(unsigned __int32)*count);
stream >> db.idxDecomp;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}

View File

@@ -0,0 +1,113 @@
/*
Copyright 2015-2016 Amebis
This file is part of ZRCola.
ZRCola is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ZRCola is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ZRCola. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
bool ZRCola::character_db::Search(_In_z_ const wchar_t *str, _In_ const std::set<chrcatid_t> &cats, _Inout_ std::map<wchar_t, unsigned long> &hits, _Inout_ std::map<wchar_t, unsigned long> &hits_sub, _In_opt_ bool (__cdecl *fn_abort)(void *cookie), _In_opt_ void *cookie) const
{
assert(str);
while (*str) {
if (fn_abort && fn_abort(cookie)) return false;
// Skip white space.
for (;;) {
if (*str == 0)
return true;
else if (!iswspace(*str))
break;
else
str++;
}
// Get term.
std::wstring term;
if (*str == L'"') {
const wchar_t *str_end = ++str;
for (;;) {
if (*str_end == 0) {
term.assign(str, str_end);
break;
} else if (*str_end == L'"') {
term.assign(str, str_end);
str_end++;
break;
} else
str_end++;
}
str = str_end;
} else {
const wchar_t *str_end = str + 1;
for (; *str_end && !iswspace(*str_end); str_end++);
term.assign(str, str_end);
str = str_end;
}
if (!term.empty()) {
if (fn_abort && fn_abort(cookie)) return false;
// Find the term.
std::transform(term.begin(), term.end(), term.begin(), std::towlower);
if (fn_abort && fn_abort(cookie)) return false;
const wchar_t *data;
size_t len;
if (idxDsc.find(term.c_str(), term.size(), &data, &len)) {
// The term was found.
for (size_t i = 0; i < len; i++) {
if (fn_abort && fn_abort(cookie)) return false;
wchar_t c = data[i];
if (cats.find(GetCharCat(c)) != cats.end()) {
std::map<wchar_t, unsigned long>::iterator idx = hits.find(c);
if (idx == hits.end()) {
// New character.
hits.insert(std::make_pair(data[i], 1));
} else {
// Increment existing character.
idx->second++;
}
}
}
}
if (idxDscSub.find(term.c_str(), term.size(), &data, &len)) {
// The term was found in the sub-term index.
for (size_t i = 0; i < len; i++) {
if (fn_abort && fn_abort(cookie)) return false;
wchar_t c = data[i];
if (cats.find(GetCharCat(c)) != cats.end()) {
std::map<wchar_t, unsigned long>::iterator idx = hits_sub.find(c);
if (idx == hits_sub.end()) {
// New character.
hits_sub.insert(std::make_pair(data[i], 1));
} else {
// Increment existing character.
idx->second++;
}
}
}
}
}
}
return true;
}

View File

@@ -24,46 +24,46 @@
void ZRCola::LangConvert(_In_ LANGID lang_win, _Inout_ ZRCola::langid_t &lang)
{
switch (PRIMARYLANGID(lang_win)) {
case LANG_BELARUSIAN : memcpy(lang, "bel", sizeof(lang)); break;
case LANG_CZECH : memcpy(lang, "cze", sizeof(lang)); break;
case LANG_DANISH : memcpy(lang, "dan", sizeof(lang)); break;
case LANG_GERMAN : memcpy(lang, "deu", sizeof(lang)); break;
case LANG_ENGLISH : memcpy(lang, "eng", sizeof(lang)); break;
case LANG_ESTONIAN : memcpy(lang, "est", sizeof(lang)); break;
case LANG_FRENCH : memcpy(lang, "fra", sizeof(lang)); break;
case LANG_IRISH : memcpy(lang, "gle", sizeof(lang)); break;
case LANG_HUNGARIAN : memcpy(lang, "hun", sizeof(lang)); break;
case LANG_LATVIAN : memcpy(lang, "lav", sizeof(lang)); break;
case LANG_LITHUANIAN : memcpy(lang, "lit", sizeof(lang)); break;
case LANG_MACEDONIAN : memcpy(lang, "mkd", sizeof(lang)); break;
case LANG_MALTESE : memcpy(lang, "mlt", sizeof(lang)); break;
case LANG_NORWEGIAN : memcpy(lang, "nor", sizeof(lang)); break;
case LANG_POLISH : memcpy(lang, "pol", sizeof(lang)); break;
case LANG_PORTUGUESE : memcpy(lang, "por", sizeof(lang)); break;
case LANG_ROMANIAN : memcpy(lang, "rum", sizeof(lang)); break;
case LANG_RUSSIAN : memcpy(lang, "rus", sizeof(lang)); break;
case LANG_SLOVAK : memcpy(lang, "slk", sizeof(lang)); break;
case LANG_SLOVENIAN : memcpy(lang, "slv", sizeof(lang)); break;
case LANG_SPANISH : memcpy(lang, "spa", sizeof(lang)); break;
case LANG_ALBANIAN : memcpy(lang, "sqi", sizeof(lang)); break;
case LANG_SWEDISH : memcpy(lang, "swe", sizeof(lang)); break;
case LANG_TURKISH : memcpy(lang, "tur", sizeof(lang)); break;
case LANG_UKRAINIAN : memcpy(lang, "ukr", sizeof(lang)); break;
case LANG_BELARUSIAN : lang = "bel"; break;
case LANG_CZECH : lang = "cze"; break;
case LANG_DANISH : lang = "dan"; break;
case LANG_GERMAN : lang = "deu"; break;
case LANG_ENGLISH : lang = "eng"; break;
case LANG_ESTONIAN : lang = "est"; break;
case LANG_FRENCH : lang = "fra"; break;
case LANG_IRISH : lang = "gle"; break;
case LANG_HUNGARIAN : lang = "hun"; break;
case LANG_LATVIAN : lang = "lav"; break;
case LANG_LITHUANIAN : lang = "lit"; break;
case LANG_MACEDONIAN : lang = "mkd"; break;
case LANG_MALTESE : lang = "mlt"; break;
case LANG_NORWEGIAN : lang = "nor"; break;
case LANG_POLISH : lang = "pol"; break;
case LANG_PORTUGUESE : lang = "por"; break;
case LANG_ROMANIAN : lang = "rum"; break;
case LANG_RUSSIAN : lang = "rus"; break;
case LANG_SLOVAK : lang = "slk"; break;
case LANG_SLOVENIAN : lang = "slv"; break;
case LANG_SPANISH : lang = "spa"; break;
case LANG_ALBANIAN : lang = "sqi"; break;
case LANG_SWEDISH : lang = "swe"; break;
case LANG_TURKISH : lang = "tur"; break;
case LANG_UKRAINIAN : lang = "ukr"; break;
case LANG_CROATIAN : // LANG_BOSNIAN, and LANG_SERBIAN
switch (SUBLANGID(lang_win)) {
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN : memcpy(lang, "bos", sizeof(lang)); break;
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC : memcpy(lang, "boz", sizeof(lang)); break;
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN : lang = "bos"; break;
case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC : lang = "boz"; break;
case SUBLANG_CROATIAN_CROATIA :
case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN : memcpy(lang, "hrv", sizeof(lang)); break;
case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN : lang = "hrv"; break;
case SUBLANG_SERBIAN_LATIN :
case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN :
case SUBLANG_SERBIAN_MONTENEGRO_LATIN :
case SUBLANG_SERBIAN_SERBIA_LATIN : memcpy(lang, "srp", sizeof(lang)); break;
case SUBLANG_SERBIAN_SERBIA_LATIN : lang = "srp"; break;
case SUBLANG_SERBIAN_CYRILLIC :
case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC :
case SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC :
case SUBLANG_SERBIAN_SERBIA_CYRILLIC : memcpy(lang, "srz", sizeof(lang)); break;
case SUBLANG_SERBIAN_SERBIA_CYRILLIC : lang = "srz"; break;
}
break;
}
@@ -83,9 +83,8 @@ bool ZRCola::langchar_db::IsLocalCharacter(_In_ wchar_t chr, _In_ ZRCola::langid
else if (lc.chr < chr ) l = m + 1;
else {
// Do the bisection test on language.
int res = memcmp(lang, lc.lang, sizeof(langid_t));
if (res < 0) r = m;
else if (res > 0) l = m + 1;
if (lang < lc.lang) r = m;
else if (lang > lc.lang) l = m + 1;
else {
// Match found.
return true;

View File

@@ -21,8 +21,12 @@
#include "../../../include/zrcola.h"
#include "../include/zrcola/character.h"
#include "../include/zrcola/language.h"
#include "../include/zrcola/normalize.h"
#include "../include/zrcola/translate.h"
#include <assert.h>
#include <algorithm>
#include <cwctype>

View File

@@ -72,6 +72,9 @@ complibZRColaUI.dll.Win32 {D9A5BF44-DDFE-4A22-89F4-14D291581829} ZRCOLABINDIR 0
!IF "$(PLAT)" == "x64"
complibZRColaUI.dll.x64 {360E78E5-9560-4C52-B806-45EDC682BB17} ZRCOLABINDIR 256 filelibZRColaUI.dll.x64
!ENDIF
!IF "$(LANG)" == "Sl"
complibZRColaUI.mo.sl_SI {EAE1C699-8415-4FC6-9EC7-FE74AFC432A9} ZRCOLALOCSLSIDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) filelibZRColaUI.mo.sl_SI
!ENDIF
<<NOKEEP
@@ -102,6 +105,9 @@ filelibZRColaUI.dll.x64 complibZRColaUI.dll.x64 LIBZRC~6.DLL|libZRColaUI10u_vc10
filelibZRColaUI.dll.x64 complibZRColaUI.dll.x64 LIBZRC~8.DLL|libZRColaUI10ud_vc100_x64.dll 0 0 1536 1
!ENDIF
!ENDIF
!IF "$(LANG)" == "Sl"
filelibZRColaUI.mo.sl_SI complibZRColaUI.mo.sl_SI LIBZRC~1.MO|libZRColaUI.mo 0 1060 0 1
!ENDIF
<<NOKEEP

View File

@@ -36,6 +36,12 @@
<ItemGroup>
<ResourceCompile Include="..\res\libZRColaUI.rc" />
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\sl_SI.po" />
</ItemGroup>
<ItemGroup>
<None Include="..\locale\libZRColaUI.pot" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C0A84BD2-3870-4CD6-B281-0AB322E3C579}</ProjectGuid>
<RootNamespace>libZRColaUI</RootNamespace>
@@ -105,5 +111,6 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\include\xgettext.targets" />
</ImportGroup>
</Project>

View File

@@ -13,6 +13,9 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Resource Files\Localization">
<UniqueIdentifier>{21f03e61-c62a-427a-bcb2-80c08dcff0bd}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\stdafx.cpp">
@@ -41,4 +44,14 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\locale\libZRColaUI.pot">
<Filter>Resource Files\Localization</Filter>
</None>
</ItemGroup>
<ItemGroup>
<POCompile Include="..\locale\sl_SI.po">
<Filter>Resource Files\Localization</Filter>
</POCompile>
</ItemGroup>
</Project>

View File

@@ -24,6 +24,7 @@
#include <stdex/idrec.h>
#include <istream>
#include <ostream>
#include <vector>
#pragma warning(push)
@@ -55,7 +56,7 @@ namespace ZRCola {
///
/// Rank index
///
class indexRnk : public index<unsigned __int16, unsigned __int32, chrgrp>
class indexRank : public index<unsigned __int16, unsigned __int32, chrgrp>
{
public:
///
@@ -63,7 +64,7 @@ namespace ZRCola {
///
/// \param[in] h Reference to vector holding the data
///
indexRnk(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, chrgrp>(h) {}
indexRank(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, chrgrp>(h) {}
///
/// Compares two character groups by rank (for searching)
@@ -126,34 +127,66 @@ namespace ZRCola {
const ZRCola::recordid_t stdex::idrec::record<ZRCola::chrgrp_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"CGR";
///
/// Writes character group database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Character group database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::chrgrp_db &db)
{
// Write rank index.
if (stream.fail()) return stream;
stream << db.idxRnk;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Reads character group database from a stream
///
/// \param[in] stream Input stream
/// \param[in ] stream Input stream
/// \param[out] db Character group database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::chrgrp_db &db)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read rank index.
db.idxRnk.resize(count);
stream.read((char*)db.idxRnk.data(), sizeof(unsigned __int32)*count);
stream >> db.idxRnk;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}

View File

@@ -23,7 +23,11 @@
#include <zrcola/common.h>
#include <stdex/idrec.h>
#include <wx/string.h>
#include <istream>
#include <ostream>
#include <vector>
#pragma warning(push)
@@ -204,6 +208,33 @@ namespace ZRCola {
/// Constructs the database
///
inline keyseq_db() : idxChr(data), idxKey(data) {}
///
/// Get text representation of a given key sequence
///
/// \param[in] seq Key sequence
/// \param[in] seq_len Number of elements in \p seq
/// \param[out] str Text representation of a \p seq key sequence
///
/// \returns
/// - \c true if conversion succeeded
/// - \c false otherwise
///
static bool GetSequenceAsText(_In_count_(seq_len) const keyseq::key_t *seq, _In_ size_t seq_len, _Out_ wxString& str);
///
/// Get text representation of a given key sequence
///
/// \param[in] seq Key sequence
/// \param[in] seq_len Number of elements in \p seq
///
/// \returns Text representation of a \p seq key sequence
///
static inline wxString GetSequenceAsText(_In_count_(seq_len) const keyseq_db::keyseq::key_t *seq, _In_ size_t seq_len)
{
wxString str;
return GetSequenceAsText(seq, seq_len, str) ? str : wxEmptyString;
}
};
@@ -214,39 +245,74 @@ namespace ZRCola {
const ZRCola::recordid_t stdex::idrec::record<ZRCola::keyseq_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"KEY";
///
/// Writes key sequence database to a stream
///
/// \param[in] stream Output stream
/// \param[in] db Key sequence database
///
/// \returns The stream \p stream
///
inline std::ostream& operator <<(_In_ std::ostream& stream, _In_ const ZRCola::keyseq_db &db)
{
// Write character index.
if (stream.fail()) return stream;
stream << db.idxChr;
// Write key index.
if (stream.fail()) return stream;
stream << db.idxKey;
// Write data count.
std::vector<unsigned __int16>::size_type data_count = db.data.size();
#if defined(_WIN64) || defined(__x86_64__) || defined(__ppc64__)
// 4G check
if (data_count > 0xffffffff) {
stream.setstate(std::ios_base::failbit);
return stream;
}
#endif
if (stream.fail()) return stream;
unsigned __int32 count = (unsigned __int32)data_count;
stream.write((const char*)&count, sizeof(count));
// Write data.
if (stream.fail()) return stream;
stream.write((const char*)db.data.data(), sizeof(unsigned __int16)*count);
return stream;
}
///
/// Reads key sequence database from a stream
///
/// \param[in] stream Input stream
/// \param[out] db Key sequence database
/// \param[out] db Key sequence database
///
/// \returns The stream \p stream
///
inline std::istream& operator >>(_In_ std::istream& stream, _Out_ ZRCola::keyseq_db &db)
{
unsigned __int32 count;
// Read index count.
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read character index.
db.idxChr.resize(count);
stream.read((char*)db.idxChr.data(), sizeof(unsigned __int32)*count);
stream >> db.idxChr;
if (!stream.good()) return stream;
// Read key index.
db.idxKey.resize(count);
stream.read((char*)db.idxKey.data(), sizeof(unsigned __int32)*count);
stream >> db.idxKey;
if (!stream.good()) return stream;
// Read data count.
unsigned __int32 count;
stream.read((char*)&count, sizeof(count));
if (!stream.good()) return stream;
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
if (count) {
// Read data.
db.data.resize(count);
stream.read((char*)db.data.data(), sizeof(unsigned __int16)*count);
} else
db.data.clear();
return stream;
}

1
lib/libZRColaUI/locale/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/*.mo

View File

@@ -0,0 +1,163 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: libZRColaUI\n"
"POT-Creation-Date: 2016-05-09 10:38+0200\n"
"PO-Revision-Date: 2016-02-06 09:04+0100\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"X-Poedit-Basepath: ..\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: src\n"
"X-Poedit-SearchPath-1: include\n"
#: src/keyboard.cpp:30 src/keyboard.cpp:72
msgid "Ctrl"
msgstr ""
#: src/keyboard.cpp:31 src/keyboard.cpp:71
msgid "Alt"
msgstr ""
#: src/keyboard.cpp:32 src/keyboard.cpp:70
msgid "Shift"
msgstr ""
#: src/keyboard.cpp:45
msgid "Esc"
msgstr ""
#: src/keyboard.cpp:47
msgid "F1"
msgstr ""
#: src/keyboard.cpp:48
msgid "F2"
msgstr ""
#: src/keyboard.cpp:49
msgid "F3"
msgstr ""
#: src/keyboard.cpp:50
msgid "F4"
msgstr ""
#: src/keyboard.cpp:51
msgid "F5"
msgstr ""
#: src/keyboard.cpp:52
msgid "F6"
msgstr ""
#: src/keyboard.cpp:53
msgid "F7"
msgstr ""
#: src/keyboard.cpp:54
msgid "F8"
msgstr ""
#: src/keyboard.cpp:55
msgid "F9"
msgstr ""
#: src/keyboard.cpp:56
msgid "F10"
msgstr ""
#: src/keyboard.cpp:57
msgid "F11"
msgstr ""
#: src/keyboard.cpp:58
msgid "F12"
msgstr ""
#: src/keyboard.cpp:60
msgid "Print Screen"
msgstr ""
#: src/keyboard.cpp:61
msgid "Scroll Lock"
msgstr ""
#: src/keyboard.cpp:62
msgid "Pause"
msgstr ""
#: src/keyboard.cpp:64
msgid "Backspace"
msgstr ""
#: src/keyboard.cpp:65
msgid "Tab"
msgstr ""
#: src/keyboard.cpp:66
msgid "Caps Lock"
msgstr ""
#: src/keyboard.cpp:67
msgid "Return"
msgstr ""
#: src/keyboard.cpp:68
msgid "Space"
msgstr ""
#: src/keyboard.cpp:73
msgid "Menu"
msgstr ""
#: src/keyboard.cpp:75
msgid "Insert"
msgstr ""
#: src/keyboard.cpp:76
msgid "Delete"
msgstr ""
#: src/keyboard.cpp:77
msgid "Page Up"
msgstr ""
#: src/keyboard.cpp:78
msgid "Page Down"
msgstr ""
#: src/keyboard.cpp:79
msgid "Home"
msgstr ""
#: src/keyboard.cpp:80
msgid "End"
msgstr ""
#: src/keyboard.cpp:82
msgid "Left"
msgstr ""
#: src/keyboard.cpp:83
msgid "Up"
msgstr ""
#: src/keyboard.cpp:84
msgid "Right"
msgstr ""
#: src/keyboard.cpp:85
msgid "Down"
msgstr ""
#: src/keyboard.cpp:87
msgid "Num Lock"
msgstr ""

View File

@@ -0,0 +1,161 @@
msgid ""
msgstr ""
"Project-Id-Version: libZRColaUI\n"
"POT-Creation-Date: 2016-05-09 10:40+0200\n"
"PO-Revision-Date: 2016-05-09 10:40+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <info@amebis.si>\n"
"Language: sl_SI\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
"%100==4 ? 2 : 3);\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-KeywordsList: _\n"
#: src/keyboard.cpp:30 src/keyboard.cpp:72
msgid "Ctrl"
msgstr "Ctrl"
#: src/keyboard.cpp:31 src/keyboard.cpp:71
msgid "Alt"
msgstr "Alt"
#: src/keyboard.cpp:32 src/keyboard.cpp:70
msgid "Shift"
msgstr "Shift"
#: src/keyboard.cpp:45
msgid "Esc"
msgstr "Esc"
#: src/keyboard.cpp:47
msgid "F1"
msgstr "F1"
#: src/keyboard.cpp:48
msgid "F2"
msgstr "F2"
#: src/keyboard.cpp:49
msgid "F3"
msgstr "F3"
#: src/keyboard.cpp:50
msgid "F4"
msgstr "F4"
#: src/keyboard.cpp:51
msgid "F5"
msgstr "F5"
#: src/keyboard.cpp:52
msgid "F6"
msgstr "F6"
#: src/keyboard.cpp:53
msgid "F7"
msgstr "F7"
#: src/keyboard.cpp:54
msgid "F8"
msgstr "F8"
#: src/keyboard.cpp:55
msgid "F9"
msgstr "F9"
#: src/keyboard.cpp:56
msgid "F10"
msgstr "F10"
#: src/keyboard.cpp:57
msgid "F11"
msgstr "F11"
#: src/keyboard.cpp:58
msgid "F12"
msgstr "F12"
#: src/keyboard.cpp:60
msgid "Print Screen"
msgstr "Print Screen"
#: src/keyboard.cpp:61
msgid "Scroll Lock"
msgstr "Scroll Lock"
#: src/keyboard.cpp:62
msgid "Pause"
msgstr "Pause"
#: src/keyboard.cpp:64
msgid "Backspace"
msgstr "Backspace"
#: src/keyboard.cpp:65
msgid "Tab"
msgstr "Tab"
#: src/keyboard.cpp:66
msgid "Caps Lock"
msgstr "Caps Lock"
#: src/keyboard.cpp:67
msgid "Return"
msgstr "Return"
#: src/keyboard.cpp:68
msgid "Space"
msgstr "preslednica"
#: src/keyboard.cpp:73
msgid "Menu"
msgstr "Menu"
#: src/keyboard.cpp:75
msgid "Insert"
msgstr "Insert"
#: src/keyboard.cpp:76
msgid "Delete"
msgstr "Delete"
#: src/keyboard.cpp:77
msgid "Page Up"
msgstr "Page Up"
#: src/keyboard.cpp:78
msgid "Page Down"
msgstr "Page Down"
#: src/keyboard.cpp:79
msgid "Home"
msgstr "Home"
#: src/keyboard.cpp:80
msgid "End"
msgstr "End"
#: src/keyboard.cpp:82
msgid "Left"
msgstr "Left"
#: src/keyboard.cpp:83
msgid "Up"
msgstr "Up"
#: src/keyboard.cpp:84
msgid "Right"
msgstr "Right"
#: src/keyboard.cpp:85
msgid "Down"
msgstr "Down"
#: src/keyboard.cpp:87
msgid "Num Lock"
msgstr "Num Lock"

View File

@@ -18,3 +18,81 @@
*/
#include "stdafx.h"
bool ZRCola::keyseq_db::GetSequenceAsText(_In_count_(seq_len) const keyseq::key_t *seq, _In_ size_t seq_len, _Out_ wxString& str)
{
assert(seq || !seq_len);
str.Clear();
for (size_t i = 0; i < seq_len; i++) {
if (i) str += wxT(", ");
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::CTRL ) { str += _("Ctrl" ); str += wxT('+'); }
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::ALT ) { str += _("Alt" ); str += wxT('+'); }
if (seq[i].modifiers & ZRCola::keyseq_db::keyseq::SHIFT) { str += _("Shift"); str += wxT('+'); }
wchar_t k = seq[i].key;
#if defined(__WXMSW__)
// Translate from U.S. Keyboard to scan code.
static const HKL s_hkl = ::LoadKeyboardLayout(_T("00000409"), 0);
k = ::MapVirtualKeyEx(k, MAPVK_VK_TO_VSC, s_hkl);
// Translate from scan code to local keyboard.
k = ::MapVirtualKey(k, MAPVK_VSC_TO_VK);
#endif
switch (k) {
case 0 : return false;
case WXK_ESCAPE : str += _("Esc" ); break;
case WXK_F1 : str += _("F1" ); break;
case WXK_F2 : str += _("F2" ); break;
case WXK_F3 : str += _("F3" ); break;
case WXK_F4 : str += _("F4" ); break;
case WXK_F5 : str += _("F5" ); break;
case WXK_F6 : str += _("F6" ); break;
case WXK_F7 : str += _("F7" ); break;
case WXK_F8 : str += _("F8" ); break;
case WXK_F9 : str += _("F9" ); break;
case WXK_F10 : str += _("F10" ); break;
case WXK_F11 : str += _("F11" ); break;
case WXK_F12 : str += _("F12" ); break;
case WXK_PRINT : str += _("Print Screen"); break;
case WXK_SCROLL : str += _("Scroll Lock" ); break;
case WXK_PAUSE : str += _("Pause" ); break;
case WXK_BACK : str += _("Backspace" ); break;
case WXK_TAB : str += _("Tab" ); break;
case WXK_CAPITAL : str += _("Caps Lock" ); break;
case WXK_RETURN : str += _("Return" ); break;
case WXK_SPACE : str += _("Space" ); break;
case WXK_SHIFT : str += _("Shift" ); break;
case WXK_ALT : str += _("Alt" ); break;
case WXK_CONTROL : str += _("Ctrl" ); break;
case WXK_MENU : str += _("Menu" ); break;
case WXK_INSERT : str += _("Insert" ); break;
case WXK_DELETE : str += _("Delete" ); break;
case WXK_PAGEUP : str += _("Page Up" ); break;
case WXK_PAGEDOWN : str += _("Page Down" ); break;
case WXK_HOME : str += _("Home" ); break;
case WXK_END : str += _("End" ); break;
case WXK_LEFT : str += _("Left" ); break;
case WXK_UP : str += _("Up" ); break;
case WXK_RIGHT : str += _("Right" ); break;
case WXK_DOWN : str += _("Down" ); break;
case WXK_NUMLOCK : str += _("Num Lock" ); break;
default:
#if defined(__WXMSW__)
k = ::MapVirtualKey(k, MAPVK_VK_TO_CHAR);
#endif
str += k;
}
}
return true;
}

View File

@@ -23,4 +23,6 @@
#include "../include/zrcolaui/chargroup.h"
#include "../include/zrcolaui/keyboard.h"
#include <wx/translation.h>
#include <assert.h>

Binary file not shown.

View File

@@ -1,3 +1,4 @@
*/wxExtend.mo
*/libZRColaUI.mo
*/wxExtend11.mo
*/ZRCola.mo
*/ZRColaCompile.mo

View File

@@ -5,7 +5,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: ZRColaCompile 2.0-alpha6\n"
"X-Generator: ZRColaCompile 2.0-alpha7\n"
msgid "Albanian"
msgstr ""
@@ -238,6 +238,21 @@ msgstr ""
msgid "Letter z"
msgstr ""
msgid "Letter, Lowercase"
msgstr ""
msgid "Letter, Modifier"
msgstr ""
msgid "Letter, Other"
msgstr ""
msgid "Letter, Titlecase"
msgstr ""
msgid "Letter, Uppercase"
msgstr ""
msgid "Ligatures"
msgstr ""
@@ -250,6 +265,15 @@ msgstr ""
msgid "Maltese"
msgstr ""
msgid "Mark, Enclosing"
msgstr ""
msgid "Mark, Non-Spacing"
msgstr ""
msgid "Mark, Spacing Combining"
msgstr ""
msgid "Metric"
msgstr ""
@@ -295,12 +319,30 @@ msgstr ""
msgid "Number 9"
msgstr ""
msgid "Number, Decimal Digit"
msgstr ""
msgid "Number, Letter"
msgstr ""
msgid "Number, Other"
msgstr ""
msgid "Numbers"
msgstr ""
msgid "Numbers - Circled"
msgstr ""
msgid "Other, Control"
msgstr ""
msgid "Other, Format"
msgstr ""
msgid "Other, Surrogate"
msgstr ""
msgid "Parentheses"
msgstr ""
@@ -310,6 +352,27 @@ msgstr ""
msgid "Portuguese"
msgstr ""
msgid "Punctuation, Close"
msgstr ""
msgid "Punctuation, Connector"
msgstr ""
msgid "Punctuation, Dash"
msgstr ""
msgid "Punctuation, Final quote"
msgstr ""
msgid "Punctuation, Initial quote"
msgstr ""
msgid "Punctuation, Open"
msgstr ""
msgid "Punctuation, Other"
msgstr ""
msgid "Quotes"
msgstr ""
@@ -319,6 +382,15 @@ msgstr ""
msgid "Russian"
msgstr ""
msgid "Separator, Line"
msgstr ""
msgid "Separator, Paragraph"
msgstr ""
msgid "Separator, Space"
msgstr ""
msgid "Serbian Cyrillic"
msgstr ""
@@ -385,6 +457,18 @@ msgstr ""
msgid "Symbol ?"
msgstr ""
msgid "Symbol, Currency"
msgstr ""
msgid "Symbol, Math"
msgstr ""
msgid "Symbol, Modifier"
msgstr ""
msgid "Symbol, Other"
msgstr ""
msgid "Turkish"
msgstr ""

Binary file not shown.

View File

@@ -245,6 +245,21 @@ msgstr "Črka y"
msgid "Letter z"
msgstr "Črka z"
msgid "Letter, Lowercase"
msgstr "Črka, mala"
msgid "Letter, Modifier"
msgstr "Črka, spreminjevalo"
msgid "Letter, Other"
msgstr "Črka, drugo"
msgid "Letter, Titlecase"
msgstr "Črka, naslovna"
msgid "Letter, Uppercase"
msgstr "Črka, velika"
msgid "Ligatures"
msgstr "Ligature"
@@ -257,6 +272,15 @@ msgstr "makedonščina"
msgid "Maltese"
msgstr "malteščina"
msgid "Mark, Enclosing"
msgstr "Ločevalo, obdajajoča"
msgid "Mark, Non-Spacing"
msgstr "Ločevalo, neločljivo"
msgid "Mark, Spacing Combining"
msgstr "Ločevalo, ločljivo"
msgid "Metric"
msgstr "Metrično"
@@ -302,12 +326,30 @@ msgstr "Številka 8"
msgid "Number 9"
msgstr "Številka 9"
msgid "Number, Decimal Digit"
msgstr "Številka, desetiška števka"
msgid "Number, Letter"
msgstr "Številka, črka"
msgid "Number, Other"
msgstr "Številka, drugo"
msgid "Numbers"
msgstr "Številke"
msgid "Numbers - Circled"
msgstr "Številke - obkroženo"
msgid "Other, Control"
msgstr "Drugo, kontrolni"
msgid "Other, Format"
msgstr "Drugo, oblikovni"
msgid "Other, Surrogate"
msgstr "Drugo, nadomestni"
msgid "Parentheses"
msgstr "Oklepaji"
@@ -317,6 +359,27 @@ msgstr "poljščina"
msgid "Portuguese"
msgstr "portugalščina"
msgid "Punctuation, Close"
msgstr "Ločilo, zapiralno"
msgid "Punctuation, Connector"
msgstr "Ločilo, povezaj"
msgid "Punctuation, Dash"
msgstr "Ločilo, pomišljaj"
msgid "Punctuation, Final quote"
msgstr "Ločilo, zaključni narekovaj"
msgid "Punctuation, Initial quote"
msgstr "Ločilo, uvodni narekovaj"
msgid "Punctuation, Open"
msgstr "Ločilo, odpiralno"
msgid "Punctuation, Other"
msgstr "Ločilo, drugo"
msgid "Quotes"
msgstr "Narekovaji"
@@ -326,6 +389,15 @@ msgstr "romunščina"
msgid "Russian"
msgstr "ruščina"
msgid "Separator, Line"
msgstr "Ločilo, vrstic"
msgid "Separator, Paragraph"
msgstr "Ločilo, odstavkov"
msgid "Separator, Space"
msgstr "Ločilo, presledek"
msgid "Serbian Cyrillic"
msgstr "srbščina cirilica"
@@ -392,6 +464,18 @@ msgstr "Simbol >"
msgid "Symbol ?"
msgstr "Simbol ?"
msgid "Symbol, Currency"
msgstr "Simbol, valuta"
msgid "Symbol, Math"
msgstr "Simbol, matematični"
msgid "Symbol, Modifier"
msgstr "Simbol, ločevalo"
msgid "Symbol, Other"
msgstr "Simbol, drugo"
msgid "Turkish"
msgstr "turščina"