]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/maskededit.py
Fix or add some DoGetBestSize's
[wxWidgets.git] / wxPython / wx / lib / maskededit.py
index 00d3c9aaa977e1a5cf629475f09872c2ada9aa5e..bdc463543e5eb03557c3b5924e51a88b88c24c30 100644 (file)
@@ -3,41 +3,57 @@
 # Authors:      Jeff Childers, Will Sadkin
 # Email:        jchilders_98@yahoo.com, wsadkin@nameconnector.com
 # Created:      02/11/2003
 # Authors:      Jeff Childers, Will Sadkin
 # Email:        jchilders_98@yahoo.com, wsadkin@nameconnector.com
 # Created:      02/11/2003
-# Copyright:    (c) 2003 by Jeff Childers, 2003
+# Copyright:    (c) 2003 by Jeff Childers, Will Sadkin, 2003
 # Portions:     (c) 2002 by Will Sadkin, 2002-2003
 # RCS-ID:       $Id$
 # Portions:     (c) 2002 by Will Sadkin, 2002-2003
 # RCS-ID:       $Id$
-# License:      wxWindows license
+# License:      wxWidgets license
 #----------------------------------------------------------------------------
 # NOTE:
 #----------------------------------------------------------------------------
 # NOTE:
-#   This was written way it is because of the lack of masked edit controls
-#   in wxWindows/wxPython.
-#
-#   wxMaskedEdit controls are based on a suggestion made on [wxPython-Users] by
+#   MaskedEdit controls are based on a suggestion made on [wxPython-Users] by
 #   Jason Hihn, and borrows liberally from Will Sadkin's original masked edit
 #   Jason Hihn, and borrows liberally from Will Sadkin's original masked edit
-#   control for time entry, wxTimeCtrl (which is now rewritten using this
+#   control for time entry, TimeCtrl (which is now rewritten using this
 #   control!).
 #
 #   control!).
 #
-#   wxMaskedEdit controls do not normally use validators, because they do
+#   MaskedEdit controls do not normally use validators, because they do
 #   careful manipulation of the cursor in the text window on each keystroke,
 #   and validation is cursor-position specific, so the control intercepts the
 #   key codes before the validator would fire.  However, validators can be
 #   provided to do data transfer to the controls.
 #   careful manipulation of the cursor in the text window on each keystroke,
 #   and validation is cursor-position specific, so the control intercepts the
 #   key codes before the validator would fire.  However, validators can be
 #   provided to do data transfer to the controls.
-##
+#
+#----------------------------------------------------------------------------
+#
+# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace. No guarantees. This is one huge file.
+# 
+# 12/13/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Missed wx.DateTime stuff earlier.
+# 
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMaskedEditMixin -> MaskedEditMixin
+# o wxMaskedTextCtrl -> MaskedTextCtrl
+# o wxMaskedComboBoxSelectEvent -> MaskedComboBoxSelectEvent
+# o wxMaskedComboBox -> MaskedComboBox
+# o wxIpAddrCtrl -> IpAddrCtrl
+# o wxTimeCtrl -> TimeCtrl
+#
 
 """\
 <b>Masked Edit Overview:
 =====================</b>
 
 """\
 <b>Masked Edit Overview:
 =====================</b>
-<b>wxMaskedTextCtrl</b>
+<b>MaskedTextCtrl</b>
     is a sublassed text control that can carefully control the user's input
     based on a mask string you provide.
 
     General usage example:
     is a sublassed text control that can carefully control the user's input
     based on a mask string you provide.
 
     General usage example:
-        control = wxMaskedTextCtrl( win, -1, '', mask = '(###) ###-####')
+        control = MaskedTextCtrl( win, -1, '', mask = '(###) ###-####')
 
     The example above will create a text control that allows only numbers to be
     entered and then only in the positions indicated in the mask by the # sign.
 
 
     The example above will create a text control that allows only numbers to be
     entered and then only in the positions indicated in the mask by the # sign.
 
-<b>wxMaskedComboBox</b>
+<b>MaskedComboBox</b>
     is a similar subclass of wxComboBox that allows the same sort of masking,
     but also can do auto-complete of values, and can require the value typed
     to be in the list of choices to be colored appropriately.
     is a similar subclass of wxComboBox that allows the same sort of masking,
     but also can do auto-complete of values, and can require the value typed
     to be in the list of choices to be colored appropriately.
 <b>wxMaskedCtrl</b>
     is actually a factory function for several types of masked edit controls:
 
 <b>wxMaskedCtrl</b>
     is actually a factory function for several types of masked edit controls:
 
-    <b>wxMaskedTextCtrl</b>   - standard masked edit text box
-    <b>wxMaskedComboBox</b>   - adds combobox capabilities
-    <b>wxIpAddrCtrl</b>       - adds special semantics for IP address entry
-    <b>wxTimeCtrl</b>         - special subclass handling lots of types as values
+    <b>MaskedTextCtrl</b>   - standard masked edit text box
+    <b>MaskedComboBox</b>   - adds combobox capabilities
+    <b>IpAddrCtrl</b>       - adds special semantics for IP address entry
+    <b>TimeCtrl</b>         - special subclass handling lots of types as values
     <b>wxMaskedNumCtrl</b>    - special subclass handling numeric values
 
     It works by looking for a <b><i>controlType</i></b> parameter in the keyword
     arguments of the control, to determine what kind of instance to return.
     If not specified as a keyword argument, the default control type returned
     <b>wxMaskedNumCtrl</b>    - special subclass handling numeric values
 
     It works by looking for a <b><i>controlType</i></b> parameter in the keyword
     arguments of the control, to determine what kind of instance to return.
     If not specified as a keyword argument, the default control type returned
-    will be wxMaskedTextCtrl.
+    will be MaskedTextCtrl.
 
     Each of the above classes has its own set of arguments, but wxMaskedCtrl
     provides a single "unified" interface for masked controls.  Those for
 
     Each of the above classes has its own set of arguments, but wxMaskedCtrl
     provides a single "unified" interface for masked controls.  Those for
-    wxMaskedTextCtrl, wxMaskedComboBox and wxIpAddrCtrl are all documented
+    MaskedTextCtrl, MaskedComboBox and IpAddrCtrl are all documented
     below; the others have their own demo pages and interface descriptions.
     (See end of following discussion for how to configure the wxMaskedCtrl()
     to select the above control types.)
     below; the others have their own demo pages and interface descriptions.
     (See end of following discussion for how to configure the wxMaskedCtrl()
     to select the above control types.)
@@ -242,7 +258,7 @@ decimalChar=</b>
         choices=        A list of strings that are allowed choices for the control.
         choiceRequired= value must be member of choices list
         compareNoCase=  Perform case-insensitive matching when validating against list
         choices=        A list of strings that are allowed choices for the control.
         choiceRequired= value must be member of choices list
         compareNoCase=  Perform case-insensitive matching when validating against list
-                        <i>Note: for wxMaskedComboBox, this defaults to True.</i>
+                        <i>Note: for MaskedComboBox, this defaults to True.</i>
         emptyInvalid=   Boolean indicating whether an empty value should be considered invalid
 
         validFunc=      A function to call of the form: bool = func(candidate_value)
         emptyInvalid=   Boolean indicating whether an empty value should be considered invalid
 
         validFunc=      A function to call of the form: bool = func(candidate_value)
@@ -396,7 +412,7 @@ decimalChar=</b>
                     after construction; it takes a list of key/value pairs as arguments,
                     where the keys can be any of the mask-specific parameters in the constructor.
                     Eg:
                     after construction; it takes a list of key/value pairs as arguments,
                     where the keys can be any of the mask-specific parameters in the constructor.
                     Eg:
-                        ctl = wxMaskedTextCtrl( self, -1 )
+                        ctl = MaskedTextCtrl( self, -1 )
                         ctl.SetCtrlParameters( mask='###-####',
                                                defaultValue='555-1212',
                                                formatcodes='F')
                         ctl.SetCtrlParameters( mask='###-####',
                                                defaultValue='555-1212',
                                                formatcodes='F')
@@ -414,6 +430,11 @@ decimalChar=</b>
           ctl.GetChoiceRequired()
           ctl.GetFormatcodes()
 
           ctl.GetChoiceRequired()
           ctl.GetFormatcodes()
 
+  <b><i>Note:</i></b> After any change in parameters, the choices for the
+      control are reevaluated to ensure that they are still legal.  If you
+      have large choice lists, it is therefore more efficient to set parameters
+      before setting the choices available.
+
   <b>.SetFieldParameters(field_index, **kwargs)</b>
                     This function allows you to specify change individual field
                     parameters after construction. (Indices are 0-based.)
   <b>.SetFieldParameters(field_index, **kwargs)</b>
                     This function allows you to specify change individual field
                     parameters after construction. (Indices are 0-based.)
@@ -427,7 +448,8 @@ The control detects certain common constructions. In order to use the signed fea
 decimal point. Without a decimal (e.g. '######', the control will treat it as an integer
 value. With a decimal (e.g. '###.##'), the control will act as a floating point control
 (i.e. press decimal to 'tab' to the decimal position). Pressing decimal in the
 decimal point. Without a decimal (e.g. '######', the control will treat it as an integer
 value. With a decimal (e.g. '###.##'), the control will act as a floating point control
 (i.e. press decimal to 'tab' to the decimal position). Pressing decimal in the
-integer control truncates the value.
+integer control truncates the value.  However, for a true numeric control,
+MaskedNumCtrl provides all this, and true numeric input/output support as well.
 
 
 Check your controls by calling each control's .IsValid() function and the
 
 
 Check your controls by calling each control's .IsValid() function and the
@@ -477,7 +499,7 @@ Naming Conventions
 
   The following methods must be used and/or defined when deriving a control
   from wxMaskedEditMixin.  NOTE: if deriving from a *masked edit* control
 
   The following methods must be used and/or defined when deriving a control
   from wxMaskedEditMixin.  NOTE: if deriving from a *masked edit* control
-  (eg. class wxIpAddrCtrl(wxMaskedTextCtrl) ), then this is NOT necessary,
+  (eg. class IpAddrCtrl(MaskedTextCtrl) ), then this is NOT necessary,
   as it's already been done for you in the base class.
 
         ._SetInitialValue()
   as it's already been done for you in the base class.
 
         ._SetInitialValue()
@@ -507,8 +529,8 @@ Naming Conventions
                         Similarly to _GetSelection, each class derived from
                         wxMaskedEditMixin must define the function for setting
                         the start and end of the current text selection.
                         Similarly to _GetSelection, each class derived from
                         wxMaskedEditMixin must define the function for setting
                         the start and end of the current text selection.
-                        (eg. .SetSelection() for wxMaskedTextCtrl, and .SetMark() for
-                        wxMaskedComboBox.
+                        (eg. .SetSelection() for MaskedTextCtrl, and .SetMark() for
+                        MaskedComboBox.
 
         ._GetInsertionPoint()
         ._SetInsertionPoint()
 
         ._GetInsertionPoint()
         ._SetInsertionPoint()
@@ -555,7 +577,7 @@ Naming Conventions
         ._IsEditable()  REQUIRED
                         Each class derived from wxMaskedEditMixin must define
                         the function used to determine if the base control is
         ._IsEditable()  REQUIRED
                         Each class derived from wxMaskedEditMixin must define
                         the function used to determine if the base control is
-                        editable or not.  (For wxMaskedComboBox, this has to
+                        editable or not.  (For MaskedComboBox, this has to
                         be done with code, rather than specifying the proper
                         function in the base control, as there isn't one...)
         ._CalcSize()    REQUIRED
                         be done with code, rather than specifying the proper
                         function in the base control, as there isn't one...)
         ._CalcSize()    REQUIRED
@@ -590,7 +612,7 @@ Event Handling
 
   These 5 handlers must be "wired up" for the wxMaskedEdit
   control to provide default behavior.  (The setupEventHandling
 
   These 5 handlers must be "wired up" for the wxMaskedEdit
   control to provide default behavior.  (The setupEventHandling
-  is an argument to wxMaskedTextCtrl and wxMaskedComboBox, so
+  is an argument to MaskedTextCtrl and MaskedComboBox, so
   that controls derived from *them* may replace one of these
   handlers if they so choose.)
 
   that controls derived from *them* may replace one of these
   handlers if they so choose.)
 
@@ -618,7 +640,7 @@ Event Handling
         ._AddNavKeycode(keycode, handler=None)
         ._AddNavKey(char, handler=None)
                         Allows controls to specify other keys (and optional handlers)
         ._AddNavKeycode(keycode, handler=None)
         ._AddNavKey(char, handler=None)
                         Allows controls to specify other keys (and optional handlers)
-                        to be treated as navigational characters. (eg. '.' in wxIpAddrCtrl)
+                        to be treated as navigational characters. (eg. '.' in IpAddrCtrl)
 
         ._GetNavKeycodes()  Returns the current list of navigational keycodes.
 
 
         ._GetNavKeycodes()  Returns the current list of navigational keycodes.
 
@@ -647,7 +669,7 @@ Event Handling
                         By default, it adjusts the year in date fields if mask is a date,
                         It can be overridden by a derived class to
                         adjust the value of the control at that time.
                         By default, it adjusts the year in date fields if mask is a date,
                         It can be overridden by a derived class to
                         adjust the value of the control at that time.
-                        (eg. wxIpAddrCtrl reformats the address in this way.)
+                        (eg. IpAddrCtrl reformats the address in this way.)
 
         ._Change()      Called by internal EVT_TEXT handler. Return False to force
                         skip of the normal class change event.
 
         ._Change()      Called by internal EVT_TEXT handler. Return False to force
                         skip of the normal class change event.
@@ -675,20 +697,56 @@ Event Handling
         _OnCtrl_Z(event)        'undo'  - resets value to previous value (if any)
 
         _OnChangeField(event)   primarily used for tab events, but can be
         _OnCtrl_Z(event)        'undo'  - resets value to previous value (if any)
 
         _OnChangeField(event)   primarily used for tab events, but can be
-                                used for other keys (eg. '.' in wxIpAddrCtrl)
+                                used for other keys (eg. '.' in IpAddrCtrl)
 
         _OnErase(event)         used for backspace and delete
         _OnHome(event)
         _OnEnd(event)
 
 
         _OnErase(event)         used for backspace and delete
         _OnHome(event)
         _OnEnd(event)
 
+    The following routine provides a hook back to any class derivations, so that
+    they can react to parameter changes before any value is set/reset as a result of
+    those changes.  (eg. MaskedComboBox needs to detect when the choices list is
+    modified, either implicitly or explicitly, so it can reset the base control
+    to have the appropriate choice list *before* the initial value is reset to match.)
+
+        _OnCtrlParametersChanged()
+
+Accessor Functions
+------------------
+    For convenience, each class derived from MaskedEditMixin should
+    define an accessors mixin, so that it exposes only those parameters
+    that make sense for the derivation.  This is done with an intermediate
+    level of inheritance, ie:
+
+    class BaseMaskedTextCtrl( TextCtrl, MaskedEditMixin ):
+
+    class MaskedTextCtrl( BaseMaskedTextCtrl, MaskedEditAccessorsMixin ):
+    class MaskedNumCtrl( BaseMaskedTextCtrl, MaskedNumCtrlAccessorsMixin ):
+    class IpAddrCtrl( BaseMaskedTextCtrl, IpAddrCtrlAccessorsMixin ):
+    class TimeCtrl( BaseMaskedTextCtrl, TimeCtrlAccessorsMixin ):
+
+    etc.
+
+    Each accessors mixin defines Get/Set functions for the base class parameters
+    that are appropriate for that derivation.
+    This allows the base classes to be "more generic," exposing the widest
+    set of options, while not requiring derived classes to be so general.
 """
 
 """
 
-from wxPython.wx import *
-import string, re, copy, difflib, types
+import  copy
+import  difflib
+import  re
+import  string
+import  types
+
+import  wx
+
+# jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would
+# be a good place to implement the 2.3 logger class
+from wx.tools.dbg import Logger 
 
 
-from wxPython.tools.dbg import Logger
 dbg = Logger()
 dbg = Logger()
-dbg(enable=0)
+##dbg(enable=0)
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
@@ -701,8 +759,15 @@ WXK_CTRL_V = (ord('V')+1) - ord('A')
 WXK_CTRL_X = (ord('X')+1) - ord('A')
 WXK_CTRL_Z = (ord('Z')+1) - ord('A')
 
 WXK_CTRL_X = (ord('X')+1) - ord('A')
 WXK_CTRL_Z = (ord('Z')+1) - ord('A')
 
-nav =     (WXK_BACK, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, WXK_TAB, WXK_HOME, WXK_END, WXK_RETURN, WXK_PRIOR, WXK_NEXT)
-control = (WXK_BACK, WXK_DELETE, WXK_CTRL_A, WXK_CTRL_C, WXK_CTRL_S, WXK_CTRL_V, WXK_CTRL_X, WXK_CTRL_Z)
+nav = (
+    wx.WXK_BACK, wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_UP, wx.WXK_DOWN, wx.WXK_TAB, 
+    wx.WXK_HOME, wx.WXK_END, wx.WXK_RETURN, wx.WXK_PRIOR, wx.WXK_NEXT
+    )
+
+control = (
+    wx.WXK_BACK, wx.WXK_DELETE, WXK_CTRL_A, WXK_CTRL_C, WXK_CTRL_S, WXK_CTRL_V, 
+    WXK_CTRL_X, WXK_CTRL_Z
+    )
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
@@ -813,17 +878,17 @@ masktags = {
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + hours + ':' + minutes + ':' + seconds + ' (A|P)M',
            'description': "US Date + Time\n(w/hypens)"
            },
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + hours + ':' + minutes + ':' + seconds + ' (A|P)M',
            'description': "US Date + Time\n(w/hypens)"
            },
-       "USDATEMILTIMEMMDDYYYY/HHMMSS": {
+       "USDATE24HRTIMEMMDDYYYY/HHMMSS": {           
            'mask': "##/##/#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "##/##/#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "US Date + Military Time"
+           'description': "US Date + 24Hr (Military) Time"           
            },
            },
-       "USDATEMILTIMEMMDDYYYY-HHMMSS": {
+       "USDATE24HRTIMEMMDDYYYY-HHMMSS": {
            'mask': "##-##-#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "##-##-#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "US Date + Military Time\n(w/hypens)"
+           'description': "US Date + 24Hr Time\n(w/hypens)"           
            },
        "USDATETIMEMMDDYYYY/HHMM": {
            'mask': "##/##/#### ##:## AM",
            },
        "USDATETIMEMMDDYYYY/HHMM": {
            'mask': "##/##/#### ##:## AM",
@@ -832,11 +897,11 @@ masktags = {
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + hours + ':' + minutes + ' (A|P)M',
            'description': "US Date + Time\n(without seconds)"
            },
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + hours + ':' + minutes + ' (A|P)M',
            'description': "US Date + Time\n(without seconds)"
            },
-       "USDATEMILTIMEMMDDYYYY/HHMM": {
+       "USDATE24HRTIMEMMDDYYYY/HHMM": {
            'mask': "##/##/#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + milhours + ':' + minutes,
            'mask': "##/##/#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '/' + days + '/' + '\d{4} ' + milhours + ':' + minutes,
-           'description': "US Date + Military Time\n(without seconds)"
+           'description': "US Date + 24Hr Time\n(without seconds)"           
            },
        "USDATETIMEMMDDYYYY-HHMM": {
            'mask': "##-##-#### ##:## AM",
            },
        "USDATETIMEMMDDYYYY-HHMM": {
            'mask': "##-##-#### ##:## AM",
@@ -845,11 +910,11 @@ masktags = {
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + hours + ':' + minutes + ' (A|P)M',
            'description': "US Date + Time\n(w/hypens and w/o secs)"
            },
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + hours + ':' + minutes + ' (A|P)M',
            'description': "US Date + Time\n(w/hypens and w/o secs)"
            },
-       "USDATEMILTIMEMMDDYYYY-HHMM": {
+       "USDATE24HRTIMEMMDDYYYY-HHMM": {
            'mask': "##-##-#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + milhours + ':' + minutes,
            'mask': "##-##-#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + months + '-' + days + '-' + '\d{4} ' + milhours + ':' + minutes,
-           'description': "US Date + Military Time\n(w/hyphens and w/o seconds)"
+           'description': "US Date + 24Hr Time\n(w/hyphens and w/o seconds)"
            },
        "USDATEMMDDYYYY/": {
            'mask': "##/##/####",
            },
        "USDATEMMDDYYYY/": {
            'mask': "##/##/####",
@@ -965,52 +1030,52 @@ masktags = {
            'description': "DD.MM.YYYY HH:MM"
            },
 
            'description': "DD.MM.YYYY HH:MM"
            },
 
-       "EUDATEMILTIMEYYYYMMDD/HHMMSS": {
+       "EUDATE24HRTIMEYYYYMMDD/HHMMSS": {
            'mask': "####/##/## ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '/' + months + '/' + days + ' ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "####/##/## ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '/' + months + '/' + days + ' ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "YYYY/MM/DD Mil. Time"
+           'description': "YYYY/MM/DD 24Hr Time"
            },
            },
-       "EUDATEMILTIMEYYYYMMDD.HHMMSS": {
+       "EUDATE24HRTIMEYYYYMMDD.HHMMSS": {
            'mask': "####.##.## ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '.' + months + '.' + days + ' ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "####.##.## ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '.' + months + '.' + days + ' ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "YYYY.MM.DD Mil. Time"
+           'description': "YYYY.MM.DD 24Hr Time"
            },
            },
-       "EUDATEMILTIMEDDMMYYYY/HHMMSS": {
+       "EUDATE24HRTIMEDDMMYYYY/HHMMSS": {
            'mask': "##/##/#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '/' + months + '/' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "##/##/#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '/' + months + '/' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "DD/MM/YYYY Mil. Time"
+           'description': "DD/MM/YYYY 24Hr Time"
            },
            },
-       "EUDATEMILTIMEDDMMYYYY.HHMMSS": {
+       "EUDATE24HRTIMEDDMMYYYY.HHMMSS": {
            'mask': "##.##.#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '.' + months + '.' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
            'mask': "##.##.#### ##:##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '.' + months + '.' + '\d{4} ' + milhours + ':' + minutes + ':' + seconds,
-           'description': "DD.MM.YYYY Mil. Time"
+           'description': "DD.MM.YYYY 24Hr Time"
            },
            },
-       "EUDATEMILTIMEYYYYMMDD/HHMM": {
+       "EUDATE24HRTIMEYYYYMMDD/HHMM": {
            'mask': "####/##/## ##:##",
            'formatcodes': 'DF','validRegex': '^' + '\d{4}'+ '/' + months + '/' + days + ' ' + milhours + ':' + minutes,
            'mask': "####/##/## ##:##",
            'formatcodes': 'DF','validRegex': '^' + '\d{4}'+ '/' + months + '/' + days + ' ' + milhours + ':' + minutes,
-           'description': "YYYY/MM/DD Mil. Time\n(w/o seconds)"
+           'description': "YYYY/MM/DD 24Hr Time\n(w/o seconds)"
            },
            },
-       "EUDATEMILTIMEYYYYMMDD.HHMM": {
+       "EUDATE24HRTIMEYYYYMMDD.HHMM": {
            'mask': "####.##.## ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '.' + months + '.' + days + ' ' + milhours + ':' + minutes,
            'mask': "####.##.## ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + '\d{4}'+ '.' + months + '.' + days + ' ' + milhours + ':' + minutes,
-           'description': "YYYY.MM.DD Mil. Time\n(w/o seconds)"
+           'description': "YYYY.MM.DD 24Hr Time\n(w/o seconds)"
            },
            },
-       "EUDATEMILTIMEDDMMYYYY/HHMM": {
+       "EUDATE24HRTIMEDDMMYYYY/HHMM": {
            'mask': "##/##/#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '/' + months + '/' + '\d{4} ' + milhours + ':' + minutes,
            'mask': "##/##/#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '/' + months + '/' + '\d{4} ' + milhours + ':' + minutes,
-           'description': "DD/MM/YYYY Mil. Time\n(w/o seconds)"
+           'description': "DD/MM/YYYY 24Hr Time\n(w/o seconds)"
            },
            },
-       "EUDATEMILTIMEDDMMYYYY.HHMM": {
+       "EUDATE24HRTIMEDDMMYYYY.HHMM": {
            'mask': "##.##.#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '.' + months + '.' + '\d{4} ' + milhours + ':' + minutes,
            'mask': "##.##.#### ##:##",
            'formatcodes': 'DF',
            'validRegex': '^' + days + '.' + months + '.' + '\d{4} ' + milhours + ':' + minutes,
-           'description': "DD.MM.YYYY Mil. Time\n(w/o seconds)"
+           'description': "DD.MM.YYYY 24Hr Time\n(w/o seconds)"
            },
 
        "TIMEHHMMSS": {
            },
 
        "TIMEHHMMSS": {
@@ -1018,26 +1083,26 @@ masktags = {
            'excludeChars': am_pm_exclude,
            'formatcodes': 'TF!',
            'validRegex': '^' + hours + ':' + minutes + ':' + seconds + ' (A|P)M',
            'excludeChars': am_pm_exclude,
            'formatcodes': 'TF!',
            'validRegex': '^' + hours + ':' + minutes + ':' + seconds + ' (A|P)M',
-           'description': "HH:MM:SS (A|P)M\n(see wxTimeCtrl)"
+           'description': "HH:MM:SS (A|P)M\n(see TimeCtrl)"
            },
        "TIMEHHMM": {
            'mask': "##:## AM",
            'excludeChars': am_pm_exclude,
            'formatcodes': 'TF!',
            'validRegex': '^' + hours + ':' + minutes + ' (A|P)M',
            },
        "TIMEHHMM": {
            'mask': "##:## AM",
            'excludeChars': am_pm_exclude,
            'formatcodes': 'TF!',
            'validRegex': '^' + hours + ':' + minutes + ' (A|P)M',
-           'description': "HH:MM (A|P)M\n(see wxTimeCtrl)"
+           'description': "HH:MM (A|P)M\n(see TimeCtrl)"
            },
            },
-       "MILTIMEHHMMSS": {
+       "24HRTIMEHHMMSS": {
            'mask': "##:##:##",
            'formatcodes': 'TF',
            'validRegex': '^' + milhours + ':' + minutes + ':' + seconds,
            'mask': "##:##:##",
            'formatcodes': 'TF',
            'validRegex': '^' + milhours + ':' + minutes + ':' + seconds,
-           'description': "Military HH:MM:SS\n(see wxTimeCtrl)"
+           'description': "24Hr HH:MM:SS\n(see TimeCtrl)"
            },
            },
-       "MILTIMEHHMM": {
+       "24HRTIMEHHMM": {
            'mask': "##:##",
            'formatcodes': 'TF',
            'validRegex': '^' + milhours + ':' + minutes,
            'mask': "##:##",
            'formatcodes': 'TF',
            'validRegex': '^' + milhours + ':' + minutes,
-           'description': "Military HH:MM\n(see wxTimeCtrl)"
+           'description': "24Hr HH:MM\n(see TimeCtrl)"
            },
        "USSOCIALSEC": {
            'mask': "###-##-####",
            },
        "USSOCIALSEC": {
            'mask': "###-##-####",
@@ -1092,7 +1157,7 @@ masktags = {
            'mask': "###.###.###.###",
            'formatcodes': 'F_Sr',
            'validRegex': "(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))(\.(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))){3}",
            'mask': "###.###.###.###",
            'formatcodes': 'F_Sr',
            'validRegex': "(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))(\.(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))){3}",
-           'description': "IP Address\n(see wxIpAddrCtrl)"
+           'description': "IP Address\n(see IpAddrCtrl)"
            }
        }
 
            }
        }
 
@@ -1140,11 +1205,11 @@ class Field:
         This is the "constructor" for setting up parameters for fields.
         a field_index of -1 is used to indicate "the entire control."
         """
         This is the "constructor" for setting up parameters for fields.
         a field_index of -1 is used to indicate "the entire control."
         """
-##        dbg('Field::Field', indent=1)
+####        dbg('Field::Field', indent=1)
         # Validate legitimate set of parameters:
         for key in kwargs.keys():
             if key not in Field.valid_params.keys():
         # Validate legitimate set of parameters:
         for key in kwargs.keys():
             if key not in Field.valid_params.keys():
-##                dbg(indent=0)
+####                dbg(indent=0)
                 raise TypeError('invalid parameter "%s"' % (key))
 
         # Set defaults for each parameter for this instance, and fully
                 raise TypeError('invalid parameter "%s"' % (key))
 
         # Set defaults for each parameter for this instance, and fully
@@ -1158,7 +1223,7 @@ class Field:
         self._SetParameters(**kwargs)
         self._ValidateParameters(**kwargs)
 
         self._SetParameters(**kwargs)
         self._ValidateParameters(**kwargs)
 
-##        dbg(indent=0)
+####        dbg(indent=0)
 
 
     def _SetParameters(self, **kwargs):
 
 
     def _SetParameters(self, **kwargs):
@@ -1166,19 +1231,21 @@ class Field:
         This function can be used to set individual or multiple parameters for
         a masked edit field parameter after construction.
         """
         This function can be used to set individual or multiple parameters for
         a masked edit field parameter after construction.
         """
-        dbg(suspend=1)
-        dbg('maskededit.Field::_SetParameters', indent=1)
+##        dbg(suspend=1)
+##        dbg('maskededit.Field::_SetParameters', indent=1)
         # Validate keyword arguments:
         for key in kwargs.keys():
             if key not in Field.valid_params.keys():
         # Validate keyword arguments:
         for key in kwargs.keys():
             if key not in Field.valid_params.keys():
-                dbg(indent=0, suspend=0)
+##                dbg(indent=0, suspend=0)
                 raise AttributeError('invalid keyword argument "%s"' % key)
 
         if self._index is not None: dbg('field index:', self._index)
                 raise AttributeError('invalid keyword argument "%s"' % key)
 
         if self._index is not None: dbg('field index:', self._index)
-        dbg('parameters:', indent=1)
+##        dbg('parameters:', indent=1)
         for key, value in kwargs.items():
         for key, value in kwargs.items():
-            dbg('%s:' % key, value)
-        dbg(indent=0)
+##            dbg('%s:' % key, value)
+            pass
+##        dbg(indent=0)
+
 
         old_fillChar = self._fillChar   # store so we can change choice lists accordingly if it changes
 
 
         old_fillChar = self._fillChar   # store so we can change choice lists accordingly if it changes
 
@@ -1212,13 +1279,13 @@ class Field:
 
         if kwargs.has_key('fillChar'):
             self._old_fillChar = old_fillChar
 
         if kwargs.has_key('fillChar'):
             self._old_fillChar = old_fillChar
-##            dbg("self._old_fillChar: '%s'" % self._old_fillChar)
+####            dbg("self._old_fillChar: '%s'" % self._old_fillChar)
 
         if kwargs.has_key('mask') or kwargs.has_key('validRegex'):  # (set/changed)
             self._isInt = isInteger(self._mask)
 
         if kwargs.has_key('mask') or kwargs.has_key('validRegex'):  # (set/changed)
             self._isInt = isInteger(self._mask)
-            dbg('isInt?', self._isInt, 'self._mask:"%s"' % self._mask)
+##            dbg('isInt?', self._isInt, 'self._mask:"%s"' % self._mask)
 
 
-        dbg(indent=0, suspend=0)
+##        dbg(indent=0, suspend=0)
 
 
     def _ValidateParameters(self, **kwargs):
 
 
     def _ValidateParameters(self, **kwargs):
@@ -1226,18 +1293,18 @@ class Field:
         This function can be used to validate individual or multiple parameters for
         a masked edit field parameter after construction.
         """
         This function can be used to validate individual or multiple parameters for
         a masked edit field parameter after construction.
         """
-        dbg(suspend=1)
-        dbg('maskededit.Field::_ValidateParameters', indent=1)
+##        dbg(suspend=1)
+##        dbg('maskededit.Field::_ValidateParameters', indent=1)
         if self._index is not None: dbg('field index:', self._index)
         if self._index is not None: dbg('field index:', self._index)
-##        dbg('parameters:', indent=1)
+####        dbg('parameters:', indent=1)
 ##        for key, value in kwargs.items():
 ##        for key, value in kwargs.items():
-##            dbg('%s:' % key, value)
-##        dbg(indent=0)
-##        dbg("self._old_fillChar: '%s'" % self._old_fillChar)
+####            dbg('%s:' % key, value)
+####        dbg(indent=0)
+####        dbg("self._old_fillChar: '%s'" % self._old_fillChar)
 
         # Verify proper numeric format params:
         if self._groupdigits and self._groupChar == self._decimalChar:
 
         # Verify proper numeric format params:
         if self._groupdigits and self._groupChar == self._decimalChar:
-            dbg(indent=0, suspend=0)
+##            dbg(indent=0, suspend=0)
             raise AttributeError("groupChar '%s' cannot be the same as decimalChar '%s'" % (self._groupChar, self._decimalChar))
 
 
             raise AttributeError("groupChar '%s' cannot be the same as decimalChar '%s'" % (self._groupChar, self._decimalChar))
 
 
@@ -1261,7 +1328,7 @@ class Field:
                     else:
                         self._filter = re.compile(self._validRegex)
                 except:
                     else:
                         self._filter = re.compile(self._validRegex)
                 except:
-                    dbg(indent=0, suspend=0)
+##                    dbg(indent=0, suspend=0)
                     raise TypeError('%s: validRegex "%s" not a legal regular expression' % (str(self._index), self._validRegex))
             else:
                 self._filter = None
                     raise TypeError('%s: validRegex "%s" not a legal regular expression' % (str(self._index), self._validRegex))
             else:
                 self._filter = None
@@ -1272,7 +1339,7 @@ class Field:
             self._rangeLow  = 0
             if self._validRange:
                 if type(self._validRange) != types.TupleType or len( self._validRange )!= 2 or self._validRange[0] > self._validRange[1]:
             self._rangeLow  = 0
             if self._validRange:
                 if type(self._validRange) != types.TupleType or len( self._validRange )!= 2 or self._validRange[0] > self._validRange[1]:
-                    dbg(indent=0, suspend=0)
+##                    dbg(indent=0, suspend=0)
                     raise TypeError('%s: validRange %s parameter must be tuple of form (a,b) where a <= b'
                                     % (str(self._index), repr(self._validRange)) )
 
                     raise TypeError('%s: validRange %s parameter must be tuple of form (a,b) where a <= b'
                                     % (str(self._index), repr(self._validRange)) )
 
@@ -1283,16 +1350,16 @@ class Field:
         if kwargs.has_key('choices') or (len(self._choices) and len(self._choices[0]) != len(self._mask)):       # (set/changed)
             self._hasList   = False
             if self._choices and type(self._choices) not in (types.TupleType, types.ListType):
         if kwargs.has_key('choices') or (len(self._choices) and len(self._choices[0]) != len(self._mask)):       # (set/changed)
             self._hasList   = False
             if self._choices and type(self._choices) not in (types.TupleType, types.ListType):
-                dbg(indent=0, suspend=0)
+##                dbg(indent=0, suspend=0)
                 raise TypeError('%s: choices must be a sequence of strings' % str(self._index))
             elif len( self._choices) > 0:
                 for choice in self._choices:
                     if type(choice) not in (types.StringType, types.UnicodeType):
                 raise TypeError('%s: choices must be a sequence of strings' % str(self._index))
             elif len( self._choices) > 0:
                 for choice in self._choices:
                     if type(choice) not in (types.StringType, types.UnicodeType):
-                        dbg(indent=0, suspend=0)
+##                        dbg(indent=0, suspend=0)
                         raise TypeError('%s: choices must be a sequence of strings' % str(self._index))
 
                 length = len(self._mask)
                         raise TypeError('%s: choices must be a sequence of strings' % str(self._index))
 
                 length = len(self._mask)
-                dbg('len(%s)' % self._mask, length, 'len(self._choices):', len(self._choices), 'length:', length, 'self._alignRight?', self._alignRight)
+##                dbg('len(%s)' % self._mask, length, 'len(self._choices):', len(self._choices), 'length:', length, 'self._alignRight?', self._alignRight)
                 if len(self._choices) and length:
                     if len(self._choices[0]) > length:
                         # changed mask without respecifying choices; readjust the width as appropriate:
                 if len(self._choices) and length:
                     if len(self._choices[0]) > length:
                         # changed mask without respecifying choices; readjust the width as appropriate:
@@ -1301,7 +1368,7 @@ class Field:
                         self._choices = [choice.rjust( length ) for choice in self._choices]
                     else:
                         self._choices = [choice.ljust( length ) for choice in self._choices]
                         self._choices = [choice.rjust( length ) for choice in self._choices]
                     else:
                         self._choices = [choice.ljust( length ) for choice in self._choices]
-                    dbg('aligned choices:', self._choices)
+##                    dbg('aligned choices:', self._choices)
 
                 if hasattr(self, '_template'):
                     # Verify each choice specified is valid:
 
                 if hasattr(self, '_template'):
                     # Verify each choice specified is valid:
@@ -1310,28 +1377,28 @@ class Field:
                             # allow empty values even if invalid, (just colored differently)
                             continue
                         if not self.IsValid(choice):
                             # allow empty values even if invalid, (just colored differently)
                             continue
                         if not self.IsValid(choice):
-                            dbg(indent=0, suspend=0)
+##                            dbg(indent=0, suspend=0)
                             raise ValueError('%s: "%s" is not a valid value for the control as specified.' % (str(self._index), choice))
                 self._hasList = True
 
                             raise ValueError('%s: "%s" is not a valid value for the control as specified.' % (str(self._index), choice))
                 self._hasList = True
 
-##        dbg("kwargs.has_key('fillChar')?", kwargs.has_key('fillChar'), "len(self._choices) > 0?", len(self._choices) > 0)
-##        dbg("self._old_fillChar:'%s'" % self._old_fillChar, "self._fillChar: '%s'" % self._fillChar)
+####        dbg("kwargs.has_key('fillChar')?", kwargs.has_key('fillChar'), "len(self._choices) > 0?", len(self._choices) > 0)
+####        dbg("self._old_fillChar:'%s'" % self._old_fillChar, "self._fillChar: '%s'" % self._fillChar)
         if kwargs.has_key('fillChar') and len(self._choices) > 0:
             if kwargs['fillChar'] != ' ':
                 self._choices = [choice.replace(' ', self._fillChar) for choice in self._choices]
             else:
                 self._choices = [choice.replace(self._old_fillChar, self._fillChar) for choice in self._choices]
         if kwargs.has_key('fillChar') and len(self._choices) > 0:
             if kwargs['fillChar'] != ' ':
                 self._choices = [choice.replace(' ', self._fillChar) for choice in self._choices]
             else:
                 self._choices = [choice.replace(self._old_fillChar, self._fillChar) for choice in self._choices]
-            dbg('updated choices:', self._choices)
+##            dbg('updated choices:', self._choices)
 
 
         if kwargs.has_key('autoSelect') and kwargs['autoSelect']:
             if not self._hasList:
 
 
         if kwargs.has_key('autoSelect') and kwargs['autoSelect']:
             if not self._hasList:
-                dbg('no list to auto complete; ignoring "autoSelect=True"')
+##                dbg('no list to auto complete; ignoring "autoSelect=True"')
                 self._autoSelect = False
 
         # reset field validity assumption:
         self._valid = True
                 self._autoSelect = False
 
         # reset field validity assumption:
         self._valid = True
-        dbg(indent=0, suspend=0)
+##        dbg(indent=0, suspend=0)
 
 
     def _GetParameter(self, paramname):
 
 
     def _GetParameter(self, paramname):
@@ -1349,28 +1416,28 @@ class Field:
         Indicates whether the specified slice is considered empty for the
         field.
         """
         Indicates whether the specified slice is considered empty for the
         field.
         """
-        dbg('Field::IsEmpty("%s")' % slice, indent=1)
+##        dbg('Field::IsEmpty("%s")' % slice, indent=1)
         if not hasattr(self, '_template'):
         if not hasattr(self, '_template'):
-            dbg(indent=0)
+##            dbg(indent=0)
             raise AttributeError('_template')
 
             raise AttributeError('_template')
 
-        dbg('self._template: "%s"' % self._template)
-        dbg('self._defaultValue: "%s"' % str(self._defaultValue))
+##        dbg('self._template: "%s"' % self._template)
+##        dbg('self._defaultValue: "%s"' % str(self._defaultValue))
         if slice == self._template and not self._defaultValue:
         if slice == self._template and not self._defaultValue:
-            dbg(indent=0)
+##            dbg(indent=0)
             return True
 
         elif slice == self._template:
             empty = True
             for pos in range(len(self._template)):
             return True
 
         elif slice == self._template:
             empty = True
             for pos in range(len(self._template)):
-##                dbg('slice[%(pos)d] != self._fillChar?' %locals(), slice[pos] != self._fillChar[pos])
+####                dbg('slice[%(pos)d] != self._fillChar?' %locals(), slice[pos] != self._fillChar[pos])
                 if slice[pos] not in (' ', self._fillChar):
                     empty = False
                     break
                 if slice[pos] not in (' ', self._fillChar):
                     empty = False
                     break
-            dbg("IsEmpty? %(empty)d (do all mask chars == fillChar?)" % locals(), indent=0)
+##            dbg("IsEmpty? %(empty)d (do all mask chars == fillChar?)" % locals(), indent=0)
             return empty
         else:
             return empty
         else:
-            dbg("IsEmpty? 0 (slice doesn't match template)", indent=0)
+##            dbg("IsEmpty? 0 (slice doesn't match template)", indent=0)
             return False
 
 
             return False
 
 
@@ -1379,23 +1446,23 @@ class Field:
         Indicates whether the specified slice is considered a valid value for the
         field.
         """
         Indicates whether the specified slice is considered a valid value for the
         field.
         """
-        dbg(suspend=1)
-        dbg('Field[%s]::IsValid("%s")' % (str(self._index), slice), indent=1)
+##        dbg(suspend=1)
+##        dbg('Field[%s]::IsValid("%s")' % (str(self._index), slice), indent=1)
         valid = True    # assume true to start
 
         if self.IsEmpty(slice):
         valid = True    # assume true to start
 
         if self.IsEmpty(slice):
-            dbg(indent=0, suspend=0)
+##            dbg(indent=0, suspend=0)
             if self._emptyInvalid:
                 return False
             else:
                 return True
 
         elif self._hasList and self._choiceRequired:
             if self._emptyInvalid:
                 return False
             else:
                 return True
 
         elif self._hasList and self._choiceRequired:
-            dbg("(member of list required)")
+##            dbg("(member of list required)")
             # do case-insensitive match on list; strip surrounding whitespace from slice (already done for choices):
             if self._fillChar != ' ':
                 slice = slice.replace(self._fillChar, ' ')
             # do case-insensitive match on list; strip surrounding whitespace from slice (already done for choices):
             if self._fillChar != ' ':
                 slice = slice.replace(self._fillChar, ' ')
-                dbg('updated slice:"%s"' % slice)
+##                dbg('updated slice:"%s"' % slice)
             compareStr = slice.strip()
 
             if self._compareNoCase:
             compareStr = slice.strip()
 
             if self._compareNoCase:
@@ -1403,7 +1470,7 @@ class Field:
             valid = compareStr in self._compareChoices
 
         elif self._hasRange and not self.IsEmpty(slice):
             valid = compareStr in self._compareChoices
 
         elif self._hasRange and not self.IsEmpty(slice):
-            dbg('validating against range')
+##            dbg('validating against range')
             try:
                 # allow float as well as int ranges (int comparisons for free.)
                 valid = self._rangeLow <= float(slice) <= self._rangeHigh
             try:
                 # allow float as well as int ranges (int comparisons for free.)
                 valid = self._rangeLow <= float(slice) <= self._rangeHigh
@@ -1411,22 +1478,22 @@ class Field:
                 valid = False
 
         elif self._validRegex and self._filter:
                 valid = False
 
         elif self._validRegex and self._filter:
-            dbg('validating against regex')
+##            dbg('validating against regex')
             valid = (re.match( self._filter, slice) is not None)
 
         if valid and self._validFunc:
             valid = (re.match( self._filter, slice) is not None)
 
         if valid and self._validFunc:
-            dbg('validating against supplied function')
+##            dbg('validating against supplied function')
             valid = self._validFunc(slice)
             valid = self._validFunc(slice)
-        dbg('valid?', valid, indent=0, suspend=0)
+##        dbg('valid?', valid, indent=0, suspend=0)
         return valid
 
 
     def _AdjustField(self, slice):
         """ 'Fixes' an integer field. Right or left-justifies, as required."""
         return valid
 
 
     def _AdjustField(self, slice):
         """ 'Fixes' an integer field. Right or left-justifies, as required."""
-        dbg('Field::_AdjustField("%s")' % slice, indent=1)
+##        dbg('Field::_AdjustField("%s")' % slice, indent=1)
         length = len(self._mask)
         length = len(self._mask)
-##        dbg('length(self._mask):', length)
-##        dbg('self._useParensForNegatives?', self._useParensForNegatives)
+####        dbg('length(self._mask):', length)
+####        dbg('self._useParensForNegatives?', self._useParensForNegatives)
         if self._isInt:
             if self._useParensForNegatives:
                 signpos = slice.find('(')
         if self._isInt:
             if self._useParensForNegatives:
                 signpos = slice.find('(')
@@ -1441,13 +1508,13 @@ class Field:
             intStr = string.replace(intStr,self._fillChar,"")       # drop extra fillchars
             intStr = string.replace(intStr,"-","")                  # drop sign, if any
             intStr = string.replace(intStr, self._groupChar, "")    # lose commas/dots
             intStr = string.replace(intStr,self._fillChar,"")       # drop extra fillchars
             intStr = string.replace(intStr,"-","")                  # drop sign, if any
             intStr = string.replace(intStr, self._groupChar, "")    # lose commas/dots
-##            dbg('intStr:"%s"' % intStr)
+####            dbg('intStr:"%s"' % intStr)
             start, end = self._extent
             field_len = end - start
             if not self._padZero and len(intStr) != field_len and intStr.strip():
                 intStr = str(long(intStr))
             start, end = self._extent
             field_len = end - start
             if not self._padZero and len(intStr) != field_len and intStr.strip():
                 intStr = str(long(intStr))
-##            dbg('raw int str: "%s"' % intStr)
-##            dbg('self._groupdigits:', self._groupdigits, 'self._formatcodes:', self._formatcodes)
+####            dbg('raw int str: "%s"' % intStr)
+####            dbg('self._groupdigits:', self._groupdigits, 'self._formatcodes:', self._formatcodes)
             if self._groupdigits:
                 new = ''
                 cnt = 1
             if self._groupdigits:
                 new = ''
                 cnt = 1
@@ -1463,8 +1530,8 @@ class Field:
                     intStr = new
                 # else... leave it without the commas...
 
                     intStr = new
                 # else... leave it without the commas...
 
-            dbg('padzero?', self._padZero)
-            dbg('len(intStr):', len(intStr), 'field length:', length)
+##            dbg('padzero?', self._padZero)
+##            dbg('len(intStr):', len(intStr), 'field length:', length)
             if self._padZero and len(intStr) < length:
                 intStr = '0' * (length - len(intStr)) + intStr
                 if signpos != -1:   # we had a sign before; restore it
             if self._padZero and len(intStr) < length:
                 intStr = '0' * (length - len(intStr)) + intStr
                 if signpos != -1:   # we had a sign before; restore it
@@ -1494,13 +1561,13 @@ class Field:
             slice = slice.ljust( length )
         if self._fillChar != ' ':
             slice = slice.replace(' ', self._fillChar)
             slice = slice.ljust( length )
         if self._fillChar != ' ':
             slice = slice.replace(' ', self._fillChar)
-        dbg('adjusted slice: "%s"' % slice, indent=0)
+##        dbg('adjusted slice: "%s"' % slice, indent=0)
         return slice
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
         return slice
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
-class wxMaskedEditMixin:
+class MaskedEditMixin:
     """
     This class allows us to abstract the masked edit functionality that could
     be associated with any text entry control. (eg. wxTextCtrl, wxComboBox, etc.)
     """
     This class allows us to abstract the masked edit functionality that could
     be associated with any text entry control. (eg. wxTextCtrl, wxComboBox, etc.)
@@ -1541,7 +1608,7 @@ class wxMaskedEditMixin:
 
         # Validate legitimate set of parameters:
         for key in kwargs.keys():
 
         # Validate legitimate set of parameters:
         for key in kwargs.keys():
-            if key.replace('Color', 'Colour') not in wxMaskedEditMixin.valid_ctrl_params.keys() + Field.valid_params.keys():
+            if key.replace('Color', 'Colour') not in MaskedEditMixin.valid_ctrl_params.keys() + Field.valid_params.keys():
                 raise TypeError('%s: invalid parameter "%s"' % (name, key))
 
         ## Set up dictionary that can be used by subclasses to override or add to default
                 raise TypeError('%s: invalid parameter "%s"' % (name, key))
 
         ## Set up dictionary that can be used by subclasses to override or add to default
@@ -1554,20 +1621,20 @@ class wxMaskedEditMixin:
         ## Initially populated with navigation and function control keys:
         self._keyhandlers = {
             # default navigation keys and handlers:
         ## Initially populated with navigation and function control keys:
         self._keyhandlers = {
             # default navigation keys and handlers:
-            WXK_BACK:   self._OnErase,
-            WXK_LEFT:   self._OnArrow,
-            WXK_RIGHT:  self._OnArrow,
-            WXK_UP:     self._OnAutoCompleteField,
-            WXK_DOWN:   self._OnAutoCompleteField,
-            WXK_TAB:    self._OnChangeField,
-            WXK_HOME:   self._OnHome,
-            WXK_END:    self._OnEnd,
-            WXK_RETURN: self._OnReturn,
-            WXK_PRIOR:  self._OnAutoCompleteField,
-            WXK_NEXT:   self._OnAutoCompleteField,
+            wx.WXK_BACK:   self._OnErase,
+            wx.WXK_LEFT:   self._OnArrow,
+            wx.WXK_RIGHT:  self._OnArrow,
+            wx.WXK_UP:     self._OnAutoCompleteField,
+            wx.WXK_DOWN:   self._OnAutoCompleteField,
+            wx.WXK_TAB:    self._OnChangeField,
+            wx.WXK_HOME:   self._OnHome,
+            wx.WXK_END:    self._OnEnd,
+            wx.WXK_RETURN: self._OnReturn,
+            wx.WXK_PRIOR:  self._OnAutoCompleteField,
+            wx.WXK_NEXT:   self._OnAutoCompleteField,
 
             # default function control keys and handlers:
 
             # default function control keys and handlers:
-            WXK_DELETE: self._OnErase,
+            wx.WXK_DELETE: self._OnErase,
             WXK_CTRL_A: self._OnCtrl_A,
             WXK_CTRL_C: self._OnCtrl_C,
             WXK_CTRL_S: self._OnCtrl_S,
             WXK_CTRL_A: self._OnCtrl_A,
             WXK_CTRL_C: self._OnCtrl_C,
             WXK_CTRL_S: self._OnCtrl_S,
@@ -1595,7 +1662,7 @@ class wxMaskedEditMixin:
             '&': string.punctuation
         }
 
             '&': string.punctuation
         }
 
-        ## self._ignoreChange is used by wxMaskedComboBox, because
+        ## self._ignoreChange is used by MaskedComboBox, because
         ## of the hack necessary to determine the selection; it causes
         ## EVT_TEXT messages from the combobox to be ignored if set.
         self._ignoreChange = False
         ## of the hack necessary to determine the selection; it causes
         ## EVT_TEXT messages from the combobox to be ignored if set.
         self._ignoreChange = False
@@ -1608,10 +1675,10 @@ class wxMaskedEditMixin:
 
         # Set defaults for each parameter for this instance, and fully
         # populate initial parameter list for configuration:
 
         # Set defaults for each parameter for this instance, and fully
         # populate initial parameter list for configuration:
-        for key, value in wxMaskedEditMixin.valid_ctrl_params.items():
+        for key, value in MaskedEditMixin.valid_ctrl_params.items():
             setattr(self, '_' + key, copy.copy(value))
             if not kwargs.has_key(key):
             setattr(self, '_' + key, copy.copy(value))
             if not kwargs.has_key(key):
-##                dbg('%s: "%s"' % (key, repr(value)))
+####                dbg('%s: "%s"' % (key, repr(value)))
                 kwargs[key] = copy.copy(value)
 
         # Create a "field" that holds global parameters for control constraints
                 kwargs[key] = copy.copy(value)
 
         # Create a "field" that holds global parameters for control constraints
@@ -1625,20 +1692,20 @@ class wxMaskedEditMixin:
         This public function can be used to set individual or multiple masked edit
         parameters after construction.
         """
         This public function can be used to set individual or multiple masked edit
         parameters after construction.
         """
-        dbg(suspend=1)
-        dbg('wxMaskedEditMixin::SetCtrlParameters', indent=1)
-##        dbg('kwargs:', indent=1)
+##        dbg(suspend=1)
+##        dbg('MaskedEditMixin::SetCtrlParameters', indent=1)
+####        dbg('kwargs:', indent=1)
 ##        for key, value in kwargs.items():
 ##        for key, value in kwargs.items():
-##            dbg(key, '=', value)
-##        dbg(indent=0)
+####            dbg(key, '=', value)
+####        dbg(indent=0)
 
         # Validate keyword arguments:
         constraint_kwargs = {}
         ctrl_kwargs = {}
         for key, value in kwargs.items():
             key = key.replace('Color', 'Colour')    # for b-c, and standard wxPython spelling
 
         # Validate keyword arguments:
         constraint_kwargs = {}
         ctrl_kwargs = {}
         for key, value in kwargs.items():
             key = key.replace('Color', 'Colour')    # for b-c, and standard wxPython spelling
-            if key not in wxMaskedEditMixin.valid_ctrl_params.keys() + Field.valid_params.keys():
-                dbg(indent=0, suspend=0)
+            if key not in MaskedEditMixin.valid_ctrl_params.keys() + Field.valid_params.keys():
+##                dbg(indent=0, suspend=0)
                 raise TypeError('Invalid keyword argument "%s" for control "%s"' % (key, self.name))
             elif key in Field.valid_params.keys():
                 constraint_kwargs[key] = value
                 raise TypeError('Invalid keyword argument "%s" for control "%s"' % (key, self.name))
             elif key in Field.valid_params.keys():
                 constraint_kwargs[key] = value
@@ -1653,8 +1720,12 @@ class wxMaskedEditMixin:
         else:
             autoformat = None
 
         else:
             autoformat = None
 
+        # handle "parochial name" backward compatibility:
+        if autoformat and autoformat.find('MILTIME') != -1 and autoformat not in masktags.keys():
+            autoformat = autoformat.replace('MILTIME', '24HRTIME')
+
         if autoformat != self._autoformat and autoformat in masktags.keys():
         if autoformat != self._autoformat and autoformat in masktags.keys():
-            dbg('autoformat:', autoformat)
+##            dbg('autoformat:', autoformat)
             self._autoformat                  = autoformat
             mask                              = masktags[self._autoformat]['mask']
             # gather rest of any autoformat parameters:
             self._autoformat                  = autoformat
             mask                              = masktags[self._autoformat]['mask']
             # gather rest of any autoformat parameters:
@@ -1665,17 +1736,17 @@ class wxMaskedEditMixin:
         elif autoformat and not autoformat in masktags.keys():
             raise AttributeError('invalid value for autoformat parameter: %s' % repr(autoformat))
         else:
         elif autoformat and not autoformat in masktags.keys():
             raise AttributeError('invalid value for autoformat parameter: %s' % repr(autoformat))
         else:
-            dbg('autoformat not selected')
+##            dbg('autoformat not selected')
             if kwargs.has_key('mask'):
                 mask = kwargs['mask']
             if kwargs.has_key('mask'):
                 mask = kwargs['mask']
-                dbg('mask:', mask)
+##                dbg('mask:', mask)
 
         ## Assign style flags
         if mask is None:
 
         ## Assign style flags
         if mask is None:
-            dbg('preserving previous mask')
+##            dbg('preserving previous mask')
             mask = self._previous_mask   # preserve previous mask
         else:
             mask = self._previous_mask   # preserve previous mask
         else:
-            dbg('mask (re)set')
+##            dbg('mask (re)set')
             reset_args['reset_mask'] = mask
             constraint_kwargs['mask'] = mask
 
             reset_args['reset_mask'] = mask
             constraint_kwargs['mask'] = mask
 
@@ -1691,28 +1762,28 @@ class wxMaskedEditMixin:
                 for i in range(len(fields)):
                     field = fields[i]
                     if not isinstance(field, Field):
                 for i in range(len(fields)):
                     field = fields[i]
                     if not isinstance(field, Field):
-                        dbg(indent=0, suspend=0)
+##                        dbg(indent=0, suspend=0)
                         raise AttributeError('invalid type for field parameter: %s' % repr(field))
                     self._fields[i] = field
 
             elif type(fields) == types.DictionaryType:
                 for index, field in fields.items():
                     if not isinstance(field, Field):
                         raise AttributeError('invalid type for field parameter: %s' % repr(field))
                     self._fields[i] = field
 
             elif type(fields) == types.DictionaryType:
                 for index, field in fields.items():
                     if not isinstance(field, Field):
-                        dbg(indent=0, suspend=0)
+##                        dbg(indent=0, suspend=0)
                         raise AttributeError('invalid type for field parameter: %s' % repr(field))
                     self._fields[index] = field
             else:
                         raise AttributeError('invalid type for field parameter: %s' % repr(field))
                     self._fields[index] = field
             else:
-                dbg(indent=0, suspend=0)
+##                dbg(indent=0, suspend=0)
                 raise AttributeError('fields parameter must be a list or dictionary; not %s' % repr(fields))
 
         # Assign constraint parameters for entire control:
                 raise AttributeError('fields parameter must be a list or dictionary; not %s' % repr(fields))
 
         # Assign constraint parameters for entire control:
-##        dbg('control constraints:', indent=1)
+####        dbg('control constraints:', indent=1)
 ##        for key, value in constraint_kwargs.items():
 ##        for key, value in constraint_kwargs.items():
-##            dbg('%s:' % key, value)
-##        dbg(indent=0)
+####            dbg('%s:' % key, value)
+####        dbg(indent=0)
 
         # determine if changing parameters that should affect the entire control:
 
         # determine if changing parameters that should affect the entire control:
-        for key in wxMaskedEditMixin.valid_ctrl_params.keys():
+        for key in MaskedEditMixin.valid_ctrl_params.keys():
             if key in ( 'mask', 'fields' ): continue    # (processed separately)
             if ctrl_kwargs.has_key(key):
                 setattr(self, '_' + key, ctrl_kwargs[key])
             if key in ( 'mask', 'fields' ): continue    # (processed separately)
             if ctrl_kwargs.has_key(key):
                 setattr(self, '_' + key, ctrl_kwargs[key])
@@ -1723,7 +1794,7 @@ class wxMaskedEditMixin:
                     'foregroundColour', 'signedForegroundColour'):
             if ctrl_kwargs.has_key(key):
                 if type(ctrl_kwargs[key]) in (types.StringType, types.UnicodeType):
                     'foregroundColour', 'signedForegroundColour'):
             if ctrl_kwargs.has_key(key):
                 if type(ctrl_kwargs[key]) in (types.StringType, types.UnicodeType):
-                    c = wxNamedColour(ctrl_kwargs[key])
+                    c = wx.NamedColour(ctrl_kwargs[key])
                     if c.Get() == (-1, -1, -1):
                         raise TypeError('%s not a legal color specification for %s' % (repr(ctrl_kwargs[key]), key))
                     else:
                     if c.Get() == (-1, -1, -1):
                         raise TypeError('%s not a legal color specification for %s' % (repr(ctrl_kwargs[key]), key))
                     else:
@@ -1732,19 +1803,19 @@ class wxMaskedEditMixin:
                         # attach a python dynamic attribute to wxColour for debug printouts
                         c._name = ctrl_kwargs[key]
 
                         # attach a python dynamic attribute to wxColour for debug printouts
                         c._name = ctrl_kwargs[key]
 
-                elif type(ctrl_kwargs[key]) != type(wxBLACK):
+                elif type(ctrl_kwargs[key]) != type(wx.BLACK):
                     raise TypeError('%s not a legal color specification for %s' % (repr(ctrl_kwargs[key]), key))
 
 
                     raise TypeError('%s not a legal color specification for %s' % (repr(ctrl_kwargs[key]), key))
 
 
-        dbg('self._retainFieldValidation:', self._retainFieldValidation)
+##        dbg('self._retainFieldValidation:', self._retainFieldValidation)
         if not self._retainFieldValidation:
             # Build dictionary of any changing parameters which should be propagated to the
             # component fields:
             for arg in Field.propagating_params:
         if not self._retainFieldValidation:
             # Build dictionary of any changing parameters which should be propagated to the
             # component fields:
             for arg in Field.propagating_params:
-##                dbg('kwargs.has_key(%s)?' % arg, kwargs.has_key(arg))
-##                dbg('getattr(self._ctrl_constraints, _%s)?' % arg, getattr(self._ctrl_constraints, '_'+arg))
+####                dbg('kwargs.has_key(%s)?' % arg, kwargs.has_key(arg))
+####                dbg('getattr(self._ctrl_constraints, _%s)?' % arg, getattr(self._ctrl_constraints, '_'+arg))
                 reset_args[arg] = kwargs.has_key(arg) and kwargs[arg] != getattr(self._ctrl_constraints, '_'+arg)
                 reset_args[arg] = kwargs.has_key(arg) and kwargs[arg] != getattr(self._ctrl_constraints, '_'+arg)
-##                dbg('reset_args[%s]?' % arg, reset_args[arg])
+####                dbg('reset_args[%s]?' % arg, reset_args[arg])
 
         # Set the control-level constraints:
         self._ctrl_constraints._SetParameters(**constraint_kwargs)
 
         # Set the control-level constraints:
         self._ctrl_constraints._SetParameters(**constraint_kwargs)
@@ -1761,7 +1832,7 @@ class wxMaskedEditMixin:
         # Validate that all choices for given fields are at least of the
         # necessary length, and that they all would be valid pastes if pasted
         # into their respective fields:
         # Validate that all choices for given fields are at least of the
         # necessary length, and that they all would be valid pastes if pasted
         # into their respective fields:
-##        dbg('validating choices')
+####        dbg('validating choices')
         self._validateChoices()
 
 
         self._validateChoices()
 
 
@@ -1788,6 +1859,9 @@ class wxMaskedEditMixin:
             elif self._autoformat.find('DMMY')  != -1: self._datestyle = 'DMY'
             elif self._autoformat.find('DMMMY') != -1: self._datestyle = 'DMY'
 
             elif self._autoformat.find('DMMY')  != -1: self._datestyle = 'DMY'
             elif self._autoformat.find('DMMMY') != -1: self._datestyle = 'DMY'
 
+        # Give derived controls a chance to react to parameter changes before
+        # potentially changing current value of the control.
+        self._OnCtrlParametersChanged()
 
         if self.controlInitialized:
             # Then the base control is available for configuration;
 
         if self.controlInitialized:
             # Then the base control is available for configuration;
@@ -1797,18 +1871,18 @@ class wxMaskedEditMixin:
                 self._setFont()
 
             if reset_args.has_key('reset_mask'):
                 self._setFont()
 
             if reset_args.has_key('reset_mask'):
-                dbg('reset mask')
+##                dbg('reset mask')
                 curvalue = self._GetValue()
                 if curvalue.strip():
                     try:
                 curvalue = self._GetValue()
                 if curvalue.strip():
                     try:
-                        dbg('attempting to _SetInitialValue(%s)' % self._GetValue())
+##                        dbg('attempting to _SetInitialValue(%s)' % self._GetValue())
                         self._SetInitialValue(self._GetValue())
                     except Exception, e:
                         self._SetInitialValue(self._GetValue())
                     except Exception, e:
-                        dbg('exception caught:', e)
-                        dbg("current value doesn't work; attempting to reset to template")
+##                        dbg('exception caught:', e)
+##                        dbg("current value doesn't work; attempting to reset to template")
                         self._SetInitialValue()
                 else:
                         self._SetInitialValue()
                 else:
-                    dbg('attempting to _SetInitialValue() with template')
+##                    dbg('attempting to _SetInitialValue() with template')
                     self._SetInitialValue()
 
             elif kwargs.has_key('useParensForNegatives'):
                     self._SetInitialValue()
 
             elif kwargs.has_key('useParensForNegatives'):
@@ -1822,19 +1896,19 @@ class wxMaskedEditMixin:
                         if newvalue[-1] in (' ', ')'):
                             newvalue = newvalue[:-1]
 
                         if newvalue[-1] in (' ', ')'):
                             newvalue = newvalue[:-1]
 
-                    dbg('reconfiguring value for parens:"%s"' % newvalue)
+##                    dbg('reconfiguring value for parens:"%s"' % newvalue)
                     self._SetValue(newvalue)
 
                     if self._prevValue != newvalue:
                         self._prevValue = newvalue  # disallow undo of sign type
 
             if self._autofit:
                     self._SetValue(newvalue)
 
                     if self._prevValue != newvalue:
                         self._prevValue = newvalue  # disallow undo of sign type
 
             if self._autofit:
-                dbg('setting client size to:', self._CalcSize())
+##                dbg('setting client size to:', self._CalcSize())
                 self.SetClientSize(self._CalcSize())
 
             # Set value/type-specific formatting
             self._applyFormatting()
                 self.SetClientSize(self._CalcSize())
 
             # Set value/type-specific formatting
             self._applyFormatting()
-        dbg(indent=0, suspend=0)
+##        dbg(indent=0, suspend=0)
 
     def SetMaskParameters(self, **kwargs):
         """ old name for this function """
 
     def SetMaskParameters(self, **kwargs):
         """ old name for this function """
@@ -1845,7 +1919,7 @@ class wxMaskedEditMixin:
         """
         Routine for retrieving the value of any given parameter
         """
         """
         Routine for retrieving the value of any given parameter
         """
-        if wxMaskedEditMixin.valid_ctrl_params.has_key(paramname.replace('Color','Colour')):
+        if MaskedEditMixin.valid_ctrl_params.has_key(paramname.replace('Color','Colour')):
             return getattr(self, '_' + paramname.replace('Color', 'Colour'))
         elif Field.valid_params.has_key(paramname):
             return self._ctrl_constraints._GetParameter(paramname)
             return getattr(self, '_' + paramname.replace('Color', 'Colour'))
         elif Field.valid_params.has_key(paramname):
             return self._ctrl_constraints._GetParameter(paramname)
@@ -1857,23 +1931,30 @@ class wxMaskedEditMixin:
         return self.GetCtrlParameter(paramname)
 
 
         return self.GetCtrlParameter(paramname)
 
 
-    # ## TRICKY BIT: to avoid a ton of boiler-plate, and to
-    # ## automate the getter/setter generation for each valid
-    # ## control parameter so we never forget to add the
-    # ## functions when adding parameters, this loop
-    # ## programmatically adds them to the class:
-    # ## (This makes it easier for Designers like Boa to
-    # ## deal with masked controls.)
-    # ##
-    for param in valid_ctrl_params.keys() + Field.valid_params.keys():
-        propname = param[0].upper() + param[1:]
-        exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
-        exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
-        if param.find('Colour') != -1:
-            # add non-british spellings, for backward-compatibility
-            propname.replace('Colour', 'Color')
-            exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
-            exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+## This idea worked, but Boa was unable to use this solution...
+##    def _attachMethod(self, func):
+##        import new
+##        setattr(self, func.__name__, new.instancemethod(func, self, self.__class__))
+##
+##
+##    def _DefinePropertyFunctions(exposed_params):
+##        for param in exposed_params:
+##            propname = param[0].upper() + param[1:]
+##
+##            exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+##            exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+##            self._attachMethod(locals()['Set%s' % propname])
+##            self._attachMethod(locals()['Get%s' % propname])
+##
+##            if param.find('Colour') != -1:
+##                # add non-british spellings, for backward-compatibility
+##                propname.replace('Colour', 'Color')
+##
+##                exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+##                exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+##                self._attachMethod(locals()['Set%s' % propname])
+##                self._attachMethod(locals()['Get%s' % propname])
+##
 
 
     def SetFieldParameters(self, field_index, **kwargs):
 
 
     def SetFieldParameters(self, field_index, **kwargs):
@@ -1979,7 +2060,7 @@ class wxMaskedEditMixin:
         of booleans indicating whether or not a given position in the mask is
         a mask character or not.
         """
         of booleans indicating whether or not a given position in the mask is
         a mask character or not.
         """
-        dbg('_processMask: mask', mask, indent=1)
+##        dbg('_processMask: mask', mask, indent=1)
         # regular expression for parsing c{n} syntax:
         rex = re.compile('([' +string.join(maskchars,"") + '])\{(\d+)\}')
         s = mask
         # regular expression for parsing c{n} syntax:
         rex = re.compile('([' +string.join(maskchars,"") + '])\{(\d+)\}')
         s = mask
@@ -1999,8 +2080,8 @@ class wxMaskedEditMixin:
         self._signOk     = '-' in self._ctrl_constraints._formatcodes and (self._isFloat or self._isInt)
         self._useParens  = self._ctrl_constraints._useParensForNegatives
         self._isNeg      = False
         self._signOk     = '-' in self._ctrl_constraints._formatcodes and (self._isFloat or self._isInt)
         self._useParens  = self._ctrl_constraints._useParensForNegatives
         self._isNeg      = False
-##        dbg('self._signOk?', self._signOk, 'self._useParens?', self._useParens)
-##        dbg('isFloatingPoint(%s)?' % (s), isFloatingPoint(s),
+####        dbg('self._signOk?', self._signOk, 'self._useParens?', self._useParens)
+####        dbg('isFloatingPoint(%s)?' % (s), isFloatingPoint(s),
 ##            'ctrl regex:', self._ctrl_constraints._validRegex)
 
         if self._signOk and s[0] != ' ':
 ##            'ctrl regex:', self._ctrl_constraints._validRegex)
 
         if self._signOk and s[0] != ' ':
@@ -2027,10 +2108,10 @@ class wxMaskedEditMixin:
                         s = s[:i] + s[i+1:]     # elide the 2nd '\' as well
             else:                       # else if special char, mark position accordingly
                 ismasked[i] = s[i] in maskchars
                         s = s[:i] + s[i+1:]     # elide the 2nd '\' as well
             else:                       # else if special char, mark position accordingly
                 ismasked[i] = s[i] in maskchars
-##            dbg('ismasked[%d]:' % i, ismasked[i], s)
+####            dbg('ismasked[%d]:' % i, ismasked[i], s)
             i += 1                      # increment to next char
             i += 1                      # increment to next char
-##        dbg('ismasked:', ismasked)
-        dbg('new mask: "%s"' % s, indent=0)
+####        dbg('ismasked:', ismasked)
+##        dbg('new mask: "%s"' % s, indent=0)
 
         return s, ismasked
 
 
         return s, ismasked
 
@@ -2067,7 +2148,7 @@ class wxMaskedEditMixin:
                     self._fields[1] = Field()
 
                 self._decimalpos = string.find( self._mask, '.')
                     self._fields[1] = Field()
 
                 self._decimalpos = string.find( self._mask, '.')
-                dbg('decimal pos =', self._decimalpos)
+##                dbg('decimal pos =', self._decimalpos)
 
                 formatcodes = self._fields[0]._GetParameter('formatcodes')
                 if 'R' not in formatcodes: formatcodes += 'R'
 
                 formatcodes = self._fields[0]._GetParameter('formatcodes')
                 if 'R' not in formatcodes: formatcodes += 'R'
@@ -2108,18 +2189,18 @@ class wxMaskedEditMixin:
                     pos = i       # figure out field for 1st editable space:
 
                 while i <= len(self._mask):
                     pos = i       # figure out field for 1st editable space:
 
                 while i <= len(self._mask):
-##                    dbg('searching: outer field loop: i = ', i)
+####                    dbg('searching: outer field loop: i = ', i)
                     if self._isMaskChar(i):
                     if self._isMaskChar(i):
-##                        dbg('1st char is mask char; recording edit_start=', i)
+####                        dbg('1st char is mask char; recording edit_start=', i)
                         edit_start = i
                         # Skip to end of editable part of current field:
                         while i < len(self._mask) and self._isMaskChar(i):
                             self._lookupField[i] = field_index
                             i += 1
                         edit_start = i
                         # Skip to end of editable part of current field:
                         while i < len(self._mask) and self._isMaskChar(i):
                             self._lookupField[i] = field_index
                             i += 1
-##                        dbg('edit_end =', i)
+####                        dbg('edit_end =', i)
                         edit_end = i
                         self._lookupField[i] = field_index
                         edit_end = i
                         self._lookupField[i] = field_index
-##                        dbg('self._fields.has_key(%d)?' % field_index, self._fields.has_key(field_index))
+####                        dbg('self._fields.has_key(%d)?' % field_index, self._fields.has_key(field_index))
                         if not self._fields.has_key(field_index):
                             kwargs = Field.valid_params.copy()
                             kwargs['index'] = field_index
                         if not self._fields.has_key(field_index):
                             kwargs = Field.valid_params.copy()
                             kwargs['index'] = field_index
@@ -2140,15 +2221,15 @@ class wxMaskedEditMixin:
                         break           # if past end, we're done
                     else:
                         field_index += 1
                         break           # if past end, we're done
                     else:
                         field_index += 1
-##                        dbg('next field:', field_index)
+####                        dbg('next field:', field_index)
 
         indices = self._fields.keys()
         indices.sort()
         self._field_indices = indices[1:]
 
         indices = self._fields.keys()
         indices.sort()
         self._field_indices = indices[1:]
-##        dbg('lookupField map:', indent=1)
+####        dbg('lookupField map:', indent=1)
 ##        for i in range(len(self._mask)):
 ##        for i in range(len(self._mask)):
-##            dbg('pos %d:' % i, self._lookupField[i])
-##        dbg(indent=0)
+####            dbg('pos %d:' % i, self._lookupField[i])
+####        dbg(indent=0)
 
         # Verify that all field indices specified are valid for mask:
         for index in self._fields.keys():
 
         # Verify that all field indices specified are valid for mask:
         for index in self._fields.keys():
@@ -2169,7 +2250,7 @@ class wxMaskedEditMixin:
             for field in self._fields.values():
                 if field._defaultValue and not reset_default:
                     default_set = True
             for field in self._fields.values():
                 if field._defaultValue and not reset_default:
                     default_set = True
-        dbg('default set?', default_set)
+##        dbg('default set?', default_set)
 
         # Determine overall new template for control, and keep track of previous
         # values, so that current control value can be modified as appropriate:
 
         # Determine overall new template for control, and keep track of previous
         # values, so that current control value can be modified as appropriate:
@@ -2191,9 +2272,9 @@ class wxMaskedEditMixin:
             field._template = ""
 
         for pos in range(len(self._mask)):
             field._template = ""
 
         for pos in range(len(self._mask)):
-##            dbg('pos:', pos)
+####            dbg('pos:', pos)
             field = self._FindField(pos)
             field = self._FindField(pos)
-##            dbg('field:', field._index)
+####            dbg('field:', field._index)
             start, end = field._extent
 
             if pos == 0 and self._signOk:
             start, end = field._extent
 
             if pos == 0 and self._signOk:
@@ -2216,32 +2297,32 @@ class wxMaskedEditMixin:
                         curvalue[pos] = fillChar
 
                 if not field._defaultValue and not self._ctrl_constraints._defaultValue:
                         curvalue[pos] = fillChar
 
                 if not field._defaultValue and not self._ctrl_constraints._defaultValue:
-##                    dbg('no default value')
+####                    dbg('no default value')
                     self._template += fillChar
                     field._template += fillChar
 
                 elif field._defaultValue and not reset_default:
                     self._template += fillChar
                     field._template += fillChar
 
                 elif field._defaultValue and not reset_default:
-##                    dbg('len(field._defaultValue):', len(field._defaultValue))
-##                    dbg('pos-start:', pos-start)
+####                    dbg('len(field._defaultValue):', len(field._defaultValue))
+####                    dbg('pos-start:', pos-start)
                     if len(field._defaultValue) > pos-start:
                     if len(field._defaultValue) > pos-start:
-##                        dbg('field._defaultValue[pos-start]: "%s"' % field._defaultValue[pos-start])
+####                        dbg('field._defaultValue[pos-start]: "%s"' % field._defaultValue[pos-start])
                         self._template += field._defaultValue[pos-start]
                         field._template += field._defaultValue[pos-start]
                     else:
                         self._template += field._defaultValue[pos-start]
                         field._template += field._defaultValue[pos-start]
                     else:
-##                        dbg('field default not long enough; using fillChar')
+####                        dbg('field default not long enough; using fillChar')
                         self._template += fillChar
                         field._template += fillChar
                 else:
                     if len(self._ctrl_constraints._defaultValue) > pos:
                         self._template += fillChar
                         field._template += fillChar
                 else:
                     if len(self._ctrl_constraints._defaultValue) > pos:
-##                        dbg('using control default')
+####                        dbg('using control default')
                         self._template += self._ctrl_constraints._defaultValue[pos]
                         field._template += self._ctrl_constraints._defaultValue[pos]
                     else:
                         self._template += self._ctrl_constraints._defaultValue[pos]
                         field._template += self._ctrl_constraints._defaultValue[pos]
                     else:
-##                        dbg('ctrl default not long enough; using fillChar')
+####                        dbg('ctrl default not long enough; using fillChar')
                         self._template += fillChar
                         field._template += fillChar
                         self._template += fillChar
                         field._template += fillChar
-##                dbg('field[%d]._template now "%s"' % (field._index, field._template))
-##                dbg('self._template now "%s"' % self._template)
+####                dbg('field[%d]._template now "%s"' % (field._index, field._template))
+####                dbg('self._template now "%s"' % self._template)
             else:
                 self._template += self._mask[pos]
 
             else:
                 self._template += self._mask[pos]
 
@@ -2254,9 +2335,9 @@ class wxMaskedEditMixin:
 
         if default_set:
             self._defaultValue = self._template
 
         if default_set:
             self._defaultValue = self._template
-            dbg('self._defaultValue:', self._defaultValue)
+##            dbg('self._defaultValue:', self._defaultValue)
             if not self.IsEmpty(self._defaultValue) and not self.IsValid(self._defaultValue):
             if not self.IsEmpty(self._defaultValue) and not self.IsValid(self._defaultValue):
-##                dbg(indent=0)
+####                dbg(indent=0)
                 raise ValueError('Default value of "%s" is not a valid value for control "%s"' % (self._defaultValue, self.name))
 
             # if no fillchar change, but old value == old template, replace it:
                 raise ValueError('Default value of "%s" is not a valid value for control "%s"' % (self._defaultValue, self.name))
 
             # if no fillchar change, but old value == old template, replace it:
@@ -2267,7 +2348,7 @@ class wxMaskedEditMixin:
             self._defaultValue = None
 
         if reset_value:
             self._defaultValue = None
 
         if reset_value:
-            dbg('resetting value to: "%s"' % newvalue)
+##            dbg('resetting value to: "%s"' % newvalue)
             pos = self._GetInsertionPoint()
             sel_start, sel_to = self._GetSelection()
             self._SetValue(newvalue)
             pos = self._GetInsertionPoint()
             sel_start, sel_to = self._GetSelection()
             self._SetValue(newvalue)
@@ -2313,11 +2394,11 @@ class wxMaskedEditMixin:
                 inherit_args['defaultValue'] = ""   # (reset for field)
 
             for param in Field.propagating_params:
                 inherit_args['defaultValue'] = ""   # (reset for field)
 
             for param in Field.propagating_params:
-##                dbg('reset_args.has_key(%s)?' % param, reset_args.has_key(param))
-##                dbg('reset_args.has_key(%(param)s) and reset_args[%(param)s]?' % locals(), reset_args.has_key(param) and reset_args[param])
+####                dbg('reset_args.has_key(%s)?' % param, reset_args.has_key(param))
+####                dbg('reset_args.has_key(%(param)s) and reset_args[%(param)s]?' % locals(), reset_args.has_key(param) and reset_args[param])
                 if reset_args.has_key(param):
                     inherit_args[param] = self.GetCtrlParameter(param)
                 if reset_args.has_key(param):
                     inherit_args[param] = self.GetCtrlParameter(param)
-##                    dbg('inherit_args[%s]' % param, inherit_args[param])
+####                    dbg('inherit_args[%s]' % param, inherit_args[param])
 
             if inherit_args:
                 field._SetParameters(**inherit_args)
 
             if inherit_args:
                 field._SetParameters(**inherit_args)
@@ -2334,22 +2415,22 @@ class wxMaskedEditMixin:
             if field._choices:
                 index = field._index
                 if len(self._field_indices) == 1 and index == 0 and field._choices == self._ctrl_constraints._choices:
             if field._choices:
                 index = field._index
                 if len(self._field_indices) == 1 and index == 0 and field._choices == self._ctrl_constraints._choices:
-                    dbg('skipping (duplicate) choice validation of field 0')
+##                    dbg('skipping (duplicate) choice validation of field 0')
                     continue
                     continue
-##                dbg('checking for choices for field', field._index)
+####                dbg('checking for choices for field', field._index)
                 start, end = field._extent
                 field_length = end - start
                 start, end = field._extent
                 field_length = end - start
-##                dbg('start, end, length:', start, end, field_length)
+####                dbg('start, end, length:', start, end, field_length)
                 for choice in field._choices:
                 for choice in field._choices:
-##                    dbg('testing "%s"' % choice)
+####                    dbg('testing "%s"' % choice)
                     valid_paste, ignore, replace_to = self._validatePaste(choice, start, end)
                     if not valid_paste:
                     valid_paste, ignore, replace_to = self._validatePaste(choice, start, end)
                     if not valid_paste:
-##                        dbg(indent=0)
+####                        dbg(indent=0)
                         raise ValueError('"%s" could not be entered into field %d of control "%s"' % (choice, index, self.name))
                     elif replace_to > end:
                         raise ValueError('"%s" could not be entered into field %d of control "%s"' % (choice, index, self.name))
                     elif replace_to > end:
-##                        dbg(indent=0)
+####                        dbg(indent=0)
                         raise ValueError('"%s" will not fit into field %d of control "%s"' (choice, index, self.name))
                         raise ValueError('"%s" will not fit into field %d of control "%s"' (choice, index, self.name))
-##                    dbg(choice, 'valid in field', index)
+####                    dbg(choice, 'valid in field', index)
 
 
     def _configure(self, mask, **reset_args):
 
 
     def _configure(self, mask, **reset_args):
@@ -2367,19 +2448,19 @@ class wxMaskedEditMixin:
         whole control.
 
         """
         whole control.
 
         """
-        dbg(suspend=1)
-        dbg('wxMaskedEditMixin::_configure("%s")' % mask, indent=1)
+##        dbg(suspend=1)
+##        dbg('MaskedEditMixin::_configure("%s")' % mask, indent=1)
 
         # Preprocess specified mask to expand {n} syntax, handle escaped
         # mask characters, etc and build the resulting positionally keyed
         # dictionary for which positions are mask vs. template characters:
         self._mask, self.ismasked = self._processMask(mask)
         self._masklength = len(self._mask)
 
         # Preprocess specified mask to expand {n} syntax, handle escaped
         # mask characters, etc and build the resulting positionally keyed
         # dictionary for which positions are mask vs. template characters:
         self._mask, self.ismasked = self._processMask(mask)
         self._masklength = len(self._mask)
-##        dbg('processed mask:', self._mask)
+####        dbg('processed mask:', self._mask)
 
         # Preserve original mask specified, for subsequent reprocessing
         # if parameters change.
 
         # Preserve original mask specified, for subsequent reprocessing
         # if parameters change.
-        dbg('mask: "%s"' % self._mask, 'previous mask: "%s"' % self._previous_mask)
+##        dbg('mask: "%s"' % self._mask, 'previous mask: "%s"' % self._previous_mask)
         self._previous_mask = mask    # save unexpanded mask for next time
             # Set expanded mask and extent of field -1 to width of entire control:
         self._ctrl_constraints._SetParameters(mask = self._mask, extent=(0,self._masklength))
         self._previous_mask = mask    # save unexpanded mask for next time
             # Set expanded mask and extent of field -1 to width of entire control:
         self._ctrl_constraints._SetParameters(mask = self._mask, extent=(0,self._masklength))
@@ -2388,7 +2469,7 @@ class wxMaskedEditMixin:
         # instances as necessary, configure them with those extents, and
         # build lookup table mapping each position for control to its corresponding
         # field.
         # instances as necessary, configure them with those extents, and
         # build lookup table mapping each position for control to its corresponding
         # field.
-##        dbg('calculating field extents')
+####        dbg('calculating field extents')
 
         self._calcFieldExtents()
 
 
         self._calcFieldExtents()
 
@@ -2398,13 +2479,13 @@ class wxMaskedEditMixin:
         reset_fillchar = reset_args.has_key('fillChar') and reset_args['fillChar']
         reset_default = reset_args.has_key('defaultValue') and reset_args['defaultValue']
 
         reset_fillchar = reset_args.has_key('fillChar') and reset_args['fillChar']
         reset_default = reset_args.has_key('defaultValue') and reset_args['defaultValue']
 
-##        dbg('calculating template')
+####        dbg('calculating template')
         self._calcTemplate(reset_fillchar, reset_default)
 
         # Propagate control-level formatting and character constraints to each
         # field if they don't already have them; if only one field, propagate
         # control-level validation constraints to field as well:
         self._calcTemplate(reset_fillchar, reset_default)
 
         # Propagate control-level formatting and character constraints to each
         # field if they don't already have them; if only one field, propagate
         # control-level validation constraints to field as well:
-##        dbg('propagating constraints')
+####        dbg('propagating constraints')
         self._propagateConstraints(**reset_args)
 
 
         self._propagateConstraints(**reset_args)
 
 
@@ -2412,10 +2493,10 @@ class wxMaskedEditMixin:
             raise AttributeError('groupChar (%s) and decimalChar (%s) must be distinct.' %
                                  (self._fields[0]._groupChar, self._decimalChar) )
 
             raise AttributeError('groupChar (%s) and decimalChar (%s) must be distinct.' %
                                  (self._fields[0]._groupChar, self._decimalChar) )
 
-##        dbg('fields:', indent=1)
+####        dbg('fields:', indent=1)
 ##        for i in [-1] + self._field_indices:
 ##        for i in [-1] + self._field_indices:
-##            dbg('field %d:' % i, self._fields[i].__dict__)
-##        dbg(indent=0)
+####            dbg('field %d:' % i, self._fields[i].__dict__)
+####        dbg(indent=0)
 
         # Set up special parameters for numeric control, if appropriate:
         if self._signOk:
 
         # Set up special parameters for numeric control, if appropriate:
         if self._signOk:
@@ -2433,7 +2514,7 @@ class wxMaskedEditMixin:
         if self._isFloat or self._isInt:
             if self.controlInitialized:
                 value = self._GetValue()
         if self._isFloat or self._isInt:
             if self.controlInitialized:
                 value = self._GetValue()
-##                dbg('value: "%s"' % value, 'len(value):', len(value),
+####                dbg('value: "%s"' % value, 'len(value):', len(value),
 ##                    'len(self._ctrl_constraints._mask):',len(self._ctrl_constraints._mask))
                 if len(value) < len(self._ctrl_constraints._mask):
                     newvalue = value
 ##                    'len(self._ctrl_constraints._mask):',len(self._ctrl_constraints._mask))
                 if len(value) < len(self._ctrl_constraints._mask):
                     newvalue = value
@@ -2446,12 +2527,12 @@ class wxMaskedEditMixin:
                             newvalue = newvalue.rjust(len(self._ctrl_constraints._mask))
                         else:
                             newvalue = newvalue.ljust(len(self._ctrl_constraints._mask))
                             newvalue = newvalue.rjust(len(self._ctrl_constraints._mask))
                         else:
                             newvalue = newvalue.ljust(len(self._ctrl_constraints._mask))
-                    dbg('old value: "%s"' % value)
-                    dbg('new value: "%s"' % newvalue)
+##                    dbg('old value: "%s"' % value)
+##                    dbg('new value: "%s"' % newvalue)
                     try:
                         self._SetValue(newvalue)
                     except Exception, e:
                     try:
                         self._SetValue(newvalue)
                     except Exception, e:
-                        dbg('exception raised:', e, 'resetting to initial value')
+##                        dbg('exception raised:', e, 'resetting to initial value')
                         self._SetInitialValue()
 
                 elif len(value) > len(self._ctrl_constraints._mask):
                         self._SetInitialValue()
 
                 elif len(value) > len(self._ctrl_constraints._mask):
@@ -2463,31 +2544,31 @@ class wxMaskedEditMixin:
                     if not self._signOk:
                         newvalue, signpos, right_signpos = self._getSignedValue(newvalue)
 
                     if not self._signOk:
                         newvalue, signpos, right_signpos = self._getSignedValue(newvalue)
 
-                    dbg('old value: "%s"' % value)
-                    dbg('new value: "%s"' % newvalue)
+##                    dbg('old value: "%s"' % value)
+##                    dbg('new value: "%s"' % newvalue)
                     try:
                         self._SetValue(newvalue)
                     except Exception, e:
                     try:
                         self._SetValue(newvalue)
                     except Exception, e:
-                        dbg('exception raised:', e, 'resetting to initial value')
+##                        dbg('exception raised:', e, 'resetting to initial value')
                         self._SetInitialValue()
                 elif not self._signOk and ('(' in value or '-' in value):
                     newvalue, signpos, right_signpos = self._getSignedValue(value)
                         self._SetInitialValue()
                 elif not self._signOk and ('(' in value or '-' in value):
                     newvalue, signpos, right_signpos = self._getSignedValue(value)
-                    dbg('old value: "%s"' % value)
-                    dbg('new value: "%s"' % newvalue)
+##                    dbg('old value: "%s"' % value)
+##                    dbg('new value: "%s"' % newvalue)
                     try:
                         self._SetValue(newvalue)
                     except e:
                     try:
                         self._SetValue(newvalue)
                     except e:
-                        dbg('exception raised:', e, 'resetting to initial value')
+##                        dbg('exception raised:', e, 'resetting to initial value')
                         self._SetInitialValue()
 
             # Replace up/down arrow default handling:
             # make down act like tab, up act like shift-tab:
 
                         self._SetInitialValue()
 
             # Replace up/down arrow default handling:
             # make down act like tab, up act like shift-tab:
 
-##            dbg('Registering numeric navigation and control handlers (if not already set)')
-            if not self._keyhandlers.has_key(WXK_DOWN):
-                self._SetKeycodeHandler(WXK_DOWN, self._OnChangeField)
-            if not self._keyhandlers.has_key(WXK_UP):
-                self._SetKeycodeHandler(WXK_UP, self._OnUpNumeric)  # (adds "shift" to up arrow, and calls _OnChangeField)
+####            dbg('Registering numeric navigation and control handlers (if not already set)')
+            if not self._keyhandlers.has_key(wx.WXK_DOWN):
+                self._SetKeycodeHandler(wx.WXK_DOWN, self._OnChangeField)
+            if not self._keyhandlers.has_key(wx.WXK_UP):
+                self._SetKeycodeHandler(wx.WXK_UP, self._OnUpNumeric)  # (adds "shift" to up arrow, and calls _OnChangeField)
 
             # On ., truncate contents right of cursor to decimal point (if any)
             # leaves cusor after decimal point if floating point, otherwise at 0.
 
             # On ., truncate contents right of cursor to decimal point (if any)
             # leaves cusor after decimal point if floating point, otherwise at 0.
@@ -2500,7 +2581,7 @@ class wxMaskedEditMixin:
             if not self._keyhandlers.has_key(ord(self._fields[0]._groupChar)):
                 self._SetKeyHandler(self._fields[0]._groupChar, self._OnGroupChar)
 
             if not self._keyhandlers.has_key(ord(self._fields[0]._groupChar)):
                 self._SetKeyHandler(self._fields[0]._groupChar, self._OnGroupChar)
 
-        dbg(indent=0, suspend=0)
+##        dbg(indent=0, suspend=0)
 
 
     def _SetInitialValue(self, value=""):
 
 
     def _SetInitialValue(self, value=""):
@@ -2509,7 +2590,7 @@ class wxMaskedEditMixin:
         It will also set/reset the font if necessary and apply
         formatting to the control at this time.
         """
         It will also set/reset the font if necessary and apply
         formatting to the control at this time.
         """
-        dbg('wxMaskedEditMixin::_SetInitialValue("%s")' % value, indent=1)
+##        dbg('MaskedEditMixin::_SetInitialValue("%s")' % value, indent=1)
         if not value:
             self._prevValue = self._curValue = self._template
             # don't apply external validation rules in this case, as template may
         if not value:
             self._prevValue = self._curValue = self._template
             # don't apply external validation rules in this case, as template may
@@ -2517,58 +2598,58 @@ class wxMaskedEditMixin:
             try:
                 self._SetValue(self._curValue)  # note the use of "raw" ._SetValue()...
             except Exception, e:
             try:
                 self._SetValue(self._curValue)  # note the use of "raw" ._SetValue()...
             except Exception, e:
-                dbg('exception thrown:', e, indent=0)
+##                dbg('exception thrown:', e, indent=0)
                 raise
         else:
             # Otherwise apply validation as appropriate to passed value:
                 raise
         else:
             # Otherwise apply validation as appropriate to passed value:
-##            dbg('value = "%s", length:' % value, len(value))
+####            dbg('value = "%s", length:' % value, len(value))
             self._prevValue = self._curValue = value
             try:
                 self.SetValue(value)            # use public (validating) .SetValue()
             except Exception, e:
             self._prevValue = self._curValue = value
             try:
                 self.SetValue(value)            # use public (validating) .SetValue()
             except Exception, e:
-                dbg('exception thrown:', e, indent=0)
+##                dbg('exception thrown:', e, indent=0)
                 raise
 
 
         # Set value/type-specific formatting
         self._applyFormatting()
                 raise
 
 
         # Set value/type-specific formatting
         self._applyFormatting()
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _calcSize(self, size=None):
         """ Calculate automatic size if allowed; must be called after the base control is instantiated"""
 
 
     def _calcSize(self, size=None):
         """ Calculate automatic size if allowed; must be called after the base control is instantiated"""
-##        dbg('wxMaskedEditMixin::_calcSize', indent=1)
-        cont = (size is None or size == wxDefaultSize)
+####        dbg('MaskedEditMixin::_calcSize', indent=1)
+        cont = (size is None or size == wx.DefaultSize)
 
         if cont and self._autofit:
             sizing_text = 'M' * self._masklength
 
         if cont and self._autofit:
             sizing_text = 'M' * self._masklength
-            if wxPlatform != "__WXMSW__":   # give it a little extra space
+            if wx.Platform != "__WXMSW__":   # give it a little extra space
                 sizing_text += 'M'
                 sizing_text += 'M'
-            if wxPlatform == "__WXMAC__":   # give it even a little more...
+            if wx.Platform == "__WXMAC__":   # give it even a little more...
                 sizing_text += 'M'
                 sizing_text += 'M'
-##            dbg('len(sizing_text):', len(sizing_text), 'sizing_text: "%s"' % sizing_text)
+####            dbg('len(sizing_text):', len(sizing_text), 'sizing_text: "%s"' % sizing_text)
             w, h = self.GetTextExtent(sizing_text)
             size = (w+4, self.GetClientSize().height)
             w, h = self.GetTextExtent(sizing_text)
             size = (w+4, self.GetClientSize().height)
-##            dbg('size:', size, indent=0)
+####            dbg('size:', size, indent=0)
         return size
 
 
     def _setFont(self):
         """ Set the control's font typeface -- pass the font name as str."""
         return size
 
 
     def _setFont(self):
         """ Set the control's font typeface -- pass the font name as str."""
-##        dbg('wxMaskedEditMixin::_setFont', indent=1)
+####        dbg('MaskedEditMixin::_setFont', indent=1)
         if not self._useFixedWidthFont:
         if not self._useFixedWidthFont:
-            self._font = wxSystemSettings_GetFont(wxSYS_DEFAULT_GUI_FONT)
+            self._font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         else:
             font = self.GetFont()   # get size, weight, etc from current font
 
         else:
             font = self.GetFont()   # get size, weight, etc from current font
 
-            # Set to teletype font (guaranteed to be mappable to all wxWindows
+            # Set to teletype font (guaranteed to be mappable to all wxWidgets
             # platforms:
             # platforms:
-            self._font = wxFont( font.GetPointSize(), wxTELETYPE, font.GetStyle(),
+            self._font = wx.Font( font.GetPointSize(), wx.TELETYPE, font.GetStyle(),
                                  font.GetWeight(), font.GetUnderlined())
                                  font.GetWeight(), font.GetUnderlined())
-##            dbg('font string: "%s"' % font.GetNativeFontInfo().ToString())
+####            dbg('font string: "%s"' % font.GetNativeFontInfo().ToString())
 
         self.SetFont(self._font)
 
         self.SetFont(self._font)
-##        dbg(indent=0)
+####        dbg(indent=0)
 
 
     def _OnTextChange(self, event):
 
 
     def _OnTextChange(self, event):
@@ -2582,31 +2663,32 @@ class wxMaskedEditMixin:
         EVT_TEXT events for the same change.)
         """
         newvalue = self._GetValue()
         EVT_TEXT events for the same change.)
         """
         newvalue = self._GetValue()
-        dbg('wxMaskedEditMixin::_OnTextChange: value: "%s"' % newvalue, indent=1)
+##        dbg('MaskedEditMixin::_OnTextChange: value: "%s"' % newvalue, indent=1)
         bValid = False
         if self._ignoreChange:      # ie. if an "intermediate text change event"
         bValid = False
         if self._ignoreChange:      # ie. if an "intermediate text change event"
-            dbg(indent=0)
+##            dbg(indent=0)
             return bValid
 
         ##! WS: For some inexplicable reason, every wxTextCtrl.SetValue
         ## call is generating two (2) EVT_TEXT events.
         ## This is the only mechanism I can find to mask this problem:
         if newvalue == self._curValue:
             return bValid
 
         ##! WS: For some inexplicable reason, every wxTextCtrl.SetValue
         ## call is generating two (2) EVT_TEXT events.
         ## This is the only mechanism I can find to mask this problem:
         if newvalue == self._curValue:
-            dbg('ignoring bogus text change event', indent=0)
+##            dbg('ignoring bogus text change event', indent=0)
+            pass
         else:
         else:
-            dbg('curvalue: "%s", newvalue: "%s"' % (self._curValue, newvalue))
+##            dbg('curvalue: "%s", newvalue: "%s"' % (self._curValue, newvalue))
             if self._Change():
                 if self._signOk and self._isNeg and newvalue.find('-') == -1 and newvalue.find('(') == -1:
             if self._Change():
                 if self._signOk and self._isNeg and newvalue.find('-') == -1 and newvalue.find('(') == -1:
-                    dbg('clearing self._isNeg')
+##                    dbg('clearing self._isNeg')
                     self._isNeg = False
                     text, self._signpos, self._right_signpos = self._getSignedValue()
                 self._CheckValid()  # Recolor control as appropriate
                     self._isNeg = False
                     text, self._signpos, self._right_signpos = self._getSignedValue()
                 self._CheckValid()  # Recolor control as appropriate
-            dbg('calling event.Skip()')
+##            dbg('calling event.Skip()')
             event.Skip()
             bValid = True
         self._prevValue = self._curValue    # save for undo
         self._curValue = newvalue           # Save last seen value for next iteration
             event.Skip()
             bValid = True
         self._prevValue = self._curValue    # save for undo
         self._curValue = newvalue           # Save last seen value for next iteration
-        dbg(indent=0)
+##        dbg(indent=0)
         return bValid
 
 
         return bValid
 
 
@@ -2620,7 +2702,7 @@ class wxMaskedEditMixin:
         if key in self._nav and event.ControlDown():
             # then this is the only place we will likely see these events;
             # process them now:
         if key in self._nav and event.ControlDown():
             # then this is the only place we will likely see these events;
             # process them now:
-            dbg('wxMaskedEditMixin::OnKeyDown: calling _OnChar')
+##            dbg('MaskedEditMixin::OnKeyDown: calling _OnChar')
             self._OnChar(event)
             return
         # else allow regular EVT_CHAR key processing
             self._OnChar(event)
             return
         # else allow regular EVT_CHAR key processing
@@ -2632,25 +2714,25 @@ class wxMaskedEditMixin:
         This is the engine of wxMaskedEdit controls.  It examines each keystroke,
         decides if it's allowed, where it should go or what action to take.
         """
         This is the engine of wxMaskedEdit controls.  It examines each keystroke,
         decides if it's allowed, where it should go or what action to take.
         """
-        dbg('wxMaskedEditMixin::_OnChar', indent=1)
+##        dbg('MaskedEditMixin::_OnChar', indent=1)
 
         # Get keypress value, adjusted by control options (e.g. convert to upper etc)
         key = event.GetKeyCode()
         orig_pos = self._GetInsertionPoint()
         orig_value = self._GetValue()
 
         # Get keypress value, adjusted by control options (e.g. convert to upper etc)
         key = event.GetKeyCode()
         orig_pos = self._GetInsertionPoint()
         orig_value = self._GetValue()
-        dbg('keycode = ', key)
-        dbg('current pos = ', orig_pos)
-        dbg('current selection = ', self._GetSelection())
+##        dbg('keycode = ', key)
+##        dbg('current pos = ', orig_pos)
+##        dbg('current selection = ', self._GetSelection())
 
         if not self._Keypress(key):
 
         if not self._Keypress(key):
-            dbg(indent=0)
+##            dbg(indent=0)
             return
 
         # If no format string for this control, or the control is marked as "read-only",
         # skip the rest of the special processing, and just "do the standard thing:"
         if not self._mask or not self._IsEditable():
             event.Skip()
             return
 
         # If no format string for this control, or the control is marked as "read-only",
         # skip the rest of the special processing, and just "do the standard thing:"
         if not self._mask or not self._IsEditable():
             event.Skip()
-            dbg(indent=0)
+##            dbg(indent=0)
             return
 
         # Process navigation and control keys first, with
             return
 
         # Process navigation and control keys first, with
@@ -2661,79 +2743,79 @@ class wxMaskedEditMixin:
                 if self._GetValue() != orig_value:
                     self.modified = True
                 if not keep_processing:
                 if self._GetValue() != orig_value:
                     self.modified = True
                 if not keep_processing:
-                    dbg(indent=0)
+##                    dbg(indent=0)
                     return
                 self._applyFormatting()
                     return
                 self._applyFormatting()
-                dbg(indent=0)
+##                dbg(indent=0)
                 return
 
         # Else... adjust the position as necessary for next input key,
         # and determine resulting selection:
         pos = self._adjustPos( orig_pos, key )    ## get insertion position, adjusted as needed
         sel_start, sel_to = self._GetSelection()                ## check for a range of selected text
                 return
 
         # Else... adjust the position as necessary for next input key,
         # and determine resulting selection:
         pos = self._adjustPos( orig_pos, key )    ## get insertion position, adjusted as needed
         sel_start, sel_to = self._GetSelection()                ## check for a range of selected text
-        dbg("pos, sel_start, sel_to:", pos, sel_start, sel_to)
+##        dbg("pos, sel_start, sel_to:", pos, sel_start, sel_to)
 
         keep_processing = True
         # Capture user past end of format field
         if pos > len(self.maskdict):
 
         keep_processing = True
         # Capture user past end of format field
         if pos > len(self.maskdict):
-            dbg("field length exceeded:",pos)
+##            dbg("field length exceeded:",pos)
             keep_processing = False
 
         if keep_processing:
             if self._isMaskChar(pos):  ## Get string of allowed characters for validation
                 okchars = self._getAllowedChars(pos)
             else:
             keep_processing = False
 
         if keep_processing:
             if self._isMaskChar(pos):  ## Get string of allowed characters for validation
                 okchars = self._getAllowedChars(pos)
             else:
-                dbg('Not a valid position: pos = ', pos,"chars=",maskchars)
+##                dbg('Not a valid position: pos = ', pos,"chars=",maskchars)
                 okchars = ""
 
         key = self._adjustKey(pos, key)     # apply formatting constraints to key:
 
         if self._keyhandlers.has_key(key):
             # there's an override for default behavior; use override function instead
                 okchars = ""
 
         key = self._adjustKey(pos, key)     # apply formatting constraints to key:
 
         if self._keyhandlers.has_key(key):
             # there's an override for default behavior; use override function instead
-            dbg('using supplied key handler:', self._keyhandlers[key])
+##            dbg('using supplied key handler:', self._keyhandlers[key])
             keep_processing = self._keyhandlers[key](event)
             if self._GetValue() != orig_value:
                 self.modified = True
             if not keep_processing:
             keep_processing = self._keyhandlers[key](event)
             if self._GetValue() != orig_value:
                 self.modified = True
             if not keep_processing:
-                dbg(indent=0)
+##                dbg(indent=0)
                 return
             # else skip default processing, but do final formatting
                 return
             # else skip default processing, but do final formatting
-        if key < WXK_SPACE or key > 255:
-            dbg('key < WXK_SPACE or key > 255')
+        if key < wx.WXK_SPACE or key > 255:
+##            dbg('key < WXK_SPACE or key > 255')
             event.Skip()                # non alphanumeric
             keep_processing = False
         else:
             field = self._FindField(pos)
             event.Skip()                # non alphanumeric
             keep_processing = False
         else:
             field = self._FindField(pos)
-            dbg("key ='%s'" % chr(key))
+##            dbg("key ='%s'" % chr(key))
             if chr(key) == ' ':
             if chr(key) == ' ':
-                dbg('okSpaces?', field._okSpaces)
-
+##                dbg('okSpaces?', field._okSpaces)
+                pass
 
 
             if chr(key) in field._excludeChars + self._ctrl_constraints._excludeChars:
                 keep_processing = False
 
             if keep_processing and self._isCharAllowed( chr(key), pos, checkRegex = True ):
 
 
             if chr(key) in field._excludeChars + self._ctrl_constraints._excludeChars:
                 keep_processing = False
 
             if keep_processing and self._isCharAllowed( chr(key), pos, checkRegex = True ):
-                dbg("key allowed by mask")
+##                dbg("key allowed by mask")
                 # insert key into candidate new value, but don't change control yet:
                 oldstr = self._GetValue()
                 newstr, newpos, new_select_to, match_field, match_index = self._insertKey(
                                 chr(key), pos, sel_start, sel_to, self._GetValue(), allowAutoSelect = True)
                 # insert key into candidate new value, but don't change control yet:
                 oldstr = self._GetValue()
                 newstr, newpos, new_select_to, match_field, match_index = self._insertKey(
                                 chr(key), pos, sel_start, sel_to, self._GetValue(), allowAutoSelect = True)
-                dbg("str with '%s' inserted:" % chr(key), '"%s"' % newstr)
+##                dbg("str with '%s' inserted:" % chr(key), '"%s"' % newstr)
                 if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
                 if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
-                    dbg('not valid; checking to see if adjusted string is:')
+##                    dbg('not valid; checking to see if adjusted string is:')
                     keep_processing = False
                     if self._isFloat and newstr != self._template:
                         newstr = self._adjustFloat(newstr)
                     keep_processing = False
                     if self._isFloat and newstr != self._template:
                         newstr = self._adjustFloat(newstr)
-                        dbg('adjusted str:', newstr)
+##                        dbg('adjusted str:', newstr)
                         if self.IsValid(newstr):
                         if self.IsValid(newstr):
-                            dbg("it is!")
+##                            dbg("it is!")
                             keep_processing = True
                             keep_processing = True
-                            wxCallAfter(self._SetInsertionPoint, self._decimalpos)
+                            wx.CallAfter(self._SetInsertionPoint, self._decimalpos)
                     if not keep_processing:
                     if not keep_processing:
-                        dbg("key disallowed by validation")
-                        if not wxValidator_IsSilent() and orig_pos == pos:
-                            wxBell()
+##                        dbg("key disallowed by validation")
+                        if not wx.Validator_IsSilent() and orig_pos == pos:
+                            wx.Bell()
 
                 if keep_processing:
                     unadjusted = newstr
 
                 if keep_processing:
                     unadjusted = newstr
@@ -2741,12 +2823,12 @@ class wxMaskedEditMixin:
                     # special case: adjust date value as necessary:
                     if self._isDate and newstr != self._template:
                         newstr = self._adjustDate(newstr)
                     # special case: adjust date value as necessary:
                     if self._isDate and newstr != self._template:
                         newstr = self._adjustDate(newstr)
-                    dbg('adjusted newstr:', newstr)
+##                    dbg('adjusted newstr:', newstr)
 
                     if newstr != orig_value:
                         self.modified = True
 
 
                     if newstr != orig_value:
                         self.modified = True
 
-                    wxCallAfter(self._SetValue, newstr)
+                    wx.CallAfter(self._SetValue, newstr)
 
                     # Adjust insertion point on date if just entered 2 digit year, and there are now 4 digits:
                     if not self.IsDefault() and self._isDate and self._4digityear:
 
                     # Adjust insertion point on date if just entered 2 digit year, and there are now 4 digits:
                     if not self.IsDefault() and self._isDate and self._4digityear:
@@ -2754,27 +2836,27 @@ class wxMaskedEditMixin:
                         if pos == year2dig and unadjusted[year2dig] != newstr[year2dig]:
                             newpos = pos+2
 
                         if pos == year2dig and unadjusted[year2dig] != newstr[year2dig]:
                             newpos = pos+2
 
-                    wxCallAfter(self._SetInsertionPoint, newpos)
+                    wx.CallAfter(self._SetInsertionPoint, newpos)
 
                     if match_field is not None:
 
                     if match_field is not None:
-                        dbg('matched field')
+##                        dbg('matched field')
                         self._OnAutoSelect(match_field, match_index)
 
                     if new_select_to != newpos:
                         self._OnAutoSelect(match_field, match_index)
 
                     if new_select_to != newpos:
-                        dbg('queuing selection: (%d, %d)' % (newpos, new_select_to))
-                        wxCallAfter(self._SetSelection, newpos, new_select_to)
+##                        dbg('queuing selection: (%d, %d)' % (newpos, new_select_to))
+                        wx.CallAfter(self._SetSelection, newpos, new_select_to)
                     else:
                         newfield = self._FindField(newpos)
                         if newfield != field and newfield._selectOnFieldEntry:
                     else:
                         newfield = self._FindField(newpos)
                         if newfield != field and newfield._selectOnFieldEntry:
-                            dbg('queuing selection: (%d, %d)' % (newfield._extent[0], newfield._extent[1]))
-                            wxCallAfter(self._SetSelection, newfield._extent[0], newfield._extent[1])
+##                            dbg('queuing selection: (%d, %d)' % (newfield._extent[0], newfield._extent[1]))
+                            wx.CallAfter(self._SetSelection, newfield._extent[0], newfield._extent[1])
                     keep_processing = False
 
             elif keep_processing:
                     keep_processing = False
 
             elif keep_processing:
-                dbg('char not allowed')
+##                dbg('char not allowed')
                 keep_processing = False
                 keep_processing = False
-                if (not wxValidator_IsSilent()) and orig_pos == pos:
-                    wxBell()
+                if (not wx.Validator_IsSilent()) and orig_pos == pos:
+                    wx.Bell()
 
         self._applyFormatting()
 
 
         self._applyFormatting()
 
@@ -2783,12 +2865,12 @@ class wxMaskedEditMixin:
             pos = self._GetInsertionPoint()
             next_entry = self._findNextEntry( pos )
             if pos != next_entry:
             pos = self._GetInsertionPoint()
             next_entry = self._findNextEntry( pos )
             if pos != next_entry:
-                dbg("moving from %(pos)d to next valid entry: %(next_entry)d" % locals())
-                wxCallAfter(self._SetInsertionPoint, next_entry )
+##                dbg("moving from %(pos)d to next valid entry: %(next_entry)d" % locals())
+                wx.CallAfter(self._SetInsertionPoint, next_entry )
 
             if self._isTemplateChar(pos):
                 self._AdjustField(pos)
 
             if self._isTemplateChar(pos):
                 self._AdjustField(pos)
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _FindFieldExtent(self, pos=None, getslice=False, value=None):
 
 
     def _FindFieldExtent(self, pos=None, getslice=False, value=None):
@@ -2812,8 +2894,7 @@ class wxMaskedEditMixin:
         10, 14
         etc.
         """
         10, 14
         etc.
         """
-        dbg('wxMaskedEditMixin::_FindFieldExtent(pos=%s, getslice=%s)' % (
-                str(pos), str(getslice)) ,indent=1)
+##        dbg('MaskedEditMixin::_FindFieldExtent(pos=%s, getslice=%s)' % (str(pos), str(getslice)) ,indent=1)
 
         field = self._FindField(pos)
         if not field:
 
         field = self._FindField(pos)
         if not field:
@@ -2825,12 +2906,12 @@ class wxMaskedEditMixin:
         if getslice:
             if value is None: value = self._GetValue()
             slice = value[edit_start:edit_end]
         if getslice:
             if value is None: value = self._GetValue()
             slice = value[edit_start:edit_end]
-            dbg('edit_start:', edit_start, 'edit_end:', edit_end, 'slice: "%s"' % slice)
-            dbg(indent=0)
+##            dbg('edit_start:', edit_start, 'edit_end:', edit_end, 'slice: "%s"' % slice)
+##            dbg(indent=0)
             return edit_start, edit_end, slice
         else:
             return edit_start, edit_end, slice
         else:
-            dbg('edit_start:', edit_start, 'edit_end:', edit_end)
-            dbg(indent=0)
+##            dbg('edit_start:', edit_start, 'edit_end:', edit_end)
+##            dbg(indent=0)
             return edit_start, edit_end
 
 
             return edit_start, edit_end
 
 
@@ -2842,23 +2923,23 @@ class wxMaskedEditMixin:
         when calculating the current field.
 
         """
         when calculating the current field.
 
         """
-##        dbg('wxMaskedEditMixin::_FindField(pos=%s)' % str(pos) ,indent=1)
+####        dbg('MaskedEditMixin::_FindField(pos=%s)' % str(pos) ,indent=1)
         if pos is None: pos = self._GetInsertionPoint()
         elif pos < 0 or pos > self._masklength:
             raise IndexError('position %s out of range of control' % str(pos))
 
         if len(self._fields) == 0:
         if pos is None: pos = self._GetInsertionPoint()
         elif pos < 0 or pos > self._masklength:
             raise IndexError('position %s out of range of control' % str(pos))
 
         if len(self._fields) == 0:
-            dbg(indent=0)
+##            dbg(indent=0)
             return None
 
         # else...
             return None
 
         # else...
-##        dbg(indent=0)
+####        dbg(indent=0)
         return self._fields[self._lookupField[pos]]
 
 
     def ClearValue(self):
         """ Blanks the current control value by replacing it with the default value."""
         return self._fields[self._lookupField[pos]]
 
 
     def ClearValue(self):
         """ Blanks the current control value by replacing it with the default value."""
-        dbg("wxMaskedEditMixin::ClearValue - value reset to default value (template)")
+##        dbg("MaskedEditMixin::ClearValue - value reset to default value (template)")
         self._SetValue( self._template )
         self._SetInsertionPoint(0)
         self.Refresh()
         self._SetValue( self._template )
         self._SetInsertionPoint(0)
         self.Refresh()
@@ -2877,11 +2958,11 @@ class wxMaskedEditMixin:
         Makes up-arrow act like shift-tab should; ie. take you to start of
         previous field.
         """
         Makes up-arrow act like shift-tab should; ie. take you to start of
         previous field.
         """
-        dbg('wxMaskedEditMixin::_OnUpNumeric', indent=1)
+##        dbg('MaskedEditMixin::_OnUpNumeric', indent=1)
         event.m_shiftDown = 1
         event.m_shiftDown = 1
-        dbg('event.ShiftDown()?', event.ShiftDown())
+##        dbg('event.ShiftDown()?', event.ShiftDown())
         self._OnChangeField(event)
         self._OnChangeField(event)
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _OnArrow(self, event):
 
 
     def _OnArrow(self, event):
@@ -2889,30 +2970,30 @@ class wxMaskedEditMixin:
         Used in response to left/right navigation keys; makes these actions skip
         over mask template chars.
         """
         Used in response to left/right navigation keys; makes these actions skip
         over mask template chars.
         """
-        dbg("wxMaskedEditMixin::_OnArrow", indent=1)
+##        dbg("MaskedEditMixin::_OnArrow", indent=1)
         pos = self._GetInsertionPoint()
         keycode = event.GetKeyCode()
         sel_start, sel_to = self._GetSelection()
         entry_end = self._goEnd(getPosOnly=True)
         pos = self._GetInsertionPoint()
         keycode = event.GetKeyCode()
         sel_start, sel_to = self._GetSelection()
         entry_end = self._goEnd(getPosOnly=True)
-        if keycode in (WXK_RIGHT, WXK_DOWN):
+        if keycode in (wx.WXK_RIGHT, wx.WXK_DOWN):
             if( ( not self._isTemplateChar(pos) and pos+1 > entry_end)
                 or ( self._isTemplateChar(pos) and pos >= entry_end) ):
             if( ( not self._isTemplateChar(pos) and pos+1 > entry_end)
                 or ( self._isTemplateChar(pos) and pos >= entry_end) ):
-                dbg("can't advance", indent=0)
+##                dbg("can't advance", indent=0)
                 return False
             elif self._isTemplateChar(pos):
                 self._AdjustField(pos)
                 return False
             elif self._isTemplateChar(pos):
                 self._AdjustField(pos)
-        elif keycode in (WXK_LEFT,WXK_UP) and sel_start == sel_to and pos > 0 and self._isTemplateChar(pos-1):
-            dbg('adjusting field')
+        elif keycode in (wx.WXK_LEFT,wx.WXK_UP) and sel_start == sel_to and pos > 0 and self._isTemplateChar(pos-1):
+##            dbg('adjusting field')
             self._AdjustField(pos)
 
         # treat as shifted up/down arrows as tab/reverse tab:
             self._AdjustField(pos)
 
         # treat as shifted up/down arrows as tab/reverse tab:
-        if event.ShiftDown() and keycode in (WXK_UP, WXK_DOWN):
+        if event.ShiftDown() and keycode in (wx.WXK_UP, wx.WXK_DOWN):
             # remove "shifting" and treat as (forward) tab:
             event.m_shiftDown = False
             keep_processing = self._OnChangeField(event)
 
         elif self._FindField(pos)._selectOnFieldEntry:
             # remove "shifting" and treat as (forward) tab:
             event.m_shiftDown = False
             keep_processing = self._OnChangeField(event)
 
         elif self._FindField(pos)._selectOnFieldEntry:
-            if( keycode in (WXK_UP, WXK_LEFT)
+            if( keycode in (wx.WXK_UP, wx.WXK_LEFT)
                 and sel_start != 0
                 and self._isTemplateChar(sel_start-1)
                 and sel_start != self._masklength
                 and sel_start != 0
                 and self._isTemplateChar(sel_start-1)
                 and sel_start != self._masklength
@@ -2923,7 +3004,7 @@ class wxMaskedEditMixin:
                 event.m_shiftDown = True
                 event.m_ControlDown = True
                 keep_processing = self._OnChangeField(event)
                 event.m_shiftDown = True
                 event.m_ControlDown = True
                 keep_processing = self._OnChangeField(event)
-            elif( keycode in (WXK_DOWN, WXK_RIGHT)
+            elif( keycode in (wx.WXK_DOWN, wx.WXK_RIGHT)
                   and sel_to != self._masklength
                   and self._isTemplateChar(sel_to)):
 
                   and sel_to != self._masklength
                   and self._isTemplateChar(sel_to)):
 
@@ -2933,29 +3014,29 @@ class wxMaskedEditMixin:
             else:
                 # treat arrows as normal, allowing selection
                 # as appropriate:
             else:
                 # treat arrows as normal, allowing selection
                 # as appropriate:
-                dbg('using base ctrl event processing')
+##                dbg('using base ctrl event processing')
                 event.Skip()
         else:
                 event.Skip()
         else:
-            if( (sel_to == self._fields[0]._extent[0] and keycode == WXK_LEFT)
-                or (sel_to == self._masklength and keycode == WXK_RIGHT) ):
-                if not wxValidator_IsSilent():
-                    wxBell()
+            if( (sel_to == self._fields[0]._extent[0] and keycode == wx.WXK_LEFT)
+                or (sel_to == self._masklength and keycode == wx.WXK_RIGHT) ):
+                if not wx.Validator_IsSilent():
+                    wx.Bell()
             else:
                 # treat arrows as normal, allowing selection
                 # as appropriate:
             else:
                 # treat arrows as normal, allowing selection
                 # as appropriate:
-                dbg('using base event processing')
+##                dbg('using base event processing')
                 event.Skip()
 
         keep_processing = False
                 event.Skip()
 
         keep_processing = False
-        dbg(indent=0)
+##        dbg(indent=0)
         return keep_processing
 
 
     def _OnCtrl_S(self, event):
         """ Default Ctrl-S handler; prints value information if demo enabled. """
         return keep_processing
 
 
     def _OnCtrl_S(self, event):
         """ Default Ctrl-S handler; prints value information if demo enabled. """
-        dbg("wxMaskedEditMixin::_OnCtrl_S")
+##        dbg("MaskedEditMixin::_OnCtrl_S")
         if self._demo:
         if self._demo:
-            print 'wxMaskedEditMixin.GetValue()       = "%s"\nwxMaskedEditMixin.GetPlainValue() = "%s"' % (self.GetValue(), self.GetPlainValue())
+            print 'MaskedEditMixin.GetValue()       = "%s"\nMaskedEditMixin.GetPlainValue() = "%s"' % (self.GetValue(), self.GetPlainValue())
             print "Valid? => " + str(self.IsValid())
             print "Current field, start, end, value =", str( self._FindFieldExtent(getslice=True))
         return False
             print "Valid? => " + str(self.IsValid())
             print "Current field, start, end, value =", str( self._FindFieldExtent(getslice=True))
         return False
@@ -2964,9 +3045,9 @@ class wxMaskedEditMixin:
     def _OnCtrl_X(self, event=None):
         """ Handles ctrl-x keypress in control and Cut operation on context menu.
             Should return False to skip other processing. """
     def _OnCtrl_X(self, event=None):
         """ Handles ctrl-x keypress in control and Cut operation on context menu.
             Should return False to skip other processing. """
-        dbg("wxMaskedEditMixin::_OnCtrl_X", indent=1)
+##        dbg("MaskedEditMixin::_OnCtrl_X", indent=1)
         self.Cut()
         self.Cut()
-        dbg(indent=0)
+##        dbg(indent=0)
         return False
 
     def _OnCtrl_C(self, event=None):
         return False
 
     def _OnCtrl_C(self, event=None):
@@ -2978,38 +3059,38 @@ class wxMaskedEditMixin:
     def _OnCtrl_V(self, event=None):
         """ Handles ctrl-V keypress in control and Paste operation on context menu.
             Should return False to skip other processing. """
     def _OnCtrl_V(self, event=None):
         """ Handles ctrl-V keypress in control and Paste operation on context menu.
             Should return False to skip other processing. """
-        dbg("wxMaskedEditMixin::_OnCtrl_V", indent=1)
+##        dbg("MaskedEditMixin::_OnCtrl_V", indent=1)
         self.Paste()
         self.Paste()
-        dbg(indent=0)
+##        dbg(indent=0)
         return False
 
     def _OnCtrl_Z(self, event=None):
         """ Handles ctrl-Z keypress in control and Undo operation on context menu.
             Should return False to skip other processing. """
         return False
 
     def _OnCtrl_Z(self, event=None):
         """ Handles ctrl-Z keypress in control and Undo operation on context menu.
             Should return False to skip other processing. """
-        dbg("wxMaskedEditMixin::_OnCtrl_Z", indent=1)
+##        dbg("MaskedEditMixin::_OnCtrl_Z", indent=1)
         self.Undo()
         self.Undo()
-        dbg(indent=0)
+##        dbg(indent=0)
         return False
 
     def _OnCtrl_A(self,event=None):
         """ Handles ctrl-a keypress in control. Should return False to skip other processing. """
         end = self._goEnd(getPosOnly=True)
         if not event or event.ShiftDown():
         return False
 
     def _OnCtrl_A(self,event=None):
         """ Handles ctrl-a keypress in control. Should return False to skip other processing. """
         end = self._goEnd(getPosOnly=True)
         if not event or event.ShiftDown():
-            wxCallAfter(self._SetInsertionPoint, 0)
-            wxCallAfter(self._SetSelection, 0, self._masklength)
+            wx.CallAfter(self._SetInsertionPoint, 0)
+            wx.CallAfter(self._SetSelection, 0, self._masklength)
         else:
         else:
-            wxCallAfter(self._SetInsertionPoint, 0)
-            wxCallAfter(self._SetSelection, 0, end)
+            wx.CallAfter(self._SetInsertionPoint, 0)
+            wx.CallAfter(self._SetSelection, 0, end)
         return False
 
 
     def _OnErase(self, event=None):
         """ Handles backspace and delete keypress in control. Should return False to skip other processing."""
         return False
 
 
     def _OnErase(self, event=None):
         """ Handles backspace and delete keypress in control. Should return False to skip other processing."""
-        dbg("wxMaskedEditMixin::_OnErase", indent=1)
+##        dbg("MaskedEditMixin::_OnErase", indent=1)
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
 
         if event is None:   # called as action routine from Cut() operation.
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
 
         if event is None:   # called as action routine from Cut() operation.
-            key = WXK_DELETE
+            key = wx.WXK_DELETE
         else:
             key = event.GetKeyCode()
 
         else:
             key = event.GetKeyCode()
 
@@ -3019,16 +3100,16 @@ class wxMaskedEditMixin:
         oldstart = sel_start
 
         # If trying to erase beyond "legal" bounds, disallow operation:
         oldstart = sel_start
 
         # If trying to erase beyond "legal" bounds, disallow operation:
-        if( (sel_to == 0 and key == WXK_BACK)
-            or (self._signOk and sel_to == 1 and value[0] == ' ' and key == WXK_BACK)
-            or (sel_to == self._masklength and sel_start == sel_to and key == WXK_DELETE and not field._insertRight)
+        if( (sel_to == 0 and key == wx.WXK_BACK)
+            or (self._signOk and sel_to == 1 and value[0] == ' ' and key == wx.WXK_BACK)
+            or (sel_to == self._masklength and sel_start == sel_to and key == wx.WXK_DELETE and not field._insertRight)
             or (self._signOk and self._useParens
                 and sel_start == sel_to
                 and sel_to == self._masklength - 1
             or (self._signOk and self._useParens
                 and sel_start == sel_to
                 and sel_to == self._masklength - 1
-                and value[sel_to] == ' ' and key == WXK_DELETE and not field._insertRight) ):
-            if not wxValidator_IsSilent():
-                wxBell()
-            dbg(indent=0)
+                and value[sel_to] == ' ' and key == wx.WXK_DELETE and not field._insertRight) ):
+            if not wx.Validator_IsSilent():
+                wx.Bell()
+##            dbg(indent=0)
             return False
 
 
             return False
 
 
@@ -3037,22 +3118,22 @@ class wxMaskedEditMixin:
             and sel_start >= start                              # and selection starts in field
             and ((sel_to == sel_start                           # and no selection
                   and sel_to == end                             # and cursor at right edge
             and sel_start >= start                              # and selection starts in field
             and ((sel_to == sel_start                           # and no selection
                   and sel_to == end                             # and cursor at right edge
-                  and key in (WXK_BACK, WXK_DELETE))            # and either delete or backspace key
+                  and key in (wx.WXK_BACK, wx.WXK_DELETE))            # and either delete or backspace key
                  or                                             # or
                  or                                             # or
-                 (key == WXK_BACK                               # backspacing
+                 (key == wx.WXK_BACK                               # backspacing
                     and (sel_to == end                          # and selection ends at right edge
                          or sel_to < end and field._allowInsert)) ) ):  # or allow right insert at any point in field
 
                     and (sel_to == end                          # and selection ends at right edge
                          or sel_to < end and field._allowInsert)) ) ):  # or allow right insert at any point in field
 
-            dbg('delete left')
+##            dbg('delete left')
             # if backspace but left of cursor is empty, adjust cursor right before deleting
             # if backspace but left of cursor is empty, adjust cursor right before deleting
-            while( key == WXK_BACK
+            while( key == wx.WXK_BACK
                    and sel_start == sel_to
                    and sel_start < end
                    and value[start:sel_start] == self._template[start:sel_start]):
                 sel_start += 1
                 sel_to = sel_start
 
                    and sel_start == sel_to
                    and sel_start < end
                    and value[start:sel_start] == self._template[start:sel_start]):
                 sel_start += 1
                 sel_to = sel_start
 
-            dbg('sel_start, start:', sel_start, start)
+##            dbg('sel_start, start:', sel_start, start)
 
             if sel_start == sel_to:
                 keep = sel_start -1
 
             if sel_start == sel_to:
                 keep = sel_start -1
@@ -3066,7 +3147,7 @@ class wxMaskedEditMixin:
                 signchar = value[0]
                 newfield = signchar + newfield
                 move_sign_into_field = True
                 signchar = value[0]
                 newfield = signchar + newfield
                 move_sign_into_field = True
-            dbg('cut newfield: "%s"' % newfield)
+##            dbg('cut newfield: "%s"' % newfield)
 
             # handle what should fill in from the left:
             left = ""
 
             # handle what should fill in from the left:
             left = ""
@@ -3080,7 +3161,7 @@ class wxMaskedEditMixin:
                 else:
                     left += self._template[i]   # this can produce strange results in combination with default values...
             newfield = left + newfield
                 else:
                     left += self._template[i]   # this can produce strange results in combination with default values...
             newfield = left + newfield
-            dbg('filled newfield: "%s"' % newfield)
+##            dbg('filled newfield: "%s"' % newfield)
 
             newstr = value[:start] + newfield + value[end:]
 
 
             newstr = value[:start] + newfield + value[end:]
 
@@ -3098,7 +3179,7 @@ class wxMaskedEditMixin:
                 # selection (if any) falls within current insert-capable field:
                 select_len = sel_to - sel_start
                 # determine where cursor should end up:
                 # selection (if any) falls within current insert-capable field:
                 select_len = sel_to - sel_start
                 # determine where cursor should end up:
-                if key == WXK_BACK:
+                if key == wx.WXK_BACK:
                     if select_len == 0:
                         newpos = sel_start -1
                     else:
                     if select_len == 0:
                         newpos = sel_start -1
                     else:
@@ -3130,7 +3211,7 @@ class wxMaskedEditMixin:
                     erase_len = erase_to - newpos
 
                     left = value[start:newpos]
                     erase_len = erase_to - newpos
 
                     left = value[start:newpos]
-                    dbg("retained ='%s'" % value[erase_to:end], 'sel_to:', sel_to, "fill: '%s'" % self._template[end - erase_len:end])
+##                    dbg("retained ='%s'" % value[erase_to:end], 'sel_to:', sel_to, "fill: '%s'" % self._template[end - erase_len:end])
                     right = value[erase_to:end] + self._template[end-erase_len:end]
                     pos_adjust = 0
                     if field._alignRight:
                     right = value[erase_to:end] + self._template[end-erase_len:end]
                     pos_adjust = 0
                     if field._alignRight:
@@ -3148,24 +3229,24 @@ class wxMaskedEditMixin:
                     if pos_adjust:
                         newfield = newfield.rjust(end-start)
                         newpos += pos_adjust
                     if pos_adjust:
                         newfield = newfield.rjust(end-start)
                         newpos += pos_adjust
-                    dbg("left='%s', right ='%s', newfield='%s'" %(left, right, newfield))
+##                    dbg("left='%s', right ='%s', newfield='%s'" %(left, right, newfield))
                     newstr = value[:start] + newfield + value[end:]
 
                 pos = newpos
 
             else:
                 if sel_start == sel_to:
                     newstr = value[:start] + newfield + value[end:]
 
                 pos = newpos
 
             else:
                 if sel_start == sel_to:
-                    dbg("current sel_start, sel_to:", sel_start, sel_to)
-                    if key == WXK_BACK:
+##                    dbg("current sel_start, sel_to:", sel_start, sel_to)
+                    if key == wx.WXK_BACK:
                         sel_start, sel_to = sel_to-1, sel_to-1
                         sel_start, sel_to = sel_to-1, sel_to-1
-                        dbg("new sel_start, sel_to:", sel_start, sel_to)
+##                        dbg("new sel_start, sel_to:", sel_start, sel_to)
 
                     if field._padZero and not value[start:sel_to].replace('0', '').replace(' ','').replace(field._fillChar, ''):
                         # preceding chars (if any) are zeros, blanks or fillchar; new char should be 0:
                         newchar = '0'
                     else:
                         newchar = self._template[sel_to] ## get an original template character to "clear" the current char
 
                     if field._padZero and not value[start:sel_to].replace('0', '').replace(' ','').replace(field._fillChar, ''):
                         # preceding chars (if any) are zeros, blanks or fillchar; new char should be 0:
                         newchar = '0'
                     else:
                         newchar = self._template[sel_to] ## get an original template character to "clear" the current char
-                    dbg('value = "%s"' % value, 'value[%d] = "%s"' %(sel_start, value[sel_start]))
+##                    dbg('value = "%s"' % value, 'value[%d] = "%s"' %(sel_start, value[sel_start]))
 
                     if self._isTemplateChar(sel_to):
                         if sel_to == 0 and self._signOk and value[sel_to] == '-':   # erasing "template" sign char
 
                     if self._isTemplateChar(sel_to):
                         if sel_to == 0 and self._signOk and value[sel_to] == '-':   # erasing "template" sign char
@@ -3202,36 +3283,38 @@ class wxMaskedEditMixin:
                 # erased right-sign marker; get rid of left-sign marker:
                 newstr = newstr[:left_signpos] + ' ' + newstr[left_signpos+1:]
 
                 # erased right-sign marker; get rid of left-sign marker:
                 newstr = newstr[:left_signpos] + ' ' + newstr[left_signpos+1:]
 
-        dbg("oldstr:'%s'" % value, 'oldpos:', oldstart)
-        dbg("newstr:'%s'" % newstr, 'pos:', pos)
+##        dbg("oldstr:'%s'" % value, 'oldpos:', oldstart)
+##        dbg("newstr:'%s'" % newstr, 'pos:', pos)
 
         # if erasure results in an invalid field, disallow it:
 
         # if erasure results in an invalid field, disallow it:
-        dbg('field._validRequired?', field._validRequired)
-        dbg('field.IsValid("%s")?' % newstr[start:end], field.IsValid(newstr[start:end]))
+##        dbg('field._validRequired?', field._validRequired)
+##        dbg('field.IsValid("%s")?' % newstr[start:end], field.IsValid(newstr[start:end]))
         if field._validRequired and not field.IsValid(newstr[start:end]):
         if field._validRequired and not field.IsValid(newstr[start:end]):
-            if not wxValidator_IsSilent():
-                wxBell()
-            dbg(indent=0)
+            if not wx.Validator_IsSilent():
+                wx.Bell()
+##            dbg(indent=0)
             return False
 
         # if erasure results in an invalid value, disallow it:
         if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
             return False
 
         # if erasure results in an invalid value, disallow it:
         if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
-            if not wxValidator_IsSilent():
-                wxBell()
-            dbg(indent=0)
+            if not wx.Validator_IsSilent():
+                wx.Bell()
+##            dbg(indent=0)
             return False
 
             return False
 
-        dbg('setting value (later) to', newstr)
-        wxCallAfter(self._SetValue, newstr)
-        dbg('setting insertion point (later) to', pos)
-        wxCallAfter(self._SetInsertionPoint, pos)
-        dbg(indent=0)
+##        dbg('setting value (later) to', newstr)
+        wx.CallAfter(self._SetValue, newstr)
+##        dbg('setting insertion point (later) to', pos)
+        wx.CallAfter(self._SetInsertionPoint, pos)
+##        dbg(indent=0)
+        if newstr != value:
+            self.modified = True
         return False
 
 
     def _OnEnd(self,event):
         """ Handles End keypress in control. Should return False to skip other processing. """
         return False
 
 
     def _OnEnd(self,event):
         """ Handles End keypress in control. Should return False to skip other processing. """
-        dbg("wxMaskedEditMixin::_OnEnd", indent=1)
+##        dbg("MaskedEditMixin::_OnEnd", indent=1)
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         if not event.ControlDown():
             end = self._masklength  # go to end of control
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         if not event.ControlDown():
             end = self._masklength  # go to end of control
@@ -3248,48 +3331,51 @@ class wxMaskedEditMixin:
             # - cursor not in same field
             # - or at or past last input already
             # - or current selection = end of current field:
             # - cursor not in same field
             # - or at or past last input already
             # - or current selection = end of current field:
-##            dbg('field != field_end?', field != field_end)
-##            dbg('sel_to >= end_of_input?', sel_to >= end_of_input)
+####            dbg('field != field_end?', field != field_end)
+####            dbg('sel_to >= end_of_input?', sel_to >= end_of_input)
             if field != field_end or sel_to >= end_of_input:
                 edit_start, edit_end = field._extent
             if field != field_end or sel_to >= end_of_input:
                 edit_start, edit_end = field._extent
-##                dbg('edit_end:', edit_end)
-##                dbg('sel_to:', sel_to)
-##                dbg('sel_to == edit_end?', sel_to == edit_end)
-##                dbg('field._index < self._field_indices[-1]?', field._index < self._field_indices[-1])
+####                dbg('edit_end:', edit_end)
+####                dbg('sel_to:', sel_to)
+####                dbg('sel_to == edit_end?', sel_to == edit_end)
+####                dbg('field._index < self._field_indices[-1]?', field._index < self._field_indices[-1])
 
                 if sel_to == edit_end and field._index < self._field_indices[-1]:
                     edit_start, edit_end = self._FindFieldExtent(self._findNextEntry(edit_end))  # go to end of next field:
                     end = edit_end
 
                 if sel_to == edit_end and field._index < self._field_indices[-1]:
                     edit_start, edit_end = self._FindFieldExtent(self._findNextEntry(edit_end))  # go to end of next field:
                     end = edit_end
-                    dbg('end moved to', end)
+##                    dbg('end moved to', end)
 
                 elif sel_to == edit_end and field._index == self._field_indices[-1]:
                     # already at edit end of last field; select to end of control:
                     end = self._masklength
 
                 elif sel_to == edit_end and field._index == self._field_indices[-1]:
                     # already at edit end of last field; select to end of control:
                     end = self._masklength
-                    dbg('end moved to', end)
+##                    dbg('end moved to', end)
                 else:
                     end = edit_end  # select to end of current field
                 else:
                     end = edit_end  # select to end of current field
-                    dbg('end moved to ', end)
+##                    dbg('end moved to ', end)
             else:
                 # select to current end of input
                 end = end_of_input
 
 
             else:
                 # select to current end of input
                 end = end_of_input
 
 
-##        dbg('pos:', pos, 'end:', end)
+####        dbg('pos:', pos, 'end:', end)
 
         if event.ShiftDown():
             if not event.ControlDown():
 
         if event.ShiftDown():
             if not event.ControlDown():
-                dbg("shift-end; select to end of control")
+##                dbg("shift-end; select to end of control")
+                pass
             else:
             else:
-                dbg("shift-ctrl-end; select to end of non-whitespace")
-            wxCallAfter(self._SetInsertionPoint, pos)
-            wxCallAfter(self._SetSelection, pos, end)
+##                dbg("shift-ctrl-end; select to end of non-whitespace")
+                pass                
+            wx.CallAfter(self._SetInsertionPoint, pos)
+            wx.CallAfter(self._SetSelection, pos, end)
         else:
             if not event.ControlDown():
         else:
             if not event.ControlDown():
-                dbg('go to end of control:')
-            wxCallAfter(self._SetInsertionPoint, end)
-            wxCallAfter(self._SetSelection, end, end)
+##                dbg('go to end of control:')
+                pass
+            wx.CallAfter(self._SetInsertionPoint, end)
+            wx.CallAfter(self._SetSelection, end, end)
 
 
-        dbg(indent=0)
+##        dbg(indent=0)
         return False
 
 
         return False
 
 
@@ -3298,14 +3384,14 @@ class wxMaskedEditMixin:
          Changes the event to look like a tab event, so we can then call
          event.Skip() on it, and have the parent form "do the right thing."
          """
          Changes the event to look like a tab event, so we can then call
          event.Skip() on it, and have the parent form "do the right thing."
          """
-         dbg('wxMaskedEditMixin::OnReturn')
-         event.m_keyCode = WXK_TAB
+##         dbg('MaskedEditMixin::OnReturn')
+         event.m_keyCode = wx.WXK_TAB
          event.Skip()
 
 
     def _OnHome(self,event):
         """ Handles Home keypress in control. Should return False to skip other processing."""
          event.Skip()
 
 
     def _OnHome(self,event):
         """ Handles Home keypress in control. Should return False to skip other processing."""
-        dbg("wxMaskedEditMixin::_OnHome", indent=1)
+##        dbg("MaskedEditMixin::_OnHome", indent=1)
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         sel_start, sel_to = self._GetSelection()
 
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         sel_start, sel_to = self._GetSelection()
 
@@ -3314,13 +3400,13 @@ class wxMaskedEditMixin:
         # 1) shift: select from start of control to end of current
         #    selection.
         if event.ShiftDown() and not event.ControlDown():
         # 1) shift: select from start of control to end of current
         #    selection.
         if event.ShiftDown() and not event.ControlDown():
-            dbg("shift-home; select to start of control")
+##            dbg("shift-home; select to start of control")
             start = 0
             end = sel_start
 
         # 2) no shift, no control: move cursor to beginning of control.
         elif not event.ControlDown():
             start = 0
             end = sel_start
 
         # 2) no shift, no control: move cursor to beginning of control.
         elif not event.ControlDown():
-            dbg("home; move to start of control")
+##            dbg("home; move to start of control")
             start = 0
             end = 0
 
             start = 0
             end = 0
 
@@ -3346,10 +3432,10 @@ class wxMaskedEditMixin:
                 start = 0
 
             if not event.ShiftDown():
                 start = 0
 
             if not event.ShiftDown():
-                dbg("ctrl-home; move to beginning of field")
+##                dbg("ctrl-home; move to beginning of field")
                 end = start
             else:
                 end = start
             else:
-                dbg("shift-ctrl-home; select to beginning of field")
+##                dbg("shift-ctrl-home; select to beginning of field")
                 end = sel_to
 
         else:
                 end = sel_to
 
         else:
@@ -3368,12 +3454,12 @@ class wxMaskedEditMixin:
             else:
                 end = start
                 end_of_field = False
             else:
                 end = start
                 end_of_field = False
-            dbg("shift-ctrl-home; unselect to beginning of field")
+##            dbg("shift-ctrl-home; unselect to beginning of field")
 
 
-        dbg('queuing new sel_start, sel_to:', (start, end))
-        wxCallAfter(self._SetInsertionPoint, start)
-        wxCallAfter(self._SetSelection, start, end)
-        dbg(indent=0)
+##        dbg('queuing new sel_start, sel_to:', (start, end))
+        wx.CallAfter(self._SetInsertionPoint, start)
+        wx.CallAfter(self._SetSelection, start, end)
+##        dbg(indent=0)
         return False
 
 
         return False
 
 
@@ -3385,19 +3471,19 @@ class wxMaskedEditMixin:
         control-shift-TAB, these events are not sent to the controls
         by the framework.
         """
         control-shift-TAB, these events are not sent to the controls
         by the framework.
         """
-        dbg('wxMaskedEditMixin::_OnChangeField', indent = 1)
+##        dbg('MaskedEditMixin::_OnChangeField', indent = 1)
         # determine end of current field:
         pos = self._GetInsertionPoint()
         # determine end of current field:
         pos = self._GetInsertionPoint()
-        dbg('current pos:', pos)
+##        dbg('current pos:', pos)
         sel_start, sel_to = self._GetSelection()
 
         if self._masklength < 0:   # no fields; process tab normally
             self._AdjustField(pos)
         sel_start, sel_to = self._GetSelection()
 
         if self._masklength < 0:   # no fields; process tab normally
             self._AdjustField(pos)
-            if event.GetKeyCode() == WXK_TAB:
-                dbg('tab to next ctrl')
+            if event.GetKeyCode() == wx.WXK_TAB:
+##                dbg('tab to next ctrl')
                 event.Skip()
             #else: do nothing
                 event.Skip()
             #else: do nothing
-            dbg(indent=0)
+##            dbg(indent=0)
             return False
 
 
             return False
 
 
@@ -3407,46 +3493,46 @@ class wxMaskedEditMixin:
 
             # NOTE: doesn't yet work with SHIFT-tab under wx; the control
             # never sees this event! (But I've coded for it should it ever work,
 
             # NOTE: doesn't yet work with SHIFT-tab under wx; the control
             # never sees this event! (But I've coded for it should it ever work,
-            # and it *does* work for '.' in wxIpAddrCtrl.)
+            # and it *does* work for '.' in IpAddrCtrl.)
             field = self._FindField(pos)
             index = field._index
             field_start = field._extent[0]
             if pos < field_start:
             field = self._FindField(pos)
             index = field._index
             field_start = field._extent[0]
             if pos < field_start:
-                dbg('cursor before 1st field; cannot change to a previous field')
-                if not wxValidator_IsSilent():
-                    wxBell()
+##                dbg('cursor before 1st field; cannot change to a previous field')
+                if not wx.Validator_IsSilent():
+                    wx.Bell()
                 return False
 
             if event.ControlDown():
                 return False
 
             if event.ControlDown():
-                dbg('queuing select to beginning of field:', field_start, pos)
-                wxCallAfter(self._SetInsertionPoint, field_start)
-                wxCallAfter(self._SetSelection, field_start, pos)
-                dbg(indent=0)
+##                dbg('queuing select to beginning of field:', field_start, pos)
+                wx.CallAfter(self._SetInsertionPoint, field_start)
+                wx.CallAfter(self._SetSelection, field_start, pos)
+##                dbg(indent=0)
                 return False
 
             elif index == 0:
                   # We're already in the 1st field; process shift-tab normally:
                 self._AdjustField(pos)
                 return False
 
             elif index == 0:
                   # We're already in the 1st field; process shift-tab normally:
                 self._AdjustField(pos)
-                if event.GetKeyCode() == WXK_TAB:
-                    dbg('tab to previous ctrl')
+                if event.GetKeyCode() == wx.WXK_TAB:
+##                    dbg('tab to previous ctrl')
                     event.Skip()
                 else:
                     event.Skip()
                 else:
-                    dbg('position at beginning')
-                    wxCallAfter(self._SetInsertionPoint, field_start)
-                dbg(indent=0)
+##                    dbg('position at beginning')
+                    wx.CallAfter(self._SetInsertionPoint, field_start)
+##                dbg(indent=0)
                 return False
             else:
                 # find beginning of previous field:
                 begin_prev = self._FindField(field_start-1)._extent[0]
                 self._AdjustField(pos)
                 return False
             else:
                 # find beginning of previous field:
                 begin_prev = self._FindField(field_start-1)._extent[0]
                 self._AdjustField(pos)
-                dbg('repositioning to', begin_prev)
-                wxCallAfter(self._SetInsertionPoint, begin_prev)
+##                dbg('repositioning to', begin_prev)
+                wx.CallAfter(self._SetInsertionPoint, begin_prev)
                 if self._FindField(begin_prev)._selectOnFieldEntry:
                     edit_start, edit_end = self._FindFieldExtent(begin_prev)
                 if self._FindField(begin_prev)._selectOnFieldEntry:
                     edit_start, edit_end = self._FindFieldExtent(begin_prev)
-                    dbg('queuing selection to (%d, %d)' % (edit_start, edit_end))
-                    wxCallAfter(self._SetInsertionPoint, edit_start)
-                    wxCallAfter(self._SetSelection, edit_start, edit_end)
-                dbg(indent=0)
+##                    dbg('queuing selection to (%d, %d)' % (edit_start, edit_end))
+                    wx.CallAfter(self._SetInsertionPoint, edit_start)
+                    wx.CallAfter(self._SetSelection, edit_start, edit_end)
+##                dbg(indent=0)
                 return False
 
         else:
                 return False
 
         else:
@@ -3454,44 +3540,44 @@ class wxMaskedEditMixin:
             field = self._FindField(sel_to)
             field_start, field_end = field._extent
             if event.ControlDown():
             field = self._FindField(sel_to)
             field_start, field_end = field._extent
             if event.ControlDown():
-                dbg('queuing select to end of field:', pos, field_end)
-                wxCallAfter(self._SetInsertionPoint, pos)
-                wxCallAfter(self._SetSelection, pos, field_end)
-                dbg(indent=0)
+##                dbg('queuing select to end of field:', pos, field_end)
+                wx.CallAfter(self._SetInsertionPoint, pos)
+                wx.CallAfter(self._SetSelection, pos, field_end)
+##                dbg(indent=0)
                 return False
             else:
                 if pos < field_start:
                 return False
             else:
                 if pos < field_start:
-                    dbg('cursor before 1st field; go to start of field')
-                    wxCallAfter(self._SetInsertionPoint, field_start)
+##                    dbg('cursor before 1st field; go to start of field')
+                    wx.CallAfter(self._SetInsertionPoint, field_start)
                     if field._selectOnFieldEntry:
                     if field._selectOnFieldEntry:
-                        wxCallAfter(self._SetSelection, field_start, field_end)
+                        wx.CallAfter(self._SetSelection, field_start, field_end)
                     else:
                     else:
-                        wxCallAfter(self._SetSelection, field_start, field_start)
+                        wx.CallAfter(self._SetSelection, field_start, field_start)
                     return False
                 # else...
                     return False
                 # else...
-                dbg('end of current field:', field_end)
-                dbg('go to next field')
+##                dbg('end of current field:', field_end)
+##                dbg('go to next field')
                 if field_end == self._fields[self._field_indices[-1]]._extent[1]:
                     self._AdjustField(pos)
                 if field_end == self._fields[self._field_indices[-1]]._extent[1]:
                     self._AdjustField(pos)
-                    if event.GetKeyCode() == WXK_TAB:
-                        dbg('tab to next ctrl')
+                    if event.GetKeyCode() == wx.WXK_TAB:
+##                        dbg('tab to next ctrl')
                         event.Skip()
                     else:
                         event.Skip()
                     else:
-                        dbg('position at end')
-                        wxCallAfter(self._SetInsertionPoint, field_end)
-                    dbg(indent=0)
+##                        dbg('position at end')
+                        wx.CallAfter(self._SetInsertionPoint, field_end)
+##                    dbg(indent=0)
                     return False
                 else:
                     # we have to find the start of the next field
                     next_pos = self._findNextEntry(field_end)
                     if next_pos == field_end:
                     return False
                 else:
                     # we have to find the start of the next field
                     next_pos = self._findNextEntry(field_end)
                     if next_pos == field_end:
-                        dbg('already in last field')
+##                        dbg('already in last field')
                         self._AdjustField(pos)
                         self._AdjustField(pos)
-                        if event.GetKeyCode() == WXK_TAB:
-                            dbg('tab to next ctrl')
+                        if event.GetKeyCode() == wx.WXK_TAB:
+##                            dbg('tab to next ctrl')
                             event.Skip()
                         #else: do nothing
                             event.Skip()
                         #else: do nothing
-                        dbg(indent=0)
+##                        dbg(indent=0)
                         return False
                     else:
                         self._AdjustField( pos )
                         return False
                     else:
                         self._AdjustField( pos )
@@ -3500,79 +3586,79 @@ class wxMaskedEditMixin:
                         field = self._FindField(next_pos)
                         edit_start, edit_end = field._extent
                         if field._selectOnFieldEntry:
                         field = self._FindField(next_pos)
                         edit_start, edit_end = field._extent
                         if field._selectOnFieldEntry:
-                            dbg('move to ', next_pos)
-                            wxCallAfter(self._SetInsertionPoint, next_pos)
+##                            dbg('move to ', next_pos)
+                            wx.CallAfter(self._SetInsertionPoint, next_pos)
                             edit_start, edit_end = self._FindFieldExtent(next_pos)
                             edit_start, edit_end = self._FindFieldExtent(next_pos)
-                            dbg('queuing select', edit_start, edit_end)
-                            wxCallAfter(self._SetSelection, edit_start, edit_end)
+##                            dbg('queuing select', edit_start, edit_end)
+                            wx.CallAfter(self._SetSelection, edit_start, edit_end)
                         else:
                             if field._insertRight:
                                 next_pos = field._extent[1]
                         else:
                             if field._insertRight:
                                 next_pos = field._extent[1]
-                            dbg('move to ', next_pos)
-                            wxCallAfter(self._SetInsertionPoint, next_pos)
-                        dbg(indent=0)
+##                            dbg('move to ', next_pos)
+                            wx.CallAfter(self._SetInsertionPoint, next_pos)
+##                        dbg(indent=0)
                         return False
 
 
     def _OnDecimalPoint(self, event):
                         return False
 
 
     def _OnDecimalPoint(self, event):
-        dbg('wxMaskedEditMixin::_OnDecimalPoint', indent=1)
+##        dbg('MaskedEditMixin::_OnDecimalPoint', indent=1)
 
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
 
         if self._isFloat:       ## handle float value, move to decimal place
 
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
 
         if self._isFloat:       ## handle float value, move to decimal place
-            dbg('key == Decimal tab; decimal pos:', self._decimalpos)
+##            dbg('key == Decimal tab; decimal pos:', self._decimalpos)
             value = self._GetValue()
             if pos < self._decimalpos:
                 clipped_text = value[0:pos] + self._decimalChar + value[self._decimalpos+1:]
             value = self._GetValue()
             if pos < self._decimalpos:
                 clipped_text = value[0:pos] + self._decimalChar + value[self._decimalpos+1:]
-                dbg('value: "%s"' % self._GetValue(), "clipped_text:'%s'" % clipped_text)
+##                dbg('value: "%s"' % self._GetValue(), "clipped_text:'%s'" % clipped_text)
                 newstr = self._adjustFloat(clipped_text)
             else:
                 newstr = self._adjustFloat(value)
                 newstr = self._adjustFloat(clipped_text)
             else:
                 newstr = self._adjustFloat(value)
-            wxCallAfter(self._SetValue, newstr)
+            wx.CallAfter(self._SetValue, newstr)
             fraction = self._fields[1]
             start, end = fraction._extent
             fraction = self._fields[1]
             start, end = fraction._extent
-            wxCallAfter(self._SetInsertionPoint, start)
+            wx.CallAfter(self._SetInsertionPoint, start)
             if fraction._selectOnFieldEntry:
             if fraction._selectOnFieldEntry:
-                dbg('queuing selection after decimal point to:', (start, end))
-                wxCallAfter(self._SetSelection, start, end)
+##                dbg('queuing selection after decimal point to:', (start, end))
+                wx.CallAfter(self._SetSelection, start, end)
             keep_processing = False
 
         if self._isInt:      ## handle integer value, truncate from current position
             keep_processing = False
 
         if self._isInt:      ## handle integer value, truncate from current position
-            dbg('key == Integer decimal event')
+##            dbg('key == Integer decimal event')
             value = self._GetValue()
             clipped_text = value[0:pos]
             value = self._GetValue()
             clipped_text = value[0:pos]
-            dbg('value: "%s"' % self._GetValue(), "clipped_text:'%s'" % clipped_text)
+##            dbg('value: "%s"' % self._GetValue(), "clipped_text:'%s'" % clipped_text)
             newstr = self._adjustInt(clipped_text)
             newstr = self._adjustInt(clipped_text)
-            dbg('newstr: "%s"' % newstr)
-            wxCallAfter(self._SetValue, newstr)
+##            dbg('newstr: "%s"' % newstr)
+            wx.CallAfter(self._SetValue, newstr)
             newpos = len(newstr.rstrip())
             if newstr.find(')') != -1:
                 newpos -= 1     # (don't move past right paren)
             newpos = len(newstr.rstrip())
             if newstr.find(')') != -1:
                 newpos -= 1     # (don't move past right paren)
-            wxCallAfter(self._SetInsertionPoint, newpos)
+            wx.CallAfter(self._SetInsertionPoint, newpos)
             keep_processing = False
             keep_processing = False
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _OnChangeSign(self, event):
 
 
     def _OnChangeSign(self, event):
-        dbg('wxMaskedEditMixin::_OnChangeSign', indent=1)
+##        dbg('MaskedEditMixin::_OnChangeSign', indent=1)
         key = event.GetKeyCode()
         pos = self._adjustPos(self._GetInsertionPoint(), key)
         value = self._eraseSelection()
         integer = self._fields[0]
         start, end = integer._extent
 
         key = event.GetKeyCode()
         pos = self._adjustPos(self._GetInsertionPoint(), key)
         value = self._eraseSelection()
         integer = self._fields[0]
         start, end = integer._extent
 
-##        dbg('adjusted pos:', pos)
+####        dbg('adjusted pos:', pos)
         if chr(key) in ('-','+','(', ')') or (chr(key) == " " and pos == self._signpos):
             cursign = self._isNeg
         if chr(key) in ('-','+','(', ')') or (chr(key) == " " and pos == self._signpos):
             cursign = self._isNeg
-            dbg('cursign:', cursign)
+##            dbg('cursign:', cursign)
             if chr(key) in ('-','(', ')'):
                 self._isNeg = (not self._isNeg)   ## flip value
             else:
                 self._isNeg = False
             if chr(key) in ('-','(', ')'):
                 self._isNeg = (not self._isNeg)   ## flip value
             else:
                 self._isNeg = False
-            dbg('isNeg?', self._isNeg)
+##            dbg('isNeg?', self._isNeg)
 
             text, self._signpos, self._right_signpos = self._getSignedValue(candidate=value)
 
             text, self._signpos, self._right_signpos = self._getSignedValue(candidate=value)
-            dbg('text:"%s"' % text, 'signpos:', self._signpos, 'right_signpos:', self._right_signpos)
+##            dbg('text:"%s"' % text, 'signpos:', self._signpos, 'right_signpos:', self._right_signpos)
             if text is None:
                 text = value
 
             if text is None:
                 text = value
 
@@ -3582,26 +3668,26 @@ class wxMaskedEditMixin:
                 else:
                     text = text[:self._signpos] + '-' + text[self._signpos+1:]
             else:
                 else:
                     text = text[:self._signpos] + '-' + text[self._signpos+1:]
             else:
-##                dbg('self._isNeg?', self._isNeg, 'self.IsValid(%s)' % text, self.IsValid(text))
+####                dbg('self._isNeg?', self._isNeg, 'self.IsValid(%s)' % text, self.IsValid(text))
                 if self._useParens:
                     text = text[:self._signpos] + ' ' + text[self._signpos+1:self._right_signpos] + ' ' + text[self._right_signpos+1:]
                 else:
                     text = text[:self._signpos] + ' ' + text[self._signpos+1:]
                 if self._useParens:
                     text = text[:self._signpos] + ' ' + text[self._signpos+1:self._right_signpos] + ' ' + text[self._right_signpos+1:]
                 else:
                     text = text[:self._signpos] + ' ' + text[self._signpos+1:]
-                dbg('clearing self._isNeg')
+##                dbg('clearing self._isNeg')
                 self._isNeg = False
 
                 self._isNeg = False
 
-            wxCallAfter(self._SetValue, text)
-            wxCallAfter(self._applyFormatting)
-            dbg('pos:', pos, 'signpos:', self._signpos)
+            wx.CallAfter(self._SetValue, text)
+            wx.CallAfter(self._applyFormatting)
+##            dbg('pos:', pos, 'signpos:', self._signpos)
             if pos == self._signpos or integer.IsEmpty(text[start:end]):
             if pos == self._signpos or integer.IsEmpty(text[start:end]):
-                wxCallAfter(self._SetInsertionPoint, self._signpos+1)
+                wx.CallAfter(self._SetInsertionPoint, self._signpos+1)
             else:
             else:
-                wxCallAfter(self._SetInsertionPoint, pos)
+                wx.CallAfter(self._SetInsertionPoint, pos)
 
             keep_processing = False
         else:
             keep_processing = True
 
             keep_processing = False
         else:
             keep_processing = True
-        dbg(indent=0)
+##        dbg(indent=0)
         return keep_processing
 
 
         return keep_processing
 
 
@@ -3610,29 +3696,29 @@ class wxMaskedEditMixin:
         This handler is only registered if the mask is a numeric mask.
         It allows the insertion of ',' or '.' if appropriate.
         """
         This handler is only registered if the mask is a numeric mask.
         It allows the insertion of ',' or '.' if appropriate.
         """
-        dbg('wxMaskedEditMixin::_OnGroupChar', indent=1)
+##        dbg('MaskedEditMixin::_OnGroupChar', indent=1)
         keep_processing = True
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         sel_start, sel_to = self._GetSelection()
         groupchar = self._fields[0]._groupChar
         if not self._isCharAllowed(groupchar, pos, checkRegex=True):
             keep_processing = False
         keep_processing = True
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         sel_start, sel_to = self._GetSelection()
         groupchar = self._fields[0]._groupChar
         if not self._isCharAllowed(groupchar, pos, checkRegex=True):
             keep_processing = False
-            if not wxValidator_IsSilent():
-                wxBell()
+            if not wx.Validator_IsSilent():
+                wx.Bell()
 
         if keep_processing:
             newstr, newpos = self._insertKey(groupchar, pos, sel_start, sel_to, self._GetValue() )
 
         if keep_processing:
             newstr, newpos = self._insertKey(groupchar, pos, sel_start, sel_to, self._GetValue() )
-            dbg("str with '%s' inserted:" % groupchar, '"%s"' % newstr)
+##            dbg("str with '%s' inserted:" % groupchar, '"%s"' % newstr)
             if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
                 keep_processing = False
             if self._ctrl_constraints._validRequired and not self.IsValid(newstr):
                 keep_processing = False
-                if not wxValidator_IsSilent():
-                        wxBell()
+                if not wx.Validator_IsSilent():
+                        wx.Bell()
 
         if keep_processing:
 
         if keep_processing:
-            wxCallAfter(self._SetValue, newstr)
-            wxCallAfter(self._SetInsertionPoint, newpos)
+            wx.CallAfter(self._SetValue, newstr)
+            wx.CallAfter(self._SetInsertionPoint, newpos)
         keep_processing = False
         keep_processing = False
-        dbg(indent=0)
+##        dbg(indent=0)
         return keep_processing
 
 
         return keep_processing
 
 
@@ -3666,7 +3752,7 @@ class wxMaskedEditMixin:
 
 
     def _OnAutoCompleteField(self, event):
 
 
     def _OnAutoCompleteField(self, event):
-        dbg('wxMaskedEditMixin::_OnAutoCompleteField', indent =1)
+##        dbg('MaskedEditMixin::_OnAutoCompleteField', indent =1)
         pos = self._GetInsertionPoint()
         field = self._FindField(pos)
         edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True)
         pos = self._GetInsertionPoint()
         field = self._FindField(pos)
         edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True)
@@ -3680,42 +3766,42 @@ class wxMaskedEditMixin:
             text = slice
         text = text.strip()
         keep_processing = True  # (assume True to start)
             text = slice
         text = text.strip()
         keep_processing = True  # (assume True to start)
-        dbg('field._hasList?', field._hasList)
+##        dbg('field._hasList?', field._hasList)
         if field._hasList:
         if field._hasList:
-            dbg('choices:', field._choices)
-            dbg('compareChoices:', field._compareChoices)
+##            dbg('choices:', field._choices)
+##            dbg('compareChoices:', field._compareChoices)
             choices, choice_required = field._compareChoices, field._choiceRequired
             choices, choice_required = field._compareChoices, field._choiceRequired
-            if keycode in (WXK_PRIOR, WXK_UP):
+            if keycode in (wx.WXK_PRIOR, wx.WXK_UP):
                 direction = -1
             else:
                 direction = 1
             match_index, partial_match = self._autoComplete(direction, choices, text, compareNoCase=field._compareNoCase, current_index = field._autoCompleteIndex)
             if( match_index is None
                 direction = -1
             else:
                 direction = 1
             match_index, partial_match = self._autoComplete(direction, choices, text, compareNoCase=field._compareNoCase, current_index = field._autoCompleteIndex)
             if( match_index is None
-                and (keycode in self._autoCompleteKeycodes + [WXK_PRIOR, WXK_NEXT]
-                     or (keycode in [WXK_UP, WXK_DOWN] and event.ShiftDown() ) ) ):
+                and (keycode in self._autoCompleteKeycodes + [wx.WXK_PRIOR, wx.WXK_NEXT]
+                     or (keycode in [wx.WXK_UP, wx.WXK_DOWN] and event.ShiftDown() ) ) ):
                 # Select the 1st thing from the list:
                 match_index = 0
 
             if( match_index is not None
                 # Select the 1st thing from the list:
                 match_index = 0
 
             if( match_index is not None
-                and ( keycode in self._autoCompleteKeycodes + [WXK_PRIOR, WXK_NEXT]
-                      or (keycode in [WXK_UP, WXK_DOWN] and event.ShiftDown())
-                      or (keycode == WXK_DOWN and partial_match) ) ):
+                and ( keycode in self._autoCompleteKeycodes + [wx.WXK_PRIOR, wx.WXK_NEXT]
+                      or (keycode in [wx.WXK_UP, wx.WXK_DOWN] and event.ShiftDown())
+                      or (keycode == wx.WXK_DOWN and partial_match) ) ):
 
                 # We're allowed to auto-complete:
 
                 # We're allowed to auto-complete:
-                dbg('match found')
+##                dbg('match found')
                 value = self._GetValue()
                 newvalue = value[:edit_start] + field._choices[match_index] + value[edit_end:]
                 value = self._GetValue()
                 newvalue = value[:edit_start] + field._choices[match_index] + value[edit_end:]
-                dbg('setting value to "%s"' % newvalue)
+##                dbg('setting value to "%s"' % newvalue)
                 self._SetValue(newvalue)
                 self._SetInsertionPoint(min(edit_end, len(newvalue.rstrip())))
                 self._OnAutoSelect(field, match_index)
                 self._CheckValid()  # recolor as appopriate
 
 
                 self._SetValue(newvalue)
                 self._SetInsertionPoint(min(edit_end, len(newvalue.rstrip())))
                 self._OnAutoSelect(field, match_index)
                 self._CheckValid()  # recolor as appopriate
 
 
-        if keycode in (WXK_UP, WXK_DOWN, WXK_LEFT, WXK_RIGHT):
+        if keycode in (wx.WXK_UP, wx.WXK_DOWN, wx.WXK_LEFT, wx.WXK_RIGHT):
             # treat as left right arrow if unshifted, tab/shift tab if shifted.
             if event.ShiftDown():
             # treat as left right arrow if unshifted, tab/shift tab if shifted.
             if event.ShiftDown():
-                if keycode in (WXK_DOWN, WXK_RIGHT):
+                if keycode in (wx.WXK_DOWN, wx.WXK_RIGHT):
                     # remove "shifting" and treat as (forward) tab:
                     event.m_shiftDown = False
                 keep_processing = self._OnChangeField(event)
                     # remove "shifting" and treat as (forward) tab:
                     event.m_shiftDown = False
                 keep_processing = self._OnChangeField(event)
@@ -3723,7 +3809,7 @@ class wxMaskedEditMixin:
                 keep_processing = self._OnArrow(event)
         # else some other key; keep processing the key
 
                 keep_processing = self._OnArrow(event)
         # else some other key; keep processing the key
 
-        dbg('keep processing?', keep_processing, indent=0)
+##        dbg('keep processing?', keep_processing, indent=0)
         return keep_processing
 
 
         return keep_processing
 
 
@@ -3732,7 +3818,7 @@ class wxMaskedEditMixin:
         Function called if autoselect feature is enabled and entire control
         is selected:
         """
         Function called if autoselect feature is enabled and entire control
         is selected:
         """
-        dbg('wxMaskedEditMixin::OnAutoSelect', field._index)
+##        dbg('MaskedEditMixin::OnAutoSelect', field._index)
         if match_index is not None:
             field._autoCompleteIndex = match_index
 
         if match_index is not None:
             field._autoCompleteIndex = match_index
 
@@ -3749,9 +3835,9 @@ class wxMaskedEditMixin:
         The function returns a 2-tuple, with the 2nd element being a boolean
         that indicates if partial match was necessary.
         """
         The function returns a 2-tuple, with the 2nd element being a boolean
         that indicates if partial match was necessary.
         """
-        dbg('autoComplete(direction=', direction, 'choices=',choices, 'value=',value,'compareNoCase?', compareNoCase, 'current_index:', current_index, indent=1)
+##        dbg('autoComplete(direction=', direction, 'choices=',choices, 'value=',value,'compareNoCase?', compareNoCase, 'current_index:', current_index, indent=1)
         if value is None:
         if value is None:
-            dbg('nothing to match against', indent=0)
+##            dbg('nothing to match against', indent=0)
             return (None, False)
 
         partial_match = False
             return (None, False)
 
         partial_match = False
@@ -3761,28 +3847,28 @@ class wxMaskedEditMixin:
 
         last_index = len(choices) - 1
         if value in choices:
 
         last_index = len(choices) - 1
         if value in choices:
-            dbg('"%s" in', choices)
+##            dbg('"%s" in', choices)
             if current_index is not None and choices[current_index] == value:
                 index = current_index
             else:
                 index = choices.index(value)
 
             if current_index is not None and choices[current_index] == value:
                 index = current_index
             else:
                 index = choices.index(value)
 
-            dbg('matched "%s" (%d)' % (choices[index], index))
+##            dbg('matched "%s" (%d)' % (choices[index], index))
             if direction == -1:
             if direction == -1:
-                dbg('going to previous')
+##                dbg('going to previous')
                 if index == 0: index = len(choices) - 1
                 else: index -= 1
             else:
                 if index == len(choices) - 1: index = 0
                 else: index += 1
                 if index == 0: index = len(choices) - 1
                 else: index -= 1
             else:
                 if index == len(choices) - 1: index = 0
                 else: index += 1
-            dbg('change value to "%s" (%d)' % (choices[index], index))
+##            dbg('change value to "%s" (%d)' % (choices[index], index))
             match = index
         else:
             partial_match = True
             value = value.strip()
             match = index
         else:
             partial_match = True
             value = value.strip()
-            dbg('no match; try to auto-complete:')
+##            dbg('no match; try to auto-complete:')
             match = None
             match = None
-            dbg('searching for "%s"' % value)
+##            dbg('searching for "%s"' % value)
             if current_index is None:
                 indices = range(len(choices))
                 if direction == -1:
             if current_index is None:
                 indices = range(len(choices))
                 if direction == -1:
@@ -3790,23 +3876,25 @@ class wxMaskedEditMixin:
             else:
                 if direction == 1:
                     indices = range(current_index +1, len(choices)) + range(current_index+1)
             else:
                 if direction == 1:
                     indices = range(current_index +1, len(choices)) + range(current_index+1)
-                    dbg('range(current_index+1 (%d), len(choices) (%d)) + range(%d):' % (current_index+1, len(choices), current_index+1), indices)
+##                    dbg('range(current_index+1 (%d), len(choices) (%d)) + range(%d):' % (current_index+1, len(choices), current_index+1), indices)
                 else:
                     indices = range(current_index-1, -1, -1) + range(len(choices)-1, current_index-1, -1)
                 else:
                     indices = range(current_index-1, -1, -1) + range(len(choices)-1, current_index-1, -1)
-                    dbg('range(current_index-1 (%d), -1) + range(len(choices)-1 (%d)), current_index-1 (%d):' % (current_index-1, len(choices)-1, current_index-1), indices)
-##            dbg('indices:', indices)
+##                    dbg('range(current_index-1 (%d), -1) + range(len(choices)-1 (%d)), current_index-1 (%d):' % (current_index-1, len(choices)-1, current_index-1), indices)
+####            dbg('indices:', indices)
             for index in indices:
                 choice = choices[index]
                 if choice.find(value, 0) == 0:
             for index in indices:
                 choice = choices[index]
                 if choice.find(value, 0) == 0:
-                    dbg('match found:', choice)
+##                    dbg('match found:', choice)
                     match = index
                     break
                 else: dbg('choice: "%s" - no match' % choice)
             if match is not None:
                     match = index
                     break
                 else: dbg('choice: "%s" - no match' % choice)
             if match is not None:
-                dbg('matched', match)
+##                dbg('matched', match)
+                pass
             else:
             else:
-                dbg('no match found')
-        dbg(indent=0)
+##                dbg('no match found')
+                pass
+##        dbg(indent=0)
         return (match, partial_match)
 
 
         return (match, partial_match)
 
 
@@ -3863,31 +3951,31 @@ class wxMaskedEditMixin:
         Checks the current insertion point position and adjusts it if
         necessary to skip over non-editable characters.
         """
         Checks the current insertion point position and adjusts it if
         necessary to skip over non-editable characters.
         """
-        dbg('_adjustPos', pos, key, indent=1)
+##        dbg('_adjustPos', pos, key, indent=1)
         sel_start, sel_to = self._GetSelection()
         # If a numeric or decimal mask, and negatives allowed, reserve the
         # first space for sign, and last one if using parens.
         if( self._signOk
             and ((pos == self._signpos and key in (ord('-'), ord('+'), ord(' ')) )
                  or self._useParens and pos == self._masklength -1)):
         sel_start, sel_to = self._GetSelection()
         # If a numeric or decimal mask, and negatives allowed, reserve the
         # first space for sign, and last one if using parens.
         if( self._signOk
             and ((pos == self._signpos and key in (ord('-'), ord('+'), ord(' ')) )
                  or self._useParens and pos == self._masklength -1)):
-            dbg('adjusted pos:', pos, indent=0)
+##            dbg('adjusted pos:', pos, indent=0)
             return pos
 
         if key not in self._nav:
             field = self._FindField(pos)
 
             return pos
 
         if key not in self._nav:
             field = self._FindField(pos)
 
-            dbg('field._insertRight?', field._insertRight)
+##            dbg('field._insertRight?', field._insertRight)
             if field._insertRight:              # if allow right-insert
                 start, end = field._extent
                 slice = self._GetValue()[start:end].strip()
                 field_len = end - start
                 if pos == end:                      # if cursor at right edge of field
                     # if not filled or supposed to stay in field, keep current position
             if field._insertRight:              # if allow right-insert
                 start, end = field._extent
                 slice = self._GetValue()[start:end].strip()
                 field_len = end - start
                 if pos == end:                      # if cursor at right edge of field
                     # if not filled or supposed to stay in field, keep current position
-##                    dbg('pos==end')
-##                    dbg('len (slice):', len(slice))
-##                    dbg('field_len?', field_len)
-##                    dbg('pos==end; len (slice) < field_len?', len(slice) < field_len)
-##                    dbg('not field._moveOnFieldFull?', not field._moveOnFieldFull)
+####                    dbg('pos==end')
+####                    dbg('len (slice):', len(slice))
+####                    dbg('field_len?', field_len)
+####                    dbg('pos==end; len (slice) < field_len?', len(slice) < field_len)
+####                    dbg('not field._moveOnFieldFull?', not field._moveOnFieldFull)
                     if len(slice) == field_len and field._moveOnFieldFull:
                         # move cursor to next field:
                         pos = self._findNextEntry(pos)
                     if len(slice) == field_len and field._moveOnFieldFull:
                         # move cursor to next field:
                         pos = self._findNextEntry(pos)
@@ -3933,7 +4021,7 @@ class wxMaskedEditMixin:
                     self._SetInsertionPoint(pos)
                     if pos < sel_to:    # restore selection
                         self._SetSelection(pos, sel_to)
                     self._SetInsertionPoint(pos)
                     if pos < sel_to:    # restore selection
                         self._SetSelection(pos, sel_to)
-        dbg('adjusted pos:', pos, indent=0)
+##        dbg('adjusted pos:', pos, indent=0)
         return pos
 
 
         return pos
 
 
@@ -3941,24 +4029,24 @@ class wxMaskedEditMixin:
         """
         'Fixes' an floating point control. Collapses spaces, right-justifies, etc.
         """
         """
         'Fixes' an floating point control. Collapses spaces, right-justifies, etc.
         """
-        dbg('wxMaskedEditMixin::_adjustFloat, candidate = "%s"' % candidate, indent=1)
+##        dbg('MaskedEditMixin::_adjustFloat, candidate = "%s"' % candidate, indent=1)
         lenInt,lenFraction  = [len(s) for s in self._mask.split('.')]  ## Get integer, fraction lengths
 
         if candidate is None: value = self._GetValue()
         else: value = candidate
         lenInt,lenFraction  = [len(s) for s in self._mask.split('.')]  ## Get integer, fraction lengths
 
         if candidate is None: value = self._GetValue()
         else: value = candidate
-        dbg('value = "%(value)s"' % locals(), 'len(value):', len(value))
+##        dbg('value = "%(value)s"' % locals(), 'len(value):', len(value))
         intStr, fracStr = value.split(self._decimalChar)
 
         intStr = self._fields[0]._AdjustField(intStr)
         intStr, fracStr = value.split(self._decimalChar)
 
         intStr = self._fields[0]._AdjustField(intStr)
-        dbg('adjusted intStr: "%s"' % intStr)
+##        dbg('adjusted intStr: "%s"' % intStr)
         lenInt = len(intStr)
         fracStr = fracStr + ('0'*(lenFraction-len(fracStr)))  # add trailing spaces to decimal
 
         lenInt = len(intStr)
         fracStr = fracStr + ('0'*(lenFraction-len(fracStr)))  # add trailing spaces to decimal
 
-        dbg('intStr "%(intStr)s"' % locals())
-        dbg('lenInt:', lenInt)
+##        dbg('intStr "%(intStr)s"' % locals())
+##        dbg('lenInt:', lenInt)
 
         intStr = string.rjust( intStr[-lenInt:], lenInt)
 
         intStr = string.rjust( intStr[-lenInt:], lenInt)
-        dbg('right-justifed intStr = "%(intStr)s"' % locals())
+##        dbg('right-justifed intStr = "%(intStr)s"' % locals())
         newvalue = intStr + self._decimalChar + fracStr
 
         if self._signOk:
         newvalue = intStr + self._decimalChar + fracStr
 
         if self._signOk:
@@ -3980,23 +4068,23 @@ class wxMaskedEditMixin:
             else:
                 newvalue = newvalue[:-1] + ' '
 
             else:
                 newvalue = newvalue[:-1] + ' '
 
-        dbg('newvalue = "%s"' % newvalue)
+##        dbg('newvalue = "%s"' % newvalue)
         if candidate is None:
         if candidate is None:
-            wxCallAfter(self._SetValue, newvalue)
-        dbg(indent=0)
+            wx.CallAfter(self._SetValue, newvalue)
+##        dbg(indent=0)
         return newvalue
 
 
     def _adjustInt(self, candidate=None):
         """ 'Fixes' an integer control. Collapses spaces, right or left-justifies."""
         return newvalue
 
 
     def _adjustInt(self, candidate=None):
         """ 'Fixes' an integer control. Collapses spaces, right or left-justifies."""
-        dbg("wxMaskedEditMixin::_adjustInt", candidate)
+##        dbg("MaskedEditMixin::_adjustInt", candidate)
         lenInt = self._masklength
         if candidate is None: value = self._GetValue()
         else: value = candidate
 
         intStr = self._fields[0]._AdjustField(value)
         intStr = intStr.strip() # drop extra spaces
         lenInt = self._masklength
         if candidate is None: value = self._GetValue()
         else: value = candidate
 
         intStr = self._fields[0]._AdjustField(value)
         intStr = intStr.strip() # drop extra spaces
-        dbg('adjusted field: "%s"' % intStr)
+##        dbg('adjusted field: "%s"' % intStr)
 
         if self._isNeg and intStr.find('-') == -1 and intStr.find('(') == -1:
             if self._useParens:
 
         if self._isNeg and intStr.find('-') == -1 and intStr.find('(') == -1:
             if self._useParens:
@@ -4022,7 +4110,7 @@ class wxMaskedEditMixin:
             intStr = intStr.ljust( lenInt )
 
         if candidate is None:
             intStr = intStr.ljust( lenInt )
 
         if candidate is None:
-            wxCallAfter(self._SetValue, intStr )
+            wx.CallAfter(self._SetValue, intStr )
         return intStr
 
 
         return intStr
 
 
@@ -4031,20 +4119,20 @@ class wxMaskedEditMixin:
         'Fixes' a date control, expanding the year if it can.
         Applies various self-formatting options.
         """
         'Fixes' a date control, expanding the year if it can.
         Applies various self-formatting options.
         """
-        dbg("wxMaskedEditMixin::_adjustDate", indent=1)
+##        dbg("MaskedEditMixin::_adjustDate", indent=1)
         if candidate is None: text    = self._GetValue()
         else: text = candidate
         if candidate is None: text    = self._GetValue()
         else: text = candidate
-        dbg('text=', text)
+##        dbg('text=', text)
         if self._datestyle == "YMD":
             year_field = 0
         else:
             year_field = 2
 
         if self._datestyle == "YMD":
             year_field = 0
         else:
             year_field = 2
 
-        dbg('getYear: "%s"' % getYear(text, self._datestyle))
+##        dbg('getYear: "%s"' % getYear(text, self._datestyle))
         year    = string.replace( getYear( text, self._datestyle),self._fields[year_field]._fillChar,"")  # drop extra fillChars
         month   = getMonth( text, self._datestyle)
         day     = getDay( text, self._datestyle)
         year    = string.replace( getYear( text, self._datestyle),self._fields[year_field]._fillChar,"")  # drop extra fillChars
         month   = getMonth( text, self._datestyle)
         day     = getDay( text, self._datestyle)
-        dbg('self._datestyle:', self._datestyle, 'year:', year, 'Month', month, 'day:', day)
+##        dbg('self._datestyle:', self._datestyle, 'year:', year, 'Month', month, 'day:', day)
 
         yearVal = None
         yearstart = self._dateExtent - 4
 
         yearVal = None
         yearstart = self._dateExtent - 4
@@ -4058,14 +4146,14 @@ class wxMaskedEditMixin:
             try:
                 yearVal = int(year)
             except:
             try:
                 yearVal = int(year)
             except:
-                dbg('bad year=', year)
+##                dbg('bad year=', year)
                 year = text[yearstart:self._dateExtent]
 
         if len(year) < 4 and yearVal:
             if len(year) == 2:
                 # Fix year adjustment to be less "20th century" :-) and to adjust heuristic as the
                 # years pass...
                 year = text[yearstart:self._dateExtent]
 
         if len(year) < 4 and yearVal:
             if len(year) == 2:
                 # Fix year adjustment to be less "20th century" :-) and to adjust heuristic as the
                 # years pass...
-                now = wxDateTime_Now()
+                now = wx.DateTime_Now()
                 century = (now.GetYear() /100) * 100        # "this century"
                 twodig_year = now.GetYear() - century       # "this year" (2 digits)
                 # if separation between today's 2-digit year and typed value > 50,
                 century = (now.GetYear() /100) * 100        # "this century"
                 twodig_year = now.GetYear() - century       # "this year" (2 digits)
                 # if separation between today's 2-digit year and typed value > 50,
@@ -4085,22 +4173,22 @@ class wxMaskedEditMixin:
                 year = "%04d" % yearVal
             if self._4digityear or force4digit_year:
                 text = makeDate(year, month, day, self._datestyle, text) + text[self._dateExtent:]
                 year = "%04d" % yearVal
             if self._4digityear or force4digit_year:
                 text = makeDate(year, month, day, self._datestyle, text) + text[self._dateExtent:]
-        dbg('newdate: "%s"' % text, indent=0)
+##        dbg('newdate: "%s"' % text, indent=0)
         return text
 
 
     def _goEnd(self, getPosOnly=False):
         """ Moves the insertion point to the end of user-entry """
         return text
 
 
     def _goEnd(self, getPosOnly=False):
         """ Moves the insertion point to the end of user-entry """
-        dbg("wxMaskedEditMixin::_goEnd; getPosOnly:", getPosOnly, indent=1)
+##        dbg("MaskedEditMixin::_goEnd; getPosOnly:", getPosOnly, indent=1)
         text = self._GetValue()
         text = self._GetValue()
-##        dbg('text: "%s"' % text)
+####        dbg('text: "%s"' % text)
         i = 0
         if len(text.rstrip()):
             for i in range( min( self._masklength-1, len(text.rstrip())), -1, -1):
         i = 0
         if len(text.rstrip()):
             for i in range( min( self._masklength-1, len(text.rstrip())), -1, -1):
-##                dbg('i:', i, 'self._isMaskChar(%d)' % i, self._isMaskChar(i))
+####                dbg('i:', i, 'self._isMaskChar(%d)' % i, self._isMaskChar(i))
                 if self._isMaskChar(i):
                     char = text[i]
                 if self._isMaskChar(i):
                     char = text[i]
-##                    dbg("text[%d]: '%s'" % (i, char))
+####                    dbg("text[%d]: '%s'" % (i, char))
                     if char != ' ':
                         i += 1
                         break
                     if char != ' ':
                         i += 1
                         break
@@ -4114,8 +4202,8 @@ class wxMaskedEditMixin:
         start, end = field._extent
         if field._insertRight and pos < end:
             pos = end
         start, end = field._extent
         if field._insertRight and pos < end:
             pos = end
-        dbg('next pos:', pos)
-        dbg(indent=0)
+##        dbg('next pos:', pos)
+##        dbg(indent=0)
         if getPosOnly:
             return pos
         else:
         if getPosOnly:
             return pos
         else:
@@ -4124,13 +4212,13 @@ class wxMaskedEditMixin:
 
     def _goHome(self, getPosOnly=False):
         """ Moves the insertion point to the beginning of user-entry """
 
     def _goHome(self, getPosOnly=False):
         """ Moves the insertion point to the beginning of user-entry """
-        dbg("wxMaskedEditMixin::_goHome; getPosOnly:", getPosOnly, indent=1)
+##        dbg("MaskedEditMixin::_goHome; getPosOnly:", getPosOnly, indent=1)
         text = self._GetValue()
         for i in range(self._masklength):
             if self._isMaskChar(i):
                 break
         pos = max(i, 0)
         text = self._GetValue()
         for i in range(self._masklength):
             if self._isMaskChar(i):
                 break
         pos = max(i, 0)
-        dbg(indent=0)
+##        dbg(indent=0)
         if getPosOnly:
             return pos
         else:
         if getPosOnly:
             return pos
         else:
@@ -4149,7 +4237,7 @@ class wxMaskedEditMixin:
             okchars += " "
         if okchars and field._includeChars:      ## any additional included characters?
             okchars += field._includeChars
             okchars += " "
         if okchars and field._includeChars:      ## any additional included characters?
             okchars += field._includeChars
-##        dbg('okchars[%d]:' % pos, okchars)
+####        dbg('okchars[%d]:' % pos, okchars)
         return okchars
 
 
         return okchars
 
 
@@ -4173,7 +4261,7 @@ class wxMaskedEditMixin:
 
     def _isCharAllowed(self, char, pos, checkRegex=False, allowAutoSelect=True, ignoreInsertRight=False):
         """ Returns True if character is allowed at the specific position, otherwise False."""
 
     def _isCharAllowed(self, char, pos, checkRegex=False, allowAutoSelect=True, ignoreInsertRight=False):
         """ Returns True if character is allowed at the specific position, otherwise False."""
-        dbg('_isCharAllowed', char, pos, checkRegex, indent=1)
+##        dbg('_isCharAllowed', char, pos, checkRegex, indent=1)
         field = self._FindField(pos)
         right_insert = False
 
         field = self._FindField(pos)
         right_insert = False
 
@@ -4204,21 +4292,21 @@ class wxMaskedEditMixin:
             if( (sel_start, sel_to) == field._extent
                 or (pos == end and input_len < field_len)):
                 pos = end - 1
             if( (sel_start, sel_to) == field._extent
                 or (pos == end and input_len < field_len)):
                 pos = end - 1
-                dbg('pos = end - 1 = ', pos, 'right_insert? 1')
+##                dbg('pos = end - 1 = ', pos, 'right_insert? 1')
                 right_insert = True
             elif( field._allowInsert and sel_start == sel_to
                   and (sel_to == end or (sel_to < self._masklength and value[sel_start] != field._fillChar))
                   and input_len < field_len ):
                 pos = sel_to - 1    # where character will go
                 right_insert = True
             elif( field._allowInsert and sel_start == sel_to
                   and (sel_to == end or (sel_to < self._masklength and value[sel_start] != field._fillChar))
                   and input_len < field_len ):
                 pos = sel_to - 1    # where character will go
-                dbg('pos = sel_to - 1 = ', pos, 'right_insert? 1')
+##                dbg('pos = sel_to - 1 = ', pos, 'right_insert? 1')
                 right_insert = True
             # else leave pos alone...
             else:
                 right_insert = True
             # else leave pos alone...
             else:
-                dbg('pos stays ', pos, 'right_insert? 0')
-
+##                dbg('pos stays ', pos, 'right_insert? 0')
+                pass
 
         if self._isTemplateChar( pos ):  ## if a template character, return empty
 
         if self._isTemplateChar( pos ):  ## if a template character, return empty
-            dbg('%d is a template character; returning False' % pos, indent=0)
+##            dbg('%d is a template character; returning False' % pos, indent=0)
             return False
 
         if self._isMaskChar( pos ):
             return False
 
         if self._isMaskChar( pos ):
@@ -4235,11 +4323,11 @@ class wxMaskedEditMixin:
                 elif self._useParens and (self._isInt or (self._isFloat and pos > self._decimalpos)):
                     okChars += ')'
 
                 elif self._useParens and (self._isInt or (self._isFloat and pos > self._decimalpos)):
                     okChars += ')'
 
-##            dbg('%s in %s?' % (char, okChars), char in okChars)
+####            dbg('%s in %s?' % (char, okChars), char in okChars)
             approved = char in okChars
 
             if approved and checkRegex:
             approved = char in okChars
 
             if approved and checkRegex:
-                dbg("checking appropriate regex's")
+##                dbg("checking appropriate regex's")
                 value = self._eraseSelection(self._GetValue())
                 if right_insert:
                     at = pos+1
                 value = self._eraseSelection(self._GetValue())
                 if right_insert:
                     at = pos+1
@@ -4249,21 +4337,21 @@ class wxMaskedEditMixin:
                     newvalue, ignore, ignore, ignore, ignore = self._insertKey(char, at, sel_start, sel_to, value, allowAutoSelect=True)
                 else:
                     newvalue, ignore = self._insertKey(char, at, sel_start, sel_to, value)
                     newvalue, ignore, ignore, ignore, ignore = self._insertKey(char, at, sel_start, sel_to, value, allowAutoSelect=True)
                 else:
                     newvalue, ignore = self._insertKey(char, at, sel_start, sel_to, value)
-                dbg('newvalue: "%s"' % newvalue)
+##                dbg('newvalue: "%s"' % newvalue)
 
                 fields = [self._FindField(pos)] + [self._ctrl_constraints]
                 for field in fields:    # includes fields[-1] == "ctrl_constraints"
                     if field._regexMask and field._filter:
 
                 fields = [self._FindField(pos)] + [self._ctrl_constraints]
                 for field in fields:    # includes fields[-1] == "ctrl_constraints"
                     if field._regexMask and field._filter:
-                        dbg('checking vs. regex')
+##                        dbg('checking vs. regex')
                         start, end = field._extent
                         slice = newvalue[start:end]
                         approved = (re.match( field._filter, slice) is not None)
                         start, end = field._extent
                         slice = newvalue[start:end]
                         approved = (re.match( field._filter, slice) is not None)
-                        dbg('approved?', approved)
+##                        dbg('approved?', approved)
                     if not approved: break
                     if not approved: break
-            dbg(indent=0)
+##            dbg(indent=0)
             return approved
         else:
             return approved
         else:
-            dbg('%d is a !???! character; returning False', indent=0)
+##            dbg('%d is a !???! character; returning False', indent=0)
             return False
 
 
             return False
 
 
@@ -4272,22 +4360,22 @@ class wxMaskedEditMixin:
             Need to find a way to call this whenever the value changes, in case the control's
             value has been changed or set programatically.
         """
             Need to find a way to call this whenever the value changes, in case the control's
             value has been changed or set programatically.
         """
-        dbg(suspend=1)
-        dbg('wxMaskedEditMixin::_applyFormatting', indent=1)
+##        dbg(suspend=1)
+##        dbg('MaskedEditMixin::_applyFormatting', indent=1)
 
         # Handle negative numbers
         if self._signOk:
             text, signpos, right_signpos = self._getSignedValue()
 
         # Handle negative numbers
         if self._signOk:
             text, signpos, right_signpos = self._getSignedValue()
-            dbg('text: "%s", signpos:' % text, signpos)
+##            dbg('text: "%s", signpos:' % text, signpos)
             if not text or text[signpos] not in ('-','('):
                 self._isNeg = False
             if not text or text[signpos] not in ('-','('):
                 self._isNeg = False
-                dbg('no valid sign found; new sign:', self._isNeg)
+##                dbg('no valid sign found; new sign:', self._isNeg)
                 if text and signpos != self._signpos:
                     self._signpos = signpos
             elif text and self._valid and not self._isNeg and text[signpos] in ('-', '('):
                 if text and signpos != self._signpos:
                     self._signpos = signpos
             elif text and self._valid and not self._isNeg and text[signpos] in ('-', '('):
-                dbg('setting _isNeg to True')
+##                dbg('setting _isNeg to True')
                 self._isNeg = True
                 self._isNeg = True
-            dbg('self._isNeg:', self._isNeg)
+##            dbg('self._isNeg:', self._isNeg)
 
         if self._signOk and self._isNeg:
             fc = self._signedForegroundColour
 
         if self._signOk and self._isNeg:
             fc = self._signedForegroundColour
@@ -4298,32 +4386,32 @@ class wxMaskedEditMixin:
             c =fc._name
         else:
             c = fc
             c =fc._name
         else:
             c = fc
-        dbg('setting foreground to', c)
+##        dbg('setting foreground to', c)
         self.SetForegroundColour(fc)
 
         if self._valid:
         self.SetForegroundColour(fc)
 
         if self._valid:
-            dbg('valid')
+##            dbg('valid')
             if self.IsEmpty():
                 bc = self._emptyBackgroundColour
             else:
                 bc = self._validBackgroundColour
         else:
             if self.IsEmpty():
                 bc = self._emptyBackgroundColour
             else:
                 bc = self._validBackgroundColour
         else:
-            dbg('invalid')
+##            dbg('invalid')
             bc = self._invalidBackgroundColour
         if hasattr(bc, '_name'):
             c =bc._name
         else:
             c = bc
             bc = self._invalidBackgroundColour
         if hasattr(bc, '_name'):
             c =bc._name
         else:
             c = bc
-        dbg('setting background to', c)
+##        dbg('setting background to', c)
         self.SetBackgroundColour(bc)
         self._Refresh()
         self.SetBackgroundColour(bc)
         self._Refresh()
-        dbg(indent=0, suspend=0)
+##        dbg(indent=0, suspend=0)
 
 
     def _getAbsValue(self, candidate=None):
         """ Return an unsigned value (i.e. strip the '-' prefix if any), and sign position(s).
         """
 
 
     def _getAbsValue(self, candidate=None):
         """ Return an unsigned value (i.e. strip the '-' prefix if any), and sign position(s).
         """
-        dbg('wxMaskedEditMixin::_getAbsValue; candidate="%s"' % candidate, indent=1)
+##        dbg('MaskedEditMixin::_getAbsValue; candidate="%s"' % candidate, indent=1)
         if candidate is None: text = self._GetValue()
         else: text = candidate
         right_signpos = text.find(')')
         if candidate is None: text = self._GetValue()
         else: text = candidate
         right_signpos = text.find(')')
@@ -4332,14 +4420,15 @@ class wxMaskedEditMixin:
             if self._ctrl_constraints._alignRight and self._fields[0]._fillChar == ' ':
                 signpos = text.find('-')
                 if signpos == -1:
             if self._ctrl_constraints._alignRight and self._fields[0]._fillChar == ' ':
                 signpos = text.find('-')
                 if signpos == -1:
-                    dbg('no - found; searching for (')
+##                    dbg('no - found; searching for (')
                     signpos = text.find('(')
                 elif signpos != -1:
                     signpos = text.find('(')
                 elif signpos != -1:
-                    dbg('- found at', signpos)
+##                    dbg('- found at', signpos)
+                    pass
 
                 if signpos == -1:
 
                 if signpos == -1:
-                    dbg('signpos still -1')
-                    dbg('len(%s) (%d) < len(%s) (%d)?' % (text, len(text), self._mask, self._masklength), len(text) < self._masklength)
+##                    dbg('signpos still -1')
+##                    dbg('len(%s) (%d) < len(%s) (%d)?' % (text, len(text), self._mask, self._masklength), len(text) < self._masklength)
                     if len(text) < self._masklength:
                         text = ' ' + text
                     if len(text) < self._masklength:
                     if len(text) < self._masklength:
                         text = ' ' + text
                     if len(text) < self._masklength:
@@ -4347,13 +4436,13 @@ class wxMaskedEditMixin:
                     if len(text) > self._masklength and text[-1] in (')', ' '):
                         text = text[:-1]
                     else:
                     if len(text) > self._masklength and text[-1] in (')', ' '):
                         text = text[:-1]
                     else:
-                        dbg('len(%s) (%d), len(%s) (%d)' % (text, len(text), self._mask, self._masklength))
-                        dbg('len(%s) - (len(%s) + 1):' % (text, text.lstrip()) , len(text) - (len(text.lstrip()) + 1))
+##                        dbg('len(%s) (%d), len(%s) (%d)' % (text, len(text), self._mask, self._masklength))
+##                        dbg('len(%s) - (len(%s) + 1):' % (text, text.lstrip()) , len(text) - (len(text.lstrip()) + 1))
                         signpos = len(text) - (len(text.lstrip()) + 1)
 
                         if self._useParens and not text.strip():
                             signpos -= 1    # empty value; use penultimate space
                         signpos = len(text) - (len(text.lstrip()) + 1)
 
                         if self._useParens and not text.strip():
                             signpos -= 1    # empty value; use penultimate space
-                dbg('signpos:', signpos)
+##                dbg('signpos:', signpos)
                 if signpos >= 0:
                     text = text[:signpos] + ' ' + text[signpos+1:]
 
                 if signpos >= 0:
                     text = text[:signpos] + ' ' + text[signpos+1:]
 
@@ -4376,25 +4465,25 @@ class wxMaskedEditMixin:
                 # figure out where it ought to go:
                 right_signpos = self._masklength - 1     # initial guess
                 if not self._ctrl_constraints._alignRight:
                 # figure out where it ought to go:
                 right_signpos = self._masklength - 1     # initial guess
                 if not self._ctrl_constraints._alignRight:
-                    dbg('not right-aligned')
+##                    dbg('not right-aligned')
                     if len(text.strip()) == 0:
                         right_signpos = signpos + 1
                     elif len(text.strip()) < self._masklength:
                         right_signpos = len(text.rstrip())
                     if len(text.strip()) == 0:
                         right_signpos = signpos + 1
                     elif len(text.strip()) < self._masklength:
                         right_signpos = len(text.rstrip())
-                dbg('right_signpos:', right_signpos)
+##                dbg('right_signpos:', right_signpos)
 
             groupchar = self._fields[0]._groupChar
             try:
                 value = long(text.replace(groupchar,'').replace('(','-').replace(')','').replace(' ', ''))
             except:
 
             groupchar = self._fields[0]._groupChar
             try:
                 value = long(text.replace(groupchar,'').replace('(','-').replace(')','').replace(' ', ''))
             except:
-                dbg('invalid number', indent=0)
+##                dbg('invalid number', indent=0)
                 return None, signpos, right_signpos
 
         else:   # float value
             try:
                 groupchar = self._fields[0]._groupChar
                 value = float(text.replace(groupchar,'').replace(self._decimalChar, '.').replace('(', '-').replace(')','').replace(' ', ''))
                 return None, signpos, right_signpos
 
         else:   # float value
             try:
                 groupchar = self._fields[0]._groupChar
                 value = float(text.replace(groupchar,'').replace(self._decimalChar, '.').replace('(', '-').replace(')','').replace(' ', ''))
-                dbg('value:', value)
+##                dbg('value:', value)
             except:
                 value = None
 
             except:
                 value = None
 
@@ -4406,15 +4495,16 @@ class wxMaskedEditMixin:
                 text = text[:signpos] + self._template[signpos] + text[signpos+1:]
             else:
                 # look forwards up to the decimal point for the 1st non-digit
                 text = text[:signpos] + self._template[signpos] + text[signpos+1:]
             else:
                 # look forwards up to the decimal point for the 1st non-digit
-                dbg('decimal pos:', self._decimalpos)
-                dbg('text: "%s"' % text)
+##                dbg('decimal pos:', self._decimalpos)
+##                dbg('text: "%s"' % text)
                 if self._signOk:
                     signpos = self._decimalpos - (len(text[:self._decimalpos].lstrip()) + 1)
                 if self._signOk:
                     signpos = self._decimalpos - (len(text[:self._decimalpos].lstrip()) + 1)
-                    if text[signpos+1] in ('-','('):
+                    # prevent checking for empty string - Tomo - Wed 14 Jan 2004 03:19:09 PM CET
+                    if len(text) >= signpos+1 and  text[signpos+1] in ('-','('):
                         signpos += 1
                 else:
                     signpos = -1
                         signpos += 1
                 else:
                     signpos = -1
-                dbg('signpos:', signpos)
+##                dbg('signpos:', signpos)
 
             if self._useParens:
                 if self._signOk:
 
             if self._useParens:
                 if self._signOk:
@@ -4429,11 +4519,11 @@ class wxMaskedEditMixin:
                         right_signpos = -1
 
             if value is None:
                         right_signpos = -1
 
             if value is None:
-                dbg('invalid number')
+##                dbg('invalid number')
                 text = None
 
                 text = None
 
-        dbg('abstext = "%s"' % text, 'signpos:', signpos, 'right_signpos:', right_signpos)
-        dbg(indent=0)
+##        dbg('abstext = "%s"' % text, 'signpos:', signpos, 'right_signpos:', right_signpos)
+##        dbg(indent=0)
         return text, signpos, right_signpos
 
 
         return text, signpos, right_signpos
 
 
@@ -4441,7 +4531,7 @@ class wxMaskedEditMixin:
         """ Return a signed value by adding a "-" prefix if the value
             is set to negative, or a space if positive.
         """
         """ Return a signed value by adding a "-" prefix if the value
             is set to negative, or a space if positive.
         """
-        dbg('wxMaskedEditMixin::_getSignedValue; candidate="%s"' % candidate, indent=1)
+##        dbg('MaskedEditMixin::_getSignedValue; candidate="%s"' % candidate, indent=1)
         if candidate is None: text = self._GetValue()
         else: text = candidate
 
         if candidate is None: text = self._GetValue()
         else: text = candidate
 
@@ -4449,7 +4539,7 @@ class wxMaskedEditMixin:
         abstext, signpos, right_signpos = self._getAbsValue(text)
         if self._signOk:
             if abstext is None:
         abstext, signpos, right_signpos = self._getAbsValue(text)
         if self._signOk:
             if abstext is None:
-                dbg(indent=0)
+##                dbg(indent=0)
                 return abstext, signpos, right_signpos
 
             if self._isNeg or text[signpos] in ('-', '('):
                 return abstext, signpos, right_signpos
 
             if self._isNeg or text[signpos] in ('-', '('):
@@ -4469,22 +4559,22 @@ class wxMaskedEditMixin:
                 text = text[:right_signpos] + ')' + text[right_signpos+1:]
         else:
             text = abstext
                 text = text[:right_signpos] + ')' + text[right_signpos+1:]
         else:
             text = abstext
-        dbg('signedtext = "%s"' % text, 'signpos:', signpos, 'right_signpos', right_signpos)
-        dbg(indent=0)
+##        dbg('signedtext = "%s"' % text, 'signpos:', signpos, 'right_signpos', right_signpos)
+##        dbg(indent=0)
         return text, signpos, right_signpos
 
 
     def GetPlainValue(self, candidate=None):
         """ Returns control's value stripped of the template text.
         return text, signpos, right_signpos
 
 
     def GetPlainValue(self, candidate=None):
         """ Returns control's value stripped of the template text.
-            plainvalue = wxMaskedEditMixin.GetPlainValue()
+            plainvalue = MaskedEditMixin.GetPlainValue()
         """
         """
-        dbg('wxMaskedEditMixin::GetPlainValue; candidate="%s"' % candidate, indent=1)
+##        dbg('MaskedEditMixin::GetPlainValue; candidate="%s"' % candidate, indent=1)
 
         if candidate is None: text = self._GetValue()
         else: text = candidate
 
         if self.IsEmpty():
 
         if candidate is None: text = self._GetValue()
         else: text = candidate
 
         if self.IsEmpty():
-            dbg('returned ""', indent=0)
+##            dbg('returned ""', indent=0)
             return ""
         else:
             plain = ""
             return ""
         else:
             plain = ""
@@ -4493,9 +4583,9 @@ class wxMaskedEditMixin:
                     plain += text[idx]
 
             if self._isFloat or self._isInt:
                     plain += text[idx]
 
             if self._isFloat or self._isInt:
-                dbg('plain so far: "%s"' % plain)
+##                dbg('plain so far: "%s"' % plain)
                 plain = plain.replace('(', '-').replace(')', ' ')
                 plain = plain.replace('(', '-').replace(')', ' ')
-                dbg('plain after sign regularization: "%s"' % plain)
+##                dbg('plain after sign regularization: "%s"' % plain)
 
                 if self._signOk and self._isNeg and plain.count('-') == 0:
                     # must be in reserved position; add to "plain value"
 
                 if self._signOk and self._isNeg and plain.count('-') == 0:
                     # must be in reserved position; add to "plain value"
@@ -4506,9 +4596,9 @@ class wxMaskedEditMixin:
                     plain = ' ' * lpad + plain.replace(',','')
                 else:
                     plain = plain.replace(',','')
                     plain = ' ' * lpad + plain.replace(',','')
                 else:
                     plain = plain.replace(',','')
-                dbg('plain after pad and group:"%s"' % plain)
+##                dbg('plain after pad and group:"%s"' % plain)
 
 
-            dbg('returned "%s"' % plain.rstrip(), indent=0)
+##            dbg('returned "%s"' % plain.rstrip(), indent=0)
             return plain.rstrip()
 
 
             return plain.rstrip()
 
 
@@ -4519,19 +4609,19 @@ class wxMaskedEditMixin:
         """
         if value is None: value = self._GetValue()
         if value == self._template and not self._defaultValue:
         """
         if value is None: value = self._GetValue()
         if value == self._template and not self._defaultValue:
-##            dbg("IsEmpty? 1 (value == self._template and not self._defaultValue)")
+####            dbg("IsEmpty? 1 (value == self._template and not self._defaultValue)")
             return True     # (all mask chars == fillChar by defn)
         elif value == self._template:
             empty = True
             for pos in range(len(self._template)):
             return True     # (all mask chars == fillChar by defn)
         elif value == self._template:
             empty = True
             for pos in range(len(self._template)):
-##                dbg('isMaskChar(%(pos)d)?' % locals(), self._isMaskChar(pos))
-##                dbg('value[%(pos)d] != self._fillChar?' %locals(), value[pos] != self._fillChar[pos])
+####                dbg('isMaskChar(%(pos)d)?' % locals(), self._isMaskChar(pos))
+####                dbg('value[%(pos)d] != self._fillChar?' %locals(), value[pos] != self._fillChar[pos])
                 if self._isMaskChar(pos) and value[pos] not in (' ', self._fillChar[pos]):
                     empty = False
                 if self._isMaskChar(pos) and value[pos] not in (' ', self._fillChar[pos]):
                     empty = False
-##            dbg("IsEmpty? %(empty)d (do all mask chars == fillChar?)" % locals())
+####            dbg("IsEmpty? %(empty)d (do all mask chars == fillChar?)" % locals())
             return empty
         else:
             return empty
         else:
-##            dbg("IsEmpty? 0 (value doesn't match template)")
+####            dbg("IsEmpty? 0 (value doesn't match template)")
             return False
 
 
             return False
 
 
@@ -4547,26 +4637,26 @@ class wxMaskedEditMixin:
     def IsValid(self, value=None):
         """ Indicates whether the value specified (or the current value of the control
         if not specified) is considered valid."""
     def IsValid(self, value=None):
         """ Indicates whether the value specified (or the current value of the control
         if not specified) is considered valid."""
-##        dbg('wxMaskedEditMixin::IsValid("%s")' % value, indent=1)
+####        dbg('MaskedEditMixin::IsValid("%s")' % value, indent=1)
         if value is None: value = self._GetValue()
         ret = self._CheckValid(value)
         if value is None: value = self._GetValue()
         ret = self._CheckValid(value)
-##        dbg(indent=0)
+####        dbg(indent=0)
         return ret
 
 
     def _eraseSelection(self, value=None, sel_start=None, sel_to=None):
         """ Used to blank the selection when inserting a new character. """
         return ret
 
 
     def _eraseSelection(self, value=None, sel_start=None, sel_to=None):
         """ Used to blank the selection when inserting a new character. """
-        dbg("wxMaskedEditMixin::_eraseSelection", indent=1)
+##        dbg("MaskedEditMixin::_eraseSelection", indent=1)
         if value is None: value = self._GetValue()
         if sel_start is None or sel_to is None:
             sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
         if value is None: value = self._GetValue()
         if sel_start is None or sel_to is None:
             sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
-        dbg('value: "%s"' % value)
-        dbg("current sel_start, sel_to:", sel_start, sel_to)
+##        dbg('value: "%s"' % value)
+##        dbg("current sel_start, sel_to:", sel_start, sel_to)
 
         newvalue = list(value)
         for i in range(sel_start, sel_to):
             if self._signOk and newvalue[i] in ('-', '(', ')'):
 
         newvalue = list(value)
         for i in range(sel_start, sel_to):
             if self._signOk and newvalue[i] in ('-', '(', ')'):
-                dbg('found sign (%s) at' % newvalue[i], i)
+##                dbg('found sign (%s) at' % newvalue[i], i)
 
                 # balance parentheses:
                 if newvalue[i] == '(':
 
                 # balance parentheses:
                 if newvalue[i] == '(':
@@ -4589,14 +4679,14 @@ class wxMaskedEditMixin:
                     newvalue[i] = self._template[i]
 
         value = string.join(newvalue,"")
                     newvalue[i] = self._template[i]
 
         value = string.join(newvalue,"")
-        dbg('new value: "%s"' % value)
-        dbg(indent=0)
+##        dbg('new value: "%s"' % value)
+##        dbg(indent=0)
         return value
 
 
     def _insertKey(self, char, pos, sel_start, sel_to, value, allowAutoSelect=False):
         """ Handles replacement of the character at the current insertion point."""
         return value
 
 
     def _insertKey(self, char, pos, sel_start, sel_to, value, allowAutoSelect=False):
         """ Handles replacement of the character at the current insertion point."""
-        dbg('wxMaskedEditMixin::_insertKey', "\'" + char + "\'", pos, sel_start, sel_to, '"%s"' % value, indent=1)
+##        dbg('MaskedEditMixin::_insertKey', "\'" + char + "\'", pos, sel_start, sel_to, '"%s"' % value, indent=1)
 
         text = self._eraseSelection(value)
         field = self._FindField(pos)
 
         text = self._eraseSelection(value)
         field = self._FindField(pos)
@@ -4608,7 +4698,7 @@ class wxMaskedEditMixin:
             # adjustpos must have moved the position; make selection match:
             sel_start = sel_to = pos
 
             # adjustpos must have moved the position; make selection match:
             sel_start = sel_to = pos
 
-        dbg('field._insertRight?', field._insertRight)
+##        dbg('field._insertRight?', field._insertRight)
         if( field._insertRight                                  # field allows right insert
             and ((sel_start, sel_to) == field._extent           # and whole field selected
                  or (sel_start == sel_to                        # or nothing selected
         if( field._insertRight                                  # field allows right insert
             and ((sel_start, sel_to) == field._extent           # and whole field selected
                  or (sel_start == sel_to                        # or nothing selected
@@ -4616,7 +4706,7 @@ class wxMaskedEditMixin:
                           or (field._allowInsert                # or field allows right-insert
                               and sel_start < end               # next to other char in field:
                               and text[sel_start] != field._fillChar) ) ) ) ):
                           or (field._allowInsert                # or field allows right-insert
                               and sel_start < end               # next to other char in field:
                               and text[sel_start] != field._fillChar) ) ) ) ):
-            dbg('insertRight')
+##            dbg('insertRight')
             fstr = text[start:end]
             erasable_chars = [field._fillChar, ' ']
 
             fstr = text[start:end]
             erasable_chars = [field._fillChar, ' ']
 
@@ -4624,42 +4714,42 @@ class wxMaskedEditMixin:
                 erasable_chars.append('0')
 
             erased = ''
                 erasable_chars.append('0')
 
             erased = ''
-##            dbg("fstr[0]:'%s'" % fstr[0])
-##            dbg('field_index:', field._index)
-##            dbg("fstr[0] in erasable_chars?", fstr[0] in erasable_chars)
-##            dbg("self._signOk and field._index == 0 and fstr[0] in ('-','(')?",
+####            dbg("fstr[0]:'%s'" % fstr[0])
+####            dbg('field_index:', field._index)
+####            dbg("fstr[0] in erasable_chars?", fstr[0] in erasable_chars)
+####            dbg("self._signOk and field._index == 0 and fstr[0] in ('-','(')?",
 ##                 self._signOk and field._index == 0 and fstr[0] in ('-','('))
             if fstr[0] in erasable_chars or (self._signOk and field._index == 0 and fstr[0] in ('-','(')):
                 erased = fstr[0]
 ##                 self._signOk and field._index == 0 and fstr[0] in ('-','('))
             if fstr[0] in erasable_chars or (self._signOk and field._index == 0 and fstr[0] in ('-','(')):
                 erased = fstr[0]
-##                dbg('value:      "%s"' % text)
-##                dbg('fstr:       "%s"' % fstr)
-##                dbg("erased:     '%s'" % erased)
+####                dbg('value:      "%s"' % text)
+####                dbg('fstr:       "%s"' % fstr)
+####                dbg("erased:     '%s'" % erased)
                 field_sel_start = sel_start - start
                 field_sel_to = sel_to - start
                 field_sel_start = sel_start - start
                 field_sel_to = sel_to - start
-                dbg('left fstr:  "%s"' % fstr[1:field_sel_start])
-                dbg('right fstr: "%s"' % fstr[field_sel_to:end])
+##                dbg('left fstr:  "%s"' % fstr[1:field_sel_start])
+##                dbg('right fstr: "%s"' % fstr[field_sel_to:end])
                 fstr = fstr[1:field_sel_start] + char + fstr[field_sel_to:end]
             if field._alignRight and sel_start != sel_to:
                 field_len = end - start
 ##                pos += (field_len - len(fstr))    # move cursor right by deleted amount
                 pos = sel_to
                 fstr = fstr[1:field_sel_start] + char + fstr[field_sel_to:end]
             if field._alignRight and sel_start != sel_to:
                 field_len = end - start
 ##                pos += (field_len - len(fstr))    # move cursor right by deleted amount
                 pos = sel_to
-                dbg('setting pos to:', pos)
+##                dbg('setting pos to:', pos)
                 if field._padZero:
                     fstr = '0' * (field_len - len(fstr)) + fstr
                 else:
                     fstr = fstr.rjust(field_len)   # adjust the field accordingly
                 if field._padZero:
                     fstr = '0' * (field_len - len(fstr)) + fstr
                 else:
                     fstr = fstr.rjust(field_len)   # adjust the field accordingly
-            dbg('field str: "%s"' % fstr)
+##            dbg('field str: "%s"' % fstr)
 
             newtext = text[:start] + fstr + text[end:]
             if erased in ('-', '(') and self._signOk:
                 newtext = erased + newtext[1:]
 
             newtext = text[:start] + fstr + text[end:]
             if erased in ('-', '(') and self._signOk:
                 newtext = erased + newtext[1:]
-            dbg('newtext: "%s"' % newtext)
+##            dbg('newtext: "%s"' % newtext)
 
             if self._signOk and field._index == 0:
                 start -= 1             # account for sign position
 
 
             if self._signOk and field._index == 0:
                 start -= 1             # account for sign position
 
-##            dbg('field._moveOnFieldFull?', field._moveOnFieldFull)
-##            dbg('len(fstr.lstrip()) == end-start?', len(fstr.lstrip()) == end-start)
+####            dbg('field._moveOnFieldFull?', field._moveOnFieldFull)
+####            dbg('len(fstr.lstrip()) == end-start?', len(fstr.lstrip()) == end-start)
             if( field._moveOnFieldFull and pos == end
                 and len(fstr.lstrip()) == end-start):   # if field now full
                 newpos = self._findNextEntry(end)       #   go to next field
             if( field._moveOnFieldFull and pos == end
                 and len(fstr.lstrip()) == end-start):   # if field now full
                 newpos = self._findNextEntry(end)       #   go to next field
@@ -4667,9 +4757,10 @@ class wxMaskedEditMixin:
                 newpos = pos                            # else keep cursor at current position
 
         if not newtext:
                 newpos = pos                            # else keep cursor at current position
 
         if not newtext:
-            dbg('not newtext')
+##            dbg('not newtext')
             if newpos != pos:
             if newpos != pos:
-                dbg('newpos:', newpos)
+##                dbg('newpos:', newpos)
+                pass
             if self._signOk and self._useParens:
                 old_right_signpos = text.find(')')
 
             if self._signOk and self._useParens:
                 old_right_signpos = text.find(')')
 
@@ -4678,10 +4769,10 @@ class wxMaskedEditMixin:
                 field_len = end - start
                 before = text[start:sel_start]
                 after = text[sel_to:end].strip()
                 field_len = end - start
                 before = text[start:sel_start]
                 after = text[sel_to:end].strip()
-##                dbg("current field:'%s'" % text[start:end])
-##                dbg("before:'%s'" % before, "after:'%s'" % after)
+####                dbg("current field:'%s'" % text[start:end])
+####                dbg("before:'%s'" % before, "after:'%s'" % after)
                 new_len = len(before) + len(after) + 1 # (for inserted char)
                 new_len = len(before) + len(after) + 1 # (for inserted char)
-##                dbg('new_len:', new_len)
+####                dbg('new_len:', new_len)
 
                 if new_len < field_len:
                     retained = after + self._template[end-(field_len-new_len):end]
 
                 if new_len < field_len:
                     retained = after + self._template[end-(field_len-new_len):end]
@@ -4691,7 +4782,7 @@ class wxMaskedEditMixin:
                     retained = after
 
                 left = text[0:start] + before
                     retained = after
 
                 left = text[0:start] + before
-##                dbg("left:'%s'" % left, "retained:'%s'" % retained)
+####                dbg("left:'%s'" % left, "retained:'%s'" % retained)
                 right   = retained + text[end:]
             else:
                 left  = text[0:pos]
                 right   = retained + text[end:]
             else:
                 left  = text[0:pos]
@@ -4720,16 +4811,16 @@ class wxMaskedEditMixin:
                             else:
                                 rstripped_text = newtext.rstrip()
                                 right_signpos = len(rstripped_text)
                             else:
                                 rstripped_text = newtext.rstrip()
                                 right_signpos = len(rstripped_text)
-                                dbg('old_right_signpos:', old_right_signpos, 'right signpos now:', right_signpos)
+##                                dbg('old_right_signpos:', old_right_signpos, 'right signpos now:', right_signpos)
                                 newtext = newtext[:right_signpos] + ')' + newtext[right_signpos+1:]
 
             if( field._insertRight                                  # if insert-right field (but we didn't start at right edge)
                 and field._moveOnFieldFull                          # and should move cursor when full
                 and len(newtext[start:end].strip()) == end-start):  # and field now full
                 newpos = self._findNextEntry(end)                   #   go to next field
                                 newtext = newtext[:right_signpos] + ')' + newtext[right_signpos+1:]
 
             if( field._insertRight                                  # if insert-right field (but we didn't start at right edge)
                 and field._moveOnFieldFull                          # and should move cursor when full
                 and len(newtext[start:end].strip()) == end-start):  # and field now full
                 newpos = self._findNextEntry(end)                   #   go to next field
-                dbg('newpos = nextentry =', newpos)
+##                dbg('newpos = nextentry =', newpos)
             else:
             else:
-                dbg('pos:', pos, 'newpos:', pos+1)
+##                dbg('pos:', pos, 'newpos:', pos+1)
                 newpos = pos+1
 
 
                 newpos = pos+1
 
 
@@ -4769,12 +4860,12 @@ class wxMaskedEditMixin:
                         # adjust position to just after partial match in control:
                         newpos = self._masklength - (len(self._ctrl_constraints._choices[match_index].strip()) - len(matched_str.strip()))
 
                         # adjust position to just after partial match in control:
                         newpos = self._masklength - (len(self._ctrl_constraints._choices[match_index].strip()) - len(matched_str.strip()))
 
-            dbg('newtext: "%s"' % newtext, 'newpos:', newpos, 'new_select_to:', new_select_to)
-            dbg(indent=0)
+##            dbg('newtext: "%s"' % newtext, 'newpos:', newpos, 'new_select_to:', new_select_to)
+##            dbg(indent=0)
             return newtext, newpos, new_select_to, match_field, match_index
         else:
             return newtext, newpos, new_select_to, match_field, match_index
         else:
-            dbg('newtext: "%s"' % newtext, 'newpos:', newpos)
-            dbg(indent=0)
+##            dbg('newtext: "%s"' % newtext, 'newpos:', newpos)
+##            dbg(indent=0)
             return newtext, newpos
 
 
             return newtext, newpos
 
 
@@ -4788,8 +4879,8 @@ class wxMaskedEditMixin:
         preserve the correct selection when the focus event is not due to tab,
         we need to pull the following trick:
         """
         preserve the correct selection when the focus event is not due to tab,
         we need to pull the following trick:
         """
-        dbg('wxMaskedEditMixin::_OnFocus')
-        wxCallAfter(self._fixSelection)
+##        dbg('MaskedEditMixin::_OnFocus')
+        wx.CallAfter(self._fixSelection)
         event.Skip()
         self.Refresh()
 
         event.Skip()
         self.Refresh()
 
@@ -4800,41 +4891,42 @@ class wxMaskedEditMixin:
         current value of the control is a "valid value," and has the side
         effect of coloring the control appropriately.
         """
         current value of the control is a "valid value," and has the side
         effect of coloring the control appropriately.
         """
-        dbg(suspend=1)
-        dbg('wxMaskedEditMixin::_CheckValid: candidate="%s"' % candidate, indent=1)
+##        dbg(suspend=1)
+##        dbg('MaskedEditMixin::_CheckValid: candidate="%s"' % candidate, indent=1)
         oldValid = self._valid
         if candidate is None: value = self._GetValue()
         else: value = candidate
         oldValid = self._valid
         if candidate is None: value = self._GetValue()
         else: value = candidate
-        dbg('value: "%s"' % value)
+##        dbg('value: "%s"' % value)
         oldvalue = value
         valid = True    # assume True
 
         if not self.IsDefault(value) and self._isDate:                    ## Date type validation
             valid = self._validateDate(value)
         oldvalue = value
         valid = True    # assume True
 
         if not self.IsDefault(value) and self._isDate:                    ## Date type validation
             valid = self._validateDate(value)
-            dbg("valid date?", valid)
+##            dbg("valid date?", valid)
 
         elif not self.IsDefault(value) and self._isTime:
             valid = self._validateTime(value)
 
         elif not self.IsDefault(value) and self._isTime:
             valid = self._validateTime(value)
-            dbg("valid time?", valid)
+##            dbg("valid time?", valid)
 
         elif not self.IsDefault(value) and (self._isInt or self._isFloat):  ## Numeric type
             valid = self._validateNumeric(value)
 
         elif not self.IsDefault(value) and (self._isInt or self._isFloat):  ## Numeric type
             valid = self._validateNumeric(value)
-            dbg("valid Number?", valid)
+##            dbg("valid Number?", valid)
 
         if valid:   # and not self.IsDefault(value):    ## generic validation accounts for IsDefault()
             ## valid so far; ensure also allowed by any list or regex provided:
             valid = self._validateGeneric(value)
 
         if valid:   # and not self.IsDefault(value):    ## generic validation accounts for IsDefault()
             ## valid so far; ensure also allowed by any list or regex provided:
             valid = self._validateGeneric(value)
-            dbg("valid value?", valid)
+##            dbg("valid value?", valid)
 
 
-        dbg('valid?', valid)
+##        dbg('valid?', valid)
 
         if not candidate:
             self._valid = valid
             self._applyFormatting()
             if self._valid != oldValid:
 
         if not candidate:
             self._valid = valid
             self._applyFormatting()
             if self._valid != oldValid:
-                dbg('validity changed: oldValid =',oldValid,'newvalid =', self._valid)
-                dbg('oldvalue: "%s"' % oldvalue, 'newvalue: "%s"' % self._GetValue())
-        dbg(indent=0, suspend=0)
+##                dbg('validity changed: oldValid =',oldValid,'newvalid =', self._valid)
+##                dbg('oldvalue: "%s"' % oldvalue, 'newvalue: "%s"' % self._GetValue())
+                pass
+##        dbg(indent=0, suspend=0)
         return valid
 
 
         return valid
 
 
@@ -4873,47 +4965,47 @@ class wxMaskedEditMixin:
                         require_digit_at = self._fields[0]._extent[1]-1
                     else:
                         require_digit_at = self._fields[0]._extent[0]
                         require_digit_at = self._fields[0]._extent[1]-1
                     else:
                         require_digit_at = self._fields[0]._extent[0]
-                    dbg('require_digit_at:', require_digit_at)
-                    dbg("value[rda]: '%s'" % value[require_digit_at])
+##                    dbg('require_digit_at:', require_digit_at)
+##                    dbg("value[rda]: '%s'" % value[require_digit_at])
                     if value[require_digit_at] not in list(string.digits):
                         valid = False
                         return valid
                 # else...
                     if value[require_digit_at] not in list(string.digits):
                         valid = False
                         return valid
                 # else...
-            dbg('number:', number)
+##            dbg('number:', number)
             if self._ctrl_constraints._hasRange:
                 valid = self._ctrl_constraints._rangeLow <= number <= self._ctrl_constraints._rangeHigh
             else:
                 valid = True
             groupcharpos = value.rfind(groupchar)
             if groupcharpos != -1:  # group char present
             if self._ctrl_constraints._hasRange:
                 valid = self._ctrl_constraints._rangeLow <= number <= self._ctrl_constraints._rangeHigh
             else:
                 valid = True
             groupcharpos = value.rfind(groupchar)
             if groupcharpos != -1:  # group char present
-                dbg('groupchar found at', groupcharpos)
+##                dbg('groupchar found at', groupcharpos)
                 if self._isFloat and groupcharpos > self._decimalpos:
                     # 1st one found on right-hand side is past decimal point
                 if self._isFloat and groupcharpos > self._decimalpos:
                     # 1st one found on right-hand side is past decimal point
-                    dbg('groupchar in fraction; illegal')
+##                    dbg('groupchar in fraction; illegal')
                     valid = False
                 elif self._isFloat:
                     integer = value[:self._decimalpos].strip()
                 else:
                     integer = value.strip()
                     valid = False
                 elif self._isFloat:
                     integer = value[:self._decimalpos].strip()
                 else:
                     integer = value.strip()
-                dbg("integer:'%s'" % integer)
+##                dbg("integer:'%s'" % integer)
                 if integer[0] in ('-', '('):
                     integer = integer[1:]
                 if integer[-1] == ')':
                     integer = integer[:-1]
 
                 parts = integer.split(groupchar)
                 if integer[0] in ('-', '('):
                     integer = integer[1:]
                 if integer[-1] == ')':
                     integer = integer[:-1]
 
                 parts = integer.split(groupchar)
-                dbg('parts:', parts)
+##                dbg('parts:', parts)
                 for i in range(len(parts)):
                     if i == 0 and abs(int(parts[0])) > 999:
                 for i in range(len(parts)):
                     if i == 0 and abs(int(parts[0])) > 999:
-                        dbg('group 0 too long; illegal')
+##                        dbg('group 0 too long; illegal')
                         valid = False
                         break
                     elif i > 0 and (len(parts[i]) != 3 or ' ' in parts[i]):
                         valid = False
                         break
                     elif i > 0 and (len(parts[i]) != 3 or ' ' in parts[i]):
-                        dbg('group %i (%s) not right size; illegal' % (i, parts[i]))
+##                        dbg('group %i (%s) not right size; illegal' % (i, parts[i]))
                         valid = False
                         break
         except ValueError:
                         valid = False
                         break
         except ValueError:
-            dbg('value not a valid number')
+##            dbg('value not a valid number')
             valid = False
         return valid
 
             valid = False
         return valid
 
@@ -4922,12 +5014,12 @@ class wxMaskedEditMixin:
         """ Validate the current date value using the provided Regex filter.
             Generally used for character types.BufferType
         """
         """ Validate the current date value using the provided Regex filter.
             Generally used for character types.BufferType
         """
-        dbg('wxMaskedEditMixin::_validateDate', indent=1)
+##        dbg('MaskedEditMixin::_validateDate', indent=1)
         if candidate is None: value = self._GetValue()
         else: value = candidate
         if candidate is None: value = self._GetValue()
         else: value = candidate
-        dbg('value = "%s"' % value)
+##        dbg('value = "%s"' % value)
         text = self._adjustDate(value, force4digit_year=True)     ## Fix the date up before validating it
         text = self._adjustDate(value, force4digit_year=True)     ## Fix the date up before validating it
-        dbg('text =', text)
+##        dbg('text =', text)
         valid = True   # assume True until proven otherwise
 
         try:
         valid = True   # assume True until proven otherwise
 
         try:
@@ -4942,19 +5034,19 @@ class wxMaskedEditMixin:
 
             year, month, day = getDateParts( datestr, self._datestyle)
             year = int(year)
 
             year, month, day = getDateParts( datestr, self._datestyle)
             year = int(year)
-            dbg('self._dateExtent:', self._dateExtent)
+##            dbg('self._dateExtent:', self._dateExtent)
             if self._dateExtent == 11:
                 month = charmonths_dict[month.lower()]
             else:
                 month = int(month)
             day = int(day)
             if self._dateExtent == 11:
                 month = charmonths_dict[month.lower()]
             else:
                 month = int(month)
             day = int(day)
-            dbg('year, month, day:', year, month, day)
+##            dbg('year, month, day:', year, month, day)
 
         except ValueError:
 
         except ValueError:
-            dbg('cannot convert string to integer parts')
+##            dbg('cannot convert string to integer parts')
             valid = False
         except KeyError:
             valid = False
         except KeyError:
-            dbg('cannot convert string to integer month')
+##            dbg('cannot convert string to integer month')
             valid = False
 
         if valid:
             valid = False
 
         if valid:
@@ -4966,12 +5058,12 @@ class wxMaskedEditMixin:
             else:
                 month -= 1
                 try:
             else:
                 month -= 1
                 try:
-                    dbg("trying to create date from values day=%d, month=%d, year=%d" % (day,month,year))
-                    dateHandler = wxDateTimeFromDMY(day,month,year)
-                    dbg("succeeded")
+##                    dbg("trying to create date from values day=%d, month=%d, year=%d" % (day,month,year))
+                    dateHandler = wx.DateTimeFromDMY(day,month,year)
+##                    dbg("succeeded")
                     dateOk = True
                 except:
                     dateOk = True
                 except:
-                    dbg('cannot convert string to valid date')
+##                    dbg('cannot convert string to valid date')
                     dateOk = False
                 if not dateOk:
                     valid = False
                     dateOk = False
                 if not dateOk:
                     valid = False
@@ -4981,16 +5073,17 @@ class wxMaskedEditMixin:
                 # so we eliminate them here:
                 timeStr     = text[self._dateExtent+1:].strip()         ## time portion of the string
                 if timeStr:
                 # so we eliminate them here:
                 timeStr     = text[self._dateExtent+1:].strip()         ## time portion of the string
                 if timeStr:
-                    dbg('timeStr: "%s"' % timeStr)
+##                    dbg('timeStr: "%s"' % timeStr)
                     try:
                         checkTime    = dateHandler.ParseTime(timeStr)
                         valid = checkTime == len(timeStr)
                     except:
                         valid = False
                     if not valid:
                     try:
                         checkTime    = dateHandler.ParseTime(timeStr)
                         valid = checkTime == len(timeStr)
                     except:
                         valid = False
                     if not valid:
-                        dbg('cannot convert string to valid time')
+##                        dbg('cannot convert string to valid time')
+                        pass                        
         if valid: dbg('valid date')
         if valid: dbg('valid date')
-        dbg(indent=0)
+##        dbg(indent=0)
         return valid
 
 
         return valid
 
 
@@ -4998,40 +5091,41 @@ class wxMaskedEditMixin:
         """ Validate the current time value using the provided Regex filter.
             Generally used for character types.BufferType
         """
         """ Validate the current time value using the provided Regex filter.
             Generally used for character types.BufferType
         """
-        dbg('wxMaskedEditMixin::_validateTime', indent=1)
+##        dbg('MaskedEditMixin::_validateTime', indent=1)
         # wxDateTime doesn't take kindly to leading/trailing spaces when parsing,
         # so we eliminate them here:
         if candidate is None: value = self._GetValue().strip()
         else: value = candidate.strip()
         # wxDateTime doesn't take kindly to leading/trailing spaces when parsing,
         # so we eliminate them here:
         if candidate is None: value = self._GetValue().strip()
         else: value = candidate.strip()
-        dbg('value = "%s"' % value)
+##        dbg('value = "%s"' % value)
         valid = True   # assume True until proven otherwise
 
         valid = True   # assume True until proven otherwise
 
-        dateHandler = wxDateTime_Today()
+        dateHandler = wx.DateTime_Today()
         try:
             checkTime    = dateHandler.ParseTime(value)
         try:
             checkTime    = dateHandler.ParseTime(value)
-            dbg('checkTime:', checkTime, 'len(value)', len(value))
+##            dbg('checkTime:', checkTime, 'len(value)', len(value))
             valid = checkTime == len(value)
         except:
             valid = False
 
         if not valid:
             valid = checkTime == len(value)
         except:
             valid = False
 
         if not valid:
-            dbg('cannot convert string to valid time')
+##            dbg('cannot convert string to valid time')
+            pass
         if valid: dbg('valid time')
         if valid: dbg('valid time')
-        dbg(indent=0)
+##        dbg(indent=0)
         return valid
 
 
     def _OnKillFocus(self,event):
         """ Handler for EVT_KILL_FOCUS event.
         """
         return valid
 
 
     def _OnKillFocus(self,event):
         """ Handler for EVT_KILL_FOCUS event.
         """
-        dbg('wxMaskedEditMixin::_OnKillFocus', 'isDate=',self._isDate, indent=1)
+##        dbg('MaskedEditMixin::_OnKillFocus', 'isDate=',self._isDate, indent=1)
         if self._mask and self._IsEditable():
             self._AdjustField(self._GetInsertionPoint())
             self._CheckValid()   ## Call valid handler
 
         self._LostFocus()    ## Provided for subclass use
         event.Skip()
         if self._mask and self._IsEditable():
             self._AdjustField(self._GetInsertionPoint())
             self._CheckValid()   ## Call valid handler
 
         self._LostFocus()    ## Provided for subclass use
         event.Skip()
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _fixSelection(self):
 
 
     def _fixSelection(self):
@@ -5048,20 +5142,20 @@ class wxMaskedEditMixin:
         we can assume the cause, change the insertion point to the start of
         the control, and deselect.
         """
         we can assume the cause, change the insertion point to the start of
         the control, and deselect.
         """
-        dbg('wxMaskedEditMixin::_fixSelection', indent=1)
+##        dbg('MaskedEditMixin::_fixSelection', indent=1)
         if not self._mask or not self._IsEditable():
         if not self._mask or not self._IsEditable():
-            dbg(indent=0)
+##            dbg(indent=0)
             return
 
         sel_start, sel_to = self._GetSelection()
             return
 
         sel_start, sel_to = self._GetSelection()
-        dbg('sel_start, sel_to:', sel_start, sel_to, 'self.IsEmpty()?', self.IsEmpty())
+##        dbg('sel_start, sel_to:', sel_start, sel_to, 'self.IsEmpty()?', self.IsEmpty())
 
         if( sel_start == 0 and sel_to >= len( self._mask )   #(can be greater in numeric controls because of reserved space)
             and (not self._ctrl_constraints._autoSelect or self.IsEmpty() or self.IsDefault() ) ):
             # This isn't normally allowed, and so assume we got here by the new
             # "tab traversal" behavior, so we need to reset the selection
             # and insertion point:
 
         if( sel_start == 0 and sel_to >= len( self._mask )   #(can be greater in numeric controls because of reserved space)
             and (not self._ctrl_constraints._autoSelect or self.IsEmpty() or self.IsDefault() ) ):
             # This isn't normally allowed, and so assume we got here by the new
             # "tab traversal" behavior, so we need to reset the selection
             # and insertion point:
-            dbg('entire text selected; resetting selection to start of control')
+##            dbg('entire text selected; resetting selection to start of control')
             self._goHome()
             field = self._FindField(self._GetInsertionPoint())
             edit_start, edit_end = field._extent
             self._goHome()
             field = self._FindField(self._GetInsertionPoint())
             edit_start, edit_end = field._extent
@@ -5081,25 +5175,26 @@ class wxMaskedEditMixin:
                 edit_start, edit_end = integer._extent
 
                 if integer._selectOnFieldEntry:
                 edit_start, edit_end = integer._extent
 
                 if integer._selectOnFieldEntry:
-                    dbg('select on field entry:')
+##                    dbg('select on field entry:')
                     self._SetInsertionPoint(edit_start)
                     self._SetSelection(edit_start, edit_end)
 
                 elif integer._insertRight:
                     self._SetInsertionPoint(edit_start)
                     self._SetSelection(edit_start, edit_end)
 
                 elif integer._insertRight:
-                    dbg('moving insertion point to end')
+##                    dbg('moving insertion point to end')
                     self._SetInsertionPoint(edit_end)
                     self._SetSelection(edit_end, edit_end)
                 else:
                     self._SetInsertionPoint(edit_end)
                     self._SetSelection(edit_end, edit_end)
                 else:
-                    dbg('numeric ctrl is empty; start at beginning after sign')
+##                    dbg('numeric ctrl is empty; start at beginning after sign')
                     self._SetInsertionPoint(signpos+1)   ## Move past minus sign space if signed
                     self._SetSelection(signpos+1, signpos+1)
 
         elif sel_start > self._goEnd(getPosOnly=True):
                     self._SetInsertionPoint(signpos+1)   ## Move past minus sign space if signed
                     self._SetSelection(signpos+1, signpos+1)
 
         elif sel_start > self._goEnd(getPosOnly=True):
-            dbg('cursor beyond the end of the user input; go to end of it')
+##            dbg('cursor beyond the end of the user input; go to end of it')
             self._goEnd()
         else:
             self._goEnd()
         else:
-            dbg('sel_start, sel_to:', sel_start, sel_to, 'self._masklength:', self._masklength)
-        dbg(indent=0)
+##            dbg('sel_start, sel_to:', sel_start, sel_to, 'self._masklength:', self._masklength)
+            pass
+##        dbg(indent=0)
 
 
     def _Keypress(self,key):
 
 
     def _Keypress(self,key):
@@ -5141,11 +5236,11 @@ class wxMaskedEditMixin:
         derived control because the mixin functions can't override a method of
         a sibling class.
         """
         derived control because the mixin functions can't override a method of
         a sibling class.
         """
-        dbg("wxMaskedEditMixin::_Cut", indent=1)
+##        dbg("MaskedEditMixin::_Cut", indent=1)
         value = self._GetValue()
         value = self._GetValue()
-        dbg('current value: "%s"' % value)
+##        dbg('current value: "%s"' % value)
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
         sel_start, sel_to = self._GetSelection()                   ## check for a range of selected text
-        dbg('selected text: "%s"' % value[sel_start:sel_to].strip())
+##        dbg('selected text: "%s"' % value[sel_start:sel_to].strip())
         do = wxTextDataObject()
         do.SetText(value[sel_start:sel_to].strip())
         wxTheClipboard.Open()
         do = wxTextDataObject()
         do.SetText(value[sel_start:sel_to].strip())
         wxTheClipboard.Open()
@@ -5154,7 +5249,7 @@ class wxMaskedEditMixin:
 
         if sel_to - sel_start != 0:
             self._OnErase()
 
         if sel_to - sel_start != 0:
             self._OnErase()
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
 # WS Note: overriding Copy is no longer necessary given that you
 
 
 # WS Note: overriding Copy is no longer necessary given that you
@@ -5198,32 +5293,32 @@ class wxMaskedEditMixin:
         returns validity, replacement text, and extent of paste in
         template.
         """
         returns validity, replacement text, and extent of paste in
         template.
         """
-        dbg(suspend=1)
-        dbg('wxMaskedEditMixin::_validatePaste("%(paste_text)s", %(sel_start)d, %(sel_to)d), raise_on_invalid? %(raise_on_invalid)d' % locals(), indent=1)
+##        dbg(suspend=1)
+##        dbg('MaskedEditMixin::_validatePaste("%(paste_text)s", %(sel_start)d, %(sel_to)d), raise_on_invalid? %(raise_on_invalid)d' % locals(), indent=1)
         select_length = sel_to - sel_start
         maxlength = select_length
         select_length = sel_to - sel_start
         maxlength = select_length
-        dbg('sel_to - sel_start:', maxlength)
+##        dbg('sel_to - sel_start:', maxlength)
         if maxlength == 0:
             maxlength = self._masklength - sel_start
             item = 'control'
         else:
             item = 'selection'
         if maxlength == 0:
             maxlength = self._masklength - sel_start
             item = 'control'
         else:
             item = 'selection'
-        dbg('maxlength:', maxlength)
+##        dbg('maxlength:', maxlength)
         length_considered = len(paste_text)
         if length_considered > maxlength:
         length_considered = len(paste_text)
         if length_considered > maxlength:
-            dbg('paste text will not fit into the %s:' % item, indent=0)
+##            dbg('paste text will not fit into the %s:' % item, indent=0)
             if raise_on_invalid:
             if raise_on_invalid:
-                dbg(indent=0, suspend=0)
+##                dbg(indent=0, suspend=0)
                 if item == 'control':
                     raise ValueError('"%s" will not fit into the control "%s"' % (paste_text, self.name))
                 else:
                     raise ValueError('"%s" will not fit into the selection' % paste_text)
             else:
                 if item == 'control':
                     raise ValueError('"%s" will not fit into the control "%s"' % (paste_text, self.name))
                 else:
                     raise ValueError('"%s" will not fit into the selection' % paste_text)
             else:
-                dbg(indent=0, suspend=0)
+##                dbg(indent=0, suspend=0)
                 return False, None, None
 
         text = self._template
                 return False, None, None
 
         text = self._template
-        dbg('length_considered:', length_considered)
+##        dbg('length_considered:', length_considered)
 
         valid_paste = True
         replacement_text = ""
 
         valid_paste = True
         replacement_text = ""
@@ -5232,7 +5327,7 @@ class wxMaskedEditMixin:
         while valid_paste and i < length_considered and replace_to < self._masklength:
             if paste_text[i:] == self._template[replace_to:length_considered]:
                 # remainder of paste matches template; skip char-by-char analysis
         while valid_paste and i < length_considered and replace_to < self._masklength:
             if paste_text[i:] == self._template[replace_to:length_considered]:
                 # remainder of paste matches template; skip char-by-char analysis
-                dbg('remainder paste_text[%d:] (%s) matches template[%d:%d]' % (i, paste_text[i:], replace_to, length_considered))
+##                dbg('remainder paste_text[%d:] (%s) matches template[%d:%d]' % (i, paste_text[i:], replace_to, length_considered))
                 replacement_text += paste_text[i:]
                 replace_to = i = length_considered
                 continue
                 replacement_text += paste_text[i:]
                 replace_to = i = length_considered
                 continue
@@ -5243,12 +5338,12 @@ class wxMaskedEditMixin:
                 if field._forceupper:   char = char.upper()
                 elif field._forcelower: char = char.lower()
 
                 if field._forceupper:   char = char.upper()
                 elif field._forcelower: char = char.lower()
 
-            dbg('char:', "'"+char+"'", 'i =', i, 'replace_to =', replace_to)
-            dbg('self._isTemplateChar(%d)?' % replace_to, self._isTemplateChar(replace_to))
+##            dbg('char:', "'"+char+"'", 'i =', i, 'replace_to =', replace_to)
+##            dbg('self._isTemplateChar(%d)?' % replace_to, self._isTemplateChar(replace_to))
             if not self._isTemplateChar(replace_to) and self._isCharAllowed( char, replace_to, allowAutoSelect=False, ignoreInsertRight=True):
                 replacement_text += char
             if not self._isTemplateChar(replace_to) and self._isCharAllowed( char, replace_to, allowAutoSelect=False, ignoreInsertRight=True):
                 replacement_text += char
-                dbg("not template(%(replace_to)d) and charAllowed('%(char)s',%(replace_to)d)" % locals())
-                dbg("replacement_text:", '"'+replacement_text+'"')
+##                dbg("not template(%(replace_to)d) and charAllowed('%(char)s',%(replace_to)d)" % locals())
+##                dbg("replacement_text:", '"'+replacement_text+'"')
                 i += 1
                 replace_to += 1
             elif( char == self._template[replace_to]
                 i += 1
                 replace_to += 1
             elif( char == self._template[replace_to]
@@ -5256,8 +5351,8 @@ class wxMaskedEditMixin:
                           ( (i == 0 and (char == '-' or (self._useParens and char == '(')))
                             or (i == self._masklength - 1 and self._useParens and char == ')') ) ) ):
                 replacement_text += char
                           ( (i == 0 and (char == '-' or (self._useParens and char == '(')))
                             or (i == self._masklength - 1 and self._useParens and char == ')') ) ) ):
                 replacement_text += char
-                dbg("'%(char)s' == template(%(replace_to)d)" % locals())
-                dbg("replacement_text:", '"'+replacement_text+'"')
+##                dbg("'%(char)s' == template(%(replace_to)d)" % locals())
+##                dbg("replacement_text:", '"'+replacement_text+'"')
                 i += 1
                 replace_to += 1
             else:
                 i += 1
                 replace_to += 1
             else:
@@ -5266,24 +5361,25 @@ class wxMaskedEditMixin:
                     valid_paste = False
                 else:
                     replacement_text += self._template[replace_to:next_entry]
                     valid_paste = False
                 else:
                     replacement_text += self._template[replace_to:next_entry]
-                    dbg("skipping template; next_entry =", next_entry)
-                    dbg("replacement_text:", '"'+replacement_text+'"')
+##                    dbg("skipping template; next_entry =", next_entry)
+##                    dbg("replacement_text:", '"'+replacement_text+'"')
                     replace_to = next_entry  # so next_entry will be considered on next loop
 
         if not valid_paste and raise_on_invalid:
                     replace_to = next_entry  # so next_entry will be considered on next loop
 
         if not valid_paste and raise_on_invalid:
-            dbg('raising exception', indent=0, suspend=0)
+##            dbg('raising exception', indent=0, suspend=0)
             raise ValueError('"%s" cannot be inserted into the control "%s"' % (paste_text, self.name))
 
         elif i < len(paste_text):
             valid_paste = False
             if raise_on_invalid:
             raise ValueError('"%s" cannot be inserted into the control "%s"' % (paste_text, self.name))
 
         elif i < len(paste_text):
             valid_paste = False
             if raise_on_invalid:
-                dbg('raising exception', indent=0, suspend=0)
+##                dbg('raising exception', indent=0, suspend=0)
                 raise ValueError('"%s" will not fit into the control "%s"' % (paste_text, self.name))
 
                 raise ValueError('"%s" will not fit into the control "%s"' % (paste_text, self.name))
 
-        dbg('valid_paste?', valid_paste)
+##        dbg('valid_paste?', valid_paste)
         if valid_paste:
         if valid_paste:
-            dbg('replacement_text: "%s"' % replacement_text, 'replace to:', replace_to)
-        dbg(indent=0, suspend=0)
+##            dbg('replacement_text: "%s"' % replacement_text, 'replace to:', replace_to)
+            pass
+##        dbg(indent=0, suspend=0)
         return valid_paste, replacement_text, replace_to
 
 
         return valid_paste, replacement_text, replace_to
 
 
@@ -5295,17 +5391,17 @@ class wxMaskedEditMixin:
         derived control because the mixin functions can't override a
         method of a sibling class.
         """
         derived control because the mixin functions can't override a
         method of a sibling class.
         """
-        dbg('wxMaskedEditMixin::_Paste (value = "%s")' % value, indent=1)
+##        dbg('MaskedEditMixin::_Paste (value = "%s")' % value, indent=1)
         if value is None:
             paste_text = self._getClipboardContents()
         else:
             paste_text = value
 
         if paste_text is not None:
         if value is None:
             paste_text = self._getClipboardContents()
         else:
             paste_text = value
 
         if paste_text is not None:
-            dbg('paste text: "%s"' % paste_text)
+##            dbg('paste text: "%s"' % paste_text)
             # (conversion will raise ValueError if paste isn't legal)
             sel_start, sel_to = self._GetSelection()
             # (conversion will raise ValueError if paste isn't legal)
             sel_start, sel_to = self._GetSelection()
-            dbg('selection:', (sel_start, sel_to))
+##            dbg('selection:', (sel_start, sel_to))
 
             # special case: handle allowInsert fields properly
             field = self._FindField(sel_start)
 
             # special case: handle allowInsert fields properly
             field = self._FindField(sel_start)
@@ -5314,7 +5410,7 @@ class wxMaskedEditMixin:
             if field._allowInsert and sel_to <= edit_end and sel_start + len(paste_text) < edit_end:
                 new_pos = sel_start + len(paste_text)   # store for subsequent positioning
                 paste_text = paste_text + self._GetValue()[sel_to:edit_end].rstrip()
             if field._allowInsert and sel_to <= edit_end and sel_start + len(paste_text) < edit_end:
                 new_pos = sel_start + len(paste_text)   # store for subsequent positioning
                 paste_text = paste_text + self._GetValue()[sel_to:edit_end].rstrip()
-                dbg('paste within insertable field; adjusted paste_text: "%s"' % paste_text, 'end:', edit_end)
+##                dbg('paste within insertable field; adjusted paste_text: "%s"' % paste_text, 'end:', edit_end)
                 sel_to = sel_start + len(paste_text)
 
             # Another special case: paste won't fit, but it's a right-insert field where entire
                 sel_to = sel_start + len(paste_text)
 
             # Another special case: paste won't fit, but it's a right-insert field where entire
@@ -5330,7 +5426,7 @@ class wxMaskedEditMixin:
                 amount_needed = len(paste_text) - (sel_to - sel_start)
                 if amount_needed <= empty_space:
                     sel_start -= amount_needed
                 amount_needed = len(paste_text) - (sel_to - sel_start)
                 if amount_needed <= empty_space:
                     sel_start -= amount_needed
-                    dbg('expanded selection to:', (sel_start, sel_to))
+##                    dbg('expanded selection to:', (sel_start, sel_to))
 
 
             # another special case: deal with signed values properly:
 
 
             # another special case: deal with signed values properly:
@@ -5341,10 +5437,10 @@ class wxMaskedEditMixin:
                     paste_signpos = paste_text.find('(')
 
                 # if paste text will result in signed value:
                     paste_signpos = paste_text.find('(')
 
                 # if paste text will result in signed value:
-##                dbg('paste_signpos != -1?', paste_signpos != -1)
-##                dbg('sel_start:', sel_start, 'signpos:', signpos)
-##                dbg('field._insertRight?', field._insertRight)
-##                dbg('sel_start - len(paste_text) >= signpos?', sel_start - len(paste_text) <= signpos)
+####                dbg('paste_signpos != -1?', paste_signpos != -1)
+####                dbg('sel_start:', sel_start, 'signpos:', signpos)
+####                dbg('field._insertRight?', field._insertRight)
+####                dbg('sel_start - len(paste_text) >= signpos?', sel_start - len(paste_text) <= signpos)
                 if paste_signpos != -1 and (sel_start <= signpos
                                             or (field._insertRight and sel_start - len(paste_text) <= signpos)):
                     signed = True
                 if paste_signpos != -1 and (sel_start <= signpos
                                             or (field._insertRight and sel_start - len(paste_text) <= signpos)):
                     signed = True
@@ -5352,32 +5448,32 @@ class wxMaskedEditMixin:
                     signed = False
                 # remove "sign" from paste text, so we can auto-adjust for sign type after paste:
                 paste_text = paste_text.replace('-', ' ').replace('(',' ').replace(')','')
                     signed = False
                 # remove "sign" from paste text, so we can auto-adjust for sign type after paste:
                 paste_text = paste_text.replace('-', ' ').replace('(',' ').replace(')','')
-                dbg('unsigned paste text: "%s"' % paste_text)
+##                dbg('unsigned paste text: "%s"' % paste_text)
             else:
                 signed = False
 
             # another special case: deal with insert-right fields when selection is empty and
             # cursor is at end of field:
             else:
                 signed = False
 
             # another special case: deal with insert-right fields when selection is empty and
             # cursor is at end of field:
-##            dbg('field._insertRight?', field._insertRight)
-##            dbg('sel_start == edit_end?', sel_start == edit_end)
-##            dbg('sel_start', sel_start, 'sel_to', sel_to)
+####            dbg('field._insertRight?', field._insertRight)
+####            dbg('sel_start == edit_end?', sel_start == edit_end)
+####            dbg('sel_start', sel_start, 'sel_to', sel_to)
             if field._insertRight and sel_start == edit_end and sel_start == sel_to:
                 sel_start -= len(paste_text)
                 if sel_start < 0:
                     sel_start = 0
             if field._insertRight and sel_start == edit_end and sel_start == sel_to:
                 sel_start -= len(paste_text)
                 if sel_start < 0:
                     sel_start = 0
-                dbg('adjusted selection:', (sel_start, sel_to))
+##                dbg('adjusted selection:', (sel_start, sel_to))
 
             try:
                 valid_paste, replacement_text, replace_to = self._validatePaste(paste_text, sel_start, sel_to, raise_on_invalid)
             except:
 
             try:
                 valid_paste, replacement_text, replace_to = self._validatePaste(paste_text, sel_start, sel_to, raise_on_invalid)
             except:
-                dbg('exception thrown', indent=0)
+##                dbg('exception thrown', indent=0)
                 raise
 
             if not valid_paste:
                 raise
 
             if not valid_paste:
-                dbg('paste text not legal for the selection or portion of the control following the cursor;')
-                if not wxValidator_IsSilent():
-                    wxBell()
-                dbg(indent=0)
+##                dbg('paste text not legal for the selection or portion of the control following the cursor;')
+                if not wx.Validator_IsSilent():
+                    wx.Bell()
+##                dbg(indent=0)
                 return False
             # else...
             text = self._eraseSelection()
                 return False
             # else...
             text = self._eraseSelection()
@@ -5395,33 +5491,35 @@ class wxMaskedEditMixin:
                     if not self._isNeg:
                         self._isNeg = 1
 
                     if not self._isNeg:
                         self._isNeg = 1
 
-            dbg("new_text:", '"'+new_text+'"')
+##            dbg("new_text:", '"'+new_text+'"')
 
             if not just_return_value:
 
             if not just_return_value:
+                if new_text != self._GetValue():
+                    self.modified = True
                 if new_text == '':
                     self.ClearValue()
                 else:
                 if new_text == '':
                     self.ClearValue()
                 else:
-                    wxCallAfter(self._SetValue, new_text)
+                    wx.CallAfter(self._SetValue, new_text)
                     if new_pos is None:
                         new_pos = sel_start + len(replacement_text)
                     if new_pos is None:
                         new_pos = sel_start + len(replacement_text)
-                    wxCallAfter(self._SetInsertionPoint, new_pos)
+                    wx.CallAfter(self._SetInsertionPoint, new_pos)
             else:
             else:
-                dbg(indent=0)
+##                dbg(indent=0)
                 return new_text
         elif just_return_value:
                 return new_text
         elif just_return_value:
-            dbg(indent=0)
+##            dbg(indent=0)
             return self._GetValue()
             return self._GetValue()
-        dbg(indent=0)
+##        dbg(indent=0)
 
     def _Undo(self):
         """ Provides an Undo() method in base controls. """
 
     def _Undo(self):
         """ Provides an Undo() method in base controls. """
-        dbg("wxMaskedEditMixin::_Undo", indent=1)
+##        dbg("MaskedEditMixin::_Undo", indent=1)
         value = self._GetValue()
         prev = self._prevValue
         value = self._GetValue()
         prev = self._prevValue
-        dbg('current value:  "%s"' % value)
-        dbg('previous value: "%s"' % prev)
+##        dbg('current value:  "%s"' % value)
+##        dbg('previous value: "%s"' % prev)
         if prev is None:
         if prev is None:
-            dbg('no previous value', indent=0)
+##            dbg('no previous value', indent=0)
             return
 
         elif value != prev:
             return
 
         elif value != prev:
@@ -5458,24 +5556,24 @@ class wxMaskedEditMixin:
             # Determine where they stop differing in "undo" result:
             sm = difflib.SequenceMatcher(None, a=value, b=prev)
             i, j, k = sm.find_longest_match(sel_start, length, sel_start, length)
             # Determine where they stop differing in "undo" result:
             sm = difflib.SequenceMatcher(None, a=value, b=prev)
             i, j, k = sm.find_longest_match(sel_start, length, sel_start, length)
-            dbg('i,j,k = ', (i,j,k), 'value[i:i+k] = "%s"' % value[i:i+k], 'prev[j:j+k] = "%s"' % prev[j:j+k] )
+##            dbg('i,j,k = ', (i,j,k), 'value[i:i+k] = "%s"' % value[i:i+k], 'prev[j:j+k] = "%s"' % prev[j:j+k] )
 
             if k == 0:                              # no match found; select to end
                 sel_to = length
             else:
                 code_5tuples = sm.get_opcodes()
                 for op, i1, i2, j1, j2 in code_5tuples:
 
             if k == 0:                              # no match found; select to end
                 sel_to = length
             else:
                 code_5tuples = sm.get_opcodes()
                 for op, i1, i2, j1, j2 in code_5tuples:
-                    dbg("%7s value[%d:%d] (%s) prev[%d:%d] (%s)" %
-                            (op, i1, i2, value[i1:i2], j1, j2, prev[j1:j2]))
+##                    dbg("%7s value[%d:%d] (%s) prev[%d:%d] (%s)" % (op, i1, i2, value[i1:i2], j1, j2, prev[j1:j2]))
+                    pass
 
                 diff_found = False
                 # look backward through operations needed to produce "previous" value;
                 # first change wins:
                 for next_op in range(len(code_5tuples)-1, -1, -1):
                     op, i1, i2, j1, j2 = code_5tuples[next_op]
 
                 diff_found = False
                 # look backward through operations needed to produce "previous" value;
                 # first change wins:
                 for next_op in range(len(code_5tuples)-1, -1, -1):
                     op, i1, i2, j1, j2 = code_5tuples[next_op]
-                    dbg('value[i1:i2]: "%s"' % value[i1:i2], 'template[i1:i2] "%s"' % self._template[i1:i2])
+##                    dbg('value[i1:i2]: "%s"' % value[i1:i2], 'template[i1:i2] "%s"' % self._template[i1:i2])
                     if op == 'insert' and prev[j1:j2] != self._template[j1:j2]:
                     if op == 'insert' and prev[j1:j2] != self._template[j1:j2]:
-                        dbg('insert found: selection =>', (j1, j2))
+##                        dbg('insert found: selection =>', (j1, j2))
                         sel_start = j1
                         sel_to = j2
                         diff_found = True
                         sel_start = j1
                         sel_to = j2
                         diff_found = True
@@ -5489,11 +5587,11 @@ class wxMaskedEditMixin:
                         else:
                             sel_start = i1
                             sel_to = j1
                         else:
                             sel_start = i1
                             sel_to = j1
-                        dbg('delete found: selection =>', (sel_start, sel_to))
+##                        dbg('delete found: selection =>', (sel_start, sel_to))
                         diff_found = True
                         break
                     elif op == 'replace':
                         diff_found = True
                         break
                     elif op == 'replace':
-                        dbg('replace found: selection =>', (j1, j2))
+##                        dbg('replace found: selection =>', (j1, j2))
                         sel_start = j1
                         sel_to = j2
                         diff_found = True
                         sel_start = j1
                         sel_to = j2
                         diff_found = True
@@ -5508,17 +5606,17 @@ class wxMaskedEditMixin:
                         if op == 'equal':
                             continue
                         elif op == 'replace':
                         if op == 'equal':
                             continue
                         elif op == 'replace':
-                            dbg('setting sel_start to', i1)
+##                            dbg('setting sel_start to', i1)
                             sel_start = i1
                             break
                         elif op == 'insert' and not value[i1:i2]:
                             sel_start = i1
                             break
                         elif op == 'insert' and not value[i1:i2]:
-                            dbg('forward %s found' % op)
+##                            dbg('forward %s found' % op)
                             if prev[j1:j2].strip():
                             if prev[j1:j2].strip():
-                                dbg('item to insert non-empty; setting sel_start to', j1)
+##                                dbg('item to insert non-empty; setting sel_start to', j1)
                                 sel_start = j1
                                 break
                             elif not field._insertRight:
                                 sel_start = j1
                                 break
                             elif not field._insertRight:
-                                dbg('setting sel_start to inserted space:', j1)
+##                                dbg('setting sel_start to inserted space:', j1)
                                 sel_start = j1
                                 break
                         elif op == 'delete' and field._insertRight and not value[i1:i2].lstrip():
                                 sel_start = j1
                                 break
                         elif op == 'delete' and field._insertRight and not value[i1:i2].lstrip():
@@ -5529,7 +5627,7 @@ class wxMaskedEditMixin:
 
 
                 if not diff_found:
 
 
                 if not diff_found:
-                    dbg('no insert,delete or replace found (!)')
+##                    dbg('no insert,delete or replace found (!)')
                     # do "left-insert"-centric processing of difference based on l.c.s.:
                     if i == j and j != sel_start:         # match starts after start of selection
                         sel_to = sel_start + (j-sel_start)  # select to start of match
                     # do "left-insert"-centric processing of difference based on l.c.s.:
                     if i == j and j != sel_start:         # match starts after start of selection
                         sel_to = sel_start + (j-sel_start)  # select to start of match
@@ -5573,7 +5671,7 @@ class wxMaskedEditMixin:
             # To get all this right, we use the previous selection recorded to help us...
 
             if (sel_start, sel_to) != self._prevSelection:
             # To get all this right, we use the previous selection recorded to help us...
 
             if (sel_start, sel_to) != self._prevSelection:
-                dbg('calculated selection', (sel_start, sel_to), "doesn't match previous", self._prevSelection)
+##                dbg('calculated selection', (sel_start, sel_to), "doesn't match previous", self._prevSelection)
 
                 prev_sel_start, prev_sel_to = self._prevSelection
                 field = self._FindField(sel_start)
 
                 prev_sel_start, prev_sel_to = self._prevSelection
                 field = self._FindField(sel_start)
@@ -5592,8 +5690,8 @@ class wxMaskedEditMixin:
                     calc_select_len = sel_to - sel_start
                     prev_select_len = prev_sel_to - prev_sel_start
 
                     calc_select_len = sel_to - sel_start
                     prev_select_len = prev_sel_to - prev_sel_start
 
-                    dbg('sel_start == prev_sel_start', sel_start == prev_sel_start)
-                    dbg('sel_to > prev_sel_to', sel_to > prev_sel_to)
+##                    dbg('sel_start == prev_sel_start', sel_start == prev_sel_start)
+##                    dbg('sel_to > prev_sel_to', sel_to > prev_sel_to)
 
                     if prev_select_len >= calc_select_len:
                         # old selection was bigger; trust it:
 
                     if prev_select_len >= calc_select_len:
                         # old selection was bigger; trust it:
@@ -5604,7 +5702,7 @@ class wxMaskedEditMixin:
                           and sel_to == len(self._template) ):  # and calculated selection goes to end of control
 
                         i, j, k = sm.find_longest_match(prev_sel_to, length, prev_sel_to, length)
                           and sel_to == len(self._template) ):  # and calculated selection goes to end of control
 
                         i, j, k = sm.find_longest_match(prev_sel_to, length, prev_sel_to, length)
-                        dbg('i,j,k = ', (i,j,k), 'value[i:i+k] = "%s"' % value[i:i+k], 'prev[j:j+k] = "%s"' % prev[j:j+k] )
+##                        dbg('i,j,k = ', (i,j,k), 'value[i:i+k] = "%s"' % value[i:i+k], 'prev[j:j+k] = "%s"' % prev[j:j+k] )
                         if k > 0:
                             # difflib must not have optimized opcodes properly;
                             sel_to = j
                         if k > 0:
                             # difflib must not have optimized opcodes properly;
                             sel_to = j
@@ -5627,9 +5725,9 @@ class wxMaskedEditMixin:
                         else:
                             test_sel_start, test_sel_to = prev_sel_start, prev_sel_to
 
                         else:
                             test_sel_start, test_sel_to = prev_sel_start, prev_sel_to
 
-                        dbg('test selection:', (test_sel_start, test_sel_to))
-                        dbg('calc change: "%s"' % self._prevValue[sel_start:sel_to])
-                        dbg('test change: "%s"' % self._prevValue[test_sel_start:test_sel_to])
+##                        dbg('test selection:', (test_sel_start, test_sel_to))
+##                        dbg('calc change: "%s"' % self._prevValue[sel_start:sel_to])
+##                        dbg('test change: "%s"' % self._prevValue[test_sel_start:test_sel_to])
 
                         # if calculated selection spans characters, and same characters
                         # "before" the previous insertion point are present there as well,
 
                         # if calculated selection spans characters, and same characters
                         # "before" the previous insertion point are present there as well,
@@ -5640,14 +5738,15 @@ class wxMaskedEditMixin:
 
                             sel_start, sel_to = test_sel_start, test_sel_to
 
 
                             sel_start, sel_to = test_sel_start, test_sel_to
 
-            dbg('sel_start, sel_to:', sel_start, sel_to)
-            dbg('previous value: "%s"' % self._prevValue)
+##            dbg('sel_start, sel_to:', sel_start, sel_to)
+##            dbg('previous value: "%s"' % self._prevValue)
             self._SetValue(self._prevValue)
             self._SetInsertionPoint(sel_start)
             self._SetSelection(sel_start, sel_to)
         else:
             self._SetValue(self._prevValue)
             self._SetInsertionPoint(sel_start)
             self._SetSelection(sel_start, sel_to)
         else:
-            dbg('no difference between previous value')
-        dbg(indent=0)
+##            dbg('no difference between previous value')
+            pass
+##        dbg(indent=0)
 
 
     def _OnClear(self, event):
 
 
     def _OnClear(self, event):
@@ -5656,7 +5755,7 @@ class wxMaskedEditMixin:
 
 
     def _OnContextMenu(self, event):
 
 
     def _OnContextMenu(self, event):
-        dbg('wxMaskedEditMixin::OnContextMenu()', indent=1)
+##        dbg('MaskedEditMixin::OnContextMenu()', indent=1)
         menu = wxMenu()
         menu.Append(wxID_UNDO, "Undo", "")
         menu.AppendSeparator()
         menu = wxMenu()
         menu.Append(wxID_UNDO, "Undo", "")
         menu.AppendSeparator()
@@ -5687,7 +5786,7 @@ class wxMaskedEditMixin:
         self.PopupMenu(menu, event.GetPosition())
         menu.Destroy()
         self._contextMenu = None
         self.PopupMenu(menu, event.GetPosition())
         menu.Destroy()
         self._contextMenu = None
-        dbg(indent=0)
+##        dbg(indent=0)
 
     def _UndoUpdateUI(self, event):
         if self._prevValue is None or self._prevValue == self._curValue:
 
     def _UndoUpdateUI(self, event):
         if self._prevValue is None or self._prevValue == self._curValue:
@@ -5696,105 +5795,166 @@ class wxMaskedEditMixin:
             self._contextMenu.Enable(wxID_UNDO, True)
 
 
             self._contextMenu.Enable(wxID_UNDO, True)
 
 
-## ---------- ---------- ---------- ---------- ---------- ---------- ----------
+    def _OnCtrlParametersChanged(self):
+        """
+        Overridable function to allow derived classes to take action as a
+        result of parameter changes prior to possibly changing the value
+        of the control.
+        """
+        pass
+
+ ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
+# ## TRICKY BIT: to avoid a ton of boiler-plate, and to
+# ## automate the getter/setter generation for each valid
+# ## control parameter so we never forget to add the
+# ## functions when adding parameters, this loop
+# ## programmatically adds them to the class:
+# ## (This makes it easier for Designers like Boa to
+# ## deal with masked controls.)
+#
+# ## To further complicate matters, this is done with an
+# ## extra level of inheritance, so that "general" classes like
+# ## MaskedTextCtrl can have all possible attributes,
+# ## while derived classes, like TimeCtrl and MaskedNumCtrl
+# ## can prevent exposure of those optional attributes of their base
+# ## class that do not make sense for their derivation.  Therefore,
+# ## we define
+# ##    BaseMaskedTextCtrl(TextCtrl, MaskedEditMixin)
+# ## and
+# ##    MaskedTextCtrl(BaseMaskedTextCtrl, MaskedEditAccessorsMixin).
+# ##
+# ## This allows us to then derive:
+# ##    MaskedNumCtrl( BaseMaskedTextCtrl )
+# ##
+# ## and not have to expose all the same accessor functions for the
+# ## derived control when they don't all make sense for it.
+# ##
+class MaskedEditAccessorsMixin:
+
+    # Define the default set of attributes exposed by the most generic masked controls:
+    exposed_basectrl_params = MaskedEditMixin.valid_ctrl_params.keys() + Field.valid_params.keys()
+    exposed_basectrl_params.remove('index')
+    exposed_basectrl_params.remove('extent')
+    exposed_basectrl_params.remove('foregroundColour')   # (base class already has this)
+
+    for param in exposed_basectrl_params:
+        propname = param[0].upper() + param[1:]
+        exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+        exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+
+        if param.find('Colour') != -1:
+            # add non-british spellings, for backward-compatibility
+            propname.replace('Colour', 'Color')
+
+            exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+            exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+
+
 
 
-class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
+
+class BaseMaskedTextCtrl( wx.TextCtrl, MaskedEditMixin ):
     """
     """
-    This is the primary derivation from wxMaskedEditMixin.  It provides
+    This is the primary derivation from MaskedEditMixin.  It provides
     a general masked text control that can be configured with different
     a general masked text control that can be configured with different
-    masks.
+    masks.  It's actually a "base masked textCtrl", so that the
+    MaskedTextCtrl class can be derived from it, and add those
+    accessor functions to it that are appropriate to the general class,
+    whilst other classes can derive from BaseMaskedTextCtrl, and
+    only define those accessor functions that are appropriate for
+    those derivations.
     """
 
     def __init__( self, parent, id=-1, value = '',
     """
 
     def __init__( self, parent, id=-1, value = '',
-                  pos = wxDefaultPosition,
-                  size = wxDefaultSize,
-                  style = wxTE_PROCESS_TAB,
-                  validator=wxDefaultValidator,     ## placeholder provided for data-transfer logic
+                  pos = wx.DefaultPosition,
+                  size = wx.DefaultSize,
+                  style = wx.TE_PROCESS_TAB,
+                  validator=wx.DefaultValidator,     ## placeholder provided for data-transfer logic
                   name = 'maskedTextCtrl',
                   setupEventHandling = True,        ## setup event handling by default
                   **kwargs):
 
                   name = 'maskedTextCtrl',
                   setupEventHandling = True,        ## setup event handling by default
                   **kwargs):
 
-        wxTextCtrl.__init__(self, parent, id, value='',
+        wx.TextCtrl.__init__(self, parent, id, value='',
                             pos=pos, size = size,
                             style=style, validator=validator,
                             name=name)
 
         self.controlInitialized = True
                             pos=pos, size = size,
                             style=style, validator=validator,
                             name=name)
 
         self.controlInitialized = True
-        wxMaskedEditMixin.__init__( self, name, **kwargs )
+        MaskedEditMixin.__init__( self, name, **kwargs )
+
         self._SetInitialValue(value)
 
         if setupEventHandling:
             ## Setup event handlers
         self._SetInitialValue(value)
 
         if setupEventHandling:
             ## Setup event handlers
-            EVT_SET_FOCUS( self, self._OnFocus )        ## defeat automatic full selection
-            EVT_KILL_FOCUS( self, self._OnKillFocus )   ## run internal validator
-            EVT_LEFT_DCLICK(self, self._OnDoubleClick)  ## select field under cursor on dclick
-            EVT_RIGHT_UP(self, self._OnContextMenu )    ## bring up an appropriate context menu
-            EVT_KEY_DOWN( self, self._OnKeyDown )       ## capture control events not normally seen, eg ctrl-tab.
-            EVT_CHAR( self, self._OnChar )              ## handle each keypress
-            EVT_TEXT( self, self.GetId(), self._OnTextChange )  ## color control appropriately & keep
+            self.Bind(wx.EVT_SET_FOCUS, self._OnFocus )         ## defeat automatic full selection
+            self.Bind(wx.EVT_KILL_FOCUS, self._OnKillFocus )    ## run internal validator
+            self.Bind(wx.EVT_LEFT_DCLICK, self._OnDoubleClick)  ## select field under cursor on dclick
+            self.Bind(wx.EVT_RIGHT_UP, self._OnContextMenu )    ## bring up an appropriate context menu
+            self.Bind(wx.EVT_KEY_DOWN, self._OnKeyDown )        ## capture control events not normally seen, eg ctrl-tab.
+            self.Bind(wx.EVT_CHAR, self._OnChar )               ## handle each keypress
+            self.Bind(wx.EVT_TEXT, self._OnTextChange )         ## color control appropriately & keep
                                                                 ## track of previous value for undo
 
 
     def __repr__(self):
                                                                 ## track of previous value for undo
 
 
     def __repr__(self):
-        return "<wxMaskedTextCtrl: %s>" % self.GetValue()
+        return "<BaseMaskedTextCtrl: %s>" % self.GetValue()
 
 
     def _GetSelection(self):
         """
         Allow mixin to get the text selection of this control.
 
 
     def _GetSelection(self):
         """
         Allow mixin to get the text selection of this control.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return self.GetSelection()
 
     def _SetSelection(self, sel_start, sel_to):
         """
         Allow mixin to set the text selection of this control.
         """
         return self.GetSelection()
 
     def _SetSelection(self, sel_start, sel_to):
         """
         Allow mixin to set the text selection of this control.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         """
-##        dbg("wxMaskedTextCtrl::_SetSelection(%(sel_start)d, %(sel_to)d)" % locals())
+####        dbg("MaskedTextCtrl::_SetSelection(%(sel_start)d, %(sel_to)d)" % locals())
         return self.SetSelection( sel_start, sel_to )
 
     def SetSelection(self, sel_start, sel_to):
         """
         This is just for debugging...
         """
         return self.SetSelection( sel_start, sel_to )
 
     def SetSelection(self, sel_start, sel_to):
         """
         This is just for debugging...
         """
-        dbg("wxMaskedTextCtrl::SetSelection(%(sel_start)d, %(sel_to)d)" % locals())
-        wxTextCtrl.SetSelection(self, sel_start, sel_to)
+##        dbg("MaskedTextCtrl::SetSelection(%(sel_start)d, %(sel_to)d)" % locals())
+        wx.TextCtrl.SetSelection(self, sel_start, sel_to)
 
 
     def _GetInsertionPoint(self):
         return self.GetInsertionPoint()
 
     def _SetInsertionPoint(self, pos):
 
 
     def _GetInsertionPoint(self):
         return self.GetInsertionPoint()
 
     def _SetInsertionPoint(self, pos):
-##        dbg("wxMaskedTextCtrl::_SetInsertionPoint(%(pos)d)" % locals())
+####        dbg("MaskedTextCtrl::_SetInsertionPoint(%(pos)d)" % locals())
         self.SetInsertionPoint(pos)
 
     def SetInsertionPoint(self, pos):
         """
         This is just for debugging...
         """
         self.SetInsertionPoint(pos)
 
     def SetInsertionPoint(self, pos):
         """
         This is just for debugging...
         """
-        dbg("wxMaskedTextCtrl::SetInsertionPoint(%(pos)d)" % locals())
-        wxTextCtrl.SetInsertionPoint(self, pos)
+##        dbg("MaskedTextCtrl::SetInsertionPoint(%(pos)d)" % locals())
+        wx.TextCtrl.SetInsertionPoint(self, pos)
 
 
     def _GetValue(self):
         """
         Allow mixin to get the raw value of the control with this function.
 
 
     def _GetValue(self):
         """
         Allow mixin to get the raw value of the control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return self.GetValue()
 
     def _SetValue(self, value):
         """
         Allow mixin to set the raw value of the control with this function.
         """
         return self.GetValue()
 
     def _SetValue(self, value):
         """
         Allow mixin to set the raw value of the control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         """
-        dbg('wxMaskedTextCtrl::_SetValue("%(value)s")' % locals(), indent=1)
+##        dbg('MaskedTextCtrl::_SetValue("%(value)s")' % locals(), indent=1)
         # Record current selection and insertion point, for undo
         self._prevSelection = self._GetSelection()
         self._prevInsertionPoint = self._GetInsertionPoint()
         # Record current selection and insertion point, for undo
         self._prevSelection = self._GetSelection()
         self._prevInsertionPoint = self._GetInsertionPoint()
-        wxTextCtrl.SetValue(self, value)
-        dbg(indent=0)
+        wx.TextCtrl.SetValue(self, value)
+##        dbg(indent=0)
 
     def SetValue(self, value):
         """
 
     def SetValue(self, value):
         """
@@ -5803,10 +5963,10 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         masked control.  NOTE: this must be done in the class derived
         from the base wx control.
         """
         masked control.  NOTE: this must be done in the class derived
         from the base wx control.
         """
-        dbg('wxMaskedTextCtrl::SetValue = "%s"' % value, indent=1)
+##        dbg('MaskedTextCtrl::SetValue = "%s"' % value, indent=1)
 
         if not self._mask:
 
         if not self._mask:
-            wxTextCtrl.SetValue(self, value)    # revert to base control behavior
+            wx.TextCtrl.SetValue(self, value)    # revert to base control behavior
             return
 
         # empty previous contents, replacing entire value:
             return
 
         # empty previous contents, replacing entire value:
@@ -5823,12 +5983,12 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
             and (self._isFloat or self._isInt)            # and it's a numeric control
             and self._ctrl_constraints._alignRight ):   # and it's a right-aligned control
 
             and (self._isFloat or self._isInt)            # and it's a numeric control
             and self._ctrl_constraints._alignRight ):   # and it's a right-aligned control
 
-            dbg('len(value)', len(value), ' < self._masklength', self._masklength)
+##            dbg('len(value)', len(value), ' < self._masklength', self._masklength)
             # try to intelligently "pad out" the value to the right size:
             value = self._template[0:self._masklength - len(value)] + value
             if self._isFloat and value.find('.') == -1:
                 value = value[1:]
             # try to intelligently "pad out" the value to the right size:
             value = self._template[0:self._masklength - len(value)] + value
             if self._isFloat and value.find('.') == -1:
                 value = value[1:]
-            dbg('padded value = "%s"' % value)
+##            dbg('padded value = "%s"' % value)
 
         # make SetValue behave the same as if you had typed the value in:
         try:
 
         # make SetValue behave the same as if you had typed the value in:
         try:
@@ -5847,36 +6007,37 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
                 dateparts = value.split(' ')
                 dateparts[0] = self._adjustDate(dateparts[0], fixcentury=True)
                 value = string.join(dateparts, ' ')
                 dateparts = value.split(' ')
                 dateparts[0] = self._adjustDate(dateparts[0], fixcentury=True)
                 value = string.join(dateparts, ' ')
-                dbg('adjusted value: "%s"' % value)
+##                dbg('adjusted value: "%s"' % value)
                 value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
             else:
                 value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
             else:
-                dbg('exception thrown', indent=0)
+##                dbg('exception thrown', indent=0)
                 raise
 
                 raise
 
-        self._SetValue(value)
-##        dbg('queuing insertion after .SetValue', self._masklength)
-        wxCallAfter(self._SetInsertionPoint, self._masklength)
-        wxCallAfter(self._SetSelection, self._masklength, self._masklength)
-        dbg(indent=0)
+        self._SetValue(value)   # note: to preserve similar capability, .SetValue()
+                                # does not change IsModified()
+####        dbg('queuing insertion after .SetValue', self._masklength)
+        wx.CallAfter(self._SetInsertionPoint, self._masklength)
+        wx.CallAfter(self._SetSelection, self._masklength, self._masklength)
+##        dbg(indent=0)
 
 
     def Clear(self):
         """ Blanks the current control value by replacing it with the default value."""
 
 
     def Clear(self):
         """ Blanks the current control value by replacing it with the default value."""
-        dbg("wxMaskedTextCtrl::Clear - value reset to default value (template)")
+##        dbg("MaskedTextCtrl::Clear - value reset to default value (template)")
         if self._mask:
             self.ClearValue()
         else:
         if self._mask:
             self.ClearValue()
         else:
-            wxTextCtrl.Clear(self)    # else revert to base control behavior
+            wx.TextCtrl.Clear(self)    # else revert to base control behavior
 
 
     def _Refresh(self):
         """
         Allow mixin to refresh the base control with this function.
 
 
     def _Refresh(self):
         """
         Allow mixin to refresh the base control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         """
-        dbg('wxMaskedTextCtrl::_Refresh', indent=1)
-        wxTextCtrl.Refresh(self)
-        dbg(indent=0)
+##        dbg('MaskedTextCtrl::_Refresh', indent=1)
+        wx.TextCtrl.Refresh(self)
+##        dbg(indent=0)
 
 
     def Refresh(self):
 
 
     def Refresh(self):
@@ -5885,18 +6046,18 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         validate the contents of the masked control as it refreshes.
         NOTE: this must be done in the class derived from the base wx control.
         """
         validate the contents of the masked control as it refreshes.
         NOTE: this must be done in the class derived from the base wx control.
         """
-        dbg('wxMaskedTextCtrl::Refresh', indent=1)
+##        dbg('MaskedTextCtrl::Refresh', indent=1)
         self._CheckValid()
         self._Refresh()
         self._CheckValid()
         self._Refresh()
-        dbg(indent=0)
+##        dbg(indent=0)
 
 
     def _IsEditable(self):
         """
         Allow mixin to determine if the base control is editable with this function.
 
 
     def _IsEditable(self):
         """
         Allow mixin to determine if the base control is editable with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         """
-        return wxTextCtrl.IsEditable(self)
+        return wx.TextCtrl.IsEditable(self)
 
 
     def Cut(self):
 
 
     def Cut(self):
@@ -5909,7 +6070,7 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         if self._mask:
             self._Cut()             # call the mixin's Cut method
         else:
         if self._mask:
             self._Cut()             # call the mixin's Cut method
         else:
-            wxTextCtrl.Cut(self)    # else revert to base control behavior
+            wx.TextCtrl.Cut(self)    # else revert to base control behavior
 
 
     def Paste(self):
 
 
     def Paste(self):
@@ -5922,7 +6083,7 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         if self._mask:
             self._Paste()                   # call the mixin's Paste method
         else:
         if self._mask:
             self._Paste()                   # call the mixin's Paste method
         else:
-            wxTextCtrl.Paste(self, value)   # else revert to base control behavior
+            wx.TextCtrl.Paste(self, value)   # else revert to base control behavior
 
 
     def Undo(self):
 
 
     def Undo(self):
@@ -5933,7 +6094,7 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         if self._mask:
             self._Undo()
         else:
         if self._mask:
             self._Undo()
         else:
-            wxTextCtrl.Undo(self)   # else revert to base control behavior
+            wx.TextCtrl.Undo(self)   # else revert to base control behavior
 
 
     def IsModified(self):
 
 
     def IsModified(self):
@@ -5944,7 +6105,7 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         keystroke to see if the value changes, and if so, it's been
         modified.
         """
         keystroke to see if the value changes, and if so, it's been
         modified.
         """
-        return wxTextCtrl.IsModified(self) or self.modified
+        return wx.TextCtrl.IsModified(self) or self.modified
 
 
     def _CalcSize(self, size=None):
 
 
     def _CalcSize(self, size=None):
@@ -5954,12 +6115,22 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
         return self._calcSize(size)
 
 
         return self._calcSize(size)
 
 
+class MaskedTextCtrl( BaseMaskedTextCtrl, MaskedEditAccessorsMixin ):
+    """
+    This extra level of inheritance allows us to add the generic set of
+    masked edit parameters only to this class while allowing other
+    classes to derive from the "base" masked text control, and provide
+    a smaller set of valid accessor functions.
+    """
+    pass
+
+
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 ## Because calling SetSelection programmatically does not fire EVT_COMBOBOX
 ## events, we have to do it ourselves when we auto-complete.
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 ## Because calling SetSelection programmatically does not fire EVT_COMBOBOX
 ## events, we have to do it ourselves when we auto-complete.
-class wxMaskedComboBoxSelectEvent(wxPyCommandEvent):
+class MaskedComboBoxSelectEvent(wx.PyCommandEvent):
     def __init__(self, id, selection = 0, object=None):
     def __init__(self, id, selection = 0, object=None):
-        wxPyCommandEvent.__init__(self, wxEVT_COMMAND_COMBOBOX_SELECTED, id)
+        wx.PyCommandEvent.__init__(self, wx.wxEVT_COMMAND_COMBOBOX_SELECTED, id)
 
         self.__selection = selection
         self.SetEventObject(object)
 
         self.__selection = selection
         self.SetEventObject(object)
@@ -5970,17 +6141,17 @@ class wxMaskedComboBoxSelectEvent(wxPyCommandEvent):
         return self.__selection
 
 
         return self.__selection
 
 
-class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
+class BaseMaskedComboBox( wx.ComboBox, MaskedEditMixin ):
     """
     This masked edit control adds the ability to use a masked input
     on a combobox, and do auto-complete of such values.
     """
     def __init__( self, parent, id=-1, value = '',
     """
     This masked edit control adds the ability to use a masked input
     on a combobox, and do auto-complete of such values.
     """
     def __init__( self, parent, id=-1, value = '',
-                  pos = wxDefaultPosition,
-                  size = wxDefaultSize,
+                  pos = wx.DefaultPosition,
+                  size = wx.DefaultSize,
                   choices = [],
                   choices = [],
-                  style = wxCB_DROPDOWN,
-                  validator = wxDefaultValidator,
+                  style = wx.CB_DROPDOWN,
+                  validator = wx.DefaultValidator,
                   name = "maskedComboBox",
                   setupEventHandling = True,        ## setup event handling by default):
                   **kwargs):
                   name = "maskedComboBox",
                   setupEventHandling = True,        ## setup event handling by default):
                   **kwargs):
@@ -5989,7 +6160,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         # This is necessary, because wxComboBox currently provides no
         # method for determining later if this was specified in the
         # constructor for the control...
         # This is necessary, because wxComboBox currently provides no
         # method for determining later if this was specified in the
         # constructor for the control...
-        self.__readonly = style & wxCB_READONLY == wxCB_READONLY
+        self.__readonly = style & wx.CB_READONLY == wx.CB_READONLY
 
         kwargs['choices'] = choices                 ## set up maskededit to work with choice list too
 
 
         kwargs['choices'] = choices                 ## set up maskededit to work with choice list too
 
@@ -5997,18 +6168,19 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         if not kwargs.has_key('compareNoCase'):
             kwargs['compareNoCase'] = True
 
         if not kwargs.has_key('compareNoCase'):
             kwargs['compareNoCase'] = True
 
-        wxMaskedEditMixin.__init__( self, name, **kwargs )
+        MaskedEditMixin.__init__( self, name, **kwargs )
+
         self._choices = self._ctrl_constraints._choices
         self._choices = self._ctrl_constraints._choices
-        dbg('self._choices:', self._choices)
+##        dbg('self._choices:', self._choices)
 
         if self._ctrl_constraints._alignRight:
             choices = [choice.rjust(self._masklength) for choice in choices]
         else:
             choices = [choice.ljust(self._masklength) for choice in choices]
 
 
         if self._ctrl_constraints._alignRight:
             choices = [choice.rjust(self._masklength) for choice in choices]
         else:
             choices = [choice.ljust(self._masklength) for choice in choices]
 
-        wxComboBox.__init__(self, parent, id, value='',
+        wx.ComboBox.__init__(self, parent, id, value='',
                             pos=pos, size = size,
                             pos=pos, size = size,
-                            choices=choices, style=style|wxWANTS_CHARS,
+                            choices=choices, style=style|wx.WANTS_CHARS,
                             validator=validator,
                             name=name)
 
                             validator=validator,
                             name=name)
 
@@ -6033,26 +6205,26 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
             self._SetInitialValue(value)
 
 
             self._SetInitialValue(value)
 
 
-        self._SetKeycodeHandler(WXK_UP, self.OnSelectChoice)
-        self._SetKeycodeHandler(WXK_DOWN, self.OnSelectChoice)
+        self._SetKeycodeHandler(wx.WXK_UP, self.OnSelectChoice)
+        self._SetKeycodeHandler(wx.WXK_DOWN, self.OnSelectChoice)
 
         if setupEventHandling:
             ## Setup event handlers
 
         if setupEventHandling:
             ## Setup event handlers
-            EVT_SET_FOCUS( self, self._OnFocus )        ## defeat automatic full selection
-            EVT_KILL_FOCUS( self, self._OnKillFocus )   ## run internal validator
-            EVT_LEFT_DCLICK(self, self._OnDoubleClick)  ## select field under cursor on dclick
-            EVT_RIGHT_UP(self, self._OnContextMenu )    ## bring up an appropriate context menu
-            EVT_CHAR( self, self._OnChar )              ## handle each keypress
-            EVT_KEY_DOWN( self, self.OnKeyDown )        ## for special processing of up/down keys
-            EVT_KEY_DOWN( self, self._OnKeyDown )       ## for processing the rest of the control keys
-                                                        ## (next in evt chain)
-            EVT_TEXT( self, self.GetId(), self._OnTextChange )  ## color control appropriately & keep
+            self.Bind(wx.EVT_SET_FOCUS, self._OnFocus )         ## defeat automatic full selection
+            self.Bind(wx.EVT_KILL_FOCUS, self._OnKillFocus )    ## run internal validator
+            self.Bind(wx.EVT_LEFT_DCLICK, self._OnDoubleClick)  ## select field under cursor on dclick
+            self.Bind(wx.EVT_RIGHT_UP, self._OnContextMenu )    ## bring up an appropriate context menu
+            self.Bind(wx.EVT_CHAR, self._OnChar )               ## handle each keypress
+            self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown )         ## for special processing of up/down keys
+            self.Bind(wx.EVT_KEY_DOWN, self._OnKeyDown )        ## for processing the rest of the control keys
+                                                                ## (next in evt chain)
+            self.Bind(wx.EVT_TEXT, self._OnTextChange )         ## color control appropriately & keep
                                                                 ## track of previous value for undo
 
 
 
     def __repr__(self):
                                                                 ## track of previous value for undo
 
 
 
     def __repr__(self):
-        return "<wxMaskedComboBox: %s>" % self.GetValue()
+        return "<MaskedComboBox: %s>" % self.GetValue()
 
 
     def _CalcSize(self, size=None):
 
 
     def _CalcSize(self, size=None):
@@ -6067,14 +6239,14 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
     def _GetSelection(self):
         """
         Allow mixin to get the text selection of this control.
     def _GetSelection(self):
         """
         Allow mixin to get the text selection of this control.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return self.GetMark()
 
     def _SetSelection(self, sel_start, sel_to):
         """
         Allow mixin to set the text selection of this control.
         """
         return self.GetMark()
 
     def _SetSelection(self, sel_start, sel_to):
         """
         Allow mixin to set the text selection of this control.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return self.SetMark( sel_start, sel_to )
 
         """
         return self.SetMark( sel_start, sel_to )
 
@@ -6089,14 +6261,14 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
     def _GetValue(self):
         """
         Allow mixin to get the raw value of the control with this function.
     def _GetValue(self):
         """
         Allow mixin to get the raw value of the control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return self.GetValue()
 
     def _SetValue(self, value):
         """
         Allow mixin to set the raw value of the control with this function.
         """
         return self.GetValue()
 
     def _SetValue(self, value):
         """
         Allow mixin to set the raw value of the control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         # For wxComboBox, ensure that values are properly padded so that
         # if varying length choices are supplied, they always show up
         """
         # For wxComboBox, ensure that values are properly padded so that
         # if varying length choices are supplied, they always show up
@@ -6110,7 +6282,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         # Record current selection and insertion point, for undo
         self._prevSelection = self._GetSelection()
         self._prevInsertionPoint = self._GetInsertionPoint()
         # Record current selection and insertion point, for undo
         self._prevSelection = self._GetSelection()
         self._prevInsertionPoint = self._GetInsertionPoint()
-        wxComboBox.SetValue(self, value)
+        wx.ComboBox.SetValue(self, value)
         # text change events don't always fire, so we check validity here
         # to make certain formatting is applied:
         self._CheckValid()
         # text change events don't always fire, so we check validity here
         # to make certain formatting is applied:
         self._CheckValid()
@@ -6123,7 +6295,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         from the base wx control.
         """
         if not self._mask:
         from the base wx control.
         """
         if not self._mask:
-            wxComboBox.SetValue(value)   # revert to base control behavior
+            wx.ComboBox.SetValue(value)   # revert to base control behavior
             return
         # else...
         # empty previous contents, replacing entire value:
             return
         # else...
         # empty previous contents, replacing entire value:
@@ -6135,7 +6307,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
             and self._ctrl_constraints._alignRight ):   # and it's a right-aligned control
             # try to intelligently "pad out" the value to the right size:
             value = self._template[0:self._masklength - len(value)] + value
             and self._ctrl_constraints._alignRight ):   # and it's a right-aligned control
             # try to intelligently "pad out" the value to the right size:
             value = self._template[0:self._masklength - len(value)] + value
-            dbg('padded value = "%s"' % value)
+##            dbg('padded value = "%s"' % value)
 
         # For wxComboBox, ensure that values are properly padded so that
         # if varying length choices are supplied, they always show up
 
         # For wxComboBox, ensure that values are properly padded so that
         # if varying length choices are supplied, they always show up
@@ -6164,23 +6336,23 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
                 dateparts = value.split(' ')
                 dateparts[0] = self._adjustDate(dateparts[0], fixcentury=True)
                 value = string.join(dateparts, ' ')
                 dateparts = value.split(' ')
                 dateparts[0] = self._adjustDate(dateparts[0], fixcentury=True)
                 value = string.join(dateparts, ' ')
-                dbg('adjusted value: "%s"' % value)
+##                dbg('adjusted value: "%s"' % value)
                 value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
             else:
                 raise
 
         self._SetValue(value)
                 value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
             else:
                 raise
 
         self._SetValue(value)
-##        dbg('queuing insertion after .SetValue', self._masklength)
-        wxCallAfter(self._SetInsertionPoint, self._masklength)
-        wxCallAfter(self._SetSelection, self._masklength, self._masklength)
+####        dbg('queuing insertion after .SetValue', self._masklength)
+        wx.CallAfter(self._SetInsertionPoint, self._masklength)
+        wx.CallAfter(self._SetSelection, self._masklength, self._masklength)
 
 
     def _Refresh(self):
         """
         Allow mixin to refresh the base control with this function.
 
 
     def _Refresh(self):
         """
         Allow mixin to refresh the base control with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         """
-        wxComboBox.Refresh(self)
+        wx.ComboBox.Refresh(self)
 
     def Refresh(self):
         """
 
     def Refresh(self):
         """
@@ -6195,7 +6367,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
     def _IsEditable(self):
         """
         Allow mixin to determine if the base control is editable with this function.
     def _IsEditable(self):
         """
         Allow mixin to determine if the base control is editable with this function.
-        REQUIRED by any class derived from wxMaskedEditMixin.
+        REQUIRED by any class derived from MaskedEditMixin.
         """
         return not self.__readonly
 
         """
         return not self.__readonly
 
@@ -6210,7 +6382,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         if self._mask:
             self._Cut()             # call the mixin's Cut method
         else:
         if self._mask:
             self._Cut()             # call the mixin's Cut method
         else:
-            wxComboBox.Cut(self)    # else revert to base control behavior
+            wx.ComboBox.Cut(self)    # else revert to base control behavior
 
 
     def Paste(self):
 
 
     def Paste(self):
@@ -6223,7 +6395,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         if self._mask:
             self._Paste()           # call the mixin's Paste method
         else:
         if self._mask:
             self._Paste()           # call the mixin's Paste method
         else:
-            wxComboBox.Paste(self)  # else revert to base control behavior
+            wx.ComboBox.Paste(self)  # else revert to base control behavior
 
 
     def Undo(self):
 
 
     def Undo(self):
@@ -6234,7 +6406,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         if self._mask:
             self._Undo()
         else:
         if self._mask:
             self._Undo()
         else:
-            wxComboBox.Undo()       # else revert to base control behavior
+            wx.ComboBox.Undo()       # else revert to base control behavior
 
 
     def Append( self, choice, clientData=None ):
 
 
     def Append( self, choice, clientData=None ):
@@ -6267,7 +6439,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
                 choice = choice.ljust(self._masklength)
             if self._ctrl_constraints._fillChar != ' ':
                 choice = choice.replace(' ', self._fillChar)
                 choice = choice.ljust(self._masklength)
             if self._ctrl_constraints._fillChar != ' ':
                 choice = choice.replace(' ', self._fillChar)
-            dbg('updated choice:', choice)
+##            dbg('updated choice:', choice)
 
 
             self._ctrl_constraints._compareChoices.append(compareChoice)
 
 
             self._ctrl_constraints._compareChoices.append(compareChoice)
@@ -6279,7 +6451,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
                 (self._ctrl_constraints.IsEmpty(choice) and self._ctrl_constraints._validRequired) ) ):
                 raise ValueError('"%s" is not a valid value for the control "%s" as specified.' % (choice, self.name))
 
                 (self._ctrl_constraints.IsEmpty(choice) and self._ctrl_constraints._validRequired) ) ):
                 raise ValueError('"%s" is not a valid value for the control "%s" as specified.' % (choice, self.name))
 
-        wxComboBox.Append(self, choice, clientData)
+        wx.ComboBox.Append(self, choice, clientData)
 
 
 
 
 
 
@@ -6293,21 +6465,19 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
             self._ctrl_constraints._autoCompleteIndex = -1
             if self._ctrl_constraints._choices:
                 self.SetCtrlParameters(choices=[])
             self._ctrl_constraints._autoCompleteIndex = -1
             if self._ctrl_constraints._choices:
                 self.SetCtrlParameters(choices=[])
-        wxComboBox.Clear(self)
+        wx.ComboBox.Clear(self)
 
 
 
 
-    def SetCtrlParameters( self, **kwargs ):
+    def _OnCtrlParametersChanged(self):
         """
         """
-        Override mixin's default SetCtrlParameters to detect changes in choice list, so
+        Override mixin's default OnCtrlParametersChanged to detect changes in choice list, so
         we can update the base control:
         """
         we can update the base control:
         """
-        wxMaskedEditMixin.SetCtrlParameters(self, **kwargs )
-        if( self.controlInitialized
-            and (kwargs.has_key('choices') or self._choices != self._ctrl_constraints._choices) ):
-            wxComboBox.Clear(self)
+        if self.controlInitialized and self._choices != self._ctrl_constraints._choices:
+            wx.ComboBox.Clear(self)
             self._choices = self._ctrl_constraints._choices
             for choice in self._choices:
             self._choices = self._ctrl_constraints._choices
             for choice in self._choices:
-                wxComboBox.Append( self, choice )
+                wx.ComboBox.Append( self, choice )
 
 
     def GetMark(self):
 
 
     def GetMark(self):
@@ -6317,33 +6487,33 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         works, but has the nasty side effect of generating lots of intermediate
         events.
         """
         works, but has the nasty side effect of generating lots of intermediate
         events.
         """
-        dbg(suspend=1)  # turn off debugging around this function
-        dbg('wxMaskedComboBox::GetMark', indent=1)
+##        dbg(suspend=1)  # turn off debugging around this function
+##        dbg('MaskedComboBox::GetMark', indent=1)
         if self.__readonly:
         if self.__readonly:
-            dbg(indent=0)
+##            dbg(indent=0)
             return 0, 0 # no selection possible for editing
 ##        sel_start, sel_to = wxComboBox.GetMark(self)        # what I'd *like* to have!
         sel_start = sel_to = self.GetInsertionPoint()
             return 0, 0 # no selection possible for editing
 ##        sel_start, sel_to = wxComboBox.GetMark(self)        # what I'd *like* to have!
         sel_start = sel_to = self.GetInsertionPoint()
-        dbg("current sel_start:", sel_start)
+##        dbg("current sel_start:", sel_start)
         value = self.GetValue()
         value = self.GetValue()
-        dbg('value: "%s"' % value)
+##        dbg('value: "%s"' % value)
 
         self._ignoreChange = True               # tell _OnTextChange() to ignore next event (if any)
 
 
         self._ignoreChange = True               # tell _OnTextChange() to ignore next event (if any)
 
-        wxComboBox.Cut(self)
+        wx.ComboBox.Cut(self)
         newvalue = self.GetValue()
         newvalue = self.GetValue()
-        dbg("value after Cut operation:", newvalue)
+##        dbg("value after Cut operation:", newvalue)
 
         if newvalue != value:                   # something was selected; calculate extent
 
         if newvalue != value:                   # something was selected; calculate extent
-            dbg("something selected")
+##            dbg("something selected")
             sel_to = sel_start + len(value) - len(newvalue)
             sel_to = sel_start + len(value) - len(newvalue)
-            wxComboBox.SetValue(self, value)    # restore original value and selection (still ignoring change)
-            wxComboBox.SetInsertionPoint(self, sel_start)
-            wxComboBox.SetMark(self, sel_start, sel_to)
+            wx.ComboBox.SetValue(self, value)    # restore original value and selection (still ignoring change)
+            wx.ComboBox.SetInsertionPoint(self, sel_start)
+            wx.ComboBox.SetMark(self, sel_start, sel_to)
 
         self._ignoreChange = False              # tell _OnTextChange() to pay attn again
 
 
         self._ignoreChange = False              # tell _OnTextChange() to pay attn again
 
-        dbg('computed selection:', sel_start, sel_to, indent=0, suspend=0)
+##        dbg('computed selection:', sel_start, sel_to, indent=0, suspend=0)
         return sel_start, sel_to
 
 
         return sel_start, sel_to
 
 
@@ -6352,12 +6522,12 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         Necessary for bookkeeping on choice selection, to keep current value
         current.
         """
         Necessary for bookkeeping on choice selection, to keep current value
         current.
         """
-        dbg('wxMaskedComboBox::SetSelection(%d)' % index)
+##        dbg('MaskedComboBox::SetSelection(%d)' % index)
         if self._mask:
             self._prevValue = self._curValue
             self._curValue = self._choices[index]
             self._ctrl_constraints._autoCompleteIndex = index
         if self._mask:
             self._prevValue = self._curValue
             self._curValue = self._choices[index]
             self._ctrl_constraints._autoCompleteIndex = index
-        wxComboBox.SetSelection(self, index)
+        wx.ComboBox.SetSelection(self, index)
 
 
     def OnKeyDown(self, event):
 
 
     def OnKeyDown(self, event):
@@ -6380,7 +6550,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         on the text of the control somehow interferes with the combobox's
         selection mechanism for the arrow keys.
         """
         on the text of the control somehow interferes with the combobox's
         selection mechanism for the arrow keys.
         """
-        dbg('wxMaskedComboBox::OnSelectChoice', indent=1)
+##        dbg('MaskedComboBox::OnSelectChoice', indent=1)
 
         if not self._mask:
             event.Skip()
 
         if not self._mask:
             event.Skip()
@@ -6391,7 +6561,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         if self._ctrl_constraints._compareNoCase:
             value = value.lower()
 
         if self._ctrl_constraints._compareNoCase:
             value = value.lower()
 
-        if event.GetKeyCode() == WXK_UP:
+        if event.GetKeyCode() == wx.WXK_UP:
             direction = -1
         else:
             direction = 1
             direction = -1
         else:
             direction = 1
@@ -6402,7 +6572,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
                                                 self._ctrl_constraints._compareNoCase,
                                                 current_index = self._ctrl_constraints._autoCompleteIndex)
         if match_index is not None:
                                                 self._ctrl_constraints._compareNoCase,
                                                 current_index = self._ctrl_constraints._autoCompleteIndex)
         if match_index is not None:
-            dbg('setting selection to', match_index)
+##            dbg('setting selection to', match_index)
             # issue appropriate event to outside:
             self._OnAutoSelect(self._ctrl_constraints, match_index=match_index)
             self._CheckValid()
             # issue appropriate event to outside:
             self._OnAutoSelect(self._ctrl_constraints, match_index=match_index)
             self._CheckValid()
@@ -6411,15 +6581,15 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
             pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
             field = self._FindField(pos)
             if self.IsEmpty() or not field._hasList:
             pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
             field = self._FindField(pos)
             if self.IsEmpty() or not field._hasList:
-                dbg('selecting 1st value in list')
+##                dbg('selecting 1st value in list')
                 self._OnAutoSelect(self._ctrl_constraints, match_index=0)
                 self._CheckValid()
                 keep_processing = False
             else:
                 # attempt field-level auto-complete
                 self._OnAutoSelect(self._ctrl_constraints, match_index=0)
                 self._CheckValid()
                 keep_processing = False
             else:
                 # attempt field-level auto-complete
-                dbg(indent=0)
+##                dbg(indent=0)
                 keep_processing = self._OnAutoCompleteField(event)
                 keep_processing = self._OnAutoCompleteField(event)
-        dbg('keep processing?', keep_processing, indent=0)
+##        dbg('keep processing?', keep_processing, indent=0)
         return keep_processing
 
 
         return keep_processing
 
 
@@ -6428,17 +6598,17 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         Override mixin (empty) autocomplete handler, so that autocompletion causes
         combobox to update appropriately.
         """
         Override mixin (empty) autocomplete handler, so that autocompletion causes
         combobox to update appropriately.
         """
-        dbg('wxMaskedComboBox::OnAutoSelect', field._index, indent=1)
+##        dbg('MaskedComboBox::OnAutoSelect', field._index, indent=1)
 ##        field._autoCompleteIndex = match_index
         if field == self._ctrl_constraints:
             self.SetSelection(match_index)
 ##        field._autoCompleteIndex = match_index
         if field == self._ctrl_constraints:
             self.SetSelection(match_index)
-            dbg('issuing combo selection event')
+##            dbg('issuing combo selection event')
             self.GetEventHandler().ProcessEvent(
             self.GetEventHandler().ProcessEvent(
-                wxMaskedComboBoxSelectEvent( self.GetId(), match_index, self ) )
+                MaskedComboBoxSelectEvent( self.GetId(), match_index, self ) )
         self._CheckValid()
         self._CheckValid()
-        dbg('field._autoCompleteIndex:', match_index)
-        dbg('self.GetSelection():', self.GetSelection())
-        dbg(indent=0)
+##        dbg('field._autoCompleteIndex:', match_index)
+##        dbg('self.GetSelection():', self.GetSelection())
+##        dbg(indent=0)
 
 
     def _OnReturn(self, event):
 
 
     def _OnReturn(self, event):
@@ -6451,31 +6621,81 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
         programmatic wxComboBox.SetSelection() call to pick the appropriate
         item in the list. (and then do the usual OnReturn bit.)
         """
         programmatic wxComboBox.SetSelection() call to pick the appropriate
         item in the list. (and then do the usual OnReturn bit.)
         """
-        dbg('wxMaskedComboBox::OnReturn', indent=1)
-        dbg('current value: "%s"' % self.GetValue(), 'current index:', self.GetSelection())
+##        dbg('MaskedComboBox::OnReturn', indent=1)
+##        dbg('current value: "%s"' % self.GetValue(), 'current index:', self.GetSelection())
         if self.GetSelection() == -1 and self.GetValue().lower().strip() in self._ctrl_constraints._compareChoices:
         if self.GetSelection() == -1 and self.GetValue().lower().strip() in self._ctrl_constraints._compareChoices:
-            wxCallAfter(self.SetSelection, self._ctrl_constraints._autoCompleteIndex)
+            wx.CallAfter(self.SetSelection, self._ctrl_constraints._autoCompleteIndex)
 
 
-        event.m_keyCode = WXK_TAB
+        event.m_keyCode = wx.WXK_TAB
         event.Skip()
         event.Skip()
-        dbg(indent=0)
+##        dbg(indent=0)
+
+
+class MaskedComboBox( BaseMaskedComboBox, MaskedEditAccessorsMixin ):
+    """
+    This extra level of inheritance allows us to add the generic set of
+    masked edit parameters only to this class while allowing other
+    classes to derive from the "base" masked combobox control, and provide
+    a smaller set of valid accessor functions.
+    """
+    pass
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
-class wxIpAddrCtrl( wxMaskedTextCtrl ):
+class IpAddrCtrlAccessorsMixin:
+    # Define IpAddrCtrl's list of attributes having their own
+    # Get/Set functions, exposing only those that make sense for
+    # an IP address control.
+
+    exposed_basectrl_params = (
+        'fields',
+        'retainFieldValidation',
+        'formatcodes',
+        'fillChar',
+        'defaultValue',
+        'description',
+
+        'useFixedWidthFont',
+        'signedForegroundColour',
+        'emptyBackgroundColour',
+        'validBackgroundColour',
+        'invalidBackgroundColour',
+
+        'emptyInvalid',
+        'validFunc',
+        'validRequired',
+        )
+
+    for param in exposed_basectrl_params:
+        propname = param[0].upper() + param[1:]
+        exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+        exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+
+        if param.find('Colour') != -1:
+            # add non-british spellings, for backward-compatibility
+            propname.replace('Colour', 'Color')
+
+            exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
+            exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
+
+
+class IpAddrCtrl( BaseMaskedTextCtrl, IpAddrCtrlAccessorsMixin ):
     """
     """
-    This class is a particular type of wxMaskedTextCtrl that accepts
+    This class is a particular type of MaskedTextCtrl that accepts
     and understands the semantics of IP addresses, reformats input
     as you move from field to field, and accepts '.' as a navigation
     character, so that typing an IP address can be done naturally.
     """
     and understands the semantics of IP addresses, reformats input
     as you move from field to field, and accepts '.' as a navigation
     character, so that typing an IP address can be done naturally.
     """
+
+
+
     def __init__( self, parent, id=-1, value = '',
     def __init__( self, parent, id=-1, value = '',
-                  pos = wxDefaultPosition,
-                  size = wxDefaultSize,
-                  style = wxTE_PROCESS_TAB,
-                  validator = wxDefaultValidator,
-                  name = 'wxIpAddrCtrl',
+                  pos = wx.DefaultPosition,
+                  size = wx.DefaultSize,
+                  style = wx.TE_PROCESS_TAB,
+                  validator = wx.DefaultValidator,
+                  name = 'IpAddrCtrl',
                   setupEventHandling = True,        ## setup event handling by default
                   **kwargs):
 
                   setupEventHandling = True,        ## setup event handling by default
                   **kwargs):
 
@@ -6487,7 +6707,7 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
             kwargs['validRegex'] = "(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))(\.(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))){3}"
 
 
             kwargs['validRegex'] = "(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))(\.(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))){3}"
 
 
-        wxMaskedTextCtrl.__init__(
+        BaseMaskedTextCtrl.__init__(
                 self, parent, id=id, value = value,
                 pos=pos, size=size,
                 style = style,
                 self, parent, id=id, value = value,
                 pos=pos, size=size,
                 style = style,
@@ -6496,6 +6716,7 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
                 setupEventHandling = setupEventHandling,
                 **kwargs)
 
                 setupEventHandling = setupEventHandling,
                 **kwargs)
 
+
         # set up individual field parameters as well:
         field_params = {}
         field_params['validRegex'] = "(   |  \d| \d |\d  | \d\d|\d\d |\d \d|(1\d\d|2[0-4]\d|25[0-5]))"
         # set up individual field parameters as well:
         field_params = {}
         field_params['validRegex'] = "(   |  \d| \d |\d  | \d\d|\d\d |\d \d|(1\d\d|2[0-4]\d|25[0-5]))"
@@ -6514,7 +6735,7 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
 
 
     def OnDot(self, event):
 
 
     def OnDot(self, event):
-        dbg('wxIpAddrCtrl::OnDot', indent=1)
+##        dbg('IpAddrCtrl::OnDot', indent=1)
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         oldvalue = self.GetValue()
         edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True)
         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
         oldvalue = self.GetValue()
         edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True)
@@ -6525,26 +6746,26 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
                 newvalue = oldvalue[:pos] + ' ' * (edit_end - pos) + oldvalue[edit_end:]
                 self._SetValue(newvalue)
                 self._SetInsertionPoint(pos)
                 newvalue = oldvalue[:pos] + ' ' * (edit_end - pos) + oldvalue[edit_end:]
                 self._SetValue(newvalue)
                 self._SetInsertionPoint(pos)
-        dbg(indent=0)
+##        dbg(indent=0)
         return self._OnChangeField(event)
 
 
 
     def GetAddress(self):
         return self._OnChangeField(event)
 
 
 
     def GetAddress(self):
-        value = wxMaskedTextCtrl.GetValue(self)
+        value = BaseMaskedTextCtrl.GetValue(self)
         return value.replace(' ','')    # remove spaces from the value
 
 
     def _OnCtrl_S(self, event):
         return value.replace(' ','')    # remove spaces from the value
 
 
     def _OnCtrl_S(self, event):
-        dbg("wxIpAddrCtrl::_OnCtrl_S")
+##        dbg("IpAddrCtrl::_OnCtrl_S")
         if self._demo:
             print "value:", self.GetAddress()
         return False
 
     def SetValue(self, value):
         if self._demo:
             print "value:", self.GetAddress()
         return False
 
     def SetValue(self, value):
-        dbg('wxIpAddrCtrl::SetValue(%s)' % str(value), indent=1)
+##        dbg('IpAddrCtrl::SetValue(%s)' % str(value), indent=1)
         if type(value) not in (types.StringType, types.UnicodeType):
         if type(value) not in (types.StringType, types.UnicodeType):
-            dbg(indent=0)
+##            dbg(indent=0)
             raise ValueError('%s must be a string', str(value))
 
         bValid = True   # assume True
             raise ValueError('%s must be a string', str(value))
 
         bValid = True   # assume True
@@ -6574,13 +6795,13 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
                     parts[i] = '   '    # convert empty field to 3-char length
 
         if not bValid:
                     parts[i] = '   '    # convert empty field to 3-char length
 
         if not bValid:
-            dbg(indent=0)
+##            dbg(indent=0)
             raise ValueError('value (%s) must be a string of form n.n.n.n where n is empty or in range 0-255' % str(value))
         else:
             raise ValueError('value (%s) must be a string of form n.n.n.n where n is empty or in range 0-255' % str(value))
         else:
-            dbg('parts:', parts)
+##            dbg('parts:', parts)
             value = string.join(parts, '.')
             value = string.join(parts, '.')
-            wxMaskedTextCtrl.SetValue(self, value)
-        dbg(indent=0)
+            BaseMaskedTextCtrl.SetValue(self, value)
+##        dbg(indent=0)
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
@@ -6695,31 +6916,31 @@ def getDay(dateStr,dateFmt):
     return parts[2]
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
     return parts[2]
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
-class test(wxPySimpleApp):
+class test(wx.PySimpleApp):
         def OnInit(self):
         def OnInit(self):
-            from wxPython.lib.rcsizer import RowColSizer
-            self.frame = wxFrame( NULL, -1, "wxMaskedEditMixin 0.0.7 Demo Page #1", size = (700,600))
-            self.panel = wxPanel( self.frame, -1)
+            from wx.lib.rcsizer import RowColSizer
+            self.frame = wx.Frame( None, -1, "MaskedEditMixin 0.0.7 Demo Page #1", size = (700,600))
+            self.panel = wx.Panel( self.frame, -1)
             self.sizer = RowColSizer()
             self.labels = []
             self.editList  = []
             rowcount    = 4
 
             self.sizer = RowColSizer()
             self.labels = []
             self.editList  = []
             rowcount    = 4
 
-            id, id1 = wxNewId(), wxNewId()
-            self.command1  = wxButton( self.panel, id, "&Close" )
-            self.command2  = wxButton( self.panel, id1, "&AutoFormats" )
-            self.sizer.Add(self.command1, row=0, col=0, flag=wxALL, border = 5)
-            self.sizer.Add(self.command2, row=0, col=1, colspan=2, flag=wxALL, border = 5)
-            EVT_BUTTON( self.panel, id, self.onClick )
+            id, id1 = wx.NewId(), wx.NewId()
+            self.command1  = wx.Button( self.panel, id, "&Close" )
+            self.command2  = wx.Button( self.panel, id1, "&AutoFormats" )
+            self.sizer.Add(self.command1, row=0, col=0, flag=wx.ALL, border = 5)
+            self.sizer.Add(self.command2, row=0, col=1, colspan=2, flag=wx.ALL, border = 5)
+            self.panel.Bind(wx.EVT_BUTTON, self.onClick, self.command1 )
 ##            self.panel.SetDefaultItem(self.command1 )
 ##            self.panel.SetDefaultItem(self.command1 )
-            EVT_BUTTON( self.panel, id1, self.onClickPage )
+            self.panel.Bind(wx.EVT_BUTTON, self.onClickPage, self.command2)
 
 
-            self.check1 = wxCheckBox( self.panel, -1, "Disallow Empty" )
-            self.check2 = wxCheckBox( self.panel, -1, "Highlight Empty" )
-            self.sizer.Add( self.check1, row=0,col=3, flag=wxALL,border=5 )
-            self.sizer.Add( self.check2, row=0,col=4, flag=wxALL,border=5 )
-            EVT_CHECKBOX( self.panel, self.check1.GetId(), self._onCheck1 )
-            EVT_CHECKBOX( self.panel, self.check2.GetId(), self._onCheck2 )
+            self.check1 = wx.CheckBox( self.panel, -1, "Disallow Empty" )
+            self.check2 = wx.CheckBox( self.panel, -1, "Highlight Empty" )
+            self.sizer.Add( self.check1, row=0,col=3, flag=wx.ALL,border=5 )
+            self.sizer.Add( self.check2, row=0,col=4, flag=wx.ALL,border=5 )
+            self.panel.Bind(wx.EVT_CHECKBOX, self._onCheck1, self.check1 )
+            self.panel.Bind(wx.EVT_CHECKBOX, self._onCheck2, self.check2 )
 
 
             label = """Press ctrl-s in any field to output the value and plain value. Press ctrl-x to clear and re-set any field.
 
 
             label = """Press ctrl-s in any field to output the value and plain value. Press ctrl-x to clear and re-set any field.
@@ -6727,28 +6948,28 @@ Note that all controls have been auto-sized by including F in the format code.
 Try entering nonsensical or partial values in validated fields to see what happens (use ctrl-s to test the valid status)."""
             label2 = "\nNote that the State and Last Name fields are list-limited (Name:Smith,Jones,Williams)."
 
 Try entering nonsensical or partial values in validated fields to see what happens (use ctrl-s to test the valid status)."""
             label2 = "\nNote that the State and Last Name fields are list-limited (Name:Smith,Jones,Williams)."
 
-            self.label1 = wxStaticText( self.panel, -1, label)
-            self.label2 = wxStaticText( self.panel, -1, "Description")
-            self.label3 = wxStaticText( self.panel, -1, "Mask Value")
-            self.label4 = wxStaticText( self.panel, -1, "Format")
-            self.label5 = wxStaticText( self.panel, -1, "Reg Expr Val. (opt)")
-            self.label6 = wxStaticText( self.panel, -1, "wxMaskedEdit Ctrl")
-            self.label7 = wxStaticText( self.panel, -1, label2)
+            self.label1 = wx.StaticText( self.panel, -1, label)
+            self.label2 = wx.StaticText( self.panel, -1, "Description")
+            self.label3 = wx.StaticText( self.panel, -1, "Mask Value")
+            self.label4 = wx.StaticText( self.panel, -1, "Format")
+            self.label5 = wx.StaticText( self.panel, -1, "Reg Expr Val. (opt)")
+            self.label6 = wx.StaticText( self.panel, -1, "wxMaskedEdit Ctrl")
+            self.label7 = wx.StaticText( self.panel, -1, label2)
             self.label7.SetForegroundColour("Blue")
             self.label1.SetForegroundColour("Blue")
             self.label7.SetForegroundColour("Blue")
             self.label1.SetForegroundColour("Blue")
-            self.label2.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label3.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label4.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label5.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label6.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-
-            self.sizer.Add( self.label1, row=1,col=0,colspan=7, flag=wxALL,border=5)
-            self.sizer.Add( self.label7, row=2,col=0,colspan=7, flag=wxALL,border=5)
-            self.sizer.Add( self.label2, row=3,col=0, flag=wxALL,border=5)
-            self.sizer.Add( self.label3, row=3,col=1, flag=wxALL,border=5)
-            self.sizer.Add( self.label4, row=3,col=2, flag=wxALL,border=5)
-            self.sizer.Add( self.label5, row=3,col=3, flag=wxALL,border=5)
-            self.sizer.Add( self.label6, row=3,col=4, flag=wxALL,border=5)
+            self.label2.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label3.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label4.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label5.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label6.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+
+            self.sizer.Add( self.label1, row=1,col=0,colspan=7, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label7, row=2,col=0,colspan=7, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label2, row=3,col=0, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label3, row=3,col=1, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label4, row=3,col=2, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label5, row=3,col=3, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label6, row=3,col=4, flag=wx.ALL,border=5)
 
             # The following list is of the controls for the demo. Feel free to play around with
             # the options!
 
             # The following list is of the controls for the demo. Feel free to play around with
             # the options!
@@ -6772,13 +6993,13 @@ Try entering nonsensical or partial values in validated fields to see what happe
            ]
 
             for control in controls:
            ]
 
             for control in controls:
-                self.sizer.Add( wxStaticText( self.panel, -1, control[0]),row=rowcount, col=0,border=5,flag=wxALL)
-                self.sizer.Add( wxStaticText( self.panel, -1, control[1]),row=rowcount, col=1,border=5, flag=wxALL)
-                self.sizer.Add( wxStaticText( self.panel, -1, control[3]),row=rowcount, col=2,border=5, flag=wxALL)
-                self.sizer.Add( wxStaticText( self.panel, -1, control[4][:20]),row=rowcount, col=3,border=5, flag=wxALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[0]),row=rowcount, col=0,border=5,flag=wx.ALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[1]),row=rowcount, col=1,border=5, flag=wx.ALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[3]),row=rowcount, col=2,border=5, flag=wx.ALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[4][:20]),row=rowcount, col=3,border=5, flag=wx.ALL)
 
                 if control in controls[:]:#-2]:
 
                 if control in controls[:]:#-2]:
-                    newControl  = wxMaskedTextCtrl( self.panel, -1, "",
+                    newControl  = MaskedTextCtrl( self.panel, -1, "",
                                                     mask         = control[1],
                                                     excludeChars = control[2],
                                                     formatcodes  = control[3],
                                                     mask         = control[1],
                                                     excludeChars = control[2],
                                                     formatcodes  = control[3],
@@ -6790,7 +7011,7 @@ Try entering nonsensical or partial values in validated fields to see what happe
                                                     demo         = True)
                     if control[6]: newControl.SetCtrlParameters(choiceRequired = True)
                 else:
                                                     demo         = True)
                     if control[6]: newControl.SetCtrlParameters(choiceRequired = True)
                 else:
-                    newControl = wxMaskedComboBox(  self.panel, -1, "",
+                    newControl = MaskedComboBox(  self.panel, -1, "",
                                                     choices = control[7],
                                                     choiceRequired  = True,
                                                     mask         = control[1],
                                                     choices = control[7],
                                                     choiceRequired  = True,
                                                     mask         = control[1],
@@ -6802,7 +7023,7 @@ Try entering nonsensical or partial values in validated fields to see what happe
                                                     demo         = True)
                 self.editList.append( newControl )
 
                                                     demo         = True)
                 self.editList.append( newControl )
 
-                self.sizer.Add( newControl, row=rowcount,col=4,flag=wxALL,border=5)
+                self.sizer.Add( newControl, row=rowcount,col=4,flag=wx.ALL,border=5)
                 rowcount += 1
 
             self.sizer.AddGrowableCol(4)
                 rowcount += 1
 
             self.sizer.AddGrowableCol(4)
@@ -6824,7 +7045,7 @@ Try entering nonsensical or partial values in validated fields to see what happe
 
         def _onCheck1(self,event):
             """ Set required value on/off """
 
         def _onCheck1(self,event):
             """ Set required value on/off """
-            value = event.Checked()
+            value = event.IsChecked()
             if value:
                 for control in self.editList:
                     control.SetCtrlParameters(emptyInvalid=True)
             if value:
                 for control in self.editList:
                     control.SetCtrlParameters(emptyInvalid=True)
@@ -6837,7 +7058,7 @@ Try entering nonsensical or partial values in validated fields to see what happe
 
         def _onCheck2(self,event):
             """ Highlight empty values"""
 
         def _onCheck2(self,event):
             """ Highlight empty values"""
-            value = event.Checked()
+            value = event.IsChecked()
             if value:
                 for control in self.editList:
                     control.SetCtrlParameters( emptyBackgroundColour = 'Aquamarine')
             if value:
                 for control in self.editList:
                     control.SetCtrlParameters( emptyBackgroundColour = 'Aquamarine')
@@ -6851,11 +7072,11 @@ Try entering nonsensical or partial values in validated fields to see what happe
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
-class test2(wxFrame):
+class test2(wx.Frame):
         def __init__(self, parent, id, caption):
         def __init__(self, parent, id, caption):
-            wxFrame.__init__( self, parent, id, "wxMaskedEdit control 0.0.7 Demo Page #2 -- AutoFormats", size = (550,600))
-            from wxPython.lib.rcsizer import RowColSizer
-            self.panel = wxPanel( self, -1)
+            wx.Frame.__init__( self, parent, id, "wxMaskedEdit control 0.0.7 Demo Page #2 -- AutoFormats", size = (550,600))
+            from wx.lib.rcsizer import RowColSizer
+            self.panel = wx.Panel( self, -1)
             self.sizer = RowColSizer()
             self.labels = []
             self.texts  = []
             self.sizer = RowColSizer()
             self.labels = []
             self.texts  = []
@@ -6866,26 +7087,26 @@ All these controls have been created by passing a single parameter, the AutoForm
 The class contains an internal dictionary of types and formats (autoformats).
 To see a great example of validations in action, try entering a bad email address, then tab out."""
 
 The class contains an internal dictionary of types and formats (autoformats).
 To see a great example of validations in action, try entering a bad email address, then tab out."""
 
-            self.label1 = wxStaticText( self.panel, -1, label)
-            self.label2 = wxStaticText( self.panel, -1, "Description")
-            self.label3 = wxStaticText( self.panel, -1, "AutoFormat Code")
-            self.label4 = wxStaticText( self.panel, -1, "wxMaskedEdit Control")
+            self.label1 = wx.StaticText( self.panel, -1, label)
+            self.label2 = wx.StaticText( self.panel, -1, "Description")
+            self.label3 = wx.StaticText( self.panel, -1, "AutoFormat Code")
+            self.label4 = wx.StaticText( self.panel, -1, "wxMaskedEdit Control")
             self.label1.SetForegroundColour("Blue")
             self.label1.SetForegroundColour("Blue")
-            self.label2.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label3.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-            self.label4.SetFont(wxFont(9,wxSWISS,wxNORMAL,wxBOLD))
-
-            self.sizer.Add( self.label1, row=1,col=0,colspan=3, flag=wxALL,border=5)
-            self.sizer.Add( self.label2, row=3,col=0, flag=wxALL,border=5)
-            self.sizer.Add( self.label3, row=3,col=1, flag=wxALL,border=5)
-            self.sizer.Add( self.label4, row=3,col=2, flag=wxALL,border=5)
-
-            id, id1 = wxNewId(), wxNewId()
-            self.command1  = wxButton( self.panel, id, "&Close")
-            self.command2  = wxButton( self.panel, id1, "&Print Formats")
-            EVT_BUTTON( self.panel, id, self.onClick)
+            self.label2.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label3.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+            self.label4.SetFont(wx.Font(9,wx.SWISS,wx.NORMAL,wx.BOLD))
+
+            self.sizer.Add( self.label1, row=1,col=0,colspan=3, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label2, row=3,col=0, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label3, row=3,col=1, flag=wx.ALL,border=5)
+            self.sizer.Add( self.label4, row=3,col=2, flag=wx.ALL,border=5)
+
+            id, id1 = wx.NewId(), wx.NewId()
+            self.command1  = wx.Button( self.panel, id, "&Close")
+            self.command2  = wx.Button( self.panel, id1, "&Print Formats")
+            self.panel.Bind(wx.EVT_BUTTON, self.onClick, self.command1)
             self.panel.SetDefaultItem(self.command1)
             self.panel.SetDefaultItem(self.command1)
-            EVT_BUTTON( self.panel, id1, self.onClickPrint)
+            self.panel.Bind(wx.EVT_BUTTON, self.onClickPrint, self.command2)
 
             # The following list is of the controls for the demo. Feel free to play around with
             # the options!
 
             # The following list is of the controls for the demo. Feel free to play around with
             # the options!
@@ -6894,7 +7115,7 @@ To see a great example of validations in action, try entering a bad email addres
            ("US Date + Time","USDATETIMEMMDDYYYY/HHMM"),
            ("US Date MMDDYYYY","USDATEMMDDYYYY/"),
            ("Time (with seconds)","TIMEHHMMSS"),
            ("US Date + Time","USDATETIMEMMDDYYYY/HHMM"),
            ("US Date MMDDYYYY","USDATEMMDDYYYY/"),
            ("Time (with seconds)","TIMEHHMMSS"),
-           ("Military Time\n(without seconds)","MILTIMEHHMM"),
+           ("Military Time\n(without seconds)","24HRTIMEHHMM"),
            ("Social Sec#","USSOCIALSEC"),
            ("Credit Card","CREDITCARD"),
            ("Expiration MM/YY","EXPDATEMMYY"),
            ("Social Sec#","USSOCIALSEC"),
            ("Credit Card","CREDITCARD"),
            ("Expiration MM/YY","EXPDATEMMYY"),
@@ -6903,24 +7124,24 @@ To see a great example of validations in action, try entering a bad email addres
            ("US Zip Code","USZIP"),
            ("US Zip+4","USZIPPLUS4"),
            ("Email Address","EMAIL"),
            ("US Zip Code","USZIP"),
            ("US Zip+4","USZIPPLUS4"),
            ("Email Address","EMAIL"),
-           ("IP Address", "(derived control wxIpAddrCtrl)")
+           ("IP Address", "(derived control IpAddrCtrl)")
            ]
 
             for control in controls:
            ]
 
             for control in controls:
-                self.sizer.Add( wxStaticText( self.panel, -1, control[0]),row=rowcount, col=0,border=5,flag=wxALL)
-                self.sizer.Add( wxStaticText( self.panel, -1, control[1]),row=rowcount, col=1,border=5, flag=wxALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[0]),row=rowcount, col=0,border=5,flag=wx.ALL)
+                self.sizer.Add( wx.StaticText( self.panel, -1, control[1]),row=rowcount, col=1,border=5, flag=wx.ALL)
                 if control in controls[:-1]:
                 if control in controls[:-1]:
-                    self.sizer.Add( wxMaskedTextCtrl( self.panel, -1, "",
+                    self.sizer.Add( MaskedTextCtrl( self.panel, -1, "",
                                                       autoformat  = control[1],
                                                       demo        = True),
                                                       autoformat  = control[1],
                                                       demo        = True),
-                                row=rowcount,col=2,flag=wxALL,border=5)
+                                row=rowcount,col=2,flag=wx.ALL,border=5)
                 else:
                 else:
-                    self.sizer.Add( wxIpAddrCtrl( self.panel, -1, "", demo=True ),
-                                    row=rowcount,col=2,flag=wxALL,border=5)
+                    self.sizer.Add( IpAddrCtrl( self.panel, -1, "", demo=True ),
+                                    row=rowcount,col=2,flag=wx.ALL,border=5)
                 rowcount += 1
 
                 rowcount += 1
 
-            self.sizer.Add(self.command1, row=0, col=0, flag=wxALL, border = 5)
-            self.sizer.Add(self.command2, row=0, col=1, flag=wxALL, border = 5)
+            self.sizer.Add(self.command1, row=0, col=0, flag=wx.ALL, border = 5)
+            self.sizer.Add(self.command2, row=0, col=1, flag=wx.ALL, border = 5)
             self.sizer.AddGrowableCol(3)
 
             self.panel.SetSizer(self.sizer)
             self.sizer.AddGrowableCol(3)
 
             self.panel.SetSizer(self.sizer)
@@ -6937,7 +7158,7 @@ To see a great example of validations in action, try entering a bad email addres
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 if __name__ == "__main__":
 ## ---------- ---------- ---------- ---------- ---------- ---------- ----------
 
 if __name__ == "__main__":
-    app = test()
+    app = test(False)
 
 i=1
 ##
 
 i=1
 ##
@@ -6951,14 +7172,14 @@ i=1
 ##      control in the EVT_TEXT handler, and if *different*, call event.Skip()
 ##      to propagate it down the event chain, and let the application see it.
 ##
 ##      control in the EVT_TEXT handler, and if *different*, call event.Skip()
 ##      to propagate it down the event chain, and let the application see it.
 ##
-## 2. WS: wxMaskedComboBox is deficient in several areas, all having to do with the
+## 2. WS: MaskedComboBox is deficient in several areas, all having to do with the
 ##      behavior of the underlying control that I can't fix.  The problems are:
 ##      a) The background coloring doesn't work in the text field of the control;
 ##         instead, there's a only border around it that assumes the correct color.
 ##      b) The control will not pass WXK_TAB to the event handler, no matter what
 ##         I do, and there's no style wxCB_PROCESS_TAB like wxTE_PROCESS_TAB to
 ##      behavior of the underlying control that I can't fix.  The problems are:
 ##      a) The background coloring doesn't work in the text field of the control;
 ##         instead, there's a only border around it that assumes the correct color.
 ##      b) The control will not pass WXK_TAB to the event handler, no matter what
 ##         I do, and there's no style wxCB_PROCESS_TAB like wxTE_PROCESS_TAB to
-##         indicate that we want these events.  As a result, wxMaskedComboBox
-##         doesn't do the nice field-tabbing that wxMaskedTextCtrl does.
+##         indicate that we want these events.  As a result, MaskedComboBox
+##         doesn't do the nice field-tabbing that MaskedTextCtrl does.
 ##      c) Auto-complete had to be reimplemented for the control because programmatic
 ##         setting of the value of the text field does not set up the auto complete
 ##         the way that the control processing keystrokes does.  (But I think I've
 ##      c) Auto-complete had to be reimplemented for the control because programmatic
 ##         setting of the value of the text field does not set up the auto complete
 ##         the way that the control processing keystrokes does.  (But I think I've
@@ -6969,7 +7190,7 @@ i=1
 ##         implemented has its flaws, not the least of which is that due to the
 ##         strategy that I'm using, the paste buffer is always replaced by the
 ##         contents of the control's selection when in focus, on each keystroke;
 ##         implemented has its flaws, not the least of which is that due to the
 ##         strategy that I'm using, the paste buffer is always replaced by the
 ##         contents of the control's selection when in focus, on each keystroke;
-##         this makes it impossible to paste anything into a wxMaskedComboBox
+##         this makes it impossible to paste anything into a MaskedComboBox
 ##         at the moment... :-(
 ##      e) The other deficient behavior, likely induced by the workaround for (d),
 ##         is that you can can't shift-left to select more than one character
 ##         at the moment... :-(
 ##      e) The other deficient behavior, likely induced by the workaround for (d),
 ##         is that you can can't shift-left to select more than one character
@@ -6978,8 +7199,8 @@ i=1
 ##
 ## 3. WS: Controls on wxPanels don't seem to pass Shift-WXK_TAB to their
 ##      EVT_KEY_DOWN or EVT_CHAR event handlers.  Until this is fixed in
 ##
 ## 3. WS: Controls on wxPanels don't seem to pass Shift-WXK_TAB to their
 ##      EVT_KEY_DOWN or EVT_CHAR event handlers.  Until this is fixed in
-##      wxWindows, shift-tab won't take you backwards through the fields of
-##      a wxMaskedTextCtrl like it should.  Until then Shifted arrow keys will
+##      wxWidgets, shift-tab won't take you backwards through the fields of
+##      a MaskedTextCtrl like it should.  Until then Shifted arrow keys will
 ##      work like shift-tab and tab ought to.
 ##
 
 ##      work like shift-tab and tab ought to.
 ##
 
@@ -6989,7 +7210,7 @@ i=1
 ##     fields.  Example: City validates against list of cities, or zip vs zip code list.
 ##  2. Allow optional monetary symbols (eg. $, pounds, etc.) at front of a "decimal"
 ##     control.
 ##     fields.  Example: City validates against list of cities, or zip vs zip code list.
 ##  2. Allow optional monetary symbols (eg. $, pounds, etc.) at front of a "decimal"
 ##     control.
-##  3. Fix shift-left selection for wxMaskedComboBox.
+##  3. Fix shift-left selection for MaskedComboBox.
 ##  5. Transform notion of "decimal control" to be less "entire control"-centric,
 ##     so that monetary symbols can be included and still have the appropriate
 ##     semantics.  (Big job, as currently written, but would make control even
 ##  5. Transform notion of "decimal control" to be less "entire control"-centric,
 ##     so that monetary symbols can be included and still have the appropriate
 ##     semantics.  (Big job, as currently written, but would make control even
@@ -6998,19 +7219,41 @@ i=1
 
 ## CHANGELOG:
 ## ====================
 
 ## CHANGELOG:
 ## ====================
+##  Version 1.5
+##  (Reported) bugs fixed:
+##   1. Crash ensues if you attempt to change the mask of a read-only
+##      MaskedComboBox after initial construction.
+##   2. Changed strategy of defining Get/Set property functions so that
+##      these are now generated dynamically at runtime, rather than as
+##      part of the class definition.  (This makes it possible to have
+##      more general base classes that have many more options for configuration
+##      without requiring that derivations support the same options.)
+##   3. Fixed IsModified for _Paste() and _OnErase().
+##
+##   Enhancements:
+##   1. Fixed "attribute function inheritance," since base control is more
+##      generic than subsequent derivations, not all property functions of a
+##      generic control should be exposed in those derivations.  New strategy
+##      uses base control classes (eg. BaseMaskedTextCtrl) that should be
+##      used to derive new class types, and mixed with their own mixins to
+##      only expose those attributes from the generic masked controls that
+##      make sense for the derivation.  (This makes Boa happier.)
+##   2. Renamed (with b-c) MILTIME autoformats to 24HRTIME, so as to be less
+##      "parochial."
+##
 ##  Version 1.4
 ##  (Reported) bugs fixed:
 ##   1. Right-click menu allowed "cut" operation that destroyed mask
 ##      (was implemented by base control)
 ##  Version 1.4
 ##  (Reported) bugs fixed:
 ##   1. Right-click menu allowed "cut" operation that destroyed mask
 ##      (was implemented by base control)
-##   2. wxMaskedComboBox didn't allow .Append() of mixed-case values; all
+##   2. MaskedComboBox didn't allow .Append() of mixed-case values; all
 ##      got converted to lower case.
 ##      got converted to lower case.
-##   3. wxMaskedComboBox selection didn't deal with spaces in values
+##   3. MaskedComboBox selection didn't deal with spaces in values
 ##      properly when autocompleting, and didn't have a concept of "next"
 ##      match for handling choice list duplicates.
 ##      properly when autocompleting, and didn't have a concept of "next"
 ##      match for handling choice list duplicates.
-##   4. Size of wxMaskedComboBox was always default.
+##   4. Size of MaskedComboBox was always default.
 ##   5. Email address regexp allowed some "non-standard" things, and wasn't
 ##      general enough.
 ##   5. Email address regexp allowed some "non-standard" things, and wasn't
 ##      general enough.
-##   6. Couldn't easily reset wxMaskedComboBox contents programmatically.
+##   6. Couldn't easily reset MaskedComboBox contents programmatically.
 ##   7. Couldn't set emptyInvalid during construction.
 ##   8. Under some versions of wxPython, readonly comboboxes can apparently
 ##      return a GetInsertionPoint() result (655535), causing masked control
 ##   7. Couldn't set emptyInvalid during construction.
 ##   8. Under some versions of wxPython, readonly comboboxes can apparently
 ##      return a GetInsertionPoint() result (655535), causing masked control
@@ -7085,7 +7328,7 @@ i=1
 ##  13. Fixed a couple of coding bugs being flagged by Python2.1.
 ##  14. Fixed several issues with sign positioning, erasure and validity
 ##      checking for "numeric" masked controls.
 ##  13. Fixed a couple of coding bugs being flagged by Python2.1.
 ##  14. Fixed several issues with sign positioning, erasure and validity
 ##      checking for "numeric" masked controls.
-##  15. Added validation to wxIpAddrCtrl.SetValue().
+##  15. Added validation to IpAddrCtrl.SetValue().
 ##
 ##  Version 1.1
 ##   1. Changed calling interface to use boolean "useFixedWidthFont" (True by default)
 ##
 ##  Version 1.1
 ##   1. Changed calling interface to use boolean "useFixedWidthFont" (True by default)
@@ -7109,7 +7352,7 @@ i=1
 ##      fixed failure to obey case conversion codes when pasting.
 ##  11. Implemented '0' (zero-pad) formatting code, as it wasn't being done anywhere...
 ##  12. Removed condition from OnDecimalPoint, so that it always truncates right on '.'
 ##      fixed failure to obey case conversion codes when pasting.
 ##  11. Implemented '0' (zero-pad) formatting code, as it wasn't being done anywhere...
 ##  12. Removed condition from OnDecimalPoint, so that it always truncates right on '.'
-##  13. Enhanced wxIpAddrCtrl to use right-insert fields, selection on field traversal,
+##  13. Enhanced IpAddrCtrl to use right-insert fields, selection on field traversal,
 ##      individual field validation to prevent field values > 255, and require explicit
 ##      tab/. to change fields.
 ##  14. Added handler for left double-click to select field under cursor.
 ##      individual field validation to prevent field values > 255, and require explicit
 ##      tab/. to change fields.
 ##  14. Added handler for left double-click to select field under cursor.
@@ -7118,7 +7361,7 @@ i=1
 ##      attribute, for more consistent and controllable coloring.
 ##  17. Added retainFieldValidation parameter, allowing top-level constraints
 ##      such as "validRequired" to be set independently of field-level equivalent.
 ##      attribute, for more consistent and controllable coloring.
 ##  17. Added retainFieldValidation parameter, allowing top-level constraints
 ##      such as "validRequired" to be set independently of field-level equivalent.
-##      (needed in wxTimeCtrl for bounds constraints.)
+##      (needed in TimeCtrl for bounds constraints.)
 ##  18. Refactored code a bit, cleaned up and commented code more heavily, fixed
 ##      some of the logic for setting/resetting parameters, eg. fillChar, defaultValue,
 ##      etc.
 ##  18. Refactored code a bit, cleaned up and commented code more heavily, fixed
 ##      some of the logic for setting/resetting parameters, eg. fillChar, defaultValue,
 ##      etc.
@@ -7155,9 +7398,9 @@ i=1
 ##      than making assumptions about character width.
 ##   7. Fixed GetMaskParameter(), which was non-functional in previous version.
 ##   8. Fixed exceptions raised to provide info on which control had the error.
 ##      than making assumptions about character width.
 ##   7. Fixed GetMaskParameter(), which was non-functional in previous version.
 ##   8. Fixed exceptions raised to provide info on which control had the error.
-##   9. Fixed bug in choice management of wxMaskedComboBox.
-##  10. Fixed bug in wxIpAddrCtrl causing traceback if field value was of
-##     the form '# #'.  Modified control code for wxIpAddrCtrl so that '.'
+##   9. Fixed bug in choice management of MaskedComboBox.
+##  10. Fixed bug in IpAddrCtrl causing traceback if field value was of
+##     the form '# #'.  Modified control code for IpAddrCtrl so that '.'
 ##     in the middle of a field clips the rest of that field, similar to
 ##     decimal and integer controls.
 ##
 ##     in the middle of a field clips the rest of that field, similar to
 ##     decimal and integer controls.
 ##
@@ -7185,14 +7428,14 @@ i=1
 ##      is not desired in every position.  Added IsDefault() function to mean "does the value
 ##      equal the template?" and modified .IsEmpty() to mean "do all of the editable
 ##      positions in the template == the fillChar?"
 ##      is not desired in every position.  Added IsDefault() function to mean "does the value
 ##      equal the template?" and modified .IsEmpty() to mean "do all of the editable
 ##      positions in the template == the fillChar?"
-##  10. Extracted mask logic into mixin, so we can have both wxMaskedTextCtrl and wxMaskedComboBox,
+##  10. Extracted mask logic into mixin, so we can have both MaskedTextCtrl and MaskedComboBox,
 ##      now included.
 ##      now included.
-##  11. wxMaskedComboBox now adds the capability to validate from list of valid values.
+##  11. MaskedComboBox now adds the capability to validate from list of valid values.
 ##      Example: City validates against list of cities, or zip vs zip code list.
 ##  12. Fixed oversight in EVT_TEXT handler that prevented the events from being
 ##      passed to the next handler in the event chain, causing updates to the
 ##      control to be invisible to the parent code.
 ##      Example: City validates against list of cities, or zip vs zip code list.
 ##  12. Fixed oversight in EVT_TEXT handler that prevented the events from being
 ##      passed to the next handler in the event chain, causing updates to the
 ##      control to be invisible to the parent code.
-##  13. Added IPADDR autoformat code, and subclass wxIpAddrCtrl for controlling tabbing within
+##  13. Added IPADDR autoformat code, and subclass IpAddrCtrl for controlling tabbing within
 ##      the control, that auto-reformats as you move between cells.
 ##  14. Mask characters [A,a,X,#] can now appear in the format string as literals, by using '\'.
 ##  15. It is now possible to specify repeating masks, e.g. #{3}-#{3}-#{14}
 ##      the control, that auto-reformats as you move between cells.
 ##  14. Mask characters [A,a,X,#] can now appear in the format string as literals, by using '\'.
 ##  15. It is now possible to specify repeating masks, e.g. #{3}-#{3}-#{14}
@@ -7213,7 +7456,7 @@ i=1
 ##  19. Enhanced tabbing logic so that tab takes you to the next field if the
 ##      control is a multi-field control.
 ##  20. Added stub method called whenever the control "changes fields", that
 ##  19. Enhanced tabbing logic so that tab takes you to the next field if the
 ##      control is a multi-field control.
 ##  20. Added stub method called whenever the control "changes fields", that
-##      can be overridden by subclasses (eg. wxIpAddrCtrl.)
+##      can be overridden by subclasses (eg. IpAddrCtrl.)
 ##  21. Changed a lot of code to be more functionally-oriented so side-effects
 ##      aren't as problematic when maintaining code and/or adding features.
 ##      Eg: IsValid() now does not have side-effects; it merely reflects the
 ##  21. Changed a lot of code to be more functionally-oriented so side-effects
 ##      aren't as problematic when maintaining code and/or adding features.
 ##      Eg: IsValid() now does not have side-effects; it merely reflects the
@@ -7277,7 +7520,7 @@ i=1
 ##      (i.e. disallow empty values if True).
 ##
 ##  Version 0.0.5
 ##      (i.e. disallow empty values if True).
 ##
 ##  Version 0.0.5
-##   1. get_plainValue method renamed to GetPlainValue following the wxWindows
+##   1. get_plainValue method renamed to GetPlainValue following the wxWidgets
 ##      StudlyCaps(tm) standard (thanks Paul Moore).  ;)
 ##   2. New format code 'F' causes the control to auto-fit (auto-size) itself
 ##      based on the length of the mask template.
 ##      StudlyCaps(tm) standard (thanks Paul Moore).  ;)
 ##   2. New format code 'F' causes the control to auto-fit (auto-size) itself
 ##      based on the length of the mask template.
@@ -7342,7 +7585,7 @@ i=1
 ##   4. Home and End keys now supported to move cursor to beginning or end of field.
 ##   5. Un-signed integers and decimals now supported.
 ##   6. Cosmetic improvements to the demo.
 ##   4. Home and End keys now supported to move cursor to beginning or end of field.
 ##   5. Un-signed integers and decimals now supported.
 ##   6. Cosmetic improvements to the demo.
-##   7. Class renamed to wxMaskedTextCtrl.
+##   7. Class renamed to MaskedTextCtrl.
 ##   8. Can now specify include characters that will override the basic
 ##      controls: for example, includeChars = "@." for email addresses
 ##   9. Added mask character 'C' -> allow any upper or lowercase character
 ##   8. Can now specify include characters that will override the basic
 ##      controls: for example, includeChars = "@." for email addresses
 ##   9. Added mask character 'C' -> allow any upper or lowercase character