(De)Composition moved to idle processing & other optimizations

(fixes #19)
This commit is contained in:
Simon Rozman 2016-05-10 09:41:35 +02:00
parent 50790ad01d
commit a27f7f470d
9 changed files with 191 additions and 145 deletions

View File

@ -67,7 +67,7 @@
<event name="OnEraseBackground"></event> <event name="OnEraseBackground"></event>
<event name="OnHibernate"></event> <event name="OnHibernate"></event>
<event name="OnIconize"></event> <event name="OnIconize"></event>
<event name="OnIdle"></event> <event name="OnIdle">OnIdle</event>
<event name="OnKeyDown"></event> <event name="OnKeyDown"></event>
<event name="OnKeyUp"></event> <event name="OnKeyUp"></event>
<event name="OnKillFocus"></event> <event name="OnKillFocus"></event>

View File

@ -103,7 +103,6 @@ void wxZRColaCharacterCatalogPanel::OnGridClick(wxGridEvent& event)
ZRColaApp *app = (ZRColaApp*)wxTheApp; ZRColaApp *app = (ZRColaApp*)wxTheApp;
if (app->m_mainWnd) { if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(event.GetRow(), event.GetCol())); app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(event.GetRow(), event.GetCol()));
app->m_mainWnd->m_panel->m_decomposed->SendTextUpdatedEvent(); // Fixes #19: Premature EN_CHANGE event on EM_REPLACESEL.
app->m_mainWnd->m_panel->m_decomposed->SetFocus(); app->m_mainWnd->m_panel->m_decomposed->SetFocus();
} }
@ -117,7 +116,6 @@ void wxZRColaCharacterCatalogPanel::OnGridKeyDown(wxKeyEvent& event)
ZRColaApp *app = (ZRColaApp*)wxTheApp; ZRColaApp *app = (ZRColaApp*)wxTheApp;
if (app->m_mainWnd) { if (app->m_mainWnd) {
app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(m_grid->GetCursorRow(), m_grid->GetCursorColumn())); app->m_mainWnd->m_panel->m_decomposed->WriteText(m_grid->GetCellValue(m_grid->GetCursorRow(), m_grid->GetCursorColumn()));
app->m_mainWnd->m_panel->m_decomposed->SendTextUpdatedEvent(); // Fixes #19: Premature EN_CHANGE event on EM_REPLACESEL.
app->m_mainWnd->m_panel->m_decomposed->SetFocus(); app->m_mainWnd->m_panel->m_decomposed->SetFocus();
event.StopPropagation(); event.StopPropagation();

View File

@ -30,7 +30,8 @@ END_EVENT_TABLE()
wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) : wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_progress(false), m_decomposedChanged(false),
m_composedChanged(false),
m_selDecomposed(0, 0), m_selDecomposed(0, 0),
m_selComposed(0, 0), m_selComposed(0, 0),
wxZRColaComposerPanelBase(parent) wxZRColaComposerPanelBase(parent)
@ -59,10 +60,15 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
file.Read(wxStringBuffer(composed, n), sizeof(wchar_t)*n); file.Read(wxStringBuffer(composed, n), sizeof(wchar_t)*n);
if (!file.Error()) { if (!file.Error()) {
// Restore state. // Restore state.
m_progress = true;
m_decomposed->SetValue(decomposed); m_decomposed->SetValue(decomposed);
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, decomposed.GetData(), decomposed.Length(), m_selDecomposed.first, m_selDecomposed.second);
m_decomposedChanged = false;
m_composed->SetValue(composed); m_composed->SetValue(composed);
m_progress = false; m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, composed.GetData(), composed.Length(), m_selComposed.first, m_selComposed.second);
m_composedChanged = false;
} }
} }
} }
@ -86,6 +92,73 @@ wxZRColaComposerPanel::~wxZRColaComposerPanel()
} }
void wxZRColaComposerPanel::SynchronizePanels()
{
if (m_decomposedChanged) {
m_timer->Stop();
wxString src;
size_t len = GetValue(m_decomposed, src);
std::wstring norm;
((ZRColaApp*)wxTheApp)->m_t_db.Decompose(src.data(), len, norm, &m_mapping1);
std::wstring dst;
((ZRColaApp*)wxTheApp)->m_t_db.Compose(norm.data(), norm.size(), dst, &m_mapping2);
m_decomposed->GetSelection(&m_selDecomposed.first, &m_selDecomposed.second);
// Update decomposed HEX dump.
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, src.data(), len, m_selDecomposed.first, m_selDecomposed.second);
// Update composed text, and its HEX dump.
m_composed->SetValue(dst);
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, dst.data(), dst.length(), m_selComposed.first, m_selComposed.second);
// Schedule state save after 3s.
m_timer->Start(3000, true);
} else if (m_composedChanged) {
m_timer->Stop();
wxString src;
size_t len = GetValue(m_composed, src);
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::wstring dst;
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), len, &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping2);
else
app->m_t_db.Decompose(src.data(), len, dst, &m_mapping2);
m_mapping1.clear();
m_mapping2.invert();
m_composed->GetSelection(&m_selComposed.first, &m_selComposed.second);
// Update composed HEX dump.
SetHexValue(m_composedHex, m_selComposedHex, m_mappingComposedHex, src.data(), len, m_selComposed.first, m_selComposed.second);
// Update decomposed text, and its HEX dump.
m_decomposed->SetValue(dst);
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
SetHexValue(m_decomposedHex, m_selDecomposedHex, m_mappingDecomposedHex, dst.data(), dst.length(), m_selDecomposed.first, m_selDecomposed.second);
// Schedule state save after 3s.
m_timer->Start(3000, true);
}
m_decomposedChanged = false;
m_composedChanged = false;
}
void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event) void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
{ {
event.Skip(); event.Skip();
@ -97,9 +170,18 @@ void wxZRColaComposerPanel::OnDecomposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop. // Save new selection first, to avoid loop.
m_selDecomposed.first = from; m_selDecomposed.first = from;
m_selDecomposed.second = to; m_selDecomposed.second = to;
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
m_composed->SetSelection(from = m_mapping2.to_dst(m_mapping1.to_dst(from)), to = m_mapping2.to_dst(m_mapping1.to_dst(to))); m_decomposedHex->SetSelection(
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to)); m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(from),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(from)),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(to )));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
} }
} }
@ -115,9 +197,18 @@ void wxZRColaComposerPanel::OnDecomposedHexPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop. // Save new selection first, to avoid loop.
m_selDecomposedHex.first = from; m_selDecomposedHex.first = from;
m_selDecomposedHex.second = to; 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_decomposed->SetSelection(
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to)); m_selDecomposed.first = m_mappingDecomposedHex.to_src(from),
m_selDecomposed.second = m_mappingDecomposedHex.to_src(to ));
m_composed->SetSelection(
m_selComposed.first = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.first )),
m_selComposed.second = m_mapping2.to_dst(m_mapping1.to_dst(m_selDecomposed.second)));
m_composedHex->SetSelection(
m_selComposedHex.first = m_mappingComposedHex.to_dst(m_selComposed.first ),
m_selComposedHex.second = m_mappingComposedHex.to_dst(m_selComposed.second));
} }
} }
@ -126,50 +217,8 @@ void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
{ {
event.Skip(); event.Skip();
if (!m_progress) { // Set the flag the decomposed text changed to trigger idle-time composition.
m_timer->Stop(); m_decomposedChanged = true;
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_decomposed->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> src(len + 1);
::GetWindowTextW(hWnd, src.data(), src.size());
#else
wxString src(m_decomposed->GetValue());
size_t len = src.Length();
#endif
std::wstring norm;
((ZRColaApp*)wxTheApp)->m_t_db.Decompose(src.data(), len, norm, &m_mapping1);
std::wstring dst;
((ZRColaApp*)wxTheApp)->m_t_db.Compose(norm.data(), norm.size(), dst, &m_mapping2);
long from, to;
m_decomposed->GetSelection(&from, &to);
// Update decomposed HEX dump.
wxString hex;
GetHex(hex, m_mappingDecomposedHex, src.data(), len);
m_decomposedHex->SetValue(hex);
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
// Update composed text.
m_progress = true;
m_composed->SetValue(dst);
m_composed->SetSelection(from = m_mapping2.to_dst(m_mapping1.to_dst(from)), to = m_mapping2.to_dst(m_mapping1.to_dst(to)));
// Update composed HEX dump.
GetHex(hex, m_mappingComposedHex, dst.data(), dst.length());
m_composedHex->SetValue(hex);
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
m_progress = false;
// Schedule state save after 3s.
m_timer->Start(3000, true);
}
} }
@ -184,9 +233,18 @@ void wxZRColaComposerPanel::OnComposedPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop. // Save new selection first, to avoid loop.
m_selComposed.first = from; m_selComposed.first = from;
m_selComposed.second = to; m_selComposed.second = to;
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
m_decomposed->SetSelection(from = m_mapping1.to_src(m_mapping2.to_src(from)), to = m_mapping1.to_src(m_mapping2.to_src(to))); m_composedHex->SetSelection(
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to)); m_selComposedHex.first = m_mappingComposedHex.to_dst(from),
m_selComposedHex.second = m_mappingComposedHex.to_dst(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(from)),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(to )));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
} }
} }
@ -202,9 +260,18 @@ void wxZRColaComposerPanel::OnComposedHexPaint(wxPaintEvent& event)
// Save new selection first, to avoid loop. // Save new selection first, to avoid loop.
m_selComposedHex.first = from; m_selComposedHex.first = from;
m_selComposedHex.second = to; 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_composed->SetSelection(
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to)); m_selComposed.first = m_mappingComposedHex.to_src(from),
m_selComposed.second = m_mappingComposedHex.to_src(to ));
m_decomposed->SetSelection(
m_selDecomposed.first = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.first )),
m_selDecomposed.second = m_mapping1.to_src(m_mapping2.to_src(m_selComposed.second)));
m_decomposedHex->SetSelection(
m_selDecomposedHex.first = m_mappingDecomposedHex.to_dst(m_selDecomposed.first ),
m_selDecomposedHex.second = m_mappingDecomposedHex.to_dst(m_selDecomposed.second));
} }
} }
@ -213,55 +280,8 @@ void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
{ {
event.Skip(); event.Skip();
if (!m_progress) { // Set the flag the composed text changed to trigger idle-time decomposition.
m_timer->Stop(); m_composedChanged = true;
#ifdef __WINDOWS__
// Use Windows GetWindowTextLength() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = m_composed->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
std::vector<wchar_t> src(len + 1);
::GetWindowTextW(hWnd, src.data(), src.size());
#else
wxString src(m_composed->GetValue());
size_t len = src.Length();
#endif
ZRColaApp *app = (ZRColaApp*)wxTheApp;
std::wstring dst;
wxZRColaFrame *mainWnd = dynamic_cast<wxZRColaFrame*>(wxGetActiveWindow());
if (mainWnd)
app->m_t_db.Decompose(src.data(), len, &app->m_lc_db, mainWnd->m_lang, dst, &m_mapping2);
else
app->m_t_db.Decompose(src.data(), len, dst, &m_mapping2);
m_mapping1.clear();
m_mapping2.invert();
long from, to;
m_composed->GetSelection(&from, &to);
// Update composed HEX dump.
wxString hex;
GetHex(hex, m_mappingComposedHex, src.data(), len);
m_composedHex->SetValue(hex);
m_composedHex->SetSelection(m_mappingComposedHex.to_dst(from), m_mappingComposedHex.to_dst(to));
// Update decomposed text.
m_progress = true;
m_decomposed->SetValue(dst);
m_decomposed->SetSelection(from = m_mapping1.to_src(m_mapping2.to_src(from)), to = m_mapping1.to_src(m_mapping2.to_src(to)));
// Update decomposed HEX dump.
GetHex(hex, m_mappingDecomposedHex, dst.data(), dst.length());
m_decomposedHex->SetValue(hex);
m_decomposedHex->SetSelection(m_mappingDecomposedHex.to_dst(from), m_mappingDecomposedHex.to_dst(to));
m_progress = false;
// Schedule state save after 3s.
m_timer->Start(3000, true);
}
} }
@ -270,37 +290,18 @@ void wxZRColaComposerPanel::OnTimerTimeout(wxTimerEvent& event)
wxString fileName(GetStateFileName()); wxString fileName(GetStateFileName());
wxFFile file(fileName, wxT("wb")); wxFFile file(fileName, wxT("wb"));
if (file.IsOpened()) { if (file.IsOpened()) {
wxString text;
size_t len;
// Save decomposed text. // Save decomposed text.
{ len = GetValue(m_decomposed, text);
#ifdef __WINDOWS__ file.Write(&len, sizeof(len));
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets. file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
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. // Save composed text.
{ len = GetValue(m_composed, text);
#ifdef __WINDOWS__ file.Write(&len, sizeof(len));
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets. file.Write((const wchar_t*)text, sizeof(wchar_t)*len);
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(); event.Skip();
@ -325,10 +326,36 @@ wxString wxZRColaComposerPanel::GetStateFileName()
} }
void wxZRColaComposerPanel::GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len) size_t wxZRColaComposerPanel::GetValue(wxTextCtrl *wnd, wxString &text)
{ {
#ifdef __WINDOWS__
// Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
WXHWND hWnd = wnd->GetHWND();
size_t len = ::GetWindowTextLengthW(hWnd);
if (len < 0x100) {
WCHAR buf[0x100];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
} else {
LPWSTR buf = new WCHAR[len + 1];
::GetWindowTextW(hWnd, buf, len + 1);
text.assign(buf, len);
delete [] buf;
}
return len;
#else
text = wnd->GetValue();
return text.Length();
#endif
}
void wxZRColaComposerPanel::SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to)
{
wxString hex;
bool first = true; bool first = true;
hex.clear();
mapping.clear(); mapping.clear();
for (size_t i = 0; i < len && src[i]; i++) { for (size_t i = 0; i < len && src[i]; i++) {
wchar_t c = src[i]; wchar_t c = src[i];
@ -341,6 +368,11 @@ void wxZRColaComposerPanel::GetHex(wxString &hex, ZRCola::mapping_vector &mappin
first = false; first = false;
} }
} }
wnd->SetValue(hex);
wnd->SetSelection(
range.first = mapping.to_dst(from),
range.second = mapping.to_dst(to ));
} }

View File

@ -46,6 +46,8 @@ public:
wxZRColaComposerPanel(wxWindow* parent); wxZRColaComposerPanel(wxWindow* parent);
virtual ~wxZRColaComposerPanel(); virtual ~wxZRColaComposerPanel();
void SynchronizePanels();
friend class wxPersistentZRColaComposerPanel; // Allow saving/restoring window state. friend class wxPersistentZRColaComposerPanel; // Allow saving/restoring window state.
protected: protected:
@ -59,10 +61,12 @@ protected:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
static wxString GetStateFileName(); static wxString GetStateFileName();
static void GetHex(wxString &hex, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len); static size_t GetValue(wxTextCtrl *wnd, wxString &text);
static void SetHexValue(wxTextCtrl *wnd, std::pair<long, long> &range, ZRCola::mapping_vector &mapping, const wchar_t *src, size_t len, long from, long to);
protected: protected:
bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls bool m_decomposedChanged; ///< Boolean flag to mark decomposed text "dirty" to trigger composition
bool m_composedChanged; ///< Boolean flag to mark composed text "dirty" to trigger decomposition
ZRCola::mapping_vector m_mapping1; ///< Character index mapping vector between decomposed and normalized text ZRCola::mapping_vector m_mapping1; ///< Character index mapping vector between decomposed and normalized text
ZRCola::mapping_vector m_mapping2; ///< Character index mapping vector between normalized and composed text ZRCola::mapping_vector m_mapping2; ///< Character index mapping vector between normalized and composed text
std::pair<long, long> std::pair<long, long>

View File

@ -337,6 +337,16 @@ void wxZRColaFrame::OnDecompLanguageChoice(wxCommandEvent& event)
m_panel->m_composed->ProcessWindowEvent(event2); m_panel->m_composed->ProcessWindowEvent(event2);
m_lang_auto = false; m_lang_auto = false;
} }
event.Skip();
}
void wxZRColaFrame::OnIdle(wxIdleEvent& event)
{
m_panel->SynchronizePanels();
event.Skip();
} }

View File

@ -78,6 +78,7 @@ protected:
void OnDecomposedLanguageUpdate(wxUpdateUIEvent& event); void OnDecomposedLanguageUpdate(wxUpdateUIEvent& event);
void OnDecomposedLanguage(wxCommandEvent& event); void OnDecomposedLanguage(wxCommandEvent& event);
virtual void OnDecompLanguageChoice(wxCommandEvent& event); virtual void OnDecompLanguageChoice(wxCommandEvent& event);
virtual void OnIdle(wxIdleEvent& event);
void OnToolbarEditUpdate(wxUpdateUIEvent& event); void OnToolbarEditUpdate(wxUpdateUIEvent& event);
void OnToolbarEdit(wxCommandEvent& event); void OnToolbarEdit(wxCommandEvent& event);
void OnToolbarComposeUpdate(wxUpdateUIEvent& event); void OnToolbarComposeUpdate(wxUpdateUIEvent& event);

View File

@ -183,12 +183,14 @@ wxZRColaFrameBase::wxZRColaFrameBase( wxWindow* parent, wxWindowID id, const wxS
this->Centre( wxBOTH ); this->Centre( wxBOTH );
// Connect Events // Connect Events
this->Connect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaFrameBase::OnIdle ) );
m_toolDecompLanguage->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this ); m_toolDecompLanguage->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
} }
wxZRColaFrameBase::~wxZRColaFrameBase() wxZRColaFrameBase::~wxZRColaFrameBase()
{ {
// Disconnect Events // Disconnect Events
this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( wxZRColaFrameBase::OnIdle ) );
m_toolDecompLanguage->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this ); m_toolDecompLanguage->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( wxZRColaFrameBase::OnDecompLanguageChoice ), NULL, this );
m_mgr.UnInit(); m_mgr.UnInit();

View File

@ -77,6 +77,7 @@ class wxZRColaFrameBase : public wxFrame
wxStatusBar* m_statusBar; wxStatusBar* m_statusBar;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnDecompLanguageChoice( wxCommandEvent& event ) { event.Skip(); } virtual void OnDecompLanguageChoice( wxCommandEvent& event ) { event.Skip(); }

View File

@ -112,7 +112,6 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) { if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) {
// Push text to source control. // Push text to source control.
((wxTextCtrl*)obj)->WriteText(ks.chr); ((wxTextCtrl*)obj)->WriteText(ks.chr);
((wxTextCtrl*)obj)->SendTextUpdatedEvent(); // Fixes #19: Premature EN_CHANGE event on EM_REPLACESEL.
// Event is fully processed now. // Event is fully processed now.
event.StopPropagation(); event.StopPropagation();
@ -154,7 +153,6 @@ bool wxZRColaKeyHandler::ProcessEvent(wxEvent& event)
if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) { if (obj && obj->IsKindOf(wxCLASSINFO(wxTextCtrl))) {
// Push text to source control. // Push text to source control.
((wxTextCtrl*)obj)->WriteText(chr); ((wxTextCtrl*)obj)->WriteText(chr);
((wxTextCtrl*)obj)->SendTextUpdatedEvent(); // Fixes #19: Premature EN_CHANGE event on EM_REPLACESEL.
} }
} }