Compare commits

..

20 Commits

Author SHA1 Message Date
Simon Rozman
5a2fcf7cb2 Version set to 2.0-alpha5. 2016-04-13 11:05:09 +02:00
Simon Rozman
4fba54bdb2 Text language for decomposition GUI support added
(closes #1)
2016-04-13 11:03:38 +02:00
Simon Rozman
ab3ef08a5f Translation database moved to ZRColaApp 2016-04-12 14:47:14 +02:00
Simon Rozman
c21e1b8198 Sub-module update 2016-04-11 13:53:08 +02:00
Simon Rozman
7e6eaefd42 Doxygen annotation update 2016-04-11 13:52:57 +02:00
Simon Rozman
f735bd5bee Decomposition can omit language specific characters now 2016-04-11 13:28:19 +02:00
Simon Rozman
b7f3305019 ZRCola::langid_t moved to common.h 2016-04-11 12:51:49 +02:00
Simon Rozman
b194662c03 Typo in documentation fixed 2016-04-11 12:41:40 +02:00
Simon Rozman
177edd19e8 Languages and language-specific characters added to the database 2016-04-11 12:41:22 +02:00
Simon Rozman
fc93474b9a Characters with decompositions starting with # do not decompose any more. 2016-04-11 10:21:11 +02:00
Simon Rozman
02f164cee6 Version set to 2.0-alpha4 2016-04-08 14:54:18 +02:00
Simon Rozman
a35c0d83ca Merge branch 'master' of https://github.com/Amebis/ZRCola 2016-04-08 14:49:47 +02:00
Simon Rozman
6b4ed23801 ZRCola database updated
(resolves #7)
2016-04-08 14:49:27 +02:00
Simon Rozman
2c602ad659 ZRCola database updated 2016-04-08 14:48:23 +02:00
Simon Rozman
279537b1f3 Combinations with partial longer match not composed issue resolved
(resolves #6)
2016-04-08 14:45:28 +02:00
Simon Rozman
f918c49bfd Accessing an element of table before determining size issue resolved 2016-04-08 13:48:33 +02:00
Simon Rozman
72c29a692e GUI aligned with stock text 2016-04-08 13:22:23 +02:00
Simon Rozman
fc78a650a2 Select All (text) feature added 2016-04-08 13:01:09 +02:00
Simon Rozman
acec7098e5 Minor GUI improvements 2016-04-08 12:44:35 +02:00
Simon Rozman
98eff47054 Clipboard events are forwarded to focused control now
(resolves #12)
2016-04-08 12:35:38 +02:00
29 changed files with 1523 additions and 213 deletions

View File

@@ -141,7 +141,7 @@
<property name="bitmap"></property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help"></property>
<property name="help">Quit this program</property>
<property name="id">wxID_EXIT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">E&amp;xit</property>
@@ -161,13 +161,13 @@
<property name="bitmap">Load From Icon Resource; edit_cut.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Cuts selected text and puts it on the clipboard</property>
<property name="help"></property>
<property name="id">wxID_CUT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Cut</property>
<property name="label"></property>
<property name="name">m_menuItemEditCut</property>
<property name="permission">none</property>
<property name="shortcut">Ctrl+X</property>
<property name="shortcut"></property>
<property name="unchecked_bitmap"></property>
<event name="OnMenuSelection"></event>
<event name="OnUpdateUI"></event>
@@ -176,13 +176,13 @@
<property name="bitmap">Load From Icon Resource; edit_copy.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Copies selected text to the clipboard</property>
<property name="help"></property>
<property name="id">wxID_COPY</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Copy</property>
<property name="label"></property>
<property name="name">m_menuItemEditCopy</property>
<property name="permission">none</property>
<property name="shortcut">Ctrl+C</property>
<property name="shortcut"></property>
<property name="unchecked_bitmap"></property>
<event name="OnMenuSelection"></event>
<event name="OnUpdateUI"></event>
@@ -191,13 +191,13 @@
<property name="bitmap">Load From Icon Resource; edit_paste.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Inserts text from the clipboard</property>
<property name="help"></property>
<property name="id">wxID_PASTE</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Paste</property>
<property name="label"></property>
<property name="name">m_menuItemEditPaste</property>
<property name="permission">none</property>
<property name="shortcut">Ctrl+V</property>
<property name="shortcut"></property>
<property name="unchecked_bitmap"></property>
<event name="OnMenuSelection"></event>
<event name="OnUpdateUI"></event>
@@ -206,11 +206,30 @@
<property name="name">m_separatorEdit1</property>
<property name="permission">none</property>
</object>
<object class="wxMenuItem" expanded="1">
<property name="bitmap"></property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Select all text</property>
<property name="id">wxID_SELECTALL</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Select &amp;All</property>
<property name="name">m_menuSelectAll</property>
<property name="permission">none</property>
<property name="shortcut">Ctrl+A</property>
<property name="unchecked_bitmap"></property>
<event name="OnMenuSelection"></event>
<event name="OnUpdateUI"></event>
</object>
<object class="separator" expanded="1">
<property name="name">m_separatorEdit2</property>
<property name="permission">none</property>
</object>
<object class="wxMenuItem" expanded="1">
<property name="bitmap">Load From Icon Resource; send_composed.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Sends composed text to source window</property>
<property name="help">Send composed text to source window</property>
<property name="id">wxID_SEND_COMPOSED</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;Send Composed</property>
@@ -225,7 +244,7 @@
<property name="bitmap">Load From Icon Resource; send_decomposed.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Sends decomposed text to source window</property>
<property name="help">Send decomposed text to source window</property>
<property name="id">wxID_SEND_DECOMPOSED</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Send &amp;Decomposed</property>
@@ -240,7 +259,7 @@
<property name="bitmap">Load From Icon Resource; send_abort.ico; [16; 16]</property>
<property name="checked">0</property>
<property name="enabled">1</property>
<property name="help">Aborts composition and returns focus to source window</property>
<property name="help">Abort composition and return focus to source window</property>
<property name="id">wxID_SEND_ABORT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">Abort (De)composition</property>
@@ -251,6 +270,12 @@
<event name="OnMenuSelection"></event>
<event name="OnUpdateUI"></event>
</object>
<object class="submenu" expanded="1">
<property name="bitmap"></property>
<property name="label">&amp;Language</property>
<property name="name">m_menuDecompLanguage</property>
<property name="permission">protected</property>
</object>
</object>
<object class="wxMenu" expanded="1">
<property name="label">&amp;Help</property>
@@ -263,7 +288,7 @@
<property name="help"></property>
<property name="id">wxID_ABOUT</property>
<property name="kind">wxITEM_NORMAL</property>
<property name="label">&amp;About</property>
<property name="label"></property>
<property name="name">m_menuItemAbout</property>
<property name="permission">none</property>
<property name="shortcut"></property>
@@ -284,7 +309,7 @@
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmapsize"></property>
<property name="bitmapsize">16,16</property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
@@ -360,7 +385,7 @@
<property name="label">Cut</property>
<property name="name">m_toolEditCut</property>
<property name="permission">protected</property>
<property name="statusbar">Cuts selected text and puts it on the clipboard</property>
<property name="statusbar">Cut selection</property>
<property name="tooltip">Cut</property>
<event name="OnAuiToolBarBeginDrag"></event>
<event name="OnAuiToolBarMiddleClick"></event>
@@ -381,7 +406,7 @@
<property name="label">Copy</property>
<property name="name">m_toolEditCopy</property>
<property name="permission">protected</property>
<property name="statusbar">Copies selected text to the clipboard</property>
<property name="statusbar">Copy selection</property>
<property name="tooltip">Copy</property>
<event name="OnAuiToolBarBeginDrag"></event>
<event name="OnAuiToolBarMiddleClick"></event>
@@ -402,7 +427,7 @@
<property name="label">Paste</property>
<property name="name">m_toolEditPaste</property>
<property name="permission">protected</property>
<property name="statusbar">Inserts text from the clipboard</property>
<property name="statusbar">Paste selection</property>
<property name="tooltip">Paste</property>
<event name="OnAuiToolBarBeginDrag"></event>
<event name="OnAuiToolBarMiddleClick"></event>
@@ -426,7 +451,7 @@
<property name="label">Send Composed</property>
<property name="name">m_toolSendComposed</property>
<property name="permission">protected</property>
<property name="statusbar">Sends composed text to source window</property>
<property name="statusbar">Send composed text to source window</property>
<property name="tooltip">Send Composed</property>
<event name="OnAuiToolBarBeginDrag"></event>
<event name="OnAuiToolBarMiddleClick"></event>
@@ -447,7 +472,7 @@
<property name="label">Send Decomposed</property>
<property name="name">m_toolSendDecomposed</property>
<property name="permission">protected</property>
<property name="statusbar">Sends decomposed text to source window</property>
<property name="statusbar">Send decomposed text to source window</property>
<property name="tooltip">Send Decomposed</property>
<event name="OnAuiToolBarBeginDrag"></event>
<event name="OnAuiToolBarMiddleClick"></event>
@@ -460,6 +485,167 @@
<event name="OnToolRClicked"></event>
<event name="OnUpdateUI"></event>
</object>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Language:</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_toolDecompLanguageLbl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_RIGHT</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
<object class="wxChoice" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices"></property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_toolDecompLanguage</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnChoice">OnDecompLanguageChoice</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>

View File

@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRCola\n"
"POT-Creation-Date: 2016-04-06 12:31+0200\n"
"PO-Revision-Date: 2016-04-06 12:31+0200\n"
"POT-Creation-Date: 2016-04-13 10:50+0200\n"
"PO-Revision-Date: 2016-04-13 10:50+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,7 +17,12 @@ msgstr ""
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: zrcolafrm.cpp:56
#: zrcolafrm.cpp:69
#, c-format
msgid "Select %s language for decomposition"
msgstr "Izberi jezik %s za razstavljanje"
#: zrcolafrm.cpp:81
msgid ""
"ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality "
"will not be available."
@@ -25,11 +30,11 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F5 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:56 zrcolafrm.cpp:58
#: zrcolafrm.cpp:81 zrcolafrm.cpp:83
msgid "Warning"
msgstr "Opozorilo"
#: zrcolafrm.cpp:58
#: zrcolafrm.cpp:83
msgid ""
"ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality "
"will not be available."
@@ -37,7 +42,7 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F6 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:119
#: zrcolafrm.cpp:205
#, c-format
msgid ""
"ZRCola v%s\n"
@@ -46,7 +51,7 @@ msgstr ""
"ZRCola v%s\n"
"Vse pravice pridržane 2015-%s Amebis"
#: zrcolafrm.cpp:119
#: zrcolafrm.cpp:205
msgid "About ZRCola"
msgstr "O ZRColi"
@@ -54,87 +59,95 @@ msgstr "O ZRColi"
msgid "E&xit"
msgstr "I&zhod"
#: zrcolagui.cpp:32
msgid "Quit this program"
msgstr "Zapri ta program"
#: zrcolagui.cpp:35
msgid "&Program"
msgstr "&Program"
#: zrcolagui.cpp:39 zrcolagui.cpp:106
msgid "Cut"
msgstr "Izreži"
#: zrcolagui.cpp:39 zrcolagui.cpp:106
msgid "Cuts selected text and puts it on the clipboard"
msgstr "Izreže izbrano besedilo in ga shrani na odložišče"
#: zrcolagui.cpp:48
msgid "&Copy"
msgstr "&Kopiraj"
#: zrcolagui.cpp:48 zrcolagui.cpp:108
msgid "Copies selected text to the clipboard"
msgstr "Kopira izbrano besedilo na odložišče"
#: zrcolagui.cpp:57
msgid "&Paste"
msgstr "&Prilepi"
#: zrcolagui.cpp:57 zrcolagui.cpp:110
msgid "Inserts text from the clipboard"
msgstr "Vstavi besedilo z odložišča"
#: zrcolagui.cpp:68
msgid "Select &All"
msgstr "Izberi &vse"
#: zrcolagui.cpp:68
msgid "Select all text"
msgstr "Izberi celotno besedilo"
#: zrcolagui.cpp:74
msgid "&Send Composed"
msgstr "Pošlji &sestavljeno"
#: zrcolagui.cpp:68 zrcolagui.cpp:114
msgid "Sends composed text to source window"
msgstr "Pošlje sestavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:74 zrcolagui.cpp:125
msgid "Send composed text to source window"
msgstr "Pošlji sestavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:77
#: zrcolagui.cpp:83
msgid "Send &Decomposed"
msgstr "Pošlji &razstavljeno"
#: zrcolagui.cpp:77 zrcolagui.cpp:116
msgid "Sends decomposed text to source window"
msgstr "Pošlje razstavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:83 zrcolagui.cpp:127
msgid "Send decomposed text to source window"
msgstr "Pošlji razstavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:86
#: zrcolagui.cpp:92
msgid "Abort (De)composition"
msgstr "Prekini raz/sestavljanje"
#: zrcolagui.cpp:86
msgid "Aborts composition and returns focus to source window"
msgstr "Prekine sestavljanje in vrne fokus nazaj izvornemu oknu"
#: zrcolagui.cpp:92
msgid "Abort composition and return focus to source window"
msgstr "Prekini sestavljanje in vrni fokus nazaj izvornemu oknu"
#: zrcolagui.cpp:94
#: zrcolagui.cpp:101
msgid "&Language"
msgstr "&Jezik"
#: zrcolagui.cpp:104
msgid "&Edit"
msgstr "Ur&edi"
#: zrcolagui.cpp:98
msgid "&About"
msgstr "O progr&amu"
#: zrcolagui.cpp:101
#: zrcolagui.cpp:111
msgid "&Help"
msgstr "&Pomoč"
#: zrcolagui.cpp:108
#: zrcolagui.cpp:117
msgid "Cut"
msgstr "Izreži"
#: zrcolagui.cpp:117
msgid "Cut selection"
msgstr "Izreži izbor"
#: zrcolagui.cpp:119
msgid "Copy"
msgstr "Kopiraj"
#: zrcolagui.cpp:110
#: zrcolagui.cpp:119
msgid "Copy selection"
msgstr "Kopiraj izbor"
#: zrcolagui.cpp:121
msgid "Paste"
msgstr "Prilepi"
#: zrcolagui.cpp:114
#: zrcolagui.cpp:121
msgid "Paste selection"
msgstr "Prilepi izbor"
#: zrcolagui.cpp:125
msgid "Send Composed"
msgstr "Pošlji sestavljeno"
#: zrcolagui.cpp:116
#: zrcolagui.cpp:127
msgid "Send Decomposed"
msgstr "Pošlji razstavljeno"
#: zrcolagui.h:64 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: zrcolagui.cpp:129
msgid "Language:"
msgstr "Jezik:"
#: zrcolagui.h:73 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
@@ -156,6 +169,24 @@ msgstr "1250"
msgid "Input system for linguistic use"
msgstr "Vnašalni sistem za jezikoslovno rabo"
#~ msgid "&About"
#~ msgstr "O progr&amu"
#~ msgid "Cuts selected text and puts it on the clipboard"
#~ msgstr "Izreže izbrano besedilo in ga shrani na odložišče"
#~ msgid "Copies selected text to the clipboard"
#~ msgstr "Kopira izbrano besedilo na odložišče"
#~ msgid "Inserts text from the clipboard"
#~ msgstr "Vstavi besedilo z odložišča"
#~ msgid "&Copy"
#~ msgstr "&Kopiraj"
#~ msgid "&Paste"
#~ msgstr "&Prilepi"
#~ msgid "&File"
#~ msgstr "&Datoteka"

View File

@@ -62,8 +62,57 @@ bool ZRColaApp::OnInit()
wxVERIFY(m_locale.AddCatalog(wxT("ZRCola")));
}
std::fstream dat((LPCTSTR)GetDatabasePath(), std::ios_base::in | std::ios_base::binary);
if (dat.good()) {
if (stdex::idrec::find<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dat, ZRCOLA_DB_ID, sizeof(ZRCola::recordid_t))) {
ZRCola::recordsize_t size;
dat.read((char*)&size, sizeof(ZRCola::recordsize_t));
if (dat.good()) {
bool has_translation_data = false;
for (;;) {
ZRCola::recordid_t id;
if (!stdex::idrec::read_id(dat, id, size)) break;
if (id == ZRCola::translation_rec::id) {
dat >> ZRCola::translation_rec(m_t_db);
if (dat.good()) {
has_translation_data = true;
} else {
wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb."));
m_t_db.idxComp .clear();
m_t_db.idxDecomp.clear();
m_t_db.data .clear();
}
} else if (id == ZRCola::langchar_rec::id) {
dat >> ZRCola::langchar_rec(m_lc_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb."));
m_lc_db.idxChr.clear();
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
m_lc_db.idxLng.clear();
#endif
m_lc_db.data .clear();
}
} else if (id == ZRCola::language_rec::id) {
dat >> ZRCola::language_rec(m_lang_db);
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb."));
m_lang_db.idxLng.clear();
m_lang_db.data .clear();
}
}
}
if (!has_translation_data)
wxFAIL_MSG(wxT("ZRCola.zrcdb has no translation data."));
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database."));
}
wxZRColaFrame* mainFrame = new wxZRColaFrame();
wxPersistentRegisterAndRestore<wxTopLevelWindow>(mainFrame);
wxPersistentRegisterAndRestore<wxZRColaFrame>(mainFrame);
mainFrame->Show();
return true;

View File

@@ -28,6 +28,8 @@ class ZRColaApp;
#include <wx/app.h>
#include <wx/config.h>
#include <wx/intl.h>
#include <zrcola/language.h>
#include <zrcola/translate.h>
///
@@ -42,8 +44,8 @@ public:
/// Called when application initializes.
///
/// \returns
/// - true if initialization succeeded
/// - false otherwise
/// - \c true if initialization succeeded
/// - \c false otherwise
///
virtual bool OnInit();
@@ -54,6 +56,11 @@ public:
inline wxString GetDatabasePath() const;
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
protected:
wxLocale m_locale; ///< Current locale
};

View File

@@ -30,28 +30,6 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_selComposed(0, 0),
wxZRColaComposerPanelBase(parent)
{
std::fstream dat((LPCTSTR)((ZRColaApp*)wxTheApp)->GetDatabasePath(), std::ios_base::in | std::ios_base::binary);
if (dat.good()) {
if (stdex::idrec::find<ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>(dat, ZRCOLA_DB_ID, sizeof(ZRCola::recordid_t))) {
ZRCola::recordsize_t size;
dat.read((char*)&size, sizeof(ZRCola::recordsize_t));
if (dat.good()) {
ZRCola::translation_rec rec(m_t_db);
if (rec.find(dat, size)) {
dat >> rec;
if (!dat.good()) {
wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb."));
m_t_db.idxComp .clear();
m_t_db.idxDecomp.clear();
m_t_db.data .clear();
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb has no translation data."));
}
} else
wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database."));
}
m_decomposed->PushEventHandler(&m_keyhandler);
}
@@ -94,7 +72,7 @@ void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
#endif
std::wstring dst;
m_t_db.Compose(src.data(), src.size(), dst, &m_mapping);
((ZRColaApp*)wxTheApp)->m_t_db.Compose(src.data(), src.size(), dst, &m_mapping);
long from, to;
m_decomposed->GetSelection(&from, &to);
@@ -140,8 +118,13 @@ void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
wxString src(m_composed->GetValue());
#endif
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::wstring dst;
m_t_db.Decompose(src.data(), src.size(), dst, &m_mapping);
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), src.size(), &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping);
else
app->m_t_db.Decompose(src.data(), src.size(), dst, &m_mapping);
long from, to;
m_composed->GetSelection(&from, &to);

View File

@@ -27,7 +27,6 @@ class wxZRColaComposerPanel;
#include "zrcolagui.h"
#include "zrcolakeyhndlr.h"
#include <zrcola/translate.h>
#include <utility>
@@ -49,7 +48,6 @@ protected:
virtual void OnComposedText(wxCommandEvent& event);
protected:
ZRCola::translation_db m_t_db; ///< Translation database
bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls
ZRCola::mapping_vector m_mapping; ///< Character index mapping vector between composed and decomposed text
std::pair<long, long>

View File

@@ -25,13 +25,21 @@
//////////////////////////////////////////////////////////////////////////
wxBEGIN_EVENT_TABLE(wxZRColaFrame, wxZRColaFrameBase)
EVT_UPDATE_UI_RANGE(wxID_SEND_COMPOSED, wxID_SEND_ABORT, wxZRColaFrame::OnSendUpdate)
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_EXIT , wxZRColaFrame::OnExit )
EVT_MENU(wxID_ABOUT , wxZRColaFrame::OnAbout )
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_MENU(wxID_EXIT , wxZRColaFrame::OnExit )
EVT_MENU(wxID_ABOUT, wxZRColaFrame::OnAbout)
wxEND_EVENT_TABLE()
@@ -49,6 +57,23 @@ wxZRColaFrame::wxZRColaFrame() :
SetIcon(wxICON(00_zrcola.ico));
#endif
// Populate language lists.
memcpy(m_lang, ZRCOLA_LANG_VOID, sizeof(m_lang));
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
m_toolDecompLanguage->Clear();
if (!app->m_lang_db.idxLng.empty()) {
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(wxString::FromAscii(lang.id, strnlen(lang.id, sizeof(lang.id))));
if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1)
m_menuDecompLanguage->Insert(i, wxID_DECOMP_LANGUAGE_START + i, label, wxString::Format(_("Select %s language for decomposition"), (const wxStringCharType*)label), wxITEM_RADIO);
m_toolDecompLanguage->Insert(label, i);
if (memcmp(m_lang, lang.id, sizeof(m_lang)) == 0)
m_toolDecompLanguage->Select(i);
}
}
// Set focus.
m_panel->m_decomposed->SetFocus();
// Register global hotkey(s).
@@ -67,6 +92,26 @@ wxZRColaFrame::~wxZRColaFrame()
}
void wxZRColaFrame::OnForwardEventUpdate(wxUpdateUIEvent& event)
{
wxControl *focusWnd = wxDynamicCast(FindFocus(), wxControl);
if (focusWnd && !m_toolbar->IsDescendant(focusWnd))
focusWnd->GetEventHandler()->ProcessEvent(event);
else
event.Enable(false);
}
void wxZRColaFrame::OnForwardEvent(wxCommandEvent& event)
{
wxControl *focusWnd = wxDynamicCast(FindFocus(), wxControl);
if (focusWnd)
focusWnd->GetEventHandler()->ProcessEvent(event);
else
event.Skip();
}
void wxZRColaFrame::OnSendUpdate(wxUpdateUIEvent& event)
{
event.Enable(m_hWndSource ? true : false);
@@ -108,6 +153,47 @@ void wxZRColaFrame::OnSendAbort(wxCommandEvent& event)
}
void wxZRColaFrame::OnDecomposedLanguageUpdate(wxUpdateUIEvent& 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);
}
void wxZRColaFrame::OnDecomposedLanguage(wxCommandEvent& 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 (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);
}
}
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);
}
}
void wxZRColaFrame::OnExit(wxCommandEvent& event)
{
Close();
@@ -199,3 +285,47 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
} else
return wxZRColaFrameBase::MSWWindowProc(message, wParam, lParam);
}
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaFrame
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersistentTLW(wnd)
{
}
void wxPersistentZRColaFrame::Save() const
{
//
const wxZRColaFrame * const wnd = static_cast<const wxZRColaFrame*>(GetWindow());
SaveValue(wxT("lang"), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang)));
wxPersistentTLW::Save();
}
bool wxPersistentZRColaFrame::Restore()
{
const bool r = wxPersistentTLW::Restore();
wxZRColaFrame * const wnd = static_cast<wxZRColaFrame*>(GetWindow());
wxString lang;
if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
memcpy(wnd->m_lang, (const char*)lang.c_str(), sizeof(wnd->m_lang));
wnd->m_toolDecompLanguage->SetStringSelection(wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang)));
} else {
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
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));
wnd->m_toolDecompLanguage->Select(0);
} else {
memcpy(wnd->m_lang, ZRCOLA_LANG_VOID, sizeof(wnd->m_lang));
}
}
return r;
}

View File

@@ -27,6 +27,8 @@ class wxZRColaFrame;
#pragma once
#include "zrcolagui.h"
#include <zrcola/language.h>
#include <wx/persist/toplevel.h>
///
@@ -42,18 +44,32 @@ class wxZRColaFrame;
class wxZRColaFrame : public wxZRColaFrameBase
{
public:
enum
{
wxID_DECOMP_LANGUAGE_START = 6000,
wxID_DECOMP_LANGUAGE_END = 6099,
};
wxZRColaFrame();
virtual ~wxZRColaFrame();
protected:
void OnForwardEventUpdate(wxUpdateUIEvent& event);
void OnForwardEvent(wxCommandEvent& event);
void OnSendUpdate(wxUpdateUIEvent& event);
void OnSendComposed(wxCommandEvent& event);
void OnSendDecomposed(wxCommandEvent& event);
void OnSendAbort(wxCommandEvent& event);
void OnDecomposedLanguageUpdate(wxUpdateUIEvent& event);
void OnDecomposedLanguage(wxCommandEvent& event);
virtual void OnDecompLanguageChoice(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
friend class wxPersistentZRColaFrame;
friend class wxZRColaComposerPanel;
private:
void DoSend(const wxString& str);
@@ -61,5 +77,25 @@ protected:
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
protected:
ZRCola::langid_t m_lang; ///< Language for decomposing
WXHWND m_hWndSource; ///< handle of the active window, when the ZRCola hotkey was pressed
};
///
/// Supports saving/restoring wxZRColaFrame GUI state
///
class wxPersistentZRColaFrame : public wxPersistentTLW
{
public:
wxPersistentZRColaFrame(wxZRColaFrame *wnd);
virtual void Save() const;
virtual bool Restore();
};
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaFrame *wnd)
{
return new wxPersistentZRColaFrame(wnd);
}

View File

@@ -29,14 +29,14 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menubar = new wxMenuBar( 0 );
m_menuProgram = new wxMenu();
wxMenuItem* m_menuItemExit;
m_menuItemExit = new wxMenuItem( m_menuProgram, wxID_EXIT, wxString( _("E&xit") ) + wxT('\t') + wxT("Alt+F4"), wxEmptyString, wxITEM_NORMAL );
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 );
m_menubar->Append( m_menuProgram, _("&Program") );
m_menuEdit = new wxMenu();
wxMenuItem* m_menuItemEditCut;
m_menuItemEditCut = new wxMenuItem( m_menuEdit, wxID_CUT, wxString( _("Cut") ) + wxT('\t') + wxT("Ctrl+X"), _("Cuts selected text and puts it on the clipboard"), wxITEM_NORMAL );
m_menuItemEditCut = new wxMenuItem( m_menuEdit, wxID_CUT, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuItemEditCut->SetBitmaps( wxIcon( wxT("edit_cut.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -45,7 +45,7 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->Append( m_menuItemEditCut );
wxMenuItem* m_menuItemEditCopy;
m_menuItemEditCopy = new wxMenuItem( m_menuEdit, wxID_COPY, wxString( _("&Copy") ) + wxT('\t') + wxT("Ctrl+C"), _("Copies selected text to the clipboard"), wxITEM_NORMAL );
m_menuItemEditCopy = new wxMenuItem( m_menuEdit, wxID_COPY, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuItemEditCopy->SetBitmaps( wxIcon( wxT("edit_copy.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -54,7 +54,7 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->Append( m_menuItemEditCopy );
wxMenuItem* m_menuItemEditPaste;
m_menuItemEditPaste = new wxMenuItem( m_menuEdit, wxID_PASTE, wxString( _("&Paste") ) + wxT('\t') + wxT("Ctrl+V"), _("Inserts text from the clipboard"), wxITEM_NORMAL );
m_menuItemEditPaste = new wxMenuItem( m_menuEdit, wxID_PASTE, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuItemEditPaste->SetBitmaps( wxIcon( wxT("edit_paste.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -64,8 +64,14 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->AppendSeparator();
wxMenuItem* m_menuSelectAll;
m_menuSelectAll = new wxMenuItem( m_menuEdit, wxID_SELECTALL, wxString( _("Select &All") ) + wxT('\t') + wxT("Ctrl+A"), _("Select all text"), wxITEM_NORMAL );
m_menuEdit->Append( m_menuSelectAll );
m_menuEdit->AppendSeparator();
wxMenuItem* m_menuItemSendComposed;
m_menuItemSendComposed = new wxMenuItem( m_menuEdit, wxID_SEND_COMPOSED, wxString( _("&Send Composed") ) + wxT('\t') + wxT("F5"), _("Sends composed text to source window"), wxITEM_NORMAL );
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__
m_menuItemSendComposed->SetBitmaps( wxIcon( wxT("send_composed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -74,7 +80,7 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->Append( m_menuItemSendComposed );
wxMenuItem* m_menuItemSendDecomposed;
m_menuItemSendDecomposed = new wxMenuItem( m_menuEdit, wxID_SEND_DECOMPOSED, wxString( _("Send &Decomposed") ) + wxT('\t') + wxT("F6"), _("Sends decomposed text to source window"), wxITEM_NORMAL );
m_menuItemSendDecomposed = new wxMenuItem( m_menuEdit, wxID_SEND_DECOMPOSED, wxString( _("Send &Decomposed") ) + wxT('\t') + wxT("F6"), _("Send decomposed text to source window"), wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuItemSendDecomposed->SetBitmaps( wxIcon( wxT("send_decomposed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -83,7 +89,7 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_menuEdit->Append( m_menuItemSendDecomposed );
wxMenuItem* m_menuItemSendAbort;
m_menuItemSendAbort = new wxMenuItem( m_menuEdit, wxID_SEND_ABORT, wxString( _("Abort (De)composition") ) + wxT('\t') + wxT("Esc"), _("Aborts composition and returns focus to source window"), wxITEM_NORMAL );
m_menuItemSendAbort = new wxMenuItem( m_menuEdit, wxID_SEND_ABORT, wxString( _("Abort (De)composition") ) + wxT('\t') + wxT("Esc"), _("Abort composition and return focus to source window"), wxITEM_NORMAL );
#ifdef __WXMSW__
m_menuItemSendAbort->SetBitmaps( wxIcon( wxT("send_abort.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 16, 16 ) );
#elif (defined( __WXGTK__ ) || defined( __WXOSX__ ))
@@ -91,30 +97,42 @@ 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 );
m_menuEdit->Append( m_menuDecompLanguageItem );
m_menubar->Append( m_menuEdit, _("&Edit") );
m_menuHelp = new wxMenu();
wxMenuItem* m_menuItemAbout;
m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( _("&About") ) , wxEmptyString, wxITEM_NORMAL );
m_menuItemAbout = new wxMenuItem( m_menuHelp, wxID_ABOUT, wxString( wxEmptyString ) , wxEmptyString, wxITEM_NORMAL );
m_menuHelp->Append( m_menuItemAbout );
m_menubar->Append( m_menuHelp, _("&Help") );
this->SetMenuBar( m_menubar );
m_toolbar = this->CreateToolBar( wxTB_HORIZONTAL, wxID_ANY );
m_toolEditCut = m_toolbar->AddTool( wxID_CUT, _("Cut"), wxIcon( wxT("edit_cut.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Cut"), _("Cuts selected text and puts it on the clipboard"), NULL );
m_toolbar = this->CreateToolBar( wxTB_HORIZONTAL, wxID_ANY );
m_toolbar->SetToolBitmapSize( wxSize( 16,16 ) );
m_toolEditCut = m_toolbar->AddTool( wxID_CUT, _("Cut"), wxIcon( wxT("edit_cut.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Cut"), _("Cut selection"), NULL );
m_toolEditCopy = m_toolbar->AddTool( wxID_COPY, _("Copy"), wxIcon( wxT("edit_copy.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Copy"), _("Copies selected text to the clipboard"), NULL );
m_toolEditCopy = m_toolbar->AddTool( wxID_COPY, _("Copy"), wxIcon( wxT("edit_copy.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Copy"), _("Copy selection"), NULL );
m_toolEditPaste = m_toolbar->AddTool( wxID_PASTE, _("Paste"), wxIcon( wxT("edit_paste.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Paste"), _("Inserts text from the clipboard"), NULL );
m_toolEditPaste = m_toolbar->AddTool( wxID_PASTE, _("Paste"), wxIcon( wxT("edit_paste.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Paste"), _("Paste selection"), NULL );
m_toolbar->AddSeparator();
m_toolSendComposed = m_toolbar->AddTool( wxID_SEND_COMPOSED, _("Send Composed"), wxIcon( wxT("send_composed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Send Composed"), _("Sends composed text to source window"), NULL );
m_toolSendComposed = m_toolbar->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_toolbar->AddTool( wxID_SEND_DECOMPOSED, _("Send Decomposed"), wxIcon( wxT("send_decomposed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Send Decomposed"), _("Sends decomposed text to source window"), NULL );
m_toolSendDecomposed = m_toolbar->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_toolDecompLanguageLbl = new wxStaticText( m_toolbar, wxID_ANY, _("Language:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT );
m_toolDecompLanguageLbl->Wrap( -1 );
m_toolbar->AddControl( m_toolDecompLanguageLbl );
wxArrayString m_toolDecompLanguageChoices;
m_toolDecompLanguage = new wxChoice( m_toolbar, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_toolDecompLanguageChoices, 0 );
m_toolDecompLanguage->SetSelection( 0 );
m_toolbar->AddControl( m_toolDecompLanguage );
m_toolbar->Realize();
wxBoxSizer* bSizerMain;
@@ -130,10 +148,16 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
this->Centre( wxBOTH );
// Connect Events
m_toolDecompLanguage->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
}
wxZRColaFrameBase::~wxZRColaFrameBase()
{
// Disconnect Events
m_toolDecompLanguage->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
}
wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )

View File

@@ -21,6 +21,8 @@
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/stattext.h>
#include <wx/choice.h>
#include <wx/toolbar.h>
#include "zrcolacomppnl.h"
#include <wx/sizer.h>
@@ -49,6 +51,7 @@ class wxZRColaFrameBase : public wxFrame
wxMenuBar* m_menubar;
wxMenu* m_menuProgram;
wxMenu* m_menuEdit;
wxMenu* m_menuDecompLanguage;
wxMenu* m_menuHelp;
wxToolBar* m_toolbar;
wxToolBarToolBase* m_toolEditCut;
@@ -56,8 +59,14 @@ class wxZRColaFrameBase : public wxFrame
wxToolBarToolBase* m_toolEditPaste;
wxToolBarToolBase* m_toolSendComposed;
wxToolBarToolBase* m_toolSendDecomposed;
wxStaticText* m_toolDecompLanguageLbl;
wxChoice* m_toolDecompLanguage;
wxZRColaComposerPanel* m_panel;
wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class
virtual void OnDecompLanguageChoice( wxCommandEvent& event ) { event.Skip(); }
public:

View File

@@ -127,6 +127,21 @@ bool ZRCola::DBSource::GetValue(const ATL::CComPtr<ADOField>& f, int& val) const
}
bool ZRCola::DBSource::GetValue(const ATL::CComPtr<ADOField>& f, std::wstring& val) const
{
wxASSERT_MSG(f, wxT("field is empty"));
ATL::CComVariant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
val.reserve(::SysStringLen(V_BSTR(&v)));
val = V_BSTR(&v);
return true;
}
bool ZRCola::DBSource::GetUnicodeCharacter(const ATL::CComPtr<ADOField>& f, wchar_t& chr) const
{
wxASSERT_MSG(f, wxT("field is empty"));
@@ -241,6 +256,45 @@ bool ZRCola::DBSource::GetKeyCode(const ATL::CComPtr<ADOField>& f, ZRCola::DBSou
}
bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADOField>& f, ZRCola::langid_t& lang) const
{
wxASSERT_MSG(f, wxT("field is empty"));
ATL::CComVariant v;
wxVERIFY(SUCCEEDED(f->get_Value(&v)));
wxCHECK(SUCCEEDED(v.ChangeType(VT_BSTR)), false);
// Convert to lowercase.
_wcslwr_l(V_BSTR(&v), m_locale);
// Parse the field.
size_t n = wcsnlen(V_BSTR(&v), ::SysStringLen(V_BSTR(&v)));
if (n != 3) {
ATL::CComBSTR fieldname; wxVERIFY(SUCCEEDED(f->get_Name(&fieldname)));
_ftprintf(stderr, wxT("%s: error ZCC0080: Syntax error in \"%.*ls\" field (\"%.*ls\"). Language ID must be exactly three (3) 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(lang)) {
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 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;
} else
lang[i] = 0;
} else
break;
}
return true;
}
bool ZRCola::DBSource::SelectTranslations(ATL::CComPtr<ADORecordset> &rs) const
{
// Create a new recordset.
@@ -347,3 +401,77 @@ bool ZRCola::DBSource::GetKeySequence(const ATL::CComPtr<ADORecordset>& rs, ZRCo
return true;
}
bool ZRCola::DBSource::SelectLanguages(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 [entCode] FROM [VRS_Jezik]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
_ftprintf(stderr, wxT("%s: error ZCC0060: Error loading languages from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
}
return true;
}
bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADORecordset>& rs, ZRCola::DBSource::language& lang) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
ATL::CComPtr<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"entCode"), &f)));
wxCHECK(GetLanguage(f, lang.id), false);
}
return true;
}
bool ZRCola::DBSource::SelectLanguageCharacters(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], [lang] FROM [VRS_CharLocal]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
_ftprintf(stderr, wxT("%s: error ZCC0090: Error loading language 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::GetLanguageCharacter(const ATL::CComPtr<ADORecordset>& rs, ZRCola::DBSource::langchar& lc) const
{
wxASSERT_MSG(rs, wxT("recordset is empty"));
ATL::CComPtr<ADOFields> flds;
wxVERIFY(SUCCEEDED(rs->get_Fields(&flds)));
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"znak"), &f)));
wxCHECK(GetUnicodeCharacter(f, lc.chr), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"lang"), &f)));
wxCHECK(GetLanguage(f, lc.lang), false);
}
return true;
}

View File

@@ -19,6 +19,8 @@
#pragma once
#include <zrcola/common.h>
#include <atlbase.h>
#include <adoint.h>
#include <string>
@@ -62,6 +64,25 @@ namespace ZRCola {
std::vector<keycode> seq; ///< Key sequence
};
///
/// Language
///
class language {
public:
ZRCola::langid_t id; ///< Language ID
};
///
/// Language Character
///
class langchar {
public:
wchar_t chr; ///> Character
ZRCola::langid_t lang; ///< Language ID
};
public:
DBSource();
virtual ~DBSource();
@@ -141,6 +162,19 @@ namespace ZRCola {
bool GetValue(const ATL::CComPtr<ADOField>& f, int& val) const;
///
/// Gets string from ZRCola.zrc database
///
/// \param[in] f Data field
/// \param[out] val Output string value
///
/// \returns
/// - true when successful
/// - false otherwise
///
bool GetValue(const ATL::CComPtr<ADOField>& f, std::wstring& val) const;
///
/// Gets encoded Unicode character from ZRCola.zrc database
///
@@ -180,6 +214,19 @@ namespace ZRCola {
bool GetKeyCode(const ATL::CComPtr<ADOField>& f, keyseq::keycode& kc) const;
///
/// Gets language ID from ZRCola.zrc database
///
/// \param[in] f Data field
/// \param[out] lang Language
///
/// \returns
/// - true when successful
/// - false otherwise
///
bool GetLanguage(const ATL::CComPtr<ADOField>& f, langid_t& lang) const;
///
/// Returns character translations
///
@@ -229,6 +276,56 @@ namespace ZRCola {
///
bool GetKeySequence(const ATL::CComPtr<ADORecordset>& rs, keyseq& ks) const;
///
/// Returns languages
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectLanguages(ATL::CComPtr<ADORecordset>& rs) const;
///
/// Returns language data
///
/// \param[in] rs Recordset with results
/// \param[out] lang Language
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetLanguage(const ATL::CComPtr<ADORecordset>& rs, language& lang) const;
///
/// Returns language character
///
/// \param[out] rs Recordset with results
///
/// \returns
/// - true when query succeeds
/// - false otherwise
///
bool SelectLanguageCharacters(ATL::CComPtr<ADORecordset>& rs) const;
///
/// Returns language character data
///
/// \param[in] rs Recordset with results
/// \param[out] lang Language character data
///
/// \returns
/// - true when succeeded
/// - false otherwise
///
bool GetLanguageCharacter(const ATL::CComPtr<ADORecordset>& rs, langchar& lc) const;
protected:
std::basic_string<TCHAR> m_filename; ///< Database filename
ATL::CComPtr<ADOConnection> m_db; ///< Database

View File

@@ -132,6 +132,117 @@ inline std::ostream& operator <<(std::ostream& stream, const ZRCola::keyseq_db &
}
///
/// 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;
}
///
/// Main function
///
@@ -259,7 +370,6 @@ int _tmain(int argc, _TCHAR *argv[])
}
}
{
// Get key sequences.
ATL::CComPtr<ADORecordset> rs;
@@ -329,6 +439,102 @@ int _tmain(int argc, _TCHAR *argv[])
}
}
{
// Get languages.
ATL::CComPtr<ADORecordset> rs;
if (src.SelectLanguages(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
ZRCola::DBSource::language lang;
ZRCola::language_db db;
// Preallocate memory.
db.idxLng.reserve(count);
db.data .reserve(count*4);
// Parse languages and build index and data.
while (!ZRCola::DBSource::IsEOF(rs)) {
// Read language from the database.
if (src.GetLanguage(rs, lang)) {
// 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.idxLng.push_back(idx);
} else
has_errors = true;
wxVERIFY(SUCCEEDED(rs->MoveNext()));
}
// Sort indices.
db.idxLng.sort();
// Write languages to file.
dst << ZRCola::language_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0009: Error getting language count from database or too many languages.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0008: Error getting languages from database. Please make sure the file is ZRCola.zrc compatible.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
}
{
// Get language characters.
ATL::CComPtr<ADORecordset> rs;
if (src.SelectLanguageCharacters(rs)) {
size_t count = src.GetRecordsetCount(rs);
if (count < 0xffffffff) { // 4G check (-1 is reserved for error condition)
ZRCola::DBSource::langchar lc;
ZRCola::langchar_db db;
// Preallocate memory.
db.idxChr.reserve(count);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.reserve(count);
#endif
db.data .reserve(count*4);
// Parse language characters and build index and data.
while (!ZRCola::DBSource::IsEOF(rs)) {
// Read language characters from the database.
if (src.GetLanguageCharacter(rs, lc)) {
// Add language characters to index and data.
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.idxChr.push_back(idx);
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.push_back(idx);
#endif
} else
has_errors = true;
wxVERIFY(SUCCEEDED(rs->MoveNext()));
}
// Sort indices.
db.idxChr .sort();
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
db.idxLng.sort();
#endif
// Write language characters to file.
dst << ZRCola::langchar_rec(db);
} else {
_ftprintf(stderr, wxT("%s: error ZCC0011: Error getting language characters count from database or too many langchars.\n"), (LPCTSTR)filenameIn.c_str());
has_errors = true;
}
} else {
_ftprintf(stderr, wxT("%s: error ZCC0010: Error getting language characters 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

@@ -24,6 +24,7 @@
#include "../include/zrcola.h"
#include "dbsource.h"
#include <zrcola/language.h>
#include <zrcola/translate.h>
#include <zrcolaui/keyboard.h>

View File

@@ -23,7 +23,7 @@
// Product version as a single DWORD
// Note: Used for version comparison within C/C++ code.
//
#define ZRCOLA_VERSION 0x01ff0300
#define ZRCOLA_VERSION 0x01ff0500
//
// Product version by components
@@ -33,26 +33,26 @@
//
#define ZRCOLA_VERSION_MAJ 1
#define ZRCOLA_VERSION_MIN 255
#define ZRCOLA_VERSION_REV 3
#define ZRCOLA_VERSION_REV 5
#define ZRCOLA_VERSION_BUILD 0
//
// Human readable product version and build year for UI
//
#define ZRCOLA_VERSION_STR "2.0-alpha3"
#define ZRCOLA_VERSION_STR "2.0-alpha5"
#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.3"
#define ZRCOLA_VERSION_INST "1.255.5"
//
// 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 "{8553943A-9CD0-4639-98CC-0A57A84A7765}"
#define ZRCOLA_VERSION_GUID "{037FA96B-4D03-41BC-A898-6300EBE2F23F}"
//
// The product vendor and application name for configuration keeping.

View File

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

View File

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

View File

@@ -44,7 +44,12 @@
///
/// Database IDs
///
#define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC")
#define ZRCOLA_DB_ID (*(ZRCola::recordid_t*)"ZRC")
///
/// Unknown language ID
///
#define ZRCOLA_LANG_VOID " "
namespace ZRCola {
@@ -52,6 +57,13 @@ namespace ZRCola {
typedef unsigned __int32 recordsize_t;
///
/// Language ID type
/// Three letter abbreviation, zero terminated
///
typedef char langid_t[4];
///
/// Memory index
///
@@ -168,8 +180,8 @@ namespace ZRCola {
/// \param[out] end Index of the first non-matching element found
///
/// \returns
/// - true if found
/// - false otherwise
/// - \c true if found
/// - \c false otherwise
///
bool find(_In_ const T_data &el, _Out_ size_type &start, _Out_ size_type &end) const
{

View File

@@ -0,0 +1,352 @@
/*
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 <vector>
#include <string>
#pragma warning(push)
#pragma warning(disable: 4200)
#pragma warning(disable: 4251)
#pragma warning(disable: 4512)
namespace ZRCola {
///
/// Language Character Database
///
class ZRCOLA_API langchar_db {
public:
#pragma pack(push)
#pragma pack(2)
///
/// Character data
///
struct langchar {
wchar_t chr; ///> Character
langid_t lang; ///< Language ID
};
#pragma pack(pop)
///
/// Character index
///
class indexChar : public index<unsigned __int16, unsigned __int32, langchar>
{
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, langchar>(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 langchar &a, _In_ const langchar &b) const
{
if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return 1;
return 0;
}
///
/// Compares two characters 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 langchar &a, _In_ const langchar &b) const
{
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;
return 0;
}
} idxChr; ///< Character index
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
///
/// Character Language Index
///
class indexCharLang : public index<unsigned __int16, unsigned __int32, langchar>
{
public:
///
/// Constructs the index
///
/// \param[in] h Reference to vector holding the data
///
indexCharLang(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, langchar>(h) {}
///
/// Compares two languages 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 langchar &a, _In_ const langchar &b) const
{
int r = memcmp(a.lang, b.lang, 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 langchar &a, _In_ const langchar &b) const
{
int r = memcmp(a.lang, b.lang, sizeof(langid_t));
if (r != 0) return r;
if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return 1;
return 0;
}
} idxLng; ///< Character language index
#endif
std::vector<unsigned __int16> data; ///< Character data
public:
///
/// Constructs the database
///
inline langchar_db() : idxChr(data)
#ifdef ZRCOLA_LANGCHAR_LANG_IDX
, idxLng(data)
#endif
{}
///
/// Tests presence of character in the given language
///
/// \param[in] chr Character (UTF-16)
/// \param[in] lang Language
///
/// \returns
/// - \c true when character is used in language
/// - \c false otherwise
bool IsLocalCharacter(_In_ wchar_t chr, _In_ langid_t lang) const;
};
typedef ZRCOLA_API stdex::idrec::record<langchar_db, recordid_t, recordsize_t, ZRCOLA_RECORD_ALIGN> langchar_rec;
///
/// Language database
///
class ZRCOLA_API language_db {
public:
#pragma pack(push)
#pragma pack(2)
///
/// Language data
///
struct language {
langid_t id; ///< Language ID
};
#pragma pack(pop)
///
/// Language index
///
class indexLang : public index<unsigned __int16, unsigned __int32, language>
{
public:
///
/// Constructs the index
///
/// \param[in] h Reference to vector holding the data
///
indexLang(_In_ std::vector<unsigned __int16> &h) : index<unsigned __int16, unsigned __int32, language>(h) {}
///
/// Compares two languages 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 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.
return 0;
}
} idxLng; ///< Language index
std::vector<unsigned __int16> data; ///< Language data
public:
///
/// Constructs the database
///
inline language_db() : idxLng(data) {}
};
typedef ZRCOLA_API stdex::idrec::record<language_db, recordid_t, recordsize_t, ZRCOLA_RECORD_ALIGN> language_rec;
};
const ZRCola::recordid_t stdex::idrec::record<ZRCola::langchar_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"L-C";
const ZRCola::recordid_t stdex::idrec::record<ZRCola::language_db, ZRCola::recordid_t, ZRCola::recordsize_t, ZRCOLA_RECORD_ALIGN>::id = *(ZRCola::recordid_t*)"LNG";
///
/// Reads language character database from a 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);
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);
if (!stream.good()) return stream;
#endif
// Read data 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);
return stream;
}
///
/// Reads language database from a 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);
if (!stream.good()) return stream;
// Read data 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);
return stream;
}
#pragma warning(pop)

View File

@@ -20,6 +20,7 @@
#pragma once
#include "common.h"
#include "language.h"
#include <stdex/idrec.h>
#include <istream>
@@ -94,8 +95,8 @@ namespace ZRCola {
///
/// Compares two transformations by string (for searching)
///
/// \param[in] a Pointer to key sequence
/// \param[in] b Pointer to second key sequence
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
@@ -150,8 +151,8 @@ namespace ZRCola {
///
/// Compares two transformations by character (for searching)
///
/// \param[in] a Pointer to key sequence
/// \param[in] b Pointer to second key sequence
/// \param[in] a Pointer to first element
/// \param[in] b Pointer to second element
///
/// \returns
/// - <0 when a < b
@@ -216,7 +217,22 @@ namespace ZRCola {
/// \param[out] output Output string (UTF-16)
/// \param[out] map The vector of source to destination index mappings (optional)
///
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;
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);
}
///
/// Decomposes string according ommiting language specific characters
///
/// \param[in] input Input string (UTF-16)
/// \param[in] inputMax Length of the input string in characters. Can be (size_t)-1 if \p input is zero terminated.
/// \param[in] lc_db Language character database
/// \param[in] lang Language ID
/// \param[out] output Output string (UTF-16)
/// \param[out] map The vector of source to destination index mappings (optional)
///
void Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _In_opt_ const langchar_db *lc_db, _In_opt_ langid_t lang, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map = NULL) const;
};

View File

@@ -0,0 +1,46 @@
/*
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::langchar_db::IsLocalCharacter(_In_ wchar_t chr, _In_ ZRCola::langid_t lang) const
{
for (size_t l = 0, r = idxChr.size(); l < r; ) {
// Test the character in the middle of the search area.
size_t m = (l + r) / 2;
const langchar &lc = idxChr[m];
// Do the bisection test on character.
if (chr < lc.chr) r = m;
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;
else {
// Match found.
return true;
}
}
}
return false;
}

View File

@@ -20,6 +20,6 @@
#include "stdafx.h"
void ZRCOLA_API ZRCola::Normalize(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map)
void ZRCola::Normalize(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map)
{
}

View File

@@ -20,7 +20,9 @@
#pragma once
#include "../../../include/zrcola.h"
#include "../include/zrcola/translate.h"
#include "../include/zrcola/language.h"
#include "../include/zrcola/normalize.h"
#include "../include/zrcola/translate.h"
#include <assert.h>

View File

@@ -37,90 +37,72 @@ void ZRCola::translation_db::Compose(_In_z_count_(inputMax) const wchar_t* input
indexComp::size_type compositionsCount = idxComp.size();
for (size_t i = 0; i < inputMax;) {
// Start with the full search area at i-th character.
for (size_t l = 0, r = compositionsCount, ii = i, j = 0;; ii++, j++) {
if (ii < inputMax) {
size_t l_prev = l;
wchar_t c = input[ii];
while (l < r) {
// Test the composition in the middle of the search area.
size_t m = (l + r) / 2;
// Find the longest matching composition at i-th character.
size_t l_match = (size_t)-1;
for (size_t l = 0, r = compositionsCount, ii = i, j = 0; ii < inputMax && l < r; ii++, j++) {
wchar_t c = input[ii];
while (l < r) {
// Test the composition in the middle of the search area.
size_t m = (l + r) / 2;
// Get the j-th character of the composition.
// All compositions that get short on characters are lexically ordered before.
// Thus the j-th character is considered 0.
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
// Get the j-th character of the composition.
// All compositions that get short on characters are lexically ordered before.
// Thus the j-th character is considered 0.
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
// Do the bisection test.
if (c < s) r = m;
else if (s < c) l = m + 1;
else {
// Character found.
// Do the bisection test.
if (c < s) r = m;
else if (s < c) l = m + 1;
else {
// Character found.
// Narrow the search area on the left to start at the first composition in the run.
for (size_t rr = m; l < rr;) {
size_t m = (l + rr) / 2;
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
if (c <= s) rr = m; else l = m + 1;
}
// Narrow the search area on the right to end at the first composition not in the run.
for (size_t ll = m + 1; ll < r;) {
size_t m = (ll + r) / 2;
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
if (s <= c) ll = m + 1; else r = m;
}
break;
// Narrow the search area on the left to start at the first composition in the run.
for (size_t rr = m; l < rr;) {
size_t m = (l + rr) / 2;
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
if (c <= s) rr = m; else l = m + 1;
}
}
if (l >= r) {
// The search area is empty.
const translation &trans = idxComp[l_prev];
if (j && l_prev < compositionsCount && j == trans.str_len) {
// The first composition of the previous run was a match.
output += trans.chr;
i = ii;
if (j > 1 && map) {
// Mapping changed.
map->push_back(ZRCola::mapping(output.length(), i));
}
} else {
// The exact match was not found.
output += input[i];
i++;
// Narrow the search area on the right to end at the first composition not in the run.
for (size_t ll = m + 1; ll < r;) {
size_t m = (ll + r) / 2;
const translation &trans = idxComp[m];
wchar_t s = j < trans.str_len ? trans.str[j] : 0;
if (s <= c) ll = m + 1; else r = m;
}
const translation &trans = idxComp[l];
if (j + 1 == trans.str_len) {
// The first composition of the run was a match (thus far). Save it.
l_match = l;
}
break;
}
} else {
// End of input reached.
const translation &trans = idxComp[l];
if (l < compositionsCount && j == trans.str_len) {
// The first composition of the previous run was a match.
output += trans.chr;
i = ii;
if (j > 1 && map) {
// Mapping changed.
map->push_back(ZRCola::mapping(output.length(), i));
}
} else {
output += input[i];
i++;
}
break;
}
}
if (l_match < compositionsCount) {
// The saved composition was an exact match.
const translation &trans = idxComp[l_match];
output += trans.chr;
i += trans.str_len;
if (trans.str_len > 1 && map) {
// Mapping changed.
map->push_back(ZRCola::mapping(output.length(), i));
}
} else {
// The match was not found.
output += input[i];
i++;
}
}
}
void ZRCOLA_API ZRCola::translation_db::Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map) const
void ZRCola::translation_db::Decompose(_In_z_count_(inputMax) const wchar_t* input, _In_ size_t inputMax, _In_ const langchar_db *lc_db, _In_ langid_t lang, _Out_ std::wstring &output, _Out_opt_ std::vector<mapping>* map) const
{
assert(input || inputMax == 0);
@@ -149,11 +131,18 @@ void ZRCOLA_API ZRCola::translation_db::Decompose(_In_z_count_(inputMax) const w
else if (decompSrc < c) l = m + 1;
else {
// Character found.
output.append(trans.str, trans.str_len);
i++;
if (map) {
// Mapping changed.
map->push_back(ZRCola::mapping(i, output.length()));
if (trans.str_len && trans.str[0] != L'#' && (!lc_db || !lc_db->IsLocalCharacter(c, lang))) {
// Append decomposed sequence.
output.append(trans.str, trans.str_len);
i++;
if (map) {
// Mapping changed.
map->push_back(ZRCola::mapping(i, output.length()));
}
} else {
// Character is inhibited to decompose.
output += c;
i++;
}
break;
}

Binary file not shown.

Binary file not shown.

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: wxWidgets 3.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-02 15:21+0100\n"
"PO-Revision-Date: 2016-03-14 17:12+0100\n"
"PO-Revision-Date: 2016-04-08 13:05+0200\n"
"Last-Translator: Simon Rozman <simon.rozman@amebis.si>\n"
"Language-Team: Simon Rozman <simon.rozman@amebis.si>\n"
"Language: sl_SI\n"
@@ -2955,7 +2955,7 @@ msgstr "Izreži"
# generic/dirdlgg.cpp:191
#: ../src/common/stockitem.cpp:259
msgid "Cut selection"
msgstr "Prilepi izbor"
msgstr "Izreži izbor"
#: ../src/common/fmapbase.cpp:152
msgid "Cyrillic (ISO-8859-5)"