(De)Composition moved to idle processing & other optimizations
(fixes #19)
This commit is contained in:
parent
50790ad01d
commit
a27f7f470d
@ -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>
|
||||||
|
@ -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();
|
||||||
|
@ -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 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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(); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user