+// ----------------------------------------------------------------------------
+// wxPrintPageTextCtrl
+// ----------------------------------------------------------------------------
+
+// This text control contains the page number in the interval specified during
+// its construction. Invalid pages are not accepted and the control contents is
+// validated when it loses focus. Conversely, if the user changes the page to
+// another valid one or presses Enter, OnGotoPage() method of the preview object
+// will be called.
+class wxPrintPageTextCtrl : public wxTextCtrl
+{
+public:
+ wxPrintPageTextCtrl(wxPreviewControlBar *preview, int minPage, int maxPage)
+ : wxTextCtrl(preview,
+ wxID_PREVIEW_GOTO,
+ PageAsString(minPage),
+ wxDefaultPosition,
+ // We use hardcoded 99999 for the width instead of fitting
+ // it to the values we can show because the control looks
+ // uncomfortably narrow if the real page number is just
+ // one or two digits.
+ wxSize(preview->GetTextExtent("99999").x, wxDefaultCoord),
+ wxTE_PROCESS_ENTER
+#if wxUSE_VALIDATORS
+ , wxTextValidator(wxFILTER_DIGITS)
+#endif // wxUSE_VALIDATORS
+ ),
+ m_preview(preview),
+ m_minPage(minPage),
+ m_maxPage(maxPage)
+ {
+ m_page = minPage;
+
+ Connect(wxEVT_KILL_FOCUS,
+ wxFocusEventHandler(wxPrintPageTextCtrl::OnKillFocus));
+ Connect(wxEVT_COMMAND_TEXT_ENTER,
+ wxCommandEventHandler(wxPrintPageTextCtrl::OnTextEnter));
+ }
+
+ // Helpers to conveniently set or get the current page number. Return value
+ // is 0 if the current controls contents is invalid.
+ void SetPageNumber(int page)
+ {
+ wxASSERT( IsValidPage(page) );
+
+ SetValue(PageAsString(page));
+ }
+
+ int GetPageNumber() const
+ {
+ long value;
+ if ( !GetValue().ToLong(&value) || !IsValidPage(value) )
+ return 0;
+
+ // Cast is safe because the value is less than (int) m_maxPage.
+ return static_cast<int>(value);
+ }
+
+private:
+ static wxString PageAsString(int page)
+ {
+ return wxString::Format("%d", page);
+ }
+
+ bool IsValidPage(int page) const
+ {
+ return page >= m_minPage && page <= m_maxPage;
+ }
+
+ bool DoChangePage()
+ {
+ const int page = GetPageNumber();
+
+ if ( !page )
+ return false;
+
+ if ( page != m_page )
+ {
+ // We have a valid page, remember it.
+ m_page = page;
+
+ // And notify the owner about the change.
+ m_preview->OnGotoPage();
+ }
+ //else: Nothing really changed.
+
+ return true;
+ }
+
+ void OnKillFocus(wxFocusEvent& event)
+ {
+ if ( !DoChangePage() )
+ {
+ // The current contents is invalid so reset it back to the last
+ // known good page index.
+ SetPageNumber(m_page);
+ }
+
+ event.Skip();
+ }
+
+ void OnTextEnter(wxCommandEvent& WXUNUSED(event))
+ {
+ DoChangePage();
+ }
+
+
+ wxPreviewControlBar * const m_preview;
+
+ const int m_minPage,
+ m_maxPage;
+
+ // This is the last valid page value that we had, we revert to it if an
+ // invalid page is entered.
+ int m_page;
+
+ wxDECLARE_NO_COPY_CLASS(wxPrintPageTextCtrl);
+};
+