Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51184 - in sandbox/mirror: boost/mirror/factory boost/mirror/factory/wx_constructor_gui libs/mirror/build/msvc/mirror_examples/fact_simple_gui
From: chochlik_at_[hidden]
Date: 2009-02-10 10:38:28


Author: matus.chochlik
Date: 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
New Revision: 51184
URL: http://svn.boost.org/trac/boost/changeset/51184

Log:
[mirror 0.3.x]
- added a regex based wxValidator for the wx_constructor_gui

Added:
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui/regex_validator.hpp (contents, props changed)
Text files modified:
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui.hpp | 18 +++++-
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui/basic.hpp | 118 +++++++++++++++++++++++++++++++++------
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui/default.hpp | 5 +
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui/manager.hpp | 39 ++++++++++++
   sandbox/mirror/boost/mirror/factory/wx_constructor_gui/utils.hpp | 3 +
   sandbox/mirror/libs/mirror/build/msvc/mirror_examples/fact_simple_gui/fact_simple_gui.vcproj | 4
   6 files changed, 159 insertions(+), 28 deletions(-)

Modified: sandbox/mirror/boost/mirror/factory/wx_constructor_gui.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory/wx_constructor_gui.hpp (original)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -40,8 +40,11 @@
         {
                 assert(parent != 0);
                 //
- // create the main panel od the dialog
+ // create the main panel of the dialog
                 wxPanel* panel = new wxPanel(parent, wxID_ANY);
+ panel->SetExtraStyle(
+ panel->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY
+ );
                 // create the main sizer
                 wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
                 // top padding
@@ -92,12 +95,21 @@
         factory< wx_constructor_gui, Product > fact;
 public:
         wx_factory_dialog(wxWindow* parent, wxString caption)
- : dialog(new wxDialog(parent, wxID_ANY, caption))
- , data(make_data(dialog))
+ : dialog(
+ new wxDialog(
+ parent,
+ wxID_ANY,
+ caption
+ )
+ ), data(make_data(dialog))
          , fact(&data, 0)
         {
                 // and resize the dialog
                 dialog->GetSizer()->SetSizeHints(dialog);
+ dialog->SetExtraStyle(
+ dialog->GetExtraStyle() |
+ wxWS_EX_VALIDATE_RECURSIVELY
+ );
         }
 
         ~wx_factory_dialog(void)

Modified: sandbox/mirror/boost/mirror/factory/wx_constructor_gui/basic.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory/wx_constructor_gui/basic.hpp (original)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui/basic.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -12,6 +12,7 @@
 
 #include <wx/wx.h>
 #include <wx/sizer.h>
+#include <boost/mirror/factory/wx_constructor_gui/regex_validator.hpp>
 
 namespace boost {
 namespace mirror {
@@ -25,11 +26,33 @@
 
         struct text_ctl_maker
         {
+ wxString pattern;
+ wxString message;
+
+ text_ctl_maker(
+ const wxString& pat,
+ const wxString& msg
+ ): pattern(pat)
+ , message(msg)
+ { }
+
                 inline wxTextCtrl* operator()(wxWindow* parent) const
                 {
- return new wxTextCtrl(parent, wxID_ANY);
+ if(pattern.empty())
+ return new wxTextCtrl(
+ parent,
+ wxID_ANY
+ );
+ else return new wxTextCtrl(
+ parent,
+ wxID_ANY,
+ wxEmptyString,
+ wxDefaultPosition,
+ wxDefaultSize,
+ 0,
+ detail::RegExValidator(pattern, message)
+ );
                 }
-
                 typedef wxTextCtrl result_type;
         };
 protected:
@@ -43,14 +66,25 @@
                 wx_constructor_gui_data* parent_data,
                 Context* pc,
                 ConstrIndex ci,
- ParamIndex pi
- ): text_ctl(make_ctl(text_ctl_maker(), parent_data, pc, ci, pi))
- { }
+ ParamIndex pi,
+ wxString pattern,
+ wxString message
+ ): text_ctl(
+ make_ctl(
+ text_ctl_maker(pattern, message),
+ parent_data,
+ pc,
+ ci,
+ pi
+ )
+ ){ }
 };
 
 #define BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI( \
         PRODUCT, \
- FUNCTOR_BODY \
+ FUNCTOR_BODY, \
+ PATTERN, \
+ MESSAGE \
 ) \
 template <> \
 class wx_constructor_gui< PRODUCT > \
@@ -66,21 +100,31 @@
                 Context* pc, \
                 ConstrIndex ci, \
                 ParamIndex pi \
- ): base_class(parent_data, pc, ci, pi) \
- { } \
+ ): base_class( \
+ parent_data, \
+ pc, \
+ ci, \
+ pi, \
+ wxT( PATTERN ), \
+ wxT( MESSAGE ) \
+ ){ } \
  \
         inline PRODUCT operator()(void) FUNCTOR_BODY \
 };
 
 BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI(
         cts::bstring,
- {return cts::bstring(get_text().c_str());}
+ {return cts::bstring(get_text().c_str());},
+ "",
+ ""
 )
 
 #define BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT( \
         TYPE, \
         TEMP_TYPE, \
- CONVERSION \
+ CONVERSION, \
+ PATTERN, \
+ MESSAGE \
 ) BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI( \
         TYPE, \
         { \
@@ -88,18 +132,52 @@
                 if(!get_text().CONVERSION(&result)) \
                         throw ::std::bad_cast(); \
                 return TYPE(result); \
- } \
+ }, \
+ PATTERN, \
+ MESSAGE \
 )
 
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(unsigned char, unsigned long, ToULong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(short, long, ToLong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(unsigned short, unsigned long, ToULong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(int, long, ToLong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(unsigned int, unsigned long, ToULong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(long, long, ToLong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(unsigned long, unsigned long, ToULong)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(float, double, ToDouble)
-BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT(double, double, ToDouble)
+#define BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_UINT(TYPE) \
+ BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT( \
+ TYPE, \
+ unsigned long, \
+ ToULong, \
+ "^[+]?[[:digit:]]+$", \
+ "invalid unsigned integer" \
+ )
+
+#define BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_INT(TYPE) \
+ BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT( \
+ TYPE, \
+ long, \
+ ToLong, \
+ "^[+-]?[[:digit:]]+$", \
+ "invalid integer" \
+ )
+
+#define BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_FLOAT(TYPE) \
+ BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT( \
+ TYPE, \
+ double, \
+ ToDouble, \
+ "^[+-]?[[:digit:]]+\\.?[[:digit:]]*$", \
+ "invalid floating point number" \
+ )
+
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_UINT(unsigned short)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_UINT(unsigned int)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_UINT(unsigned long)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_INT(short)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_INT(int)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_INT(long)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_FLOAT(float)
+BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_FLOAT(double)
+
+
+#undef BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_UINT
+#undef BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_INT
+#undef BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_FLOAT
+#undef BOOST_MIRROR_FACTORY_PLUGINS_SPECIALIZE_WX_CONSTR_GUI_WX_CONVERT
 
 } // namespace utils
 } // namespace mirror

Modified: sandbox/mirror/boost/mirror/factory/wx_constructor_gui/default.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory/wx_constructor_gui/default.hpp (original)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui/default.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -45,7 +45,10 @@
                 // all child widgets
                 wxPanel* panel = new wxPanel(
                         parent_data->get_window(),
- wxID_ANY
+ wxID_ANY
+ );
+ panel->SetExtraStyle(
+ panel->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY
                 );
                 // the sizer
                 wxStaticBoxSizer* sizer = new wxStaticBoxSizer(

Modified: sandbox/mirror/boost/mirror/factory/wx_constructor_gui/manager.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory/wx_constructor_gui/manager.hpp (original)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui/manager.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -28,7 +28,32 @@
         // pointer to the parent data
         wx_constructor_gui_data* parent_data;
         //
- typedef wxChoicebook BookCtrl;
+ class BookCtrl : public wxChoicebook
+ {
+ private:
+ public:
+ BookCtrl(wxWindow* parent, int id)
+ : wxChoicebook(parent, id)
+ { }
+
+ virtual bool Validate()
+ {
+ // validate only the currently selected page
+ wxWindow* visible_child(GetCurrentPage());
+ if(visible_child)
+ return visible_child->Validate();
+ else return true;
+ }
+
+ virtual bool TransferDataFromWindow()
+ {
+ // validate only the currently selected page
+ wxWindow* visible_child(GetCurrentPage());
+ if(visible_child)
+ return visible_child->TransferDataFromWindow();
+ else return true;
+ }
+ };
         // the book ctrl
         BookCtrl* book_ctl;
         static inline BookCtrl* make_book_ctl(
@@ -42,6 +67,10 @@
                         parent_data->get_window(),
                         wxID_ANY
                 );
+ book_ctl->SetExtraStyle(
+ book_ctl->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY
+ );
+
                 // add the widget to the sizer
                 parent_data->get_sizer()->Add(book_ctl, 0, wxEXPAND);
                 // return the pointer
@@ -98,7 +127,13 @@
         {
                 assert(parent_data);
                 // create a panel and a sizer for the page
- wxPanel* panel = new wxPanel(book_ctl, wxID_ANY);
+ wxPanel* panel = new wxPanel(
+ book_ctl,
+ wxID_ANY
+ );
+ panel->SetExtraStyle(
+ panel->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY
+ );
                 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
                 panel->SetSizer(sizer);
                 //

Added: sandbox/mirror/boost/mirror/factory/wx_constructor_gui/regex_validator.hpp
==============================================================================
--- (empty file)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui/regex_validator.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -0,0 +1,245 @@
+/**
+ * \file boost/mirror/factory/wx_constructor_gui/regex_validator.hpp
+ *
+ *
+ * Copyright 2008 Matus Chochlik. Distributed under the Boost
+ * Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_MIRROR_FACTORY_WX_CONSTRUCTOR_GUI_REGEX_VALIDATOR_HPP
+#define BOOST_MIRROR_FACTORY_WX_CONSTRUCTOR_GUI_REGEX_VALIDATOR_HPP
+
+#include <wx/wx.h>
+#include <wx/sizer.h>
+#include <wx/checkbox.h>
+#include <wx/regex.h>
+#include <wx/tipwin.h>
+
+#include <assert.h>
+
+
+namespace boost {
+namespace mirror {
+namespace utils {
+namespace detail {
+
+class RegExValidator: public wxValidator
+{
+protected:
+ wxString pattern;
+ wxRegEx regex;
+ wxString message;
+ wxArrayString* matches;
+ wxTipWindow* tip;
+ //
+ bool CheckValidator(void) const
+ {
+ wxCHECK_MSG(
+ m_validatorWindow,
+ false,
+ wxT("No window associated with validator")
+ );
+ wxCHECK_MSG(
+ m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl)),
+ false,
+ wxT("RegExValidator is only for wxTextCtrl's")
+ );
+ return true;
+ }
+private:
+ // no assignment
+ RegExValidator& operator=(const RegExValidator&);
+ void Init(void)
+ {
+ this->Connect(
+ wxEVT_CHAR,
+ wxObjectEventFunction(&RegExValidator::OnChar)
+ );
+ }
+public:
+ RegExValidator(
+ wxString _pattern,
+ wxString msg = wxString(wxT("invalid value")),
+ wxArrayString* strings = 0
+ ): pattern(_pattern)
+ , regex(pattern)
+ , message(msg)
+ , matches(strings)
+ , tip(0)
+ {
+ Init();
+ }
+
+ RegExValidator(const RegExValidator& val)
+ : pattern(val.pattern)
+ , regex(pattern)
+ , message(val.message)
+ , matches(val.matches)
+ , tip(0)
+ {
+ Init();
+ }
+
+ virtual ~RegExValidator(void){ }
+
+ // Make a clone of this validator (or return NULL) - currently necessary
+ // if you're passing a reference to a validator.
+ // Another possibility is to always pass a pointer to a new validator
+ // (so the calling code can use a copy constructor of the relevant class).
+ virtual wxObject *Clone() const
+ {
+ return new RegExValidator(*this);
+ }
+
+ inline wxTextCtrl* GetControl(void)
+ {
+ assert(CheckValidator());
+ return (wxTextCtrl *) m_validatorWindow;
+ }
+
+ inline bool QueryValue(wxString& value)
+ {
+ if(!CheckValidator())
+ return false;
+ // If window is disabled, simply return
+ if (GetControl()->IsEnabled())
+ value.assign(GetControl()->GetValue());
+ else value.clear();
+ return true;
+ }
+
+ // Called when the value in the window must be validated.
+ // This function can pop up an error message.
+ virtual bool Validate(wxWindow *parent)
+ {
+ wxString val;
+ if(!QueryValue(val)) return false;
+ bool ok = regex.Matches(val);
+ if(!ok && (tip == 0) && !wxValidator::IsSilent())
+ {
+ tip = new wxTipWindow(
+ GetControl(),
+ message,
+ 100, // max length
+ &tip
+ );
+ wxBell();
+ }
+ return ok;
+ }
+
+ // Called to transfer data to the window
+ virtual bool TransferToWindow()
+ {
+ return true;
+ }
+
+ // Called to transfer data from the window
+ virtual bool TransferFromWindow()
+ {
+ wxString val;
+ if(!QueryValue(val)) return false;
+ if(regex.Matches(val))
+ {
+ if(matches != 0)
+ {
+ matches->clear();
+ for(int i=0,n=regex.GetMatchCount();i<n;++i)
+ {
+ size_t start, len;
+ if(!regex.GetMatch(&start, &len, i))
+ {
+ return false;
+ }
+ matches->Add(wxString(val, start, len));
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ bool IsNavigationKey(int key_code)
+ {
+ return
+ key_code == WXK_END ||
+ key_code == WXK_HOME ||
+ key_code == WXK_LEFT ||
+ key_code == WXK_RIGHT ||
+ key_code == WXK_UP ||
+ key_code == WXK_DOWN ;
+ }
+
+ // Filter keystrokes
+ void OnChar(wxKeyEvent& event)
+ {
+ bool accept = false;
+ wxString val;
+ if(QueryValue(val))
+ {
+ // if we've got the value
+ int key_code = event.GetKeyCode();
+ // get the position of the cursor
+ int pos = GetControl()->GetInsertionPoint();
+ // if a navigation key was pressed
+ if(IsNavigationKey(key_code))
+ {
+ accept = true;
+ }
+ // if the delete key was pressed
+ else if(key_code == WXK_DELETE)
+ {
+ // erase the character
+ val.erase(pos);
+ }
+ // if the backspace key was pressed
+ else if(key_code == WXK_BACK)
+ {
+ // erase the previous character
+ if(pos > 0)
+ val.erase(pos-1);
+ }
+ else
+ {
+ // if this is a regular character
+ // insert it into the temporary string
+ val.insert(pos, wxString(event.GetUnicodeKey(), 1));
+ }
+ // if the new string matches the expression
+ if(regex.Matches(val))
+ {
+ // accept the event
+ accept = true;
+ }
+ }
+ // if the value is acceptable ..
+ if(accept)
+ {
+ GetControl()->SetBackgroundColour(
+ wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)
+ );
+ }
+ else
+ {
+ GetControl()->SetBackgroundColour(
+ wxColour(0xFF, 0xA0, 0xA0)
+ );
+ if(!wxValidator::IsSilent())
+ {
+ wxBell();
+ }
+ }
+ // accept the event
+ event.Skip();
+ }
+};
+
+
+} // namespace detail
+} // namespace utils
+} // namespace mirror
+} // namespace boost
+
+#endif //include guard
+

Modified: sandbox/mirror/boost/mirror/factory/wx_constructor_gui/utils.hpp
==============================================================================
--- sandbox/mirror/boost/mirror/factory/wx_constructor_gui/utils.hpp (original)
+++ sandbox/mirror/boost/mirror/factory/wx_constructor_gui/utils.hpp 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -44,6 +44,9 @@
                         parent_data->get_window(),
                         wxID_ANY
                 );
+ panel->SetExtraStyle(
+ panel->GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY
+ );
                 // the sizer
                 wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
                 panel->SetSizer(sizer);

Modified: sandbox/mirror/libs/mirror/build/msvc/mirror_examples/fact_simple_gui/fact_simple_gui.vcproj
==============================================================================
--- sandbox/mirror/libs/mirror/build/msvc/mirror_examples/fact_simple_gui/fact_simple_gui.vcproj (original)
+++ sandbox/mirror/libs/mirror/build/msvc/mirror_examples/fact_simple_gui/fact_simple_gui.vcproj 2009-02-10 10:38:27 EST (Tue, 10 Feb 2009)
@@ -62,7 +62,7 @@
                         />
                         <Tool
                                 Name="VCLinkerTool"
- AdditionalDependencies="wxbase$(WXWIDGETS_VERSION)ud.lib wxmsw$(WXWIDGETS_VERSION)ud_core.lib wxmsw$(WXWIDGETS_VERSION)ud_adv.lib comctl32.lib winmm.lib advapi32.lib rpcrt4.lib"
+ AdditionalDependencies="wxbase$(WXWIDGETS_VERSION)ud.lib wxmsw$(WXWIDGETS_VERSION)ud_core.lib wxmsw$(WXWIDGETS_VERSION)ud_adv.lib wxregexud.lib comctl32.lib winmm.lib advapi32.lib rpcrt4.lib"
                                 LinkIncremental="2"
                                 AdditionalLibraryDirectories="$(WXWIDGETS_ROOT)\lib\vc_lib"
                                 GenerateDebugInformation="true"
@@ -137,7 +137,7 @@
                         />
                         <Tool
                                 Name="VCLinkerTool"
- AdditionalDependencies="wxbase28ud.lib wxmsw28ud_core.lib wxmsw28ud_adv.lib comctl32.lib winmm.lib advapi32.lib rpcrt4.lib"
+ AdditionalDependencies="wxbase$(WXWIDGETS_VERSION)u.lib wxmsw$(WXWIDGETS_VERSION)u_core.lib wxmsw$(WXWIDGETS_VERSION)u_adv.lib wxregexu.lib comctl32.lib winmm.lib advapi32.lib rpcrt4.lib"
                                 LinkIncremental="1"
                                 AdditionalLibraryDirectories="$(WXWIDGETS_ROOT)\lib\vc_lib"
                                 GenerateDebugInformation="true"


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk