From 4fba54bdb243c5f6e495173db8c9f3bd41db8ca3 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 13 Apr 2016 11:02:58 +0200 Subject: [PATCH] Text language for decomposition GUI support added (closes #1) --- ZRCola/ZRCola.fbp | 167 +++++++++++++++++++++++++++++++++++++++ ZRCola/locale/sl_SI.po | 53 ++++++++----- ZRCola/zrcolaapp.cpp | 19 ++++- ZRCola/zrcolaapp.h | 3 + ZRCola/zrcolacomppnl.cpp | 7 +- ZRCola/zrcolafrm.cpp | 107 ++++++++++++++++++++++++- ZRCola/zrcolafrm.h | 34 ++++++++ ZRCola/zrcolagui.cpp | 17 ++++ ZRCola/zrcolagui.h | 9 +++ 9 files changed, 393 insertions(+), 23 deletions(-) diff --git a/ZRCola/ZRCola.fbp b/ZRCola/ZRCola.fbp index 5d092f8..8d42908 100644 --- a/ZRCola/ZRCola.fbp +++ b/ZRCola/ZRCola.fbp @@ -270,6 +270,12 @@ + + + &Language + m_menuDecompLanguage + protected + &Help @@ -479,6 +485,167 @@ + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Language: + + 0 + + + 0 + + 1 + m_toolDecompLanguageLbl + 1 + + + protected + 1 + + Resizable + 1 + + wxALIGN_RIGHT + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_toolDecompLanguage + 1 + + + protected + 1 + + Resizable + 0 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + OnDecompLanguageChoice + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ZRCola/locale/sl_SI.po b/ZRCola/locale/sl_SI.po index fc91876..0faf363 100644 --- a/ZRCola/locale/sl_SI.po +++ b/ZRCola/locale/sl_SI.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: ZRCola\n" -"POT-Creation-Date: 2016-04-08 13:13+0200\n" -"PO-Revision-Date: 2016-04-08 13:13+0200\n" +"POT-Creation-Date: 2016-04-13 10:50+0200\n" +"PO-Revision-Date: 2016-04-13 10:50+0200\n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" "Language: sl_SI\n" @@ -17,7 +17,12 @@ msgstr "" "X-Poedit-KeywordsList: _\n" "X-Poedit-SearchPath-0: .\n" -#: zrcolafrm.cpp:61 +#: zrcolafrm.cpp:69 +#, c-format +msgid "Select %s language for decomposition" +msgstr "Izberi jezik %s za razstavljanje" + +#: zrcolafrm.cpp:81 msgid "" "ZRCola keyboard shortcut Win+F5 could not be registered. Some functionality " "will not be available." @@ -25,11 +30,11 @@ msgstr "" "ZRColine bližnjice na tipkovnici Win+F5 ni mogoče registrirati. Nekaj " "funkcionalnosti ne bo na voljo." -#: zrcolafrm.cpp:61 zrcolafrm.cpp:63 +#: zrcolafrm.cpp:81 zrcolafrm.cpp:83 msgid "Warning" msgstr "Opozorilo" -#: zrcolafrm.cpp:63 +#: zrcolafrm.cpp:83 msgid "" "ZRCola keyboard shortcut Win+F6 could not be registered. Some functionality " "will not be available." @@ -37,7 +42,7 @@ msgstr "" "ZRColine bližnjice na tipkovnici Win+F6 ni mogoče registrirati. Nekaj " "funkcionalnosti ne bo na voljo." -#: zrcolafrm.cpp:144 +#: zrcolafrm.cpp:205 #, c-format msgid "" "ZRCola v%s\n" @@ -46,7 +51,7 @@ msgstr "" "ZRCola v%s\n" "Vse pravice pridržane 2015-%s Amebis" -#: zrcolafrm.cpp:144 +#: zrcolafrm.cpp:205 msgid "About ZRCola" msgstr "O ZRColi" @@ -74,7 +79,7 @@ msgstr "Izberi celotno besedilo" msgid "&Send Composed" msgstr "Pošlji &sestavljeno" -#: zrcolagui.cpp:74 zrcolagui.cpp:121 +#: zrcolagui.cpp:74 zrcolagui.cpp:125 msgid "Send composed text to source window" msgstr "Pošlji sestavljeno besedilo izvornemu oknu" @@ -82,7 +87,7 @@ msgstr "Pošlji sestavljeno besedilo izvornemu oknu" msgid "Send &Decomposed" msgstr "Pošlji &razstavljeno" -#: zrcolagui.cpp:83 zrcolagui.cpp:123 +#: zrcolagui.cpp:83 zrcolagui.cpp:127 msgid "Send decomposed text to source window" msgstr "Pošlji razstavljeno besedilo izvornemu oknu" @@ -94,47 +99,55 @@ msgstr "Prekini raz/sestavljanje" msgid "Abort composition and return focus to source window" msgstr "Prekini sestavljanje in vrni fokus nazaj izvornemu oknu" -#: zrcolagui.cpp:100 +#: zrcolagui.cpp:101 +msgid "&Language" +msgstr "&Jezik" + +#: zrcolagui.cpp:104 msgid "&Edit" msgstr "Ur&edi" -#: zrcolagui.cpp:107 +#: zrcolagui.cpp:111 msgid "&Help" msgstr "&Pomoč" -#: zrcolagui.cpp:113 +#: zrcolagui.cpp:117 msgid "Cut" msgstr "Izreži" -#: zrcolagui.cpp:113 +#: zrcolagui.cpp:117 msgid "Cut selection" msgstr "Izreži izbor" -#: zrcolagui.cpp:115 +#: zrcolagui.cpp:119 msgid "Copy" msgstr "Kopiraj" -#: zrcolagui.cpp:115 +#: zrcolagui.cpp:119 msgid "Copy selection" msgstr "Kopiraj izbor" -#: zrcolagui.cpp:117 +#: zrcolagui.cpp:121 msgid "Paste" msgstr "Prilepi" -#: zrcolagui.cpp:117 +#: zrcolagui.cpp:121 msgid "Paste selection" msgstr "Prilepi izbor" -#: zrcolagui.cpp:121 +#: zrcolagui.cpp:125 msgid "Send Composed" msgstr "Pošlji sestavljeno" -#: zrcolagui.cpp:123 +#: zrcolagui.cpp:127 msgid "Send Decomposed" msgstr "Pošlji razstavljeno" -#: zrcolagui.h:64 MSIBuild/En.Win32.Release.Feature-2.idtx:4 +#: zrcolagui.cpp:129 +msgid "Language:" +msgstr "Jezik:" + +#: zrcolagui.h:73 MSIBuild/En.Win32.Release.Feature-2.idtx:4 #: MSIBuild/En.Win32.Release.Shortcut-2.idtx:4 #: MSIBuild/En.x64.Release.Feature-2.idtx:4 #: MSIBuild/En.x64.Release.Shortcut-2.idtx:4 diff --git a/ZRCola/zrcolaapp.cpp b/ZRCola/zrcolaapp.cpp index db8b7fe..3df385f 100644 --- a/ZRCola/zrcolaapp.cpp +++ b/ZRCola/zrcolaapp.cpp @@ -84,6 +84,23 @@ bool ZRColaApp::OnInit() m_t_db.idxDecomp.clear(); m_t_db.data .clear(); } + } else if (id == ZRCola::langchar_rec::id) { + dat >> ZRCola::langchar_rec(m_lc_db); + if (!dat.good()) { + wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb.")); + m_lc_db.idxChr.clear(); +#ifdef ZRCOLA_LANGCHAR_LANG_IDX + m_lc_db.idxLng.clear(); +#endif + m_lc_db.data .clear(); + } + } else if (id == ZRCola::language_rec::id) { + dat >> ZRCola::language_rec(m_lang_db); + if (!dat.good()) { + wxFAIL_MSG(wxT("Error reading language character data from ZRCola.zrcdb.")); + m_lang_db.idxLng.clear(); + m_lang_db.data .clear(); + } } } @@ -95,7 +112,7 @@ bool ZRColaApp::OnInit() } wxZRColaFrame* mainFrame = new wxZRColaFrame(); - wxPersistentRegisterAndRestore(mainFrame); + wxPersistentRegisterAndRestore(mainFrame); mainFrame->Show(); return true; diff --git a/ZRCola/zrcolaapp.h b/ZRCola/zrcolaapp.h index 75962a6..0190842 100644 --- a/ZRCola/zrcolaapp.h +++ b/ZRCola/zrcolaapp.h @@ -28,6 +28,7 @@ class ZRColaApp; #include #include #include +#include #include @@ -57,6 +58,8 @@ public: public: ZRCola::translation_db m_t_db; ///< Translation database + ZRCola::langchar_db m_lc_db; ///< Language character database + ZRCola::language_db m_lang_db; ///< Language database protected: wxLocale m_locale; ///< Current locale diff --git a/ZRCola/zrcolacomppnl.cpp b/ZRCola/zrcolacomppnl.cpp index f78f58e..21125f9 100644 --- a/ZRCola/zrcolacomppnl.cpp +++ b/ZRCola/zrcolacomppnl.cpp @@ -118,8 +118,13 @@ void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event) wxString src(m_composed->GetValue()); #endif + ZRColaApp *app = (ZRColaApp*)wxTheApp; std::wstring dst; - ((ZRColaApp*)wxTheApp)->m_t_db.Decompose(src.data(), src.size(), dst, &m_mapping); + wxZRColaFrame *mainWnd = dynamic_cast(wxGetActiveWindow()); + if (mainWnd) + app->m_t_db.Decompose(src.data(), src.size(), &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping); + else + app->m_t_db.Decompose(src.data(), src.size(), dst, &m_mapping); long from, to; m_composed->GetSelection(&from, &to); diff --git a/ZRCola/zrcolafrm.cpp b/ZRCola/zrcolafrm.cpp index d43ae18..95b7b18 100644 --- a/ZRCola/zrcolafrm.cpp +++ b/ZRCola/zrcolafrm.cpp @@ -35,6 +35,9 @@ wxBEGIN_EVENT_TABLE(wxZRColaFrame, wxZRColaFrameBase) EVT_MENU(wxID_SEND_DECOMPOSED, wxZRColaFrame::OnSendDecomposed ) EVT_MENU(wxID_SEND_ABORT , wxZRColaFrame::OnSendAbort ) + EVT_UPDATE_UI_RANGE(wxID_DECOMP_LANGUAGE_START, wxID_DECOMP_LANGUAGE_END, wxZRColaFrame::OnDecomposedLanguageUpdate) + EVT_MENU_RANGE(wxID_DECOMP_LANGUAGE_START, wxID_DECOMP_LANGUAGE_END, wxZRColaFrame::OnDecomposedLanguage) + EVT_MENU(wxID_EXIT , wxZRColaFrame::OnExit ) EVT_MENU(wxID_ABOUT, wxZRColaFrame::OnAbout) wxEND_EVENT_TABLE() @@ -54,6 +57,23 @@ wxZRColaFrame::wxZRColaFrame() : SetIcon(wxICON(00_zrcola.ico)); #endif + // Populate language lists. + memcpy(m_lang, ZRCOLA_LANG_VOID, sizeof(m_lang)); + ZRColaApp *app = ((ZRColaApp*)wxTheApp); + m_toolDecompLanguage->Clear(); + if (!app->m_lang_db.idxLng.empty()) { + for (size_t i = 0, n = app->m_lang_db.idxLng.size(); i < n; i++) { + const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i]; + wxString label(wxString::FromAscii(lang.id, strnlen(lang.id, sizeof(lang.id)))); + if (i < wxID_DECOMP_LANGUAGE_END - wxID_DECOMP_LANGUAGE_START + 1) + m_menuDecompLanguage->Insert(i, wxID_DECOMP_LANGUAGE_START + i, label, wxString::Format(_("Select %s language for decomposition"), (const wxStringCharType*)label), wxITEM_RADIO); + m_toolDecompLanguage->Insert(label, i); + if (memcmp(m_lang, lang.id, sizeof(m_lang)) == 0) + m_toolDecompLanguage->Select(i); + } + } + + // Set focus. m_panel->m_decomposed->SetFocus(); // Register global hotkey(s). @@ -75,7 +95,7 @@ wxZRColaFrame::~wxZRColaFrame() void wxZRColaFrame::OnForwardEventUpdate(wxUpdateUIEvent& event) { wxControl *focusWnd = wxDynamicCast(FindFocus(), wxControl); - if (focusWnd) + if (focusWnd && !m_toolbar->IsDescendant(focusWnd)) focusWnd->GetEventHandler()->ProcessEvent(event); else event.Enable(false); @@ -133,6 +153,47 @@ void wxZRColaFrame::OnSendAbort(wxCommandEvent& event) } +void wxZRColaFrame::OnDecomposedLanguageUpdate(wxUpdateUIEvent& event) +{ + ZRColaApp *app = ((ZRColaApp*)wxTheApp); + const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[event.GetId() - wxID_DECOMP_LANGUAGE_START]; + event.Check(memcmp(m_lang, lang.id, sizeof(m_lang)) == 0); +} + + +void wxZRColaFrame::OnDecomposedLanguage(wxCommandEvent& event) +{ + ZRColaApp *app = ((ZRColaApp*)wxTheApp); + size_t i = event.GetId() - wxID_DECOMP_LANGUAGE_START; + const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i]; + + if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) { + memcpy(m_lang, lang.id, sizeof(m_lang)); + m_toolDecompLanguage->Select(i); + + // Notify composed text something changed and should re-decompose. + wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED); + m_panel->m_composed->ProcessWindowEvent(event2); + } +} + + +void wxZRColaFrame::OnDecompLanguageChoice(wxCommandEvent& event) +{ + ZRColaApp *app = ((ZRColaApp*)wxTheApp); + size_t i = event.GetSelection(); + const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[i]; + + if (memcmp(m_lang, lang.id, sizeof(m_lang)) != 0) { + memcpy(m_lang, lang.id, sizeof(m_lang)); + + // Notify composed text something changed and should re-decompose. + wxCommandEvent event2(wxEVT_COMMAND_TEXT_UPDATED); + m_panel->m_composed->ProcessWindowEvent(event2); + } +} + + void wxZRColaFrame::OnExit(wxCommandEvent& event) { Close(); @@ -224,3 +285,47 @@ WXLRESULT wxZRColaFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM } else return wxZRColaFrameBase::MSWWindowProc(message, wParam, lParam); } + + +////////////////////////////////////////////////////////////////////////// +// wxPersistentZRColaFrame +////////////////////////////////////////////////////////////////////////// + +wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersistentTLW(wnd) +{ +} + + +void wxPersistentZRColaFrame::Save() const +{ + // + const wxZRColaFrame * const wnd = static_cast(GetWindow()); + + SaveValue(wxT("lang"), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang))); + wxPersistentTLW::Save(); +} + + +bool wxPersistentZRColaFrame::Restore() +{ + const bool r = wxPersistentTLW::Restore(); + + wxZRColaFrame * const wnd = static_cast(GetWindow()); + + wxString lang; + if (RestoreValue(wxT("lang"), &lang) && lang.Length() == 3) { + memcpy(wnd->m_lang, (const char*)lang.c_str(), sizeof(wnd->m_lang)); + wnd->m_toolDecompLanguage->SetStringSelection(wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang))); + } else { + ZRColaApp *app = ((ZRColaApp*)wxTheApp); + if (!app->m_lang_db.idxLng.empty()) { + const ZRCola::language_db::language &lang = app->m_lang_db.idxLng[0]; + memcpy(wnd->m_lang, lang.id, sizeof(wnd->m_lang)); + wnd->m_toolDecompLanguage->Select(0); + } else { + memcpy(wnd->m_lang, ZRCOLA_LANG_VOID, sizeof(wnd->m_lang)); + } + } + + return r; +} diff --git a/ZRCola/zrcolafrm.h b/ZRCola/zrcolafrm.h index 8365548..b960062 100644 --- a/ZRCola/zrcolafrm.h +++ b/ZRCola/zrcolafrm.h @@ -27,6 +27,8 @@ class wxZRColaFrame; #pragma once #include "zrcolagui.h" +#include +#include /// @@ -42,6 +44,12 @@ class wxZRColaFrame; class wxZRColaFrame : public wxZRColaFrameBase { public: + enum + { + wxID_DECOMP_LANGUAGE_START = 6000, + wxID_DECOMP_LANGUAGE_END = 6099, + }; + wxZRColaFrame(); virtual ~wxZRColaFrame(); @@ -52,10 +60,16 @@ protected: void OnSendComposed(wxCommandEvent& event); void OnSendDecomposed(wxCommandEvent& event); void OnSendAbort(wxCommandEvent& event); + void OnDecomposedLanguageUpdate(wxUpdateUIEvent& event); + void OnDecomposedLanguage(wxCommandEvent& event); + virtual void OnDecompLanguageChoice(wxCommandEvent& event); void OnExit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); wxDECLARE_EVENT_TABLE(); + friend class wxPersistentZRColaFrame; + friend class wxZRColaComposerPanel; + private: void DoSend(const wxString& str); @@ -63,5 +77,25 @@ protected: virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam); protected: + ZRCola::langid_t m_lang; ///< Language for decomposing WXHWND m_hWndSource; ///< handle of the active window, when the ZRCola hotkey was pressed }; + + +/// +/// Supports saving/restoring wxZRColaFrame GUI state +/// +class wxPersistentZRColaFrame : public wxPersistentTLW +{ +public: + wxPersistentZRColaFrame(wxZRColaFrame *wnd); + + virtual void Save() const; + virtual bool Restore(); +}; + + +inline wxPersistentObject *wxCreatePersistentObject(wxZRColaFrame *wnd) +{ + return new wxPersistentZRColaFrame(wnd); +} diff --git a/ZRCola/zrcolagui.cpp b/ZRCola/zrcolagui.cpp index b87940f..0b74a13 100644 --- a/ZRCola/zrcolagui.cpp +++ b/ZRCola/zrcolagui.cpp @@ -97,6 +97,10 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS #endif m_menuEdit->Append( m_menuItemSendAbort ); + m_menuDecompLanguage = new wxMenu(); + wxMenuItem* m_menuDecompLanguageItem = new wxMenuItem( m_menuEdit, wxID_ANY, _("&Language"), wxEmptyString, wxITEM_NORMAL, m_menuDecompLanguage ); + m_menuEdit->Append( m_menuDecompLanguageItem ); + m_menubar->Append( m_menuEdit, _("&Edit") ); m_menuHelp = new wxMenu(); @@ -122,6 +126,13 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS m_toolSendDecomposed = m_toolbar->AddTool( wxID_SEND_DECOMPOSED, _("Send Decomposed"), wxIcon( wxT("send_decomposed.ico"), wxBITMAP_TYPE_ICO_RESOURCE, 24, 24 ), wxNullBitmap, wxITEM_NORMAL, _("Send Decomposed"), _("Send decomposed text to source window"), NULL ); + m_toolDecompLanguageLbl = new wxStaticText( m_toolbar, wxID_ANY, _("Language:"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT ); + m_toolDecompLanguageLbl->Wrap( -1 ); + m_toolbar->AddControl( m_toolDecompLanguageLbl ); + wxArrayString m_toolDecompLanguageChoices; + m_toolDecompLanguage = new wxChoice( m_toolbar, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_toolDecompLanguageChoices, 0 ); + m_toolDecompLanguage->SetSelection( 0 ); + m_toolbar->AddControl( m_toolDecompLanguage ); m_toolbar->Realize(); wxBoxSizer* bSizerMain; @@ -137,10 +148,16 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS m_statusBar = this->CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY ); this->Centre( wxBOTH ); + + // Connect Events + m_toolDecompLanguage->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this ); } wxZRColaFrameBase::~wxZRColaFrameBase() { + // Disconnect Events + m_toolDecompLanguage->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this ); + } wxZRColaComposerPanelBase::wxZRColaComposerPanelBase( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style ) : wxPanel( parent, id, pos, size, style ) diff --git a/ZRCola/zrcolagui.h b/ZRCola/zrcolagui.h index cd189a9..f62eeb9 100644 --- a/ZRCola/zrcolagui.h +++ b/ZRCola/zrcolagui.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include "zrcolacomppnl.h" #include @@ -49,6 +51,7 @@ class wxZRColaFrameBase : public wxFrame wxMenuBar* m_menubar; wxMenu* m_menuProgram; wxMenu* m_menuEdit; + wxMenu* m_menuDecompLanguage; wxMenu* m_menuHelp; wxToolBar* m_toolbar; wxToolBarToolBase* m_toolEditCut; @@ -56,8 +59,14 @@ class wxZRColaFrameBase : public wxFrame wxToolBarToolBase* m_toolEditPaste; wxToolBarToolBase* m_toolSendComposed; wxToolBarToolBase* m_toolSendDecomposed; + wxStaticText* m_toolDecompLanguageLbl; + wxChoice* m_toolDecompLanguage; wxZRColaComposerPanel* m_panel; wxStatusBar* m_statusBar; + + // Virtual event handlers, overide them in your derived class + virtual void OnDecompLanguageChoice( wxCommandEvent& event ) { event.Skip(); } + public: