diff --git a/ZRCola/ZRCola.vcxproj b/ZRCola/ZRCola.vcxproj index 1b2d895..6a976ac 100644 --- a/ZRCola/ZRCola.vcxproj +++ b/ZRCola/ZRCola.vcxproj @@ -84,6 +84,7 @@ + @@ -91,6 +92,7 @@ + diff --git a/ZRCola/ZRCola.vcxproj.filters b/ZRCola/ZRCola.vcxproj.filters index 61540d1..ade3712 100644 --- a/ZRCola/ZRCola.vcxproj.filters +++ b/ZRCola/ZRCola.vcxproj.filters @@ -34,6 +34,9 @@ Source Files + + Source Files + @@ -51,6 +54,9 @@ Header Files + + Header Files + diff --git a/ZRCola/stdafx.h b/ZRCola/stdafx.h index 407bab1..b6731c1 100644 --- a/ZRCola/stdafx.h +++ b/ZRCola/stdafx.h @@ -23,6 +23,7 @@ #include "zrcolaapp.h" #include "zrcolacomppnl.h" #include "zrcolafrm.h" +#include "zrcolakeyhndlr.h" #include #include diff --git a/ZRCola/zrcolacomppnl.cpp b/ZRCola/zrcolacomppnl.cpp index 2c74877..8982ad5 100644 --- a/ZRCola/zrcolacomppnl.cpp +++ b/ZRCola/zrcolacomppnl.cpp @@ -20,32 +20,6 @@ #include "stdafx.h" -////////////////////////////////////////////////////////////////////////// -// wxZRColaComposerPanelEvtHandler -////////////////////////////////////////////////////////////////////////// - -wxZRColaComposerPanelEvtHandler::wxZRColaComposerPanelEvtHandler(wxZRColaComposerPanel *target) : - m_target(target), - wxEvtHandler() -{ -} - - -bool wxZRColaComposerPanelEvtHandler::ProcessEvent(wxEvent& event) -{ - if (m_target && event.IsCommandEvent()) { - int id = event.GetId(); - if (wxZRColaComposerPanel::wxID_ACCEL <= id && id < wxZRColaComposerPanel::wxID_ACCEL + m_target->m_ks_db.idxKey.size()) { - const ZRCola::keyseq_db::keyseq &ks = (const ZRCola::keyseq_db::keyseq&)m_target->m_ks_db.data[m_target->m_ks_db.idxKey[id - wxZRColaComposerPanel::wxID_ACCEL]]; - m_target->m_decomposed->WriteText(ks.chr); - return true; - } - } - - return wxEvtHandler::ProcessEvent(event); -} - - ////////////////////////////////////////////////////////////////////////// // wxZRColaComposerPanel ////////////////////////////////////////////////////////////////////////// @@ -54,7 +28,6 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) : m_progress(false), m_selDecomposed(0, 0), m_selComposed(0, 0), - eh(this), wxZRColaComposerPanelBase(parent) { wxString sPath(wxPathOnly(wxTheApp->argv[0])); @@ -66,63 +39,29 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) : ZRCola::recordsize_t size; dat.read((char*)&size, sizeof(ZRCola::recordsize_t)); if (dat.good()) { - bool has_translation_data = false; - - for (;;) { - ZRCola::recordid_t id; - if (!stdex::idrec::read_id(dat, id, size)) break; - - if (id == ZRCola::translation_rec::id) { - dat >> ZRCola::translation_rec(m_t_db); - if (dat.good()) { - has_translation_data = true; - } else { - wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb.")); - m_t_db.idxComp .clear(); - m_t_db.idxDecomp.clear(); - m_t_db.data .clear(); - } - } else if (id == ZRCola::keyseq_rec::id) { - dat >> ZRCola::keyseq_rec(m_ks_db); - if (!dat.good()) { - wxFAIL_MSG(wxT("Error reading key sequence data from ZRCola.zrcdb.")); - m_ks_db.idxChr.clear(); - m_ks_db.idxKey.clear(); - m_ks_db.data .clear(); - } + ZRCola::translation_rec rec(m_t_db); + if (rec.find(dat, size)) { + dat >> rec; + if (!dat.good()) { + wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb.")); + m_t_db.idxComp .clear(); + m_t_db.idxDecomp.clear(); + m_t_db.data .clear(); } - } - - if (!has_translation_data) + } else wxFAIL_MSG(wxT("ZRCola.zrcdb has no translation data.")); } } else wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database.")); } - std::vector::size_type n = m_ks_db.idxKey.size(); - std::vector entries; - entries.reserve(n); - for (std::vector::size_type i = 0; i < n; i++) { - const ZRCola::keyseq_db::keyseq &ks = (const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[i]]; - if (ks.seq_len == 1) { - // The key sequence is trivial. - entries.push_back(wxAcceleratorEntry( - ((ks.seq[0].modifiers & ZRCola::keyseq_db::keyseq::SHIFT) ? wxACCEL_SHIFT : 0) | - ((ks.seq[0].modifiers & ZRCola::keyseq_db::keyseq::CTRL ) ? wxACCEL_CTRL : 0) | - ((ks.seq[0].modifiers & ZRCola::keyseq_db::keyseq::ALT ) ? wxACCEL_ALT : 0), ks.seq[0].key, wxID_ACCEL + i)); - } - } - wxAcceleratorTable accel(entries.size(), entries.data()); - SetAcceleratorTable(accel); - - PushEventHandler(&eh); + m_decomposed->PushEventHandler(&m_keyhandler); } wxZRColaComposerPanel::~wxZRColaComposerPanel() { - PopEventHandler(); + m_decomposed->PopEventHandler(); } diff --git a/ZRCola/zrcolacomppnl.h b/ZRCola/zrcolacomppnl.h index d9bc0bc..626cfd0 100644 --- a/ZRCola/zrcolacomppnl.h +++ b/ZRCola/zrcolacomppnl.h @@ -20,48 +20,27 @@ /// /// Forward declarations /// -class wxZRColaComposerPanelEvtHandler; class wxZRColaComposerPanel; #pragma once #include "zrcolagui.h" +#include "zrcolakeyhndlr.h" #include -#include #include -/// -/// ZRCola composer panel event handler -/// -class wxZRColaComposerPanelEvtHandler : public wxEvtHandler -{ -public: - wxZRColaComposerPanelEvtHandler(wxZRColaComposerPanel *target); - - virtual bool ProcessEvent(wxEvent& event); - -public: - wxZRColaComposerPanel *m_target; ///< Composer panel window -}; - - /// /// ZRCola composer panel /// class wxZRColaComposerPanel : public wxZRColaComposerPanelBase { - enum { - wxID_ACCEL = wxID_HIGHEST - }; - public: wxZRColaComposerPanel(wxWindow* parent); virtual ~wxZRColaComposerPanel(); friend class wxZRColaFrame; // Allow main frame direct access to our members. - friend class wxZRColaComposerPanelEvtHandler; // Allow own event handler direct access to our members. protected: virtual void OnDecomposedPaint(wxPaintEvent& event); @@ -71,11 +50,10 @@ protected: protected: ZRCola::translation_db m_t_db; ///< Translation database - ZRCola::keyseq_db m_ks_db; ///< Key sequence database bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls ZRCola::mapping_vector m_mapping; ///< Character index mapping vector between composed and decomposed text std::pair m_selDecomposed, ///< Character index of selected text in decomposed text control m_selComposed; ///< Character index of selected text in composed text control - wxZRColaComposerPanelEvtHandler eh; ///< Event handler + wxZRColaKeyHandler m_keyhandler; ///< Key handler for decomposed window }; diff --git a/ZRCola/zrcolakeyhndlr.cpp b/ZRCola/zrcolakeyhndlr.cpp new file mode 100644 index 0000000..11fc207 --- /dev/null +++ b/ZRCola/zrcolakeyhndlr.cpp @@ -0,0 +1,93 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of ZRCola. + + ZRCola is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ZRCola is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ZRCola. If not, see . +*/ + +#include "stdafx.h" + + +////////////////////////////////////////////////////////////////////////// +// wxZRColaKeyHandler +////////////////////////////////////////////////////////////////////////// + +wxZRColaKeyHandler::wxZRColaKeyHandler() : wxEvtHandler() +{ + wxString sPath(wxPathOnly(wxTheApp->argv[0])); + sPath << wxT("\\..\\data\\ZRCola.zrcdb"); // TODO: Make database file configurable + + std::fstream dat((LPCTSTR)sPath, std::ios_base::in | std::ios_base::binary); + if (dat.good()) { + if (stdex::idrec::find(dat, ZRCOLA_DB_ID, sizeof(ZRCola::recordid_t))) { + ZRCola::recordsize_t size; + dat.read((char*)&size, sizeof(ZRCola::recordsize_t)); + if (dat.good()) { + ZRCola::keyseq_rec rec(m_ks_db); + if (rec.find(dat, size)) { + dat >> rec; + if (!dat.good()) { + wxFAIL_MSG(wxT("Error reading translation data from ZRCola.zrcdb.")); + m_ks_db.idxChr.clear(); + m_ks_db.idxKey.clear(); + m_ks_db.data .clear(); + } + } else + wxFAIL_MSG(wxT("ZRCola.zrcdb has no translation data.")); + } + } else + wxFAIL_MSG(wxT("ZRCola.zrcdb is not a valid ZRCola database.")); + } +} + + +bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event) +{ + if (event.GetEventType() == wxEVT_CHAR) { + // The character event occured. + ZRCola::keyseq_db::indexKey::size_type start, end; + bool found; + + { + wxKeyEvent &e = (wxKeyEvent&)event; + ZRCola::keyseq_db::keyseq *ks = (ZRCola::keyseq_db::keyseq*)new char[sizeof(ZRCola::keyseq_db::keyseq) + sizeof(ZRCola::keyseq_db::keyseq::key_t)*1]; + ks->chr = 0; + ks->seq_len = 1; + ks->seq[0].key = wxToupper(e.m_uniChar); + ks->seq[0].modifiers = + (e.ShiftDown() ? ZRCola::keyseq_db::keyseq::SHIFT : 0) | + (e.ControlDown() ? ZRCola::keyseq_db::keyseq::CTRL : 0) | + (e.AltDown() ? ZRCola::keyseq_db::keyseq::ALT : 0); + found = m_ks_db.idxKey.find((const unsigned __int16&)*ks, start, end); + delete ks; + } + + if (found) { + const ZRCola::keyseq_db::keyseq &ks = (const ZRCola::keyseq_db::keyseq&)m_ks_db.data[m_ks_db.idxKey[start]]; + + wxObject *obj = event.GetEventObject(); + if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) { + // Push text to source control. + ((wxTextCtrl*)obj)->WriteText(ks.chr); + + // Event is fully processed now. + event.StopPropagation(); + return true; + } + } + } + + return wxEvtHandler::ProcessEvent(event); +} diff --git a/ZRCola/zrcolakeyhndlr.h b/ZRCola/zrcolakeyhndlr.h new file mode 100644 index 0000000..f878f5f --- /dev/null +++ b/ZRCola/zrcolakeyhndlr.h @@ -0,0 +1,44 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of ZRCola. + + ZRCola is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ZRCola is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ZRCola. If not, see . +*/ + +/// +/// Forward declarations +/// +class wxZRColaKeyHandler; + + +#pragma once + +#include +#include + + +/// +/// ZRCola keyboard event handler +/// +class wxZRColaKeyHandler : public wxEvtHandler +{ +public: + wxZRColaKeyHandler(); + + virtual bool ProcessEvent(wxEvent& event); + +protected: + ZRCola::keyseq_db m_ks_db; ///< Key sequence database +};