diff --git a/ZRCola/ZRCola.fbp b/ZRCola/ZRCola.fbp
index 8d42908..7912864 100644
--- a/ZRCola/ZRCola.fbp
+++ b/ZRCola/ZRCola.fbp
@@ -805,7 +805,7 @@
-
+ ZRColaComposerPanel
wxTAB_TRAVERSAL
diff --git a/ZRCola/stdafx.h b/ZRCola/stdafx.h
index b6360e2..6f92d90 100644
--- a/ZRCola/stdafx.h
+++ b/ZRCola/stdafx.h
@@ -25,6 +25,7 @@
#include "zrcolafrm.h"
#include "zrcolakeyhndlr.h"
+#include
#include
#include
#include
diff --git a/ZRCola/zrcolacomppnl.cpp b/ZRCola/zrcolacomppnl.cpp
index 62fdb1a..f5c2e07 100644
--- a/ZRCola/zrcolacomppnl.cpp
+++ b/ZRCola/zrcolacomppnl.cpp
@@ -24,6 +24,11 @@
// wxZRColaComposerPanel
//////////////////////////////////////////////////////////////////////////
+BEGIN_EVENT_TABLE(wxZRColaComposerPanel, wxZRColaComposerPanelBase)
+ EVT_TIMER(1, wxZRColaComposerPanel::OnTimerTimeout)
+END_EVENT_TABLE()
+
+
wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
m_progress(false),
m_selDecomposed(0, 0),
@@ -31,12 +36,22 @@ wxZRColaComposerPanel::wxZRColaComposerPanel(wxWindow* parent) :
wxZRColaComposerPanelBase(parent)
{
m_decomposed->PushEventHandler(&m_keyhandler);
+
+ m_timer = new wxTimer(this, 1);
+
+ wxPersistentZRColaComposerPanel(this).Restore();
}
wxZRColaComposerPanel::~wxZRColaComposerPanel()
{
+ if (m_timer)
+ delete m_timer;
+
m_decomposed->PopEventHandler();
+
+ // This is a controlled exit. Purge saved state.
+ wxPersistentZRColaComposerPanel(this).Clear();
}
@@ -86,6 +101,9 @@ void wxZRColaComposerPanel::OnDecomposedText(wxCommandEvent& event)
m_composed->SetSelection(m_mapping2.to_dst(m_mapping1.to_dst(from)), m_mapping2.to_dst(m_mapping1.to_dst(to)));
event.Skip();
m_progress = false;
+
+ // Schedule state save after 3s.
+ m_timer->Start(3000, true);
}
}
@@ -141,5 +159,143 @@ void wxZRColaComposerPanel::OnComposedText(wxCommandEvent& event)
m_decomposed->SetSelection(m_mapping1.to_src(m_mapping2.to_src(from)), m_mapping1.to_src(m_mapping2.to_src(to)));
event.Skip();
m_progress = false;
+
+ // Schedule state save after 3s.
+ m_timer->Start(3000, true);
}
}
+
+
+void wxZRColaComposerPanel::OnTimerTimeout(wxTimerEvent& event)
+{
+ wxPersistentZRColaComposerPanel(this).Save();
+
+ event.Skip();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// wxPersistentZRColaComposerPanel
+//////////////////////////////////////////////////////////////////////////
+
+wxPersistentZRColaComposerPanel::wxPersistentZRColaComposerPanel(wxZRColaComposerPanel *wnd) : wxPersistentWindow(wnd)
+{
+}
+
+
+wxString wxPersistentZRColaComposerPanel::GetKind() const
+{
+ return wxT("ZRColaComposerPanel");
+}
+
+
+void wxPersistentZRColaComposerPanel::Save() const
+{
+ wxString fileName(GetStateFileName());
+ wxFFile file(fileName, wxT("wb"));
+ if (!file.IsOpened())
+ return;
+
+ const wxZRColaComposerPanel * const wnd = static_cast(GetWindow());
+
+ // Save decomposed text.
+ {
+#ifdef __WINDOWS__
+ // Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
+ WXHWND hWnd = wnd->m_decomposed->GetHWND();
+ std::vector text((std::vector::size_type)::GetWindowTextLengthW(hWnd) + 1);
+ ::GetWindowTextW(hWnd, text.data(), text.size());
+ unsigned __int64 n = text.size() - 1;
+#else
+ wxString text(m_decomposed->GetValue());
+ unsigned __int64 n = text.size();
+#endif
+ file.Write(&n, sizeof(n));
+ file.Write(text.data(), sizeof(wchar_t)*n);
+ }
+
+ // Save composed text.
+ {
+#ifdef __WINDOWS__
+ // Use Windows GetWindowText() function to avoid line ending conversion incompletely imposed by wxWidgets.
+ WXHWND hWnd = wnd->m_composed->GetHWND();
+ std::vector text((std::vector::size_type)::GetWindowTextLengthW(hWnd) + 1);
+ ::GetWindowTextW(hWnd, text.data(), text.size());
+ unsigned __int64 n = text.size() - 1;
+#else
+ wxString text(m_composed->GetValue());
+ unsigned __int64 n = text.size();
+#endif
+ file.Write(&n, sizeof(n));
+ file.Write(text.data(), sizeof(wchar_t)*n);
+ }
+}
+
+
+bool wxPersistentZRColaComposerPanel::Restore()
+{
+ wxString fileName(GetStateFileName());
+
+ if (!wxFileExists(fileName))
+ return false;
+
+ wxFFile file(fileName, wxT("rb"));
+ if (!file.IsOpened())
+ return false;
+
+ wxZRColaComposerPanel * const wnd = static_cast(GetWindow());
+
+ // 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.
+ wnd->m_progress = true;
+ wnd->m_decomposed->SetValue(decomposed);
+ wnd->m_composed->SetValue(composed);
+ wnd->m_progress = false;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
+void wxPersistentZRColaComposerPanel::Clear() const
+{
+ wxString fileName(GetStateFileName());
+
+ if (wxFileExists(fileName))
+ wxRemoveFile(fileName);
+}
+
+
+wxString wxPersistentZRColaComposerPanel::GetStateFileName() const
+{
+ wxString path;
+
+ path = wxFileName::GetTempDir();
+ if (!wxEndsWithPathSeparator(path))
+ path += wxFILE_SEP_PATH;
+
+ if (!wxDirExists(path))
+ wxMkdir(path);
+
+ wxString fileName(path);
+ fileName += GetKind();
+ fileName += wxT("-state.tmp");
+
+ return fileName;
+}
diff --git a/ZRCola/zrcolacomppnl.h b/ZRCola/zrcolacomppnl.h
index 3f25d8d..9e297df 100644
--- a/ZRCola/zrcolacomppnl.h
+++ b/ZRCola/zrcolacomppnl.h
@@ -27,6 +27,8 @@ class wxZRColaComposerPanel;
#include "zrcolagui.h"
#include "zrcolakeyhndlr.h"
+#include
+#include
#include
@@ -39,13 +41,16 @@ public:
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 OnDecomposedText(wxCommandEvent& event);
virtual void OnComposedPaint(wxPaintEvent& event);
virtual void OnComposedText(wxCommandEvent& event);
+ virtual void OnTimerTimeout(wxTimerEvent& event);
+ DECLARE_EVENT_TABLE()
protected:
bool m_progress; ///< Boolean flag to avoid recursive updates of composed and decomposed text controls
@@ -55,4 +60,29 @@ protected:
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
+ wxTimer *m_timer; ///< Timer to trigger the state save
};
+
+
+///
+/// Supports saving/restoring wxZRColaComposerPanel state
+///
+class wxPersistentZRColaComposerPanel : public wxPersistentWindow
+{
+public:
+ wxPersistentZRColaComposerPanel(wxZRColaComposerPanel *wnd);
+
+ virtual wxString GetKind() const;
+ virtual void Save() const;
+ virtual bool Restore();
+ virtual void Clear() const;
+
+protected:
+ wxString GetStateFileName() const;
+};
+
+
+inline wxPersistentObject *wxCreatePersistentObject(wxZRColaComposerPanel *wnd)
+{
+ return new wxPersistentZRColaComposerPanel(wnd);
+}
diff --git a/ZRCola/zrcolafrm.cpp b/ZRCola/zrcolafrm.cpp
index 615115e..8b64f15 100644
--- a/ZRCola/zrcolafrm.cpp
+++ b/ZRCola/zrcolafrm.cpp
@@ -298,7 +298,6 @@ wxPersistentZRColaFrame::wxPersistentZRColaFrame(wxZRColaFrame *wnd) : wxPersist
void wxPersistentZRColaFrame::Save() const
{
- //
const wxZRColaFrame * const wnd = static_cast(GetWindow());
SaveValue(wxT("lang"), wxString::FromAscii(wnd->m_lang, sizeof(wnd->m_lang)));
diff --git a/ZRCola/zrcolagui.cpp b/ZRCola/zrcolagui.cpp
index 0b74a13..394497a 100644
--- a/ZRCola/zrcolagui.cpp
+++ b/ZRCola/zrcolagui.cpp
@@ -160,7 +160,7 @@ 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 );
diff --git a/ZRCola/zrcolagui.h b/ZRCola/zrcolagui.h
index f62eeb9..7523308 100644
--- a/ZRCola/zrcolagui.h
+++ b/ZRCola/zrcolagui.h
@@ -96,7 +96,7 @@ class wxZRColaComposerPanelBase : public wxPanel
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();
};