Compare commits

...

22 Commits

Author SHA1 Message Date
Simon Rozman
4ef335b6aa Version set to 2.0-alpha6 2016-04-29 13:09:19 +02:00
Simon Rozman
15365aff46 Input language detection added
(closes #2)
2016-04-29 12:54:39 +02:00
Simon Rozman
4a27d62b4e ZRCola::LangConvert() function added 2016-04-29 12:35:59 +02:00
Simon Rozman
38bf070a4a Auto-start on logon feature added
(closes #8)
2016-04-29 09:51:40 +02:00
Simon Rozman
c7df06ba1e Fixed order in SQL queries for consistent ZRCola.zrcdb generation 2016-04-26 15:43:33 +02:00
Simon Rozman
b9d636fb30 CharDescGenerate job added to generate character descriptions 2016-04-26 15:26:11 +02:00
Simon Rozman
ac005c0b77 Merge branch 'master' of https://github.com/Amebis/ZRCola 2016-04-23 22:23:00 +02:00
Simon Rozman
58f354f028 GUI edit boxes labeled now 2016-04-23 22:22:46 +02:00
Simon Rozman
a1a1852552 GUI edit boxes labeled now 2016-04-23 22:16:03 +02:00
Simon Rozman
7807e8a918 ZRCola.fbp added to project 2016-04-23 22:14:49 +02:00
Simon Rozman
3daaff4260 Script to import UnicodeData.txt to ZRCola.mdb added 2016-04-23 14:02:50 +02:00
Simon Rozman
840c8240b7 Composer panel settings moved for simpler configuration organization 2016-04-23 06:38:48 +02:00
Simon Rozman
21114d818c On-screen Unicode dump added
(closes #14)
2016-04-22 16:12:59 +02:00
Simon Rozman
7a424da3fc Code to Save & Restore text moved to wxZRColaComposerPanel to avoid confusion with GUI persistence 2016-04-22 14:24:17 +02:00
Simon Rozman
82d2fc42bd Minor updates of auto-saving feature 2016-04-22 13:39:34 +02:00
Simon Rozman
5f755aa3d9 Auto-Save & Restore of text added
(closes #16)
2016-04-22 13:29:30 +02:00
Simon Rozman
8c51f9c2a6 Ambiguous decomposition sequences now decompose to first ranked decomposition
(resolves #18)
2016-04-22 11:30:42 +02:00
Simon Rozman
5df7ca886b Decomposition before composition added
(resolves #17)
2016-04-22 11:00:11 +02:00
Simon Rozman
2e89edb62c Source and destination index mapping on the left side of the first transformation issue fixed 2016-04-22 10:59:29 +02:00
Simon Rozman
a021dd31f7 ZRCola::mapping is generic now 2016-04-20 12:24:23 +02:00
Simon Rozman
5e4331903b Language names are displayed with the localized full name now
(closes #15)
2016-04-13 20:39:14 +02:00
Simon Rozman
55c76265df Redundant check removed 2016-04-13 12:41:41 +02:00
31 changed files with 2794 additions and 215 deletions

View File

@@ -64,6 +64,9 @@ comp00_ZRCola_Re.ttf {B6CE8B39-11DC-4B59-B10C-3F0FFE8F81AF} FontsFolder 0 file0
comp00_ZRCola_It.ttf {10613965-2874-470D-9D5A-B7D535AA3317} FontsFolder 0 file00_ZRCola_It.ttf
comp00_ZRCola_Bd.ttf {C036BE8D-6D2F-4DBF-99D6-F53702EAEBB6} FontsFolder 0 file00_ZRCola_Bd.ttf
comp00_ZRCola_BI.ttf {883DDA9A-DA85-4FC4-95B7-EF0E08766DEF} FontsFolder 0 file00_ZRCola_BI.ttf
!IF "$(LANG)" == "Sl"
compZRCola.zrcdb.mo.sl_SI {6572EAD1-EE48-46A1-A28E-77985B667F67} ZRCOLALOCSLSIDIR $(MSIBUILD_COMPONENT_ATTRIB_FILE) fileZRCola.zrcdb.mo.sl_SI
!ENDIF
<<NOKEEP
@@ -236,6 +239,9 @@ file00_ZRCola_Re.ttf comp00_ZRCola_Re.ttf 00_ZRC~1.TTF|00_ZRCola_Re.ttf 0 0 1
file00_ZRCola_It.ttf comp00_ZRCola_It.ttf 00_ZRC~2.TTF|00_ZRCola_It.ttf 0 0 1
file00_ZRCola_Bd.ttf comp00_ZRCola_Bd.ttf 00_ZRC~3.TTF|00_ZRCola_Bd.ttf 0 0 1
file00_ZRCola_BI.ttf comp00_ZRCola_BI.ttf 00_ZRC~4.TTF|00_ZRCola_BI.ttf 0 0 1
!IF "$(LANG)" == "Sl"
fileZRCola.zrcdb.mo.sl_SI compZRCola.zrcdb.mo.sl_SI ZRCOLA~1.MO|ZRCola-zrcdb.mo 0 1060 0 1
!ENDIF
<<NOKEEP

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -113,6 +113,7 @@
<None Include="res\send_composed.ico" />
<None Include="res\send_decomposed.ico" />
<None Include="res\zrcola.ico" />
<None Include="ZRCola.fbp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ZRCola.rc" />

View File

@@ -80,6 +80,9 @@
<None Include="res\edit_paste.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="ZRCola.fbp">
<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-04-13 10:50+0200\n"
"PO-Revision-Date: 2016-04-13 10:50+0200\n"
"POT-Creation-Date: 2016-04-29 12:50+0200\n"
"PO-Revision-Date: 2016-04-29 12: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,12 +17,12 @@ msgstr ""
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: zrcolafrm.cpp:69
#: zrcolafrm.cpp:76
#, c-format
msgid "Select %s language for decomposition"
msgstr "Izberi jezik %s za razstavljanje"
#: zrcolafrm.cpp:81
#: zrcolafrm.cpp:87
msgid ""
"ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality "
"will not be available."
@@ -30,11 +30,11 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F5 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:81 zrcolafrm.cpp:83
#: zrcolafrm.cpp:87 zrcolafrm.cpp:89
msgid "Warning"
msgstr "Opozorilo"
#: zrcolafrm.cpp:83
#: zrcolafrm.cpp:89
msgid ""
"ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality "
"will not be available."
@@ -42,7 +42,11 @@ msgstr ""
"ZRColine bližnjice na tipkovnici Win+F6 ni mogoče registrirati. Nekaj "
"funkcionalnosti ne bo na voljo."
#: zrcolafrm.cpp:205
#: zrcolafrm.cpp:151
msgid "Start ZRCola automatically on logon"
msgstr "Samodejno zaženi ZRColo ob prijavi"
#: zrcolafrm.cpp:309
#, c-format
msgid ""
"ZRCola v%s\n"
@@ -51,103 +55,135 @@ msgstr ""
"ZRCola v%s\n"
"Vse pravice pridržane 2015-%s Amebis"
#: zrcolafrm.cpp:205
#: zrcolafrm.cpp:309
msgid "About ZRCola"
msgstr "O ZRColi"
#: zrcolagui.cpp:32
msgid "&Start on Logon"
msgstr "Z&aženi ob prijavi"
#: zrcolagui.cpp:32
msgid "Start this program automatically on logon"
msgstr "Samodejno zaženi ta program ob prijavi"
#: zrcolagui.cpp:38
msgid "E&xit"
msgstr "I&zhod"
#: zrcolagui.cpp:32
#: zrcolagui.cpp:38
msgid "Quit this program"
msgstr "Zapri ta program"
#: zrcolagui.cpp:35
#: zrcolagui.cpp:41
msgid "&Program"
msgstr "&Program"
#: zrcolagui.cpp:68
#: zrcolagui.cpp:74
msgid "Select &All"
msgstr "Izberi &vse"
#: zrcolagui.cpp:68
#: zrcolagui.cpp:74
msgid "Select all text"
msgstr "Izberi celotno besedilo"
#: zrcolagui.cpp:74
#: zrcolagui.cpp:80
msgid "&Send Composed"
msgstr "Pošlji &sestavljeno"
#: zrcolagui.cpp:74 zrcolagui.cpp:125
#: zrcolagui.cpp:80 zrcolagui.cpp:137
msgid "Send composed text to source window"
msgstr "Pošlji sestavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:83
#: zrcolagui.cpp:89
msgid "Send &Decomposed"
msgstr "Pošlji &razstavljeno"
#: zrcolagui.cpp:83 zrcolagui.cpp:127
#: zrcolagui.cpp:89 zrcolagui.cpp:139
msgid "Send decomposed text to source window"
msgstr "Pošlji razstavljeno besedilo izvornemu oknu"
#: zrcolagui.cpp:92
#: zrcolagui.cpp:98
msgid "Abort (De)composition"
msgstr "Prekini raz/sestavljanje"
#: zrcolagui.cpp:92
#: zrcolagui.cpp:98
msgid "Abort composition and return focus to source window"
msgstr "Prekini sestavljanje in vrni fokus nazaj izvornemu oknu"
#: zrcolagui.cpp:101
#: zrcolagui.cpp:107
msgid "&Language"
msgstr "&Jezik"
#: zrcolagui.cpp:104
#: zrcolagui.cpp:109
msgid "&Automatic"
msgstr "S&amodejno"
#: zrcolagui.cpp:109
msgid "Set language according to keyboard layout automatically"
msgstr "Samodejno nastavi jezik glede na izbrano tipkovnico"
#: zrcolagui.cpp:116
msgid "&Edit"
msgstr "Ur&edi"
#: zrcolagui.cpp:111
#: zrcolagui.cpp:123
msgid "&Help"
msgstr "&Pomoč"
#: zrcolagui.cpp:117
#: zrcolagui.cpp:129
msgid "Cut"
msgstr "Izreži"
#: zrcolagui.cpp:117
#: zrcolagui.cpp:129
msgid "Cut selection"
msgstr "Izreži izbor"
#: zrcolagui.cpp:119
#: zrcolagui.cpp:131
msgid "Copy"
msgstr "Kopiraj"
#: zrcolagui.cpp:119
#: zrcolagui.cpp:131
msgid "Copy selection"
msgstr "Kopiraj izbor"
#: zrcolagui.cpp:121
#: zrcolagui.cpp:133
msgid "Paste"
msgstr "Prilepi"
#: zrcolagui.cpp:121
#: zrcolagui.cpp:133
msgid "Paste selection"
msgstr "Prilepi izbor"
#: zrcolagui.cpp:125
#: zrcolagui.cpp:137
msgid "Send Composed"
msgstr "Pošlji sestavljeno"
#: zrcolagui.cpp:127
#: zrcolagui.cpp:139
msgid "Send Decomposed"
msgstr "Pošlji razstavljeno"
#: zrcolagui.cpp:129
#: zrcolagui.cpp:141
msgid "Language:"
msgstr "Jezik:"
#: zrcolagui.h:73 MSIBuild/En.Win32.Release.Feature-2.idtx:4
#: zrcolagui.cpp:190
msgid "Decomposed Text"
msgstr "Razstavljeno besedilo"
#: zrcolagui.cpp:210
msgid "Decomposed Unicode Dump"
msgstr "Unicode razstavljenega"
#: zrcolagui.cpp:237
msgid "Composed Text"
msgstr "Sestavljeno besedilo"
#: zrcolagui.cpp:257
msgid "Composed Unicode Dump"
msgstr "Unicode sestavljenega"
#: zrcolagui.h:77 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

View File

@@ -25,6 +25,7 @@
#include "zrcolafrm.h"
#include "zrcolakeyhndlr.h"
#include <wx/ffile.h>
#include <wx/msgdlg.h>
#include <wx/persist.h>
#include <wx/persist/toplevel.h>
@@ -38,4 +39,6 @@
#if defined(__WXMSW__)
#include <Msi.h>
#include <ShObjIdl.h>
#include <ShlGuid.h>
#endif

View File

@@ -60,6 +60,7 @@ bool ZRColaApp::OnInit()
wxVERIFY(m_locale.Init(language));
wxVERIFY(m_locale.AddCatalog(wxT("wxExtend")));
wxVERIFY(m_locale.AddCatalog(wxT("ZRCola")));
wxVERIFY(m_locale.AddCatalog(wxT("ZRCola-zrcdb")));
}
std::fstream dat((LPCTSTR)GetDatabasePath(), std::ios_base::in | std::ios_base::binary);

View File

@@ -24,6 +24,11 @@
// wxZRColaComposerPanel
//////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(wxZRColaComposerPanel, wxZRColaComposerPanelBase)
EVT_TIMER(wxZRColaComposerPanel::wxID_TIMER, wxZRColaComposerPanel::OnTimerTimeout)
END_EVENT_TABLE()
wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_progress(false),
m_selDecomposed(0, 0),
@@ -31,12 +36,53 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
wxZRColaComposerPanelBase(parent)
{
m_decomposed->PushEventHandler(&m_keyhandler);
// Create timer for saving the state.
m_timer = new wxTimer(this, wxID_TIMER);
// Restore the previously saved state (if exists).
wxString fileName(GetStateFileName());
if (wxFileExists(fileName)) {
wxFFile file(fileName, wxT("rb"));
if (file.IsOpened()) {
// Load decomposed text.
unsigned __int64 n;
file.Read(&n, sizeof(n));
if (!file.Error()) {
wxString decomposed;
file.Read(wxStringBuffer(decomposed, n), sizeof(wchar_t)*n);
if (!file.Error()) {
// Load composed text.
file.Read(&n, sizeof(n));
if (!file.Error()) {
wxString composed;
file.Read(wxStringBuffer(composed, n), sizeof(wchar_t)*n);
if (!file.Error()) {
// Restore state.
m_progress = true;
m_decomposed->SetValue(decomposed);
m_composed->SetValue(composed);
m_progress = false;
}
}
}
}
}
}
}
wxZRColaComposerPanel::~wxZRColaComposerPanel()
{
if (m_timer)
delete m_timer;
m_decomposed->PopEventHandler();
// This is a controlled exit. Purge saved state.
wxString fileName(GetStateFileName());
if (wxFileExists(fileName))
wxRemoveFile(fileName);
}
@@ -51,7 +97,27 @@ void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selDecomposed.first = from;
m_selDecomposed.second = to;
m_composed->SetSelection(m_mapping.to_composed(from), m_mapping.to_composed(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));
}
}
void wxZRColaComposerPanel::OnDecomposedHexPaint(wxPaintEvent& event)
{
event.Skip();
long from, to;
m_decomposedHex->GetSelection(&from, &to);
if (m_selDecomposedHex.first != from || m_selDecomposedHex.second != to) {
// 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));
}
}
@@ -62,27 +128,49 @@ void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
// We are being updated by wxZRColaComposerPanel::OnComposedText()
event.Skip();
} else {
m_timer->Stop();
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_decomposed->GetHWND();
std::vector<wchar_t> src((std::vector<wchar_t>::size_type)::GetWindowTextLengthW(hWnd) + 1);
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(src.data(), src.size(), dst, &m_mapping);
((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(m_mapping.to_composed(from), m_mapping.to_composed(to));
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);
}
}
@@ -98,7 +186,27 @@ void wxZRColaComposerPanel::OnComposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop.
m_selComposed.first = from;
m_selComposed.second = to;
m_decomposed->SetSelection(m_mapping.to_decomposed(from), m_mapping.to_decomposed(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));
}
}
void wxZRColaComposerPanel::OnComposedHexPaint(wxPaintEvent& event)
{
event.Skip();
long from, to;
m_composedHex->GetSelection(&from, &to);
if (m_selComposedHex.first != from || m_selComposedHex.second != to) {
// 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));
}
}
@@ -109,31 +217,178 @@ void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
// We are being updated by wxZRColaComposerPanel::OnDecomposedText()
event.Skip();
} else {
m_timer->Stop();
#ifdef __WINDOWS__
// Use Windows GetWindowTextLength() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_composed->GetHWND();
std::vector<wchar_t> src((std::vector<wchar_t>::size_type)::GetWindowTextLengthW(hWnd) + 1);
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(), src.size(), &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping);
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(), src.size(), dst, &m_mapping);
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(m_mapping.to_decomposed(from), m_mapping.to_decomposed(to));
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);
}
}
void wxZRColaComposerPanel::OnTimerTimeout(wxTimerEvent& event)
{
wxString fileName(GetStateFileName());
wxFFile file(fileName, wxT("wb"));
if (file.IsOpened()) {
// 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);
}
// 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);
}
}
event.Skip();
}
wxString wxZRColaComposerPanel::GetStateFileName()
{
wxString path;
path = wxFileName::GetTempDir();
if (!wxEndsWithPathSeparator(path))
path += wxFILE_SEP_PATH;
if (!wxDirExists(path))
wxMkdir(path);
wxString fileName(path);
fileName += wxT("ZRColaComposerPanel-state.tmp");
return fileName;
}
void wxZRColaComposerPanel::GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len)
{
bool first = true;
hex.clear();
mapping.clear();
for (size_t i = 0; i < len && src[i]; i++) {
wchar_t c = src[i];
if (c == L'\n' || c == '\r') {
hex += c;
first = true;
} else {
hex += wxString::Format(first ? wxT("%04X") : wxT(" %04X"), src[i]);
mapping.push_back(ZRCola::mapping(i + 1, hex.Length()));
first = false;
}
}
}
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaComposerPanel
//////////////////////////////////////////////////////////////////////////
wxPersistentZRColaComposerPanel::wxPersistentZRColaComposerPanel(wxZRColaComposerPanel *wnd) : wxPersistentWindow<wxZRColaComposerPanel>(wnd)
{
}
wxString wxPersistentZRColaComposerPanel::GetKind() const
{
return wxT(wxPERSIST_TLW_KIND);
}
void wxPersistentZRColaComposerPanel::Save() const
{
const wxZRColaComposerPanel * const wnd = static_cast<const wxZRColaComposerPanel*>(GetWindow());
SaveValue(wxT("splitDecomposed"), wnd->m_splitterDecomposed->GetSashPosition());
SaveValue(wxT("splitComposed" ), wnd->m_splitterComposed ->GetSashPosition());
}
bool wxPersistentZRColaComposerPanel::Restore()
{
wxZRColaComposerPanel * const wnd = static_cast<wxZRColaComposerPanel*>(GetWindow());
int sashVal;
if (RestoreValue(wxT("splitDecomposed"), &sashVal)) {
// wxFormBuilder sets initial splitter stash in idle event handler after GUI settles. Overriding our loaded value. Disconnect it's idle event handler.
wnd->m_splitterDecomposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDecomposedOnIdle ), NULL, wnd );
wnd->m_splitterDecomposed->SetSashPosition(sashVal);
}
if (RestoreValue(wxT("splitComposed"), &sashVal)) {
// wxFormBuilder sets initial splitter stash in idle event handler after GUI settles. Overriding our loaded value. Disconnect it's idle event handler.
wnd->m_splitterComposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterComposedOnIdle ), NULL, wnd );
wnd->m_splitterComposed->SetSashPosition(sashVal);
}
return true;
}

View File

@@ -27,6 +27,8 @@ class wxZRColaComposerPanel;
#include "zrcolagui.h"
#include "zrcolakeyhndlr.h"
#include <wx/persist/window.h>
#include <wx/timer.h>
#include <utility>
@@ -36,22 +38,61 @@ class wxZRColaComposerPanel;
class wxZRColaComposerPanel : public wxZRColaComposerPanelBase
{
public:
enum
{
wxID_TIMER = 1,
};
wxZRColaComposerPanel(wxWindow* parent);
virtual ~wxZRColaComposerPanel();
friend class wxZRColaFrame; // Allow main frame direct access to our members.
friend class wxZRColaFrame; // Allow main frame direct access to our members.
friend class wxPersistentZRColaComposerPanel; // Allow saving/restoring window state.
protected:
virtual void OnDecomposedPaint(wxPaintEvent& event);
virtual void OnDecomposedHexPaint(wxPaintEvent& event);
virtual void OnDecomposedText(wxCommandEvent& event);
virtual void OnComposedPaint(wxPaintEvent& event);
virtual void OnComposedHexPaint(wxPaintEvent& event);
virtual void OnComposedText(wxCommandEvent& event);
virtual void OnTimerTimeout(wxTimerEvent& event);
DECLARE_EVENT_TABLE()
static wxString GetStateFileName();
static void GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len);
protected:
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
bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls
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>
m_selDecomposed, ///< Character index of selected text in decomposed text control
m_selComposed; ///< Character index of selected text in composed text control
wxZRColaKeyHandler m_keyhandler; ///< Key handler for decomposed window
m_selDecomposed, ///< Character index of selected text in decomposed text control
m_selDecomposedHex, ///< Character index of selected text in decomposed HEX dump text control
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
};
///
/// Supports saving/restoring wxZRColaComposerPanel state
///
class wxPersistentZRColaComposerPanel : public wxPersistentWindow<wxZRColaComposerPanel>
{
public:
wxPersistentZRColaComposerPanel(wxZRColaComposerPanel *wnd);
virtual wxString GetKind() const;
virtual void Save() const;
virtual bool Restore();
};
inline wxPersistentObject *wxCreatePersistentObject(wxZRColaComposerPanel *wnd)
{
return new wxPersistentZRColaComposerPanel(wnd);
}

View File

@@ -25,25 +25,31 @@
//////////////////////////////////////////////////////////////////////////
wxBEGIN_EVENT_TABLE(wxZRColaFrame, wxZRColaFrameBase)
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 (wxID_AUTOSTART , wxZRColaFrame::OnAutostartUpdate )
EVT_MENU (wxID_AUTOSTART , wxZRColaFrame::OnAutostart )
EVT_MENU (wxID_EXIT , wxZRColaFrame::OnExit )
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_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_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_MENU(wxID_EXIT , wxZRColaFrame::OnExit )
EVT_MENU(wxID_ABOUT, wxZRColaFrame::OnAbout)
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_MENU (wxID_ABOUT , wxZRColaFrame::OnAbout )
wxEND_EVENT_TABLE()
wxZRColaFrame::wxZRColaFrame() :
m_lang_auto(true),
m_hWndSource(NULL),
wxZRColaFrameBase(NULL)
{
@@ -61,16 +67,16 @@ wxZRColaFrame::wxZRColaFrame() :
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);
}
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));
if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1)
m_menuDecompLanguage->AppendRadioItem(wxID_DECOMP_LANGUAGE_START + i, label_tran, wxString::Format(_("Select %s language for decomposition"), (const wxStringCharType*)label_tran));
m_toolDecompLanguage->Insert(label_tran, i);
if (memcmp(m_lang, lang.id, sizeof(m_lang)) == 0)
m_toolDecompLanguage->Select(i);
}
// Set focus.
@@ -81,17 +87,95 @@ wxZRColaFrame::wxZRColaFrame() :
wxMessageBox(_("ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality will not be available."), _("Warning"), wxOK | wxICON_WARNING);
if (!RegisterHotKey(wxZRColaHKID_INVOKE_DECOMPOSE, wxMOD_WIN, VK_F6))
wxMessageBox(_("ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality will not be available."), _("Warning"), wxOK | wxICON_WARNING);
#if defined(__WXMSW__)
// Register notification sink for language detection.
m_ulRefCount = 1;
m_tfSource = NULL;
ITfInputProcessorProfiles *pProfiles;
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, (LPVOID*)&pProfiles);
if(SUCCEEDED(hr)) {
hr = pProfiles->QueryInterface(IID_ITfSource, (LPVOID*)&m_tfSource);
if(SUCCEEDED(hr)) {
hr = m_tfSource->AdviseSink(IID_ITfLanguageProfileNotifySink, (ITfLanguageProfileNotifySink*)this, &m_dwCookie);
if (FAILED(hr) || m_dwCookie == -1) {
m_tfSource->Release();
m_tfSource = NULL;
}
}
pProfiles->Release();
}
#endif
}
wxZRColaFrame::~wxZRColaFrame()
{
#if defined(__WXMSW__)
if (m_tfSource) {
m_tfSource->UnadviseSink(m_dwCookie);
m_tfSource->Release();
}
#endif
// Unregister global hotkey(s).
UnregisterHotKey(wxZRColaHKID_INVOKE_DECOMPOSE);
UnregisterHotKey(wxZRColaHKID_INVOKE_COMPOSE);
}
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();
}
void wxZRColaFrame::OnForwardEventUpdate(wxUpdateUIEvent& event)
{
wxControl *focusWnd = wxDynamicCast(FindFocus(), wxControl);
@@ -153,6 +237,32 @@ void wxZRColaFrame::OnSendAbort(wxCommandEvent& event)
}
void wxZRColaFrame::OnDecomposedLanguageAutoUpdate(wxUpdateUIEvent& event)
{
#if defined(__WXMSW__)
event.Check(m_lang_auto);
#else
event.Enable(false);
#endif
}
void wxZRColaFrame::OnDecomposedLanguageAuto(wxCommandEvent& event)
{
// Toggle auto language flag.
m_lang_auto = !m_lang_auto;
if (m_lang_auto) {
#if defined(__WXMSW__)
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), m_lang);
UpdateDecomposedLanguage();
#endif
}
}
void wxZRColaFrame::OnDecomposedLanguageUpdate(wxUpdateUIEvent& event)
{
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
@@ -174,6 +284,7 @@ void wxZRColaFrame::OnDecomposedLanguage(wxCommandEvent& event)
// 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;
}
}
@@ -190,22 +301,77 @@ void wxZRColaFrame::OnDecompLanguageChoice(wxCommandEvent& event)
// 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::OnExit(wxCommandEvent& event)
{
Close();
}
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);
}
#if defined(__WXMSW__)
HRESULT STDMETHODCALLTYPE wxZRColaFrame::OnLanguageChange(LANGID langid, __RPC__out BOOL *pfAccept)
{
if (pfAccept) *pfAccept = TRUE;
return S_OK;
}
HRESULT STDMETHODCALLTYPE wxZRColaFrame::OnLanguageChanged()
{
if (m_lang_auto) {
// Set keyboard language.
HKL hkl = ::GetKeyboardLayout(0);
ZRCola::LangConvert(LOWORD(hkl), m_lang);
UpdateDecomposedLanguage();
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE wxZRColaFrame::QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
if (!ppvObject)
return E_INVALIDARG;
if (riid == IID_IUnknown)
*ppvObject = static_cast<IUnknown*>(this);
else if (riid == IID_ITfLanguageProfileNotifySink)
*ppvObject = static_cast<ITfLanguageProfileNotifySink*>(this);
else {
*ppvObject = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
ULONG STDMETHODCALLTYPE wxZRColaFrame::AddRef()
{
InterlockedIncrement(&m_ulRefCount);
return m_ulRefCount;
}
ULONG STDMETHODCALLTYPE wxZRColaFrame::Release()
{
// Decrement the object's internal counter.
ULONG ulRefCount = InterlockedDecrement(&m_ulRefCount);
if (m_ulRefCount == 0)
delete this;
return ulRefCount;
}
#endif
void wxZRColaFrame::DoSend(const wxString& str)
{
// Prepare the INPUT table.
@@ -240,6 +406,22 @@ 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)
{
if (message == WM_HOTKEY) {
@@ -286,6 +468,8 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM
return wxZRColaFrameBase::MSWWindowProc(message, wParam, lParam);
}
#endif
//////////////////////////////////////////////////////////////////////////
// wxPersistentZRColaFrame
@@ -298,10 +482,11 @@ wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersist
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)));
wxPersistentZRColaComposerPanel(wnd->m_panel).Save();
SaveValue(wxT("langAuto"), wnd->m_lang_auto);
SaveValue(wxT("lang" ), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang)));
wxPersistentTLW::Save();
}
@@ -312,20 +497,28 @@ bool wxPersistentZRColaFrame::Restore()
wxZRColaFrame * const wnd = static_cast<wxZRColaFrame*>(GetWindow());
ZRColaApp *app = ((ZRColaApp*)wxTheApp);
wxString lang;
if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) {
// 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));
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));
}
}
} 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();
wxPersistentZRColaComposerPanel(wnd->m_panel).Restore();
return r;
}

View File

@@ -29,6 +29,9 @@ class wxZRColaFrame;
#include "zrcolagui.h"
#include <zrcola/language.h>
#include <wx/persist/toplevel.h>
#if defined(__WXMSW__)
#include <msctf.h>
#endif
///
@@ -41,7 +44,11 @@ class wxZRColaFrame;
///
/// ZRCola main frame
///
class wxZRColaFrame : public wxZRColaFrameBase
class wxZRColaFrame :
public wxZRColaFrameBase
#if defined(__WXMSW__)
, protected ITfLanguageProfileNotifySink
#endif
{
public:
enum
@@ -53,30 +60,54 @@ public:
wxZRColaFrame();
virtual ~wxZRColaFrame();
friend class wxPersistentZRColaFrame;
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 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 OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
friend class wxPersistentZRColaFrame;
friend class wxZRColaComposerPanel;
protected:
#if defined(__WXMSW__)
ITfSource *m_tfSource; ///< Text Services install sink helper
DWORD m_dwCookie; ///< Text Services installed sink cookie
// ITfLanguageProfileNotifySink implementation
virtual HRESULT STDMETHODCALLTYPE OnLanguageChange(LANGID langid, __RPC__out BOOL *pfAccept);
virtual HRESULT STDMETHODCALLTYPE OnLanguageChanged();
// IUnknown implementation
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
ULONG m_ulRefCount; ///< COM object reference count
#endif
private:
void DoSend(const wxString& str);
void UpdateDecomposedLanguage();
protected:
#ifdef __WXMSW__
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
#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
};

View File

@@ -28,6 +28,12 @@ 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 );
@@ -99,6 +105,12 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
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_menuDecompLanguage->AppendSeparator();
m_menuEdit->Append( m_menuDecompLanguageItem );
m_menubar->Append( m_menuEdit, _("&Edit") );
@@ -160,33 +172,117 @@ wxZRColaFrameBase::~wxZRColaFrameBase()
}
wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style )
wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* bSizerEditor;
bSizerEditor = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_decomposed = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE );
m_splitterDecomposed = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE );
m_splitterDecomposed->SetSashGravity( 1 );
m_splitterDecomposed->Connect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDecomposedOnIdle ), NULL, this );
m_splitterDecomposed->SetMinimumPaneSize( 5 );
m_panelDecomposedEdit = new wxPanel( m_splitterDecomposed, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerDecomposedEdit;
bSizerDecomposedEdit = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* bSizerDecomposedEdit2;
bSizerDecomposedEdit2 = new wxStaticBoxSizer( new wxStaticBox( m_panelDecomposedEdit, wxID_ANY, _("Decomposed Text") ), wxVERTICAL );
m_decomposed = new wxTextCtrl( bSizerDecomposedEdit2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
m_decomposed->SetFont( wxFont( 20, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_decomposed->SetMinSize( wxSize( 100,25 ) );
bSizerEditor->Add( m_decomposed, 50, wxALL|wxEXPAND, 5 );
bSizerDecomposedEdit2->Add( m_decomposed, 1, wxEXPAND, 5 );
m_composed = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CENTRE|wxTE_MULTILINE );
bSizerDecomposedEdit->Add( bSizerDecomposedEdit2, 1, wxEXPAND, 5 );
m_panelDecomposedEdit->SetSizer( bSizerDecomposedEdit );
m_panelDecomposedEdit->Layout();
bSizerDecomposedEdit->Fit( m_panelDecomposedEdit );
m_panelDecomposedHex = new wxPanel( m_splitterDecomposed, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerDecomposedHex;
bSizerDecomposedHex = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* bSizerDecomposedHex2;
bSizerDecomposedHex2 = new wxStaticBoxSizer( new wxStaticBox( m_panelDecomposedHex, wxID_ANY, _("Decomposed Unicode Dump") ), wxVERTICAL );
m_decomposedHex = new wxTextCtrl( bSizerDecomposedHex2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
m_decomposedHex->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 76, 90, 90, false, wxEmptyString ) );
bSizerDecomposedHex2->Add( m_decomposedHex, 1, wxEXPAND, 5 );
bSizerDecomposedHex->Add( bSizerDecomposedHex2, 1, wxEXPAND, 5 );
m_panelDecomposedHex->SetSizer( bSizerDecomposedHex );
m_panelDecomposedHex->Layout();
bSizerDecomposedHex->Fit( m_panelDecomposedHex );
m_splitterDecomposed->SplitVertically( m_panelDecomposedEdit, m_panelDecomposedHex, -5 );
bSizerMain->Add( m_splitterDecomposed, 50, wxALL|wxEXPAND, 5 );
m_splitterComposed = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_LIVE_UPDATE );
m_splitterComposed->SetSashGravity( 1 );
m_splitterComposed->Connect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterComposedOnIdle ), NULL, this );
m_splitterComposed->SetMinimumPaneSize( 5 );
m_panelComposedEdit = new wxPanel( m_splitterComposed, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerComposedEdit;
bSizerComposedEdit = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* bSizerComposedEdit2;
bSizerComposedEdit2 = new wxStaticBoxSizer( new wxStaticBox( m_panelComposedEdit, wxID_ANY, _("Composed Text") ), wxVERTICAL );
m_composed = new wxTextCtrl( bSizerComposedEdit2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE );
m_composed->SetFont( wxFont( 20, 70, 90, 90, false, wxT("00 ZRCola") ) );
m_composed->SetMinSize( wxSize( 100,25 ) );
bSizerEditor->Add( m_composed, 50, wxALL|wxEXPAND, 5 );
bSizerComposedEdit2->Add( m_composed, 1, wxEXPAND, 5 );
this->SetSizer( bSizerEditor );
bSizerComposedEdit->Add( bSizerComposedEdit2, 1, wxEXPAND, 5 );
m_panelComposedEdit->SetSizer( bSizerComposedEdit );
m_panelComposedEdit->Layout();
bSizerComposedEdit->Fit( m_panelComposedEdit );
m_panelComposedHex = new wxPanel( m_splitterComposed, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerComposedHex;
bSizerComposedHex = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* bSizerComposedHex2;
bSizerComposedHex2 = new wxStaticBoxSizer( new wxStaticBox( m_panelComposedHex, wxID_ANY, _("Composed Unicode Dump") ), wxVERTICAL );
m_composedHex = new wxTextCtrl( bSizerComposedHex2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
m_composedHex->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 76, 90, 90, false, wxEmptyString ) );
bSizerComposedHex2->Add( m_composedHex, 1, wxEXPAND, 5 );
bSizerComposedHex->Add( bSizerComposedHex2, 1, wxEXPAND, 5 );
m_panelComposedHex->SetSizer( bSizerComposedHex );
m_panelComposedHex->Layout();
bSizerComposedHex->Fit( m_panelComposedHex );
m_splitterComposed->SplitVertically( m_panelComposedEdit, m_panelComposedHex, -5 );
bSizerMain->Add( m_splitterComposed, 50, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerEditor->Fit( this );
bSizerMain->Fit( this );
// Connect Events
m_decomposed->Connect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnDecomposedPaint ), NULL, this );
m_decomposed->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaComposerPanelBase::OnDecomposedText ), NULL, this );
m_decomposedHex->Connect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnDecomposedHexPaint ), NULL, this );
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 );
}
wxZRColaComposerPanelBase::~wxZRColaComposerPanelBase()
@@ -194,7 +290,9 @@ wxZRColaComposerPanelBase::~wxZRColaComposerPanelBase()
// Disconnect Events
m_decomposed->Disconnect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnDecomposedPaint ), NULL, this );
m_decomposed->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( wxZRColaComposerPanelBase::OnDecomposedText ), NULL, this );
m_decomposedHex->Disconnect( wxEVT_PAINT, wxPaintEventHandler( wxZRColaComposerPanelBase::OnDecomposedHexPaint ), NULL, this );
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 );
}

View File

@@ -29,7 +29,9 @@
#include <wx/statusbr.h>
#include <wx/frame.h>
#include <wx/textctrl.h>
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
///////////////////////////////////////////////////////////////////////////
@@ -43,9 +45,11 @@ class wxZRColaFrameBase : public wxFrame
protected:
enum
{
wxID_SEND_COMPOSED = 1000,
wxID_AUTOSTART = 1000,
wxID_SEND_COMPOSED,
wxID_SEND_DECOMPOSED,
wxID_SEND_ABORT
wxID_SEND_ABORT,
wxID_DECOMP_LANG_AUTO
};
wxMenuBar* m_menubar;
@@ -84,20 +88,42 @@ class wxZRColaComposerPanelBase : public wxPanel
private:
protected:
wxSplitterWindow* m_splitterDecomposed;
wxPanel* m_panelDecomposedEdit;
wxTextCtrl* m_decomposed;
wxPanel* m_panelDecomposedHex;
wxTextCtrl* m_decomposedHex;
wxSplitterWindow* m_splitterComposed;
wxPanel* m_panelComposedEdit;
wxTextCtrl* m_composed;
wxPanel* m_panelComposedHex;
wxTextCtrl* m_composedHex;
// Virtual event handlers, overide them in your derived class
virtual void OnDecomposedPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnDecomposedText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDecomposedHexPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnComposedPaint( wxPaintEvent& event ) { event.Skip(); }
virtual void OnComposedText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnComposedHexPaint( wxPaintEvent& event ) { event.Skip(); }
public:
wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL );
wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxT("ZRColaComposerPanel") );
~wxZRColaComposerPanelBase();
void m_splitterDecomposedOnIdle( wxIdleEvent& )
{
m_splitterDecomposed->SetSashPosition( -5 );
m_splitterDecomposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterDecomposedOnIdle ), NULL, this );
}
void m_splitterComposedOnIdle( wxIdleEvent& )
{
m_splitterComposed->SetSashPosition( -5 );
m_splitterComposed->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaComposerPanelBase::m_splitterComposedOnIdle ), NULL, this );
}
};

View File

@@ -302,7 +302,12 @@ bool ZRCola::DBSource::SelectTranslations(ATL::CComPtr<ADORecordset> &rs) const
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT [komb], [znak] FROM [VRS_ReplChar] WHERE [rang_komb]=1"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT [komb], [znak], [rang_znak] "
L"FROM [VRS_ReplChar] "
L"WHERE [rang_komb]=1 "
L"ORDER BY [znak], [rang_znak], [komb]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0040: Error loading compositions from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
@@ -331,6 +336,12 @@ bool ZRCola::DBSource::GetTranslation(const ATL::CComPtr<ADORecordset>& rs, ZRCo
wxCHECK(GetUnicodeCharacter(f, t.chr), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"rang_znak"), &f)));
wxCHECK(GetValue(f, t.rank), false);
}
return true;
}
@@ -342,7 +353,11 @@ bool ZRCola::DBSource::SelectKeySequences(ATL::CComPtr<ADORecordset> &rs) const
wxCHECK(SUCCEEDED(::CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_ALL, IID_IADORecordset, (LPVOID*)&rs)), false);
// Open it.
if (FAILED(rs->Open(ATL::CComVariant(L"SELECT DISTINCT [VRS_KeyCodes].[Znak], [VRS_CharGroup].[Name] AS [CharGroup], [VRS_KeyCodes].[KeyCode], [VRS_KeyCodes].[Shift] FROM [VRS_KeyCodes] LEFT JOIN [VRS_CharGroup] ON [VRS_CharGroup].[CharGroup]=[VRS_KeyCodes].[CharGroup]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText))) {
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT DISTINCT [VRS_KeyCodes].[Znak], [VRS_CharGroup].[Name] AS [CharGroup], [VRS_KeyCodes].[KeyCode], [VRS_KeyCodes].[Shift] "
L"FROM [VRS_KeyCodes] LEFT JOIN [VRS_CharGroup] ON [VRS_CharGroup].[CharGroup]=[VRS_KeyCodes].[CharGroup] "
L"ORDER BY [VRS_CharGroup].[Name], [VRS_KeyCodes].[KeyCode], [VRS_KeyCodes].[Shift], [VRS_KeyCodes].[Znak]"), ATL::CComVariant(m_db), adOpenStatic, adLockReadOnly, adCmdText)))
{
_ftprintf(stderr, wxT("%s: error ZCC0050: Error loading key sequences from database. Please make sure the file is ZRCola.zrc compatible.\n"), m_filename.c_str());
LogErrors();
return false;
@@ -410,7 +425,11 @@ bool ZRCola::DBSource::SelectLanguages(ATL::CComPtr<ADORecordset> &rs) const
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))) {
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT DISTINCT [entCode], [Jezik_En] "
L"FROM [VRS_Jezik] "
L"ORDER BY [entCode], [Jezik_En]"), 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;
@@ -433,6 +452,12 @@ bool ZRCola::DBSource::GetLanguage(const ATL::CComPtr<ADORecordset>& rs, ZRCola:
wxCHECK(GetLanguage(f, lang.id), false);
}
{
ATL::CComPtr<ADOField> f;
wxVERIFY(SUCCEEDED(flds->get_Item(ATL::CComVariant(L"Jezik_En"), &f)));
wxCHECK(GetValue(f, lang.name), false);
}
return true;
}
@@ -444,7 +469,11 @@ bool ZRCola::DBSource::SelectLanguageCharacters(ATL::CComPtr<ADORecordset> &rs)
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))) {
if (FAILED(rs->Open(ATL::CComVariant(
L"SELECT DISTINCT [znak], [lang] "
L"FROM [VRS_CharLocal] "
L"ORDER BY [znak], [lang]"), 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;

View File

@@ -41,6 +41,7 @@ namespace ZRCola {
public:
wchar_t chr; ///< Composed character
std::wstring str; ///< Decomposed string
int rank; ///< Decomposition rank
};
@@ -71,6 +72,7 @@ namespace ZRCola {
class language {
public:
ZRCola::langid_t id; ///< Language ID
std::wstring name; ///< Language name
};

View File

@@ -1,8 +1,8 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRColaCompile\n"
"POT-Creation-Date: 2016-03-14 17:18+0100\n"
"PO-Revision-Date: 2016-03-14 17:18+0100\n"
"POT-Creation-Date: 2016-04-13 18:11+0200\n"
"PO-Revision-Date: 2016-04-13 18:11+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,14 +17,18 @@ msgstr ""
"X-Poedit-KeywordsList: _\n"
"X-Poedit-SearchPath-0: .\n"
#: main.cpp:165
#: main.cpp:276
msgid "Show this help message"
msgstr "Pokaži to sporočilo pomoči"
#: main.cpp:166
msgid "input file"
msgstr "vhodna datoteka"
#: main.cpp:277
msgid "<input file>"
msgstr "<vhodna datoteka>"
#: main.cpp:167
msgid "output file"
msgstr "izhodna datoteka"
#: main.cpp:278
msgid "<output file>"
msgstr "<izhodna datoteka>"
#: main.cpp:279
msgid "<output POT catalog>"
msgstr "<izhodni katalog POT>"

View File

@@ -274,8 +274,9 @@ int _tmain(int argc, _TCHAR *argv[])
static const wxCmdLineEntryDesc cmdLineDesc[] =
{
{ wxCMD_LINE_SWITCH, "h" , "help", _("Show this help message"), wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP },
{ wxCMD_LINE_PARAM , NULL, NULL , _("input file") , wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("output file") , wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<input file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<output file>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION_MANDATORY },
{ wxCMD_LINE_PARAM , NULL, NULL , _("<output POT catalog>" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_OPTION },
{ wxCMD_LINE_NONE }
};
@@ -317,6 +318,10 @@ int _tmain(int argc, _TCHAR *argv[])
bool has_errors = false;
// Set of strings to translate.
bool build_pot = parser.GetParamCount() > 2;
std::set<std::wstring> pot;
// Open file ID.
std::streamoff dst_start = stdex::idrec::open<ZRCola::recordid_t, ZRCola::recordsize_t>(dst, ZRCOLA_DB_ID);
@@ -341,6 +346,8 @@ int _tmain(int argc, _TCHAR *argv[])
// Add translation to index and data.
unsigned __int32 idx = db.data.size();
db.data.push_back(trans.chr);
wxASSERT_MSG((int)0xffff8000 <= trans.rank && trans.rank <= (int)0x00007fff, wxT("transformation rank out of bounds"));
db.data.push_back((unsigned __int16)trans.rank);
std::wstring::size_type n = trans.str.length();
wxASSERT_MSG(n <= 0xffff, wxT("transformation string too long"));
db.data.push_back((unsigned __int16)n);
@@ -460,7 +467,14 @@ int _tmain(int argc, _TCHAR *argv[])
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]);
std::wstring::size_type n = lang.name.length();
wxASSERT_MSG(n <= 0xffff, wxT("language name too long"));
db.data.push_back((unsigned __int16)n);
for (std::wstring::size_type i = 0; i < n; i++)
db.data.push_back(lang.name[i]);
db.idxLng.push_back(idx);
if (build_pot)
pot.insert(lang.name);
} else
has_errors = true;
@@ -542,6 +556,50 @@ int _tmain(int argc, _TCHAR *argv[])
has_errors = true;
}
if (!has_errors && build_pot) {
const wxString& filenamePot = parser.GetParam(2);
std::fstream dst((LPCTSTR)filenamePot, std::ios_base::out | std::ios_base::trunc);
if (dst.good()) {
dst << "msgid \"\"" << std::endl
<< "msgstr \"\"" << std::endl
<< "\"Project-Id-Version: ZRCola.zrcdb\\n\"" << std::endl
<< "\"Language: en\\n\"" << std::endl
<< "\"MIME-Version: 1.0\\n\"" << std::endl
<< "\"Content-Type: text/plain; charset=UTF-8\\n\"" << std::endl
<< "\"Content-Transfer-Encoding: 8bit\\n\"" << std::endl
<< "\"X-Generator: ZRColaCompile " << ZRCOLA_VERSION_STR << "\\n\"" << std::endl;
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
for (std::set<std::wstring>::const_iterator i = pot.cbegin(); i != pot.cend(); ++i) {
// Convert UTF-16 to UTF-8 and escape.
std::string t(conv.to_bytes(*i)), u;
for (size_t i = 0, n = t.size(); i < n; i++) {
char c = t[i];
switch (c) {
case '\'': u += "\\\'"; break;
case '\"': u += "\\\""; break;
case '\n': u += "\\\n"; break;
case '\t': u += "\\\t"; break;
default : u += c;
}
}
dst << std::endl
<< "msgid \"" << u << "\"" << std::endl
<< "msgstr \"\"" << std::endl;
}
if (dst.fail()) {
_ftprintf(stderr, wxT("%s: error ZCC0013: Writing to POT catalog failed.\n"), (LPCTSTR)filenameOut.c_str());
has_errors = true;
}
dst.close();
} else {
_ftprintf(stderr, wxT("%s: error ZCC0012: Error opening POT catalog.\n"), filenameOut.fn_str());
has_errors = true;
}
}
if (has_errors) {
dst.close();
wxRemoveFile(filenameOut);

View File

@@ -46,4 +46,6 @@
#include <stdlib.h>
#include <codecvt>
#include <fstream>
#include <set>

655
bin/ZRCUpdate.wsf Normal file
View File

@@ -0,0 +1,655 @@
<?xml version="1.0"?>
<!--
Copyright 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/>.
-->
<package>
<job id="CharImport">
<runtime>
<description>Unicode Character Description Update - Amebis, Copyright © 2016</description>
<unnamed name="&lt;ZRCola.mdb&gt;" required="true" helpstring="ZRCola database"/>
<unnamed name="&lt;UnicodeData.txt&gt;" required="true" helpstring="Unicode character database (from http://www.unicode.org/Public/UNIDATA/UnicodeData.txt)"/>
<named name="F" type="simple" required="false" helpstring="Force overwrite of existing data"/>
</runtime>
<reference object="ADODB.Connection"/>
<reference object="ADODB.Command"/>
<reference object="ADODB.Recordset"/>
<reference object="Scripting.FileSystemObject"/>
<script language="JScript"><![CDATA[
if (WScript.Arguments.Unnamed.Length < 2) {
WScript.Arguments.ShowUsage();
WScript.Quit(1);
}
var force = WScript.Arguments.Named.Exists("F") ? true : false;
// Open ZRCola database.
var db = WScript.CreateObject("ADODB.Connection");
db.Open("Driver={Microsoft Access Driver (*.mdb)};Dbq=" + WScript.Arguments.Unnamed(0) + ";Uid=;Pwd=;");
try {
// Open Unicode Data file.
var
fso = WScript.CreateObject("Scripting.FileSystemObject"),
f = fso.OpenTextFile(WScript.Arguments.Unnamed(1), ForReading);
try {
var
now = new Date(),
com = WScript.CreateObject("ADODB.Command"), param_znak,
rs = WScript.CreateObject("ADODB.Recordset");
com.Prepared = true;
com.ActiveConnection = db;
com.CommandType = adCmdText;
com.CommandText = "SELECT TOP 1 * FROM [VRS_CharList] WHERE [znak]=?";
com.Parameters.Append(param_znak = com.CreateParameter("znak", adChar, adParamInput, 4));
rs.CursorLocation = adUseClient;
rs.CursorType = adOpenDynamic;
rs.LockType = adLockOptimistic;
db.BeginTrans();
try {
// Parse Unicode Data file.
while (!f.AtEndOfStream) {
var
line = f.ReadLine(),
fields = line.split(";"),
unicode = parseInt(fields[0], 16),
v;
if (unicode < 0x0020 || 0xffff < unicode) {
// Skip characters outside of 0020-FFFF range.
continue;
}
// Convert Unicode HEX code to uppercase for consistent database experience.
fields[ 0] = fields[ 0].toUpperCase();
fields[12] = fields[12] != "" ? fields[12].toUpperCase() : fields[ 0];
fields[13] = fields[13] != "" ? fields[13].toUpperCase() : fields[ 0];
fields[14] = fields[14] != "" ? fields[14].toUpperCase() : fields[12];
var
desc_en = fields[1] != "<control>" ? fields[1] : fields[10],
dig_dec = fields[6] != "" ? parseInt(fields[6], 10) : null,
digit = fields[7] != "" ? parseInt(fields[7], 10) : null,
mirror = fields[9] == "Y" || fields[9] == "y";
if (fields[1].charAt(0) == "<") {
// Skip range start and stop descriptors.
continue;
}
// Search the character.
param_znak.Value = fields[0];
rs.Open(com);
try {
if (rs.EOF) {
// If a character does not exist yet, create it.
rs.AddNew();
rs("znak" ).Value = fields[0];
rs("znakZRCOLA" ).Value = String.fromCharCode(unicode);
rs("opis_en" ).Value = desc_en;
rs("kat" ).Value = fields[2];
rs("komb" ).Value = parseInt(fields[3], 10);
rs("stevka10" ).Value = dig_dec;
rs("stevka" ).Value = digit;
rs("stevilo" ).Value = fields[8];
rs("zrcali" ).Value = mirror ? 1 : 0;
rs("znak_v" ).Value = fields[12];
rs("znakZRCOLA_v" ).Value = String.fromCharCode(parseInt(fields[12], 16));
rs("znak_m" ).Value = fields[13];
rs("znakZRCOLA_m" ).Value = String.fromCharCode(parseInt(fields[13], 16));
rs("znak_tc" ).Value = fields[14];
rs("znakZRCOLA_tc").Value = String.fromCharCode(parseInt(fields[14], 16));
rs.Update();
} else {
var updated = false;
if (force || (v = rs("opis_en").Value) == null || v == "") { rs("opis_en" ).Value = desc_en; updated = true; }
if (force || (v = rs("kat" ).Value) == null || v == "") { rs("kat" ).Value = fields[2]; updated = true; }
if (force || (v = rs("komb" ).Value) == null ) { rs("komb" ).Value = parseInt(fields[3], 10); updated = true; }
if (force ) { rs("stevka10").Value = dig_dec; updated = true; }
if (force ) { rs("stevka" ).Value = digit; updated = true; }
if (force ) { rs("stevilo" ).Value = fields[8]; updated = true; }
if (force ) { rs("zrcali" ).Value = mirror ? 1 : 0; updated = true; }
if (force ) { rs("znak_v" ).Value = fields[12]; rs("znakZRCOLA_v" ).Value = String.fromCharCode(parseInt(fields[12], 16)); updated = true; }
if (force ) { rs("znak_m" ).Value = fields[13]; rs("znakZRCOLA_m" ).Value = String.fromCharCode(parseInt(fields[13], 16)); updated = true; }
if (force ) { rs("znak_tc" ).Value = fields[14]; rs("znakZRCOLA_tc").Value = String.fromCharCode(parseInt(fields[14], 16)); updated = true; }
if (updated) {
// Changing [updat] field causes Microsoft Cursor Engine: Row cannot be located for updating. Some values may have been changed since it was last read.
//rs("updat").Value = (new Date(now.getTime() + now.getTimezoneOffset()*60*1000)).getVarDate();
rs.Update();
}
}
} finally {
rs.Close();
}
}
db.CommitTrans();
} catch (err) {
db.RollbackTrans();
throw err;
}
} finally {
f.Close();
}
} finally {
db.Close();
}
WScript.Quit(0);
]]></script>
</job>
<job id="CharDescGenerate">
<runtime>
<description>Dynamic Character Description Generator - Amebis, Copyright © 2016</description>
<unnamed name="&lt;ZRCola.mdb&gt;" required="true" helpstring="ZRCola database"/>
<named name="F" type="simple" required="false" helpstring="Force overwrite of existing data"/>
</runtime>
<reference object="ADODB.Connection"/>
<reference object="ADODB.Command"/>
<reference object="ADODB.Recordset"/>
<script language="JScript"><![CDATA[
if (WScript.Arguments.Unnamed.Length < 1) {
WScript.Arguments.ShowUsage();
WScript.Quit(1);
}
function ZRColaDecompositionParser(db)
{
// Prepare query for existing character description search.
this.com_desc = WScript.CreateObject("ADODB.Command");
this.com_desc.Prepared = true;
this.com_desc.ActiveConnection = db;
this.com_desc.CommandType = adCmdText;
this.com_desc.CommandText = "SELECT TOP 1 [opis_en] FROM [VRS_CharList] WHERE [znak]=?";
this.com_desc.Parameters.Append(this.param_desc_znak = this.com_desc.CreateParameter("znak", adChar, adParamInput, 4));
this.rs_desc = WScript.CreateObject("ADODB.Recordset");
this.rs_desc.CursorLocation = adUseClient;
this.rs_desc.CursorType = adOpenStatic;
this.rs_desc.LockType = adLockReadOnly;
}
ZRColaDecompositionParser.prototype.nextChar = function()
{
if (!this.decomposed.length) {
this.sym = null;
this.desc = null;
return;
}
// Get next character.
this.sym = this.decomposed.shift();
// Get character's description.
this.param_desc_znak.Value = this.sym;
this.rs_desc.Open(this.com_desc);
try {
if (!this.rs_desc.EOF) {
var v;
if ((v = this.rs_desc("opis_en").Value) != null && v != "")
this.desc = v;
else
throw new Error(this.sym + " character has no description.");
} else
throw new Error(this.sym + " character not found.");
} finally {
this.rs_desc.Close();
}
}
ZRColaDecompositionParser.prototype.modifiers = function()
{
var desc = "";
for (;;) {
if (
this.sym >= "E000" && this.sym <= "E05B" || // 1st Set of Modifiers
this.sym >= "E063" && this.sym <= "E0BB" || // 2nd Set of Modifiers
this.sym == "003A" || // Colon
this.sym == "2019") // Right Single Quotation Mark
{
desc += (desc.length ? " AND " : "") + this.desc;
this.nextChar();
} else if (this.sym >= "02B0" && this.sym <= "02FF") {
// Standard Unicode Modifiers
if (this.desc.indexOf("MODIFIER LETTER ") == 0)
this.desc = this.desc.substring(16);
desc += (desc.length ? " AND " : "") + this.desc;
this.nextChar();
} else
break;
}
return desc.length ? desc : null;
}
ZRColaDecompositionParser.prototype.envelopes = function()
{
var desc = "";
for (;;) {
if (
this.sym == "E0C0" || // Circle
this.sym == "E0C2" || // Square
this.sym == "E0CA") // Diamond
{
desc += (desc.length ? " AND " : "") + this.desc;
this.nextChar();
} else
break;
}
return desc.length ? desc : null;
}
ZRColaDecompositionParser.prototype.parentheses = function(open, close, desc)
{
if (this.sym == open) {
// Parenthesis Start
this.nextChar();
var desc_p = desc + " " + this.expression();
if (this.sym == close) {
// Parenthesis End
this.nextChar();
} else
throw new Error(this.sym + " is unexpected. Should end with " + close + ".");
return desc_p;
} else
return null;
}
ZRColaDecompositionParser.prototype.character = function()
{
var desc;
if (desc = this.parentheses("E0C5", "E0C6", "SUPERSCRIPTED")) {
// Superscript
return desc;
} else if (desc = this.parentheses("E2E0", "E2E1", "EVA DOUBLED")) {
// EVA Double
return desc;
} else if (desc = this.parentheses("E2E2", "E2E3", "EVA CONDENSED")) {
// EVA Condensed
return desc;
} else if (desc = this.parentheses("E2E4", "E2E5", "EVA EMPHASIZED")) {
// EVA Emphasis
return desc;
} else if (desc = this.parentheses("E2E6", "E2E7", "EVA STRIKED")) {
// EVA Strike
return desc;
} else if (desc = this.parentheses("E2E8", "E2E9", "EVA UNDEALED")) {
// EVA Undeal
return desc;
} else if (desc = this.parentheses("E2EA", "E2EB", "EVA ITALIC")) {
// EVA Italic
return desc;
} else if (desc = this.parentheses("E2EC", "E2ED", "EVA SUPERSCRIPTED")) {
// EVA Superscript
return desc;
} else if (desc = this.parentheses("E2EE", "E2EF", "EVA SUBSCRIPTED")) {
// EVA Subscript
return desc;
} else if (this.sym < "E000" || this.sym > "E0FC") {
// Base Character
desc = this.desc;
this.nextChar();
var has_with = desc.indexOf(" WITH ") >= 0;
for (;;) {
var desc2;
if (desc2 = this.modifiers()) {
desc += (has_with ? " AND " : " WITH ") + desc2;
has_with = true;
} else if (desc2 = this.envelopes()) {
desc += " IN " + desc2;
has_with = false;
} else
break;
}
return desc;
} else
throw new Error("Syntax error");
}
ZRColaDecompositionParser.prototype.term = function()
{
var desc = new Array(this.character());
while (this.sym == "E0C4") {
// Ligature
this.nextChar();
desc.push(this.character());
}
if (desc.length == 1) {
return desc[0];
} else if (desc.length == 2) {
if (desc[0] == desc[1])
return "DOUBLE " + desc[0];
} else if (desc.length == 3) {
if (desc[0] == desc[1] && desc[0] == desc[2])
return "TRIPLE " + desc[0];
}
return desc.join(" AND ") + " LIGATURE";
}
ZRColaDecompositionParser.prototype.expression = function()
{
var desc = "";
if (this.sym >= "E0F0" && this.sym <= "E0FC") {
// Prefix modifier
desc += this.desc + " ";
this.nextChar();
}
desc += this.term();
while (
this.sym >= "E05C" && this.sym <= "E062" ||
this.sym == "E0C1" || this.sym == "E0C3" || this.sym == "E0C7" || this.sym == "E0CB" || this.sym == "E0D0" || this.sym == "E0D1")
{
// Joiner
desc += " " + this.desc + " WITH ";
this.nextChar();
var desc2 = "";
for (;;) {
var desc3;
if (desc3 = this.modifiers())
desc2 += (desc2.length ? " AND " : " WITH ") + desc3;
else if (desc3 = this.envelopes())
desc2 += " IN " + desc3;
else
break;
}
desc += this.term();
desc += desc2;
}
return desc;
}
ZRColaDecompositionParser.prototype.parse = function(decomposed)
{
this.decomposed = decomposed.slice(0); // Duplicate array.
this.nextChar();
var desc = this.expression();
if (this.sym != null)
throw new Error("Unexpected trailing characters.");
return desc;
}
var force = WScript.Arguments.Named.Exists("F") ? true : false;
// Open ZRCola database.
var db = WScript.CreateObject("ADODB.Connection");
db.Open("Driver={Microsoft Access Driver (*.mdb)};Dbq=" + WScript.Arguments.Unnamed(0) + ";Uid=;Pwd=;");
try {
// Prepare query for character decomposition.
var com_comp = WScript.CreateObject("ADODB.Command"), param_comp_znak;
com_comp.Prepared = true;
com_comp.ActiveConnection = db;
com_comp.CommandType = adCmdText;
com_comp.CommandText = "SELECT UCase([komb]) AS [kombUC] FROM [VRS_ReplChar] WHERE [znak]=? ORDER BY [rang_znak] ASC";
com_comp.Parameters.Append(param_comp_znak = com_comp.CreateParameter("znak", adChar, adParamInput, 4));
db.BeginTrans();
try {
// Query all private-use characters.
var rs = WScript.CreateObject("ADODB.Recordset");
rs.CursorLocation = adUseClient;
rs.Open("SELECT * FROM [VRS_CharList] WHERE 'E000'<=[znak] AND [znak]<='F8FF' AND [kat] IS NULL", db, adOpenDynamic, adLockOptimistic, adCmdText);
try {
var rs_comp = WScript.CreateObject("ADODB.Recordset");
rs_comp.CursorLocation = adUseClient;
rs_comp.CursorType = adOpenStatic;
rs_comp.LockType = adLockReadOnly;
var parser = new ZRColaDecompositionParser(db);
for (; !rs.EOF; rs.MoveNext()) {
var v;
if (!force && (v = rs("opis_en").Value) != null && v != "") {
// This character already has the description.
continue;
}
// Decompose character.
var chr = rs("znak").Value;
param_comp_znak.Value = chr;
rs_comp.Open(com_comp);
try {
for (; !rs_comp.EOF; rs_comp.MoveNext()) {
var
decomposed = (v = rs_comp("kombUC").Value) != null ? (new String(v)).split("+") : new Array(),
n = decomposed.length;
if (n > 0) {
try {
var desc = parser.parse(decomposed);
rs("opis_en").value = desc;
rs.update();
break;
} catch (err) {
// We couldn't generate character description according to decomposition.
WScript.Echo(chr + " >> " + decomposed.join("+") + ": " + err.message);
}
};
}
} finally {
rs_comp.Close();
}
}
} finally {
rs.Close();
}
db.CommitTrans();
} catch (err) {
db.RollbackTrans();
throw err;
}
} finally {
db.Close();
}
WScript.Quit(0);
]]></script>
</job>
<signature>
** SIG ** MIIXmAYJKoZIhvcNAQcCoIIXiTCCF4UCAQExCzAJBgUr
** SIG ** DgMCGgUAMGcGCisGAQQBgjcCAQSgWTBXMDIGCisGAQQB
** SIG ** gjcCAR4wJAIBAQQQcAVhGs441BGiowAQS9NQkAIBAAIB
** SIG ** AAIBAAIBAAIBADAhMAkGBSsOAwIaBQAEFPhq7XksMSKn
** SIG ** 4Rdbedv+eKDdjJ50oIISyDCCA+4wggNXoAMCAQICEH6T
** SIG ** 6/t8xk5Z6kuad9QG/DswDQYJKoZIhvcNAQEFBQAwgYsx
** SIG ** CzAJBgNVBAYTAlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENh
** SIG ** cGUxFDASBgNVBAcTC0R1cmJhbnZpbGxlMQ8wDQYDVQQK
** SIG ** EwZUaGF3dGUxHTAbBgNVBAsTFFRoYXd0ZSBDZXJ0aWZp
** SIG ** Y2F0aW9uMR8wHQYDVQQDExZUaGF3dGUgVGltZXN0YW1w
** SIG ** aW5nIENBMB4XDTEyMTIyMTAwMDAwMFoXDTIwMTIzMDIz
** SIG ** NTk1OVowXjELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5
** SIG ** bWFudGVjIENvcnBvcmF0aW9uMTAwLgYDVQQDEydTeW1h
** SIG ** bnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIENBIC0g
** SIG ** RzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
** SIG ** AQCxrLNJVEuXHBIK2CV5kSJXKm/cuCbEQ3Nrwr8uUFr7
** SIG ** FMJ2jkMBJUO0oeJF9Oi3e8N0zCLXtJQAAvdN7b+0t0Qk
** SIG ** a81fRTvRRM5DEnMXgotptCvLmR6schsmTXEfsTHd+1Fh
** SIG ** AlOmqvVJLAV4RaUvic7nmef+jOJXPz3GktxK+Hsz5HkK
** SIG ** +/B1iEGc/8UDUZmq12yfk2mHZSmDhcJgFMTIyTsU2sCB
** SIG ** 8B8NdN6SIqvK9/t0fCfm90obf6fDni2uiuqm5qonFn1h
** SIG ** 95hxEbziUKFL5V365Q6nLJ+qZSDT2JboyHylTkhE/xni
** SIG ** RAeSC9dohIBdanhkRc1gRn5UwRN8xXnxycFxAgMBAAGj
** SIG ** gfowgfcwHQYDVR0OBBYEFF+a9W5czMx0mtTdfe8/2+xM
** SIG ** gC7dMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW
** SIG ** aHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMBAf8E
** SIG ** CDAGAQH/AgEAMD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6
** SIG ** Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVUaW1lc3RhbXBp
** SIG ** bmdDQS5jcmwwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDgYD
** SIG ** VR0PAQH/BAQDAgEGMCgGA1UdEQQhMB+kHTAbMRkwFwYD
** SIG ** VQQDExBUaW1lU3RhbXAtMjA0OC0xMA0GCSqGSIb3DQEB
** SIG ** BQUAA4GBAAMJm495739ZMKrvaLX64wkdu0+CBl03X6ZS
** SIG ** nxaN6hySCURu9W3rWHww6PlpjSNzCxJvR6muORH4KrGb
** SIG ** sBrDjutZlgCtzgxNstAxpghcKnr84nodV0yoZRjpeUBi
** SIG ** JZZux8c3aoMhCI5B6t3ZVz8dd0mHKhYGXqY4aiISo1EZ
** SIG ** g362MIIEozCCA4ugAwIBAgIQDs/0OMj+vzVuBNhqmBsa
** SIG ** UDANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJVUzEd
** SIG ** MBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAu
** SIG ** BgNVBAMTJ1N5bWFudGVjIFRpbWUgU3RhbXBpbmcgU2Vy
** SIG ** dmljZXMgQ0EgLSBHMjAeFw0xMjEwMTgwMDAwMDBaFw0y
** SIG ** MDEyMjkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMR0wGwYD
** SIG ** VQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjE0MDIGA1UE
** SIG ** AxMrU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNl
** SIG ** cyBTaWduZXIgLSBHNDCCASIwDQYJKoZIhvcNAQEBBQAD
** SIG ** ggEPADCCAQoCggEBAKJjCzlEuLsjp0RJuw7/ofBhClOT
** SIG ** sJjbrSwPSsVu/4Y8U1UPFc4EPyv9qZaW2b5heQtbyUyG
** SIG ** duXgQ0sile7CK0PBn9hotI5AT+6FOLkRxSPyZFjwFTJv
** SIG ** TlehroikAtcqHs1L4d1j1ReJMluwXplaqJ0oUA4X7pbb
** SIG ** YTtFUR3PElYLkkf8q672Zj1HrHBy55LnX80QucSDZJQZ
** SIG ** vSWA4ejSIqXQugJ6oXeTW2XD7hd0vEGGKtwITIySjJEt
** SIG ** nndEH2jWqHR32w5bMotWizO92WPISZ06xcXqMwvS8aMb
** SIG ** 9Iu+2bNXizveBKd6IrIkri7HcMW+ToMmCPsLvalPmQjh
** SIG ** EChyqs0CAwEAAaOCAVcwggFTMAwGA1UdEwEB/wQCMAAw
** SIG ** FgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/
** SIG ** BAQDAgeAMHMGCCsGAQUFBwEBBGcwZTAqBggrBgEFBQcw
** SIG ** AYYeaHR0cDovL3RzLW9jc3Aud3Muc3ltYW50ZWMuY29t
** SIG ** MDcGCCsGAQUFBzAChitodHRwOi8vdHMtYWlhLndzLnN5
** SIG ** bWFudGVjLmNvbS90c3MtY2EtZzIuY2VyMDwGA1UdHwQ1
** SIG ** MDMwMaAvoC2GK2h0dHA6Ly90cy1jcmwud3Muc3ltYW50
** SIG ** ZWMuY29tL3Rzcy1jYS1nMi5jcmwwKAYDVR0RBCEwH6Qd
** SIG ** MBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0yMDQ4LTIwHQYD
** SIG ** VR0OBBYEFEbGaaMOShQe1UzaUmMXP142vA3mMB8GA1Ud
** SIG ** IwQYMBaAFF+a9W5czMx0mtTdfe8/2+xMgC7dMA0GCSqG
** SIG ** SIb3DQEBBQUAA4IBAQB4O7SRKgBM8I9iMDd4o4QnB28Y
** SIG ** st4l3KDUlAOqhk4ln5pAAxzdzuN5yyFoBtq2MrRtv/Qs
** SIG ** JmMz5ElkbQ3mw2cO9wWkNWx8iRbG6bLfsundIMZxD82V
** SIG ** dNy2XN69Nx9DeOZ4tc0oBCCjqvFLxIgpkQ6A0RH83Vx2
** SIG ** bk9eDkVGQW4NsOo4mrE62glxEPwcebSAe6xp9P2ctgwW
** SIG ** K/F/Wwk9m1viFsoTgW0ALjgNqCmPLOGy9FqpAa8VnCwv
** SIG ** SRvbIrvD/niUUcOGsYKIXfA9tFGheTMrLnu53CAJE3Hr
** SIG ** ahlbz+ilMFcsiUk/uc9/yb8+ImhjU5q9aXSsxR08f5Lg
** SIG ** w7wc2AR1MIIEzjCCA7agAwIBAgIQMHo2eqo+aIGm+U8I
** SIG ** yzs5ZDANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQGEwJV
** SIG ** UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24x
** SIG ** HzAdBgNVBAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsx
** SIG ** MDAuBgNVBAMTJ1N5bWFudGVjIENsYXNzIDMgU0hBMjU2
** SIG ** IENvZGUgU2lnbmluZyBDQTAeFw0xNTEwMDkwMDAwMDBa
** SIG ** Fw0xODExMDcyMzU5NTlaMGExCzAJBgNVBAYTAlNJMREw
** SIG ** DwYDVQQIEwhTbG92ZW5pYTEPMA0GA1UEBxMGS2Ftbmlr
** SIG ** MRYwFAYDVQQKFA1BbWViaXMgZC5vLm8uMRYwFAYDVQQD
** SIG ** FA1BbWViaXMgZC5vLm8uMIIBIjANBgkqhkiG9w0BAQEF
** SIG ** AAOCAQ8AMIIBCgKCAQEAl/LoF3DHaSrIaG1pgBmBwDyl
** SIG ** Yt7sRvIuoEdGr/yMhV9RfUIft+xsTPVQOAirvgG+KUbc
** SIG ** E3KMnGH+VuK7Y+vYzRp3dYTLinSQz1NKYAELyTdVzmmY
** SIG ** mU3LX764yk3ABtSZsZwPoiCy+TXE9ZsCkugB2c7Qp9N/
** SIG ** O9EjjQDRwZlUa3nLoY96Y3qNPwkCn04ppYiqPeIXTRz8
** SIG ** XBLs4Nl/bD9wymEuNSV75vzobJ7BUYQwRU7lmNL2SwRY
** SIG ** ENaf0DpdiyFLBsNafHjGYiXQHgNxZUBpj7OoRDNBvMQY
** SIG ** L+LM8OrjhGIK1uGL5CqBD/p81ebeFsAZVxg9hrgnkPVQ
** SIG ** w77U0LZw8wIDAQABo4IBYjCCAV4wCQYDVR0TBAIwADAO
** SIG ** BgNVHQ8BAf8EBAMCB4AwKwYDVR0fBCQwIjAgoB6gHIYa
** SIG ** aHR0cDovL3N2LnN5bWNiLmNvbS9zdi5jcmwwZgYDVR0g
** SIG ** BF8wXTBbBgtghkgBhvhFAQcXAzBMMCMGCCsGAQUFBwIB
** SIG ** FhdodHRwczovL2Quc3ltY2IuY29tL2NwczAlBggrBgEF
** SIG ** BQcCAjAZDBdodHRwczovL2Quc3ltY2IuY29tL3JwYTAT
** SIG ** BgNVHSUEDDAKBggrBgEFBQcDAzBXBggrBgEFBQcBAQRL
** SIG ** MEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zdi5zeW1jZC5j
** SIG ** b20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9zdi5zeW1jYi5j
** SIG ** b20vc3YuY3J0MB8GA1UdIwQYMBaAFJY7U/B5M5evfYPv
** SIG ** LivMyreGHnJmMB0GA1UdDgQWBBT3B72WgJotdMR/DD09
** SIG ** J93UkAqfzDANBgkqhkiG9w0BAQsFAAOCAQEAinEvQC+1
** SIG ** yttKEsqAjt2YufpYlul3OQH17YKbUy4AAiKiAsUXWfTu
** SIG ** XRVdkT6CrEYcHyOLaHfe36jVHw8vLIiR2cyEcB3vweyr
** SIG ** JnNpt+Za4I/XZMoG/vvCJmSltOj8C/7PRKWklGgynPNe
** SIG ** HI8+0d1vLzRtK77hFeV7CIMIfnpoYThJKTSLxdr0kn+j
** SIG ** M8otfdLN2aDonnxe0Mf+2rkrX8AFIIHPpIXZj2X2VEmk
** SIG ** ZdyFINgI+KlJVQY/RY9BFMM2htLAIkNcDP1QVzFajhGH
** SIG ** yj+C+UtZQf5PceGYtJHNeq3cm6omjnEfyzi8/NwYFlkW
** SIG ** hvzJEH3woPqKgUramNFFLD0W5zCCBVkwggRBoAMCAQIC
** SIG ** ED141/l2SWCyYX308B7KhiowDQYJKoZIhvcNAQELBQAw
** SIG ** gcoxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2ln
** SIG ** biwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3Qg
** SIG ** TmV0d29yazE6MDgGA1UECxMxKGMpIDIwMDYgVmVyaVNp
** SIG ** Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
** SIG ** eTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMyBQdWJs
** SIG ** aWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
** SIG ** eSAtIEc1MB4XDTEzMTIxMDAwMDAwMFoXDTIzMTIwOTIz
** SIG ** NTk1OVowfzELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5
** SIG ** bWFudGVjIENvcnBvcmF0aW9uMR8wHQYDVQQLExZTeW1h
** SIG ** bnRlYyBUcnVzdCBOZXR3b3JrMTAwLgYDVQQDEydTeW1h
** SIG ** bnRlYyBDbGFzcyAzIFNIQTI1NiBDb2RlIFNpZ25pbmcg
** SIG ** Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
** SIG ** AQCXgx4AFq8ssdIIxNdok1FgHnH24ke021hNI2JqtL9a
** SIG ** G1H3ow0Yd2i72DarLyFQ2p7z518nTgvCl8gJcJOp2lwN
** SIG ** TqQNkaC07BTOkXJULs6j20TpUhs/QTzKSuSqwOg5q1PM
** SIG ** IdDMz3+b5sLMWGqCFe49Ns8cxZcHJI7xe74xLT1u3LWZ
** SIG ** Qp9LYZVfHHDuF33bi+VhiXjHaBuvEXgamK7EVUdT2bMy
** SIG ** 1qEORkDFl5KK0VOnmVuFNVfT6pNiYSAKxzB3JBFNYoO2
** SIG ** untogjHuZcrf+dWNsjXcjCtvanJcYISc8gyUXsBWUgBI
** SIG ** zNP4pX3eL9cT5DiohNVGuBOGwhud6lo43ZvbAgMBAAGj
** SIG ** ggGDMIIBfzAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUH
** SIG ** MAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/
** SIG ** BAgwBgEB/wIBADBsBgNVHSAEZTBjMGEGC2CGSAGG+EUB
** SIG ** BxcDMFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3lt
** SIG ** YXV0aC5jb20vY3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6
** SIG ** Ly93d3cuc3ltYXV0aC5jb20vcnBhMDAGA1UdHwQpMCcw
** SIG ** JaAjoCGGH2h0dHA6Ly9zMS5zeW1jYi5jb20vcGNhMy1n
** SIG ** NS5jcmwwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF
** SIG ** BwMDMA4GA1UdDwEB/wQEAwIBBjApBgNVHREEIjAgpB4w
** SIG ** HDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01NjcwHQYD
** SIG ** VR0OBBYEFJY7U/B5M5evfYPvLivMyreGHnJmMB8GA1Ud
** SIG ** IwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
** SIG ** SIb3DQEBCwUAA4IBAQAThRoeaak396C9pK9+HWFT/p2M
** SIG ** XgymdR54FyPd/ewaA1U5+3GVx2Vap44w0kRaYdtwb9oh
** SIG ** BcIuc7pJ8dGT/l3JzV4D4ImeP3Qe1/c4i6nWz7s1LzNY
** SIG ** qJJW0chNO4LmeYQW/CiwsUfzHaI+7ofZpn+kVqU/rYQu
** SIG ** Kd58vKiqoz0EAeq6k6IOUCIpF0yH5DoRX9akJYmbBWsv
** SIG ** tMkBTCd7C6wZBSKgYBU/2sn7TUyP+3Jnd/0nlMe6NQ6I
** SIG ** Sf6N/SivShK9DbOXBd5EDBX6NisD3MFQAfGhEV0U5eK9
** SIG ** J0tUviuEXg+mw3QFCu+Xw4kisR93873NQ9TxTKk/tYuE
** SIG ** r2Ty0BQhMYIEPDCCBDgCAQEwgZMwfzELMAkGA1UEBhMC
** SIG ** VVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9u
** SIG ** MR8wHQYDVQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3Jr
** SIG ** MTAwLgYDVQQDEydTeW1hbnRlYyBDbGFzcyAzIFNIQTI1
** SIG ** NiBDb2RlIFNpZ25pbmcgQ0ECEDB6NnqqPmiBpvlPCMs7
** SIG ** OWQwCQYFKw4DAhoFAKBwMBAGCisGAQQBgjcCAQwxAjAA
** SIG ** MBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG
** SIG ** AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3
** SIG ** DQEJBDEWBBTtnq9nJTyuGwPUm/NL7IROjIWVujANBgkq
** SIG ** hkiG9w0BAQEFAASCAQBFZwe6d/h0FY6FPwyAJvEIjoFa
** SIG ** QzBNIjLHoMLr+qLIqOvAOj07kwp4+eb19gKa4V3ePaH+
** SIG ** g8ZXDLRIMWZEtpEuqKYxW5RnOd/iHg4h+PfVhtU4cixr
** SIG ** NK731fhhcYeDWrzPiAKVWqkdHcHFMSRdFNXrGtbpKWMR
** SIG ** 38T9CeAoC7whXK/N61WhBZOs2WqBn2e2bxsCMLPJzpez
** SIG ** 57mYjk8Zlk1d8DkaxiamkmDkpnzL+eFuKiEZSuvgZ7il
** SIG ** UDmtbdOvpUHTQqdZpNksZSUTGX87TvqGh7wxV5xPV0Bj
** SIG ** kRHYIbDoncD99xleC4H7En7aAS1CPOwsGi6ydHjYr6Mk
** SIG ** XKIxeI6ioYICCzCCAgcGCSqGSIb3DQEJBjGCAfgwggH0
** SIG ** AgEBMHIwXjELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5
** SIG ** bWFudGVjIENvcnBvcmF0aW9uMTAwLgYDVQQDEydTeW1h
** SIG ** bnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIENBIC0g
** SIG ** RzICEA7P9DjI/r81bgTYapgbGlAwCQYFKw4DAhoFAKBd
** SIG ** MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI
** SIG ** hvcNAQkFMQ8XDTE2MDQyNjEzMjQ1MlowIwYJKoZIhvcN
** SIG ** AQkEMRYEFOCXzSMTEghkr0AunGczGHuQzCc+MA0GCSqG
** SIG ** SIb3DQEBAQUABIIBAJHp1Wtc6YKicRqFnBN/mw7NsTNB
** SIG ** fYvf1CYHBhl6JX6aRlvehLeXJO4rF46tXV0lSAVONEMs
** SIG ** Cjxc8j2AqEPlHbmL+uiZEwuHquZv+nS1yM1ulNDEiwou
** SIG ** FxUtdRSg3y1KuQ1aTKUhHQ//mxiLhIGzvw8lZcJDqayo
** SIG ** a/0AEkgc8LPbFs5wp+jrNEAxDvTU38ERPjSm6LeCrCeR
** SIG ** pLRkbCAyayCyE+S0Y8dP2Yv1TS0dbPeL5pnBEsr/ym7F
** SIG ** 5DP1tBIm2Rbjl0pxGwTq502wqKGGdJakoxu4wr5xuUXk
** SIG ** BCZCD4OPmggdTYANy+fdmDfv/d0VxgOBmXJKE4nHBGtz
** SIG ** KWx/g/Q=
</signature>
</package>

View File

@@ -23,7 +23,7 @@
// Product version as a single DWORD
// Note: Used for version comparison within C/C++ code.
//
#define ZRCOLA_VERSION 0x01ff0500
#define ZRCOLA_VERSION 0x01ff0600
//
// Product version by components
@@ -33,26 +33,26 @@
//
#define ZRCOLA_VERSION_MAJ 1
#define ZRCOLA_VERSION_MIN 255
#define ZRCOLA_VERSION_REV 5
#define ZRCOLA_VERSION_REV 6
#define ZRCOLA_VERSION_BUILD 0
//
// Human readable product version and build year for UI
//
#define ZRCOLA_VERSION_STR "2.0-alpha5"
#define ZRCOLA_VERSION_STR "2.0-alpha6"
#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.5"
#define ZRCOLA_VERSION_INST "1.255.6"
//
// 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 "{037FA96B-4D03-41BC-A898-6300EBE2F23F}"
#define ZRCOLA_VERSION_GUID "{D1BCE36B-C032-476A-8129-5F284C1CB405}"
//
// The product vendor and application name for configuration keeping.

View File

@@ -20,6 +20,9 @@
#pragma once
#include <vector>
#ifdef _WIN32
#include <Windows.h>
#endif
///
@@ -64,6 +67,17 @@ namespace ZRCola {
typedef char langid_t[4];
#ifdef _WIN32
///
/// Converts language from Windows to ZRCola notation.
///
/// \param[in] lang_win Windows language ID
/// \param[in,out] lang ZRCola language ID
///
void ZRCOLA_API LangConvert(_In_ LANGID lang_win, _Inout_ langid_t &lang);
#endif
///
/// Memory index
///
@@ -223,15 +237,20 @@ namespace ZRCola {
///
/// Composed-decomposed index transformation mapping
/// Source-destination index transformation mapping
///
class ZRCOLA_NOVTABLE ZRCOLA_API mapping {
public:
size_t cmp; ///< Character index in composed string
size_t decmp; ///< Character index in decomposed string
size_t src; ///< Character index in source string
size_t dst; ///< Character index in destination string
inline mapping() {};
inline mapping(_In_ size_t c, _In_ size_t d) : cmp(c), decmp(d) {}
inline mapping(_In_ size_t s, _In_ size_t d) : src(s), dst(d) {}
///
/// Reverses source and destination indexes
///
inline void invert() { size_t tmp = src; src = dst; dst = tmp; }
};
@@ -241,22 +260,31 @@ namespace ZRCola {
class ZRCOLA_API mapping_vector : public std::vector<mapping> {
public:
///
/// Transforms character index of decomposed to composed string
/// Transforms character index of destination to source
///
/// \param[in] decmp Character index in decomposed string
/// \param[in] decmp Character index in destination string
///
/// \returns Character index in composed string
/// \returns Character index in source string
///
size_t to_composed(_In_ size_t decmp) const;
size_t to_src(_In_ size_t dst) const;
///
/// Transforms destination index to source index
/// Transforms source index to destination index
///
/// \param[in] cmp Character index in composed string
/// \param[in] cmp Character index in source string
///
/// \returns Character index in decomposed string
/// \returns Character index in destination string
///
size_t to_decomposed(_In_ size_t cmp) const;
size_t to_dst(_In_ size_t src) const;
///
/// Reverses source and destination indexes
///
inline void invert()
{
for (iterator i = begin(), iEnd = end(); i != iEnd; ++i)
i->invert();
}
};
};

View File

@@ -202,6 +202,8 @@ namespace ZRCola {
///
struct language {
langid_t id; ///< Language ID
unsigned __int16 name_len; ///< \c name length (in characters)
wchar_t name[]; ///< Language name
};
#pragma pack(pop)

View File

@@ -46,6 +46,7 @@ namespace ZRCola {
///
struct translation {
wchar_t chr; ///< Composed character
unsigned __int16 rank; ///< Decomposition rank
unsigned __int16 str_len; ///< \c str length (in characters)
wchar_t str[]; ///< Decomposed string
@@ -183,6 +184,9 @@ namespace ZRCola {
if (a.chr < b.chr) return -1;
else if (a.chr > b.chr) return +1;
if (a.rank < b.rank) return -1;
else if (a.rank > b.rank) return +1;
int r = translation::CompareString(a.str, a.str_len, b.str, b.str_len);
if (r != 0) return r;

View File

@@ -20,6 +20,57 @@
#include "stdafx.h"
#ifdef _WIN32
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_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_CROATIAN_CROATIA :
case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN : memcpy(lang, "hrv", sizeof(lang)); 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_CYRILLIC :
case SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC :
case SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC :
case SUBLANG_SERBIAN_SERBIA_CYRILLIC : memcpy(lang, "srz", sizeof(lang)); break;
}
break;
}
}
#endif
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; ) {

View File

@@ -20,51 +20,63 @@
#include "stdafx.h"
size_t ZRCola::mapping_vector::to_composed(_In_ size_t decmp) const
size_t ZRCola::mapping_vector::to_src(_In_ size_t dst) const
{
if (empty()) {
// One-to-one mapping.
return dst;
}
for (size_type l = 0, r = size();;) {
if (l < r) {
size_type m = (l + r) / 2;
const mapping &el = (*this)[m];
if (decmp < el.decmp) r = m;
else if (el.decmp < decmp) l = m + 1;
if ( dst < el.dst) r = m;
else if (el.dst < dst) l = m + 1;
else {
// An exact match found.
return el.cmp;
return el.src;
}
} else if (l) {
// We found a map interval.
const mapping &el = (*this)[l - 1];
return el.cmp + (decmp - el.decmp);
return el.src + (dst - el.dst);
} else {
// The decomposed character index is far left.
return decmp;
// The destination character index is left of the first transformation.
const mapping &el = (*this)[0];
return std::min<size_t>(dst, el.src);
}
}
}
size_t ZRCola::mapping_vector::to_decomposed(_In_ size_t cmp) const
size_t ZRCola::mapping_vector::to_dst(_In_ size_t src) const
{
if (empty()) {
// One-to-one mapping.
return src;
}
for (size_type l = 0, r = size();;) {
if (l < r) {
size_type m = (l + r) / 2;
const mapping &el = (*this)[m];
if (cmp < el.cmp) r = m;
else if (el.cmp < cmp) l = m + 1;
if ( src < el.src) r = m;
else if (el.src < src) l = m + 1;
else {
// An exact match found.
return el.decmp;
return el.dst;
}
} else if (l) {
// We found a map interval.
const mapping &el = (*this)[l - 1];
return el.decmp + (cmp - el.cmp);
return el.dst + (src - el.src);
} else {
// The composed character index is far left.
return cmp;
// The source character index is left of the first transformation.
const mapping &el = (*this)[0];
return std::min<size_t>(src, el.dst);
}
}
}

View File

@@ -91,7 +91,7 @@ void ZRCola::translation_db::Compose(_In_z_count_(inputMax) const wchar_t* input
i += trans.str_len;
if (trans.str_len > 1 && map) {
// Mapping changed.
map->push_back(ZRCola::mapping(output.length(), i));
map->push_back(ZRCola::mapping(i, output.length()));
}
} else {
// The match was not found.
@@ -131,6 +131,16 @@ void ZRCola::translation_db::Decompose(_In_z_count_(inputMax) const wchar_t* inp
else if (decompSrc < c) l = m + 1;
else {
// Character found.
// Narrow the search area on the left to start at the first decomposition in the run (first by rank).
for (size_t rr = m; l < rr;) {
size_t m = (l + rr) / 2;
const translation &trans = idxDecomp[m];
wchar_t decompSrc = trans.chr;
if (c <= decompSrc) rr = m; else l = m + 1;
}
const translation &trans = idxDecomp[l];
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);

Binary file not shown.

View File

@@ -0,0 +1,116 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRCola.zrcdb\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: ZRColaCompile 2.0-alpha5\n"
msgid "Albanian"
msgstr ""
msgid "Belarusian"
msgstr ""
msgid "Bosnian Cyrillic"
msgstr ""
msgid "Bosnian Latinic"
msgstr ""
msgid "Croatian"
msgstr ""
msgid "Czech"
msgstr ""
msgid "Danish"
msgstr ""
msgid "English"
msgstr ""
msgid "Estonian"
msgstr ""
msgid "French"
msgstr ""
msgid "Friulian"
msgstr ""
msgid "German"
msgstr ""
msgid "Hungarian"
msgstr ""
msgid "Irish Gaelic"
msgstr ""
msgid "Kashubian"
msgstr ""
msgid "Latin"
msgstr ""
msgid "Latvian"
msgstr ""
msgid "Lithuanian"
msgstr ""
msgid "Macedonian"
msgstr ""
msgid "Maltese"
msgstr ""
msgid "Moldavian Cyrillic"
msgstr ""
msgid "Moldavian Latinic"
msgstr ""
msgid "Norwegian"
msgstr ""
msgid "Polish"
msgstr ""
msgid "Portuguese"
msgstr ""
msgid "Romanian"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Serbian Cyrillic"
msgstr ""
msgid "Serbian Latinic"
msgstr ""
msgid "Slovak"
msgstr ""
msgid "Slovenian"
msgstr ""
msgid "Sorbian"
msgstr ""
msgid "Spanish"
msgstr ""
msgid "Swedish"
msgstr ""
msgid "Turkish"
msgstr ""
msgid "Ukrainian"
msgstr ""

Binary file not shown.

View File

@@ -0,0 +1,123 @@
msgid ""
msgstr ""
"Project-Id-Version: ZRCola.zrcdb\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \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"
"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"
msgid "Albanian"
msgstr "albanščina"
msgid "Belarusian"
msgstr "beloruščina"
msgid "Bosnian Cyrillic"
msgstr "bosanščina cirilica"
msgid "Bosnian Latinic"
msgstr "bosanščina latinica"
msgid "Croatian"
msgstr "hrvaščina"
msgid "Czech"
msgstr "češčina"
msgid "Danish"
msgstr "danščina"
msgid "English"
msgstr "angleščina"
msgid "Estonian"
msgstr "estonščina"
msgid "French"
msgstr "francoščina"
msgid "Friulian"
msgstr "furlanščina"
msgid "German"
msgstr "nemščina"
msgid "Hungarian"
msgstr "madžarščina"
msgid "Irish Gaelic"
msgstr "irščina"
msgid "Kashubian"
msgstr "kašubščina"
msgid "Latin"
msgstr "latinščina"
msgid "Latvian"
msgstr "letonščina"
msgid "Lithuanian"
msgstr "litovščina"
msgid "Macedonian"
msgstr "makedonščina"
msgid "Maltese"
msgstr "malteščina"
msgid "Moldavian Cyrillic"
msgstr "moldavščina cirilica"
msgid "Moldavian Latinic"
msgstr "moldavščina latinica"
msgid "Norwegian"
msgstr "norveščina"
msgid "Polish"
msgstr "poljščina"
msgid "Portuguese"
msgstr "portugalščina"
msgid "Romanian"
msgstr "romunščina"
msgid "Russian"
msgstr "ruščina"
msgid "Serbian Cyrillic"
msgstr "srbščina cirilica"
msgid "Serbian Latinic"
msgstr "srbščina latinica"
msgid "Slovak"
msgstr "slovaščina"
msgid "Slovenian"
msgstr "slovenščina"
msgid "Sorbian"
msgstr "lužiščini"
msgid "Spanish"
msgstr "španščina"
msgid "Swedish"
msgstr "švedščina"
msgid "Turkish"
msgstr "turščina"
msgid "Ukrainian"
msgstr "ukrajinščina"