]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/maskednumctrl.py
Allow overriding ApplyParentThemeBackground
[wxWidgets.git] / wxPython / wx / lib / maskednumctrl.py
index f3ab3375e29be134b7387bb0b90ad6e0e3db04fa..9a3d234793026dbb8dc4ce3021da0656fee3f626 100644 (file)
@@ -4,15 +4,15 @@
 # Created:      09/06/2003
 # Copyright:   (c) 2003 by Will Sadkin
 # RCS-ID:      $Id$
-# License:     wxWindows license
+# License:     wxWidgets license
 #----------------------------------------------------------------------------
 # NOTE:
 #   This was written to provide a numeric edit control for wxPython that
 #   does things like right-insert (like a calculator), and does grouping, etc.
-#   (ie. the features of wxMaskedTextCtrl), but allows Get/Set of numeric
+#   (ie. the features of MaskedTextCtrl), but allows Get/Set of numeric
 #   values, rather than text.
 #
-#   wxMaskedNumCtrl permits integer, and floating point values to be set
+#   MaskedNumCtrl permits integer, and floating point values to be set
 #   retrieved or set via .GetValue() and .SetValue() (type chosen based on
 #   fraction width, and provides an EVT_MASKEDNUM() event function for trapping
 #   changes to the control.
 #   Similarly, replacing the contents of the control with '-' will result in
 #   a selected (absolute) value of -1.
 #
-#   wxMaskedNumCtrl also supports range limits, with the option of either
+#   MaskedNumCtrl also supports range limits, with the option of either
 #   enforcing them or simply coloring the text of the control if the limits
 #   are exceeded.
 #
-#   wxMaskedNumCtrl is intended to support fixed-point numeric entry, and
-#   is derived from  wxMaskedTextCtrl.  As such, it supports a limited range
+#   MaskedNumCtrl is intended to support fixed-point numeric entry, and
+#   is derived from BaseMaskedTextCtrl.  As such, it supports a limited range
 #   of values to comply with a fixed-width entry mask.
+#----------------------------------------------------------------------------
+# 12/09/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o Updated for wx namespace
+# 
+# 12/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
+#
+# o wxMaskedEditMixin -> MaskedEditMixin
+# o wxMaskedTextCtrl -> MaskedTextCtrl
+# o wxMaskedNumNumberUpdatedEvent -> MaskedNumNumberUpdatedEvent
+# o wxMaskedNumCtrl -> MaskedNumCtrl
+#
+
 """<html><body>
 <P>
-<B>wxMaskedNumCtrl:</B>
+<B>MaskedNumCtrl:</B>
 <UL>
 <LI>allows you to get and set integer or floating point numbers as value,</LI>
 <LI>provides bounds support and optional value limiting,</LI>
-<LI>has the right-insert input style that wxMaskedTextCtrl supports,</LI>
+<LI>has the right-insert input style that MaskedTextCtrl supports,</LI>
 <LI>provides optional automatic grouping, sign control and format, grouping and decimal
 character selection, etc. etc.</LI>
 </UL>
 <P>
-Being derived from wxMaskedTextCtrl, the control only allows
+Being derived from MaskedTextCtrl, the control only allows
 fixed-point  notation.  That is, it has a fixed (though reconfigurable)
 maximum width for the integer portion and optional fixed width
 fractional portion.
 <P>
 Here's the API:
 <DL><PRE>
-    <B>wxMaskedNumCtrl</B>(
+    <B>MaskedNumCtrl</B>(
          parent, id = -1,
          <B>value</B> = 0,
-         pos = wxDefaultPosition,
-         size = wxDefaultSize,
+         pos = wx.DefaultPosition,
+         size = wx.DefaultSize,
          style = 0,
-         validator = wxDefaultValidator,
+         validator = wx.DefaultValidator,
          name = "maskednumber",
          <B>integerWidth</B> = 10,
          <B>fractionWidth</B> = 0,
@@ -74,6 +87,7 @@ Here's the API:
          <B>emptyBackgroundColour</B> = "White",
          <B>validBackgroundColour</B> = "White",
          <B>invalidBackgroundColour</B> = "Yellow",
+         <B>autoSize</B> = True         
          )
 </PRE>
 <UL>
@@ -164,11 +178,20 @@ Here's the API:
     <DT><B>invalidBackgroundColour</B>
     <DD>Color value used for illegal values or values out-of-bounds of the
         control when the bounds are set but the control is not limited.
+    <BR>
+    <DT><B>autoSize</B>
+    <DD>Boolean indicating whether or not the control should set its own
+        width based on the integer and fraction widths.  True by default.
+        <B><I>Note:</I></B> Setting this to False will produce seemingly odd
+        behavior unless the control is large enough to hold the maximum
+        specified value given the widths and the sign positions; if not,
+        the control will appear to "jump around" as the contents scroll.
+        (ie. autoSize is highly recommended.)
 </UL>
 <BR>
 <BR>
 <DT><B>EVT_MASKEDNUM(win, id, func)</B>
-<DD>Respond to a wxEVT_COMMAND_MASKED_NUMBER_UPDATED event, generated when
+<DD>Respond to a EVT_COMMAND_MASKED_NUMBER_UPDATED event, generated when
 the value changes. Notice that this event will always be sent when the
 control's contents changes - whether this is due to user input or
 comes from the program itself (for example, if SetValue() is called.)
@@ -340,36 +363,41 @@ within the control.  (The default is True.)
 the field values on entry.
 <BR>
 <BR>
+<DT><B>SetAutoSize(bool)</B>
+<DD>Resets the autoSize attribute of the control.
+<DT><B>GetAutoSize()</B>
+<DD>Returns the current state of the autoSize attribute for the control.
+<BR>
+<BR>
 </DL>
 </body></html>
 """
 
-from wxPython.wx import *
-import types, string, copy
+import  copy
+import  string
+import  types
+
+import  wx
+
 from sys import maxint
 MAXINT = maxint     # (constants should be in upper case)
 MININT = -maxint-1
 
-from wxPython.tools.dbg import Logger
-from wxPython.lib.maskededit import wxMaskedEditMixin, wxMaskedTextCtrl, Field
-
+from wx.tools.dbg import Logger
+from wx.lib.maskededit import MaskedEditMixin, BaseMaskedTextCtrl, Field
 dbg = Logger()
 dbg(enable=0)
 
 #----------------------------------------------------------------------------
 
-wxEVT_COMMAND_MASKED_NUMBER_UPDATED = wxNewEventType()
-
-
-def EVT_MASKEDNUM(win, id, func):
-    """Used to trap events indicating that the current
-    integer value of the control has been changed."""
-    win.Connect(id, -1, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, func)
+wxEVT_COMMAND_MASKED_NUMBER_UPDATED = wx.NewEventType()
+EVT_MASKEDNUM = wx.PyEventBinder(wxEVT_COMMAND_MASKED_NUMBER_UPDATED, 1)
 
+#----------------------------------------------------------------------------
 
-class wxMaskedNumNumberUpdatedEvent(wxPyCommandEvent):
+class MaskedNumNumberUpdatedEvent(wx.PyCommandEvent):
     def __init__(self, id, value = 0, object=None):
-        wxPyCommandEvent.__init__(self, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, id)
+        wx.PyCommandEvent.__init__(self, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, id)
 
         self.__value = value
         self.SetEventObject(object)
@@ -381,16 +409,55 @@ class wxMaskedNumNumberUpdatedEvent(wxPyCommandEvent):
 
 
 #----------------------------------------------------------------------------
+class MaskedNumCtrlAccessorsMixin:
+    # Define wxMaskedNumCtrl's list of attributes having their own
+    # Get/Set functions, ignoring those that make no sense for
+    # an numeric control.
+    exposed_basectrl_params = (
+         'decimalChar',
+         'shiftDecimalChar',
+         'groupChar',
+         'useParensForNegatives',
+         'defaultValue',
+         'description',
+
+         'useFixedWidthFont',
+         'autoSize',
+         '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 MaskedNumCtrl(BaseMaskedTextCtrl, MaskedNumCtrlAccessorsMixin):
 
-class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
     valid_ctrl_params = {
         'integerWidth': 10,                 # by default allow all 32-bit integers
-        'fractionWidth': 0,                  # by default, use integers
+        'fractionWidth': 0,                 # by default, use integers
         'decimalChar': '.',                 # by default, use '.' for decimal point
         'allowNegative': True,              # by default, allow negative numbers
         'useParensForNegatives': False,     # by default, use '-' to indicate negatives
-        'groupDigits': True,             # by default, don't insert grouping
+        'groupDigits': True,                # by default, don't insert grouping
         'groupChar': ',',                   # by default, use ',' for grouping
         'min': None,                        # by default, no bounds set
         'max': None,
@@ -402,32 +469,33 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         'emptyBackgroundColour': "White",
         'validBackgroundColour': "White",
         'invalidBackgroundColour': "Yellow",
-        'useFixedWidthFont': True,  # by default, use a fixed-width font
+        'useFixedWidthFont': True,          # by default, use a fixed-width font
+        'autoSize': True,                   # by default, set the width of the control based on the mask        
         }
 
 
     def __init__ (
                 self, parent, id=-1, value = 0,
-                pos = wxDefaultPosition, size = wxDefaultSize,
-                style = wxTE_PROCESS_TAB, validator = wxDefaultValidator,
+                pos = wx.DefaultPosition, size = wx.DefaultSize,
+                style = wx.TE_PROCESS_TAB, validator = wx.DefaultValidator,
                 name = "maskednum",
                 **kwargs ):
 
-        dbg('wxMaskedNumCtrl::__init__', indent=1)
+        dbg('MaskedNumCtrl::__init__', indent=1)
 
         # Set defaults for control:
         dbg('setting defaults:')
-        for key, param_value in wxMaskedNumCtrl.valid_ctrl_params.items():
+        for key, param_value in MaskedNumCtrl.valid_ctrl_params.items():
             # This is done this way to make setattr behave consistently with
             # "private attribute" name mangling
             setattr(self, '_' + key, copy.copy(param_value))
 
         # Assign defaults for all attributes:
-        init_args = copy.deepcopy(wxMaskedNumCtrl.valid_ctrl_params)
+        init_args = copy.deepcopy(MaskedNumCtrl.valid_ctrl_params)
         dbg('kwargs:', kwargs)
         for key, param_value in kwargs.items():
             key = key.replace('Color', 'Colour')
-            if key not in wxMaskedNumCtrl.valid_ctrl_params.keys():
+            if key not in MaskedNumCtrl.valid_ctrl_params.keys():
                 raise AttributeError('invalid keyword argument "%s"' % key)
             else:
                 init_args[key] = param_value
@@ -475,6 +543,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         del init_args['integerWidth']
         del init_args['fractionWidth']
 
+        self._autoSize = init_args['autoSize']
+        if self._autoSize:
+            formatcodes = 'FR<'
+        else:
+            formatcodes = 'R<'
+
 
         mask = intmask+fracmask
 
@@ -484,22 +558,22 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         self._typedSign = False
 
         # Construct the base control:
-        wxMaskedTextCtrl.__init__(
+        BaseMaskedTextCtrl.__init__(
                 self, parent, id, '',
                 pos, size, style, validator, name,
                 mask = mask,
-                formatcodes = 'FR<',
+                formatcodes = formatcodes,
                 fields = fields,
                 validFunc=self.IsInBounds,
                 setupEventHandling = False)
 
-        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
 
         # Establish any additional parameters, with appropriate error checking
@@ -511,21 +585,22 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         # Ensure proper coloring:
         self.Refresh()
-        dbg('finished wxMaskedNumCtrl::__init__', indent=0)
+        dbg('finished MaskedNumCtrl::__init__', indent=0)
 
 
     def SetParameters(self, **kwargs):
         """
         This routine is used to initialize and reconfigure the control:
         """
-        dbg('wxMaskedNumCtrl::SetParameters', indent=1)
+        dbg('MaskedNumCtrl::SetParameters', indent=1)
         maskededit_kwargs = {}
         reset_fraction_width = False
 
 
         if( (kwargs.has_key('integerWidth') and kwargs['integerWidth'] != self._integerWidth)
             or (kwargs.has_key('fractionWidth') and kwargs['fractionWidth'] != self._fractionWidth)
-            or (kwargs.has_key('groupDigits') and kwargs['groupDigits'] != self._groupDigits) ):
+            or (kwargs.has_key('groupDigits') and kwargs['groupDigits'] != self._groupDigits)
+            or (kwargs.has_key('autoSize') and kwargs['autoSize'] != self._autoSize) ):
 
             fields = {}
 
@@ -590,9 +665,9 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         # for all other parameters, assign keyword args as appropriate:
         for key, param_value in kwargs.items():
             key = key.replace('Color', 'Colour')
-            if key not in wxMaskedNumCtrl.valid_ctrl_params.keys():
+            if key not in MaskedNumCtrl.valid_ctrl_params.keys():
                 raise AttributeError('invalid keyword argument "%s"' % key)
-            elif key not in wxMaskedEditMixin.valid_ctrl_params.keys():
+            elif key not in MaskedEditMixin.valid_ctrl_params.keys():
                 setattr(self, '_' + key, param_value)
             elif key in ('mask', 'autoformat'): # disallow explicit setting of mask
                 raise AttributeError('invalid keyword argument "%s"' % key)
@@ -601,7 +676,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         dbg('kwargs:', kwargs)
 
         # reprocess existing format codes to ensure proper resulting format:
-        formatcodes = self.GetFormatcodes()
+        formatcodes = self.GetCtrlParameter('formatcodes')        
         if kwargs.has_key('allowNegative'):
             if kwargs['allowNegative'] and '-' not in formatcodes:
                 formatcodes += '-'
@@ -628,6 +703,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                 formatcodes = formatcodes.replace('S','')
                 maskededit_kwargs['formatcodes'] = formatcodes
 
+        if kwargs.has_key('autoSize'):
+            self._autoSize = kwargs['autoSize']
+            if kwargs['autoSize'] and 'F' not in formatcodes:
+                formatcodes += 'F'
+                maskededit_kwargs['formatcodes'] = formatcodes
+            elif not kwargs['autoSize'] and 'F' in formatcodes:
+                formatcodes = formatcodes.replace('F', '')
+                maskededit_kwargs['formatcodes'] = formatcodes
+
+
         if 'r' in formatcodes and self._fractionWidth:
             # top-level mask should only be right insert if no fractional
             # part will be shown; ie. if reconfiguring control, remove
@@ -635,6 +720,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             formatcodes = formatcodes.replace('r', '')
             maskededit_kwargs['formatcodes'] = formatcodes
 
+
         if kwargs.has_key('limited'):
             if kwargs['limited'] and not self._limited:
                 maskededit_kwargs['validRequired'] = True
@@ -648,6 +734,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         # Record end of integer and place cursor there:
         integerEnd = self._fields[0]._extent[1]
+        self.SetInsertionPoint(0)
         self.SetInsertionPoint(integerEnd)
         self.SetSelection(integerEnd, integerEnd)
 
@@ -710,7 +797,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         if kwargs.has_key('decimalChar') and text.find(old_decimalchar) != -1:
             text = text.replace(old_decimalchar, self._decimalChar)
         if text != self._GetValue():
-            wxTextCtrl.SetValue(self, text)
+            wx.TextCtrl.SetValue(self, text)
 
         value = self.GetValue()
 
@@ -720,7 +807,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             dbg('abs(value):', value)
             self._isNeg = False
 
-        elif not self._allowNone and wxMaskedTextCtrl.GetValue(self) == '':
+        elif not self._allowNone and BaseMaskedTextCtrl.GetValue(self) == '':
             if self._min > 0:
                 value = self._min
             else:
@@ -740,7 +827,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             sel_start, sel_to = self.GetSelection()
             self._SetValue(self._toGUI(value))
         self.Refresh() # recolor as appropriate
-        dbg('finished wxMaskedNumCtrl::SetParameters', indent=0)
+        dbg('finished MaskedNumCtrl::SetParameters', indent=0)
 
 
 
@@ -762,7 +849,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         else:
             fracstart, fracend = self._fields[1]._extent
             if candidate is None:
-                value = self._toGUI(wxMaskedTextCtrl.GetValue(self))
+                value = self._toGUI(BaseMaskedTextCtrl.GetValue(self))
             else:
                 value = self._toGUI(candidate)
             fracstring = value[fracstart:fracend].strip()
@@ -772,23 +859,23 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                 return string.atof(fracstring)
 
     def _OnChangeSign(self, event):
-        dbg('wxMaskedNumCtrl::_OnChangeSign', indent=1)
+        dbg('MaskedNumCtrl::_OnChangeSign', indent=1)
         self._typedSign = True
-        wxMaskedEditMixin._OnChangeSign(self, event)
+        MaskedEditMixin._OnChangeSign(self, event)
         dbg(indent=0)
 
 
     def _disallowValue(self):
-        dbg('wxMaskedNumCtrl::_disallowValue')
+        dbg('MaskedNumCtrl::_disallowValue')
         # limited and -1 is out of bounds
         if self._typedSign:
             self._isNeg = False
-        if not wxValidator_IsSilent():
-            wxBell()
+        if not wx.Validator_IsSilent():
+            wx.Bell()
         sel_start, sel_to = self._GetSelection()
         dbg('queuing reselection of (%d, %d)' % (sel_start, sel_to))
-        wxCallAfter(self.SetInsertionPoint, sel_start)      # preserve current selection/position
-        wxCallAfter(self.SetSelection, sel_start, sel_to)
+        wx.CallAfter(self.SetInsertionPoint, sel_start)      # preserve current selection/position
+        wx.CallAfter(self.SetSelection, sel_start, sel_to)
 
     def _SetValue(self, value):
         """
@@ -799,7 +886,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         by the user.
         """
 
-        dbg('wxMaskedNumCtrl::_SetValue("%s")' % value, indent=1)
+        dbg('MaskedNumCtrl::_SetValue("%s")' % value, indent=1)
 
         if( (self._fractionWidth and value.find(self._decimalChar) == -1) or
             (self._fractionWidth == 0 and value.find(self._decimalChar) != -1) ) :
@@ -811,8 +898,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         if numvalue == "":
             if self._allowNone:
-                dbg('calling base wxMaskedTextCtrl._SetValue(self, "%s")' % value)
-                wxMaskedTextCtrl._SetValue(self, value)
+                dbg('calling base BaseMaskedTextCtrl._SetValue(self, "%s")' % value)
+                BaseMaskedTextCtrl._SetValue(self, value)
                 self.Refresh()
                 return
             elif self._min > 0 and self.IsLimited():
@@ -888,12 +975,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                         # is attempting to insert a digit in the middle of the control
                         # resulting in something like "   3   45". Disallow such actions:
                         dbg('>>>>>>>>>>>>>>>> "%s" does not convert to a long!' % int)
-                        if not wxValidator_IsSilent():
-                            wxBell()
+                        if not wx.Validator_IsSilent():
+                            wx.Bell()
                         sel_start, sel_to = self._GetSelection()
                         dbg('queuing reselection of (%d, %d)' % (sel_start, sel_to))
-                        wxCallAfter(self.SetInsertionPoint, sel_start)      # preserve current selection/position
-                        wxCallAfter(self.SetSelection, sel_start, sel_to)
+                        wx.CallAfter(self.SetInsertionPoint, sel_start)      # preserve current selection/position
+                        wx.CallAfter(self.SetSelection, sel_start, sel_to)
                         dbg(indent=0)
                         return
 
@@ -912,11 +999,11 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             # reasonable instead:
             dbg('setting replacement value:', replacement)
             self._SetValue(self._toGUI(replacement))
-            sel_start = wxMaskedTextCtrl.GetValue(self).find(str(abs(replacement)))   # find where it put the 1, so we can select it
+            sel_start = BaseMaskedTextCtrl.GetValue(self).find(str(abs(replacement)))   # find where it put the 1, so we can select it            
             sel_to = sel_start + len(str(abs(replacement)))
             dbg('queuing selection of (%d, %d)' %(sel_start, sel_to))
-            wxCallAfter(self.SetInsertionPoint, sel_start)
-            wxCallAfter(self.SetSelection, sel_start, sel_to)
+            wx.CallAfter(self.SetInsertionPoint, sel_start)
+            wx.CallAfter(self.SetSelection, sel_start, sel_to)
             dbg(indent=0)
             return
 
@@ -938,18 +1025,18 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
 
         sel_start, sel_to = self._GetSelection()     # record current insertion point
-        dbg('calling base wxMaskedTextCtrl._SetValue(self, "%s")' % adjvalue)
-        wxMaskedTextCtrl._SetValue(self, adjvalue)
+        dbg('calling BaseMaskedTextCtrl._SetValue(self, "%s")' % adjvalue)
+        BaseMaskedTextCtrl._SetValue(self, adjvalue)
         # After all actions so far scheduled, check that resulting cursor
         # position is appropriate, and move if not:
-        wxCallAfter(self._CheckInsertionPoint)
+        wx.CallAfter(self._CheckInsertionPoint)
 
-        dbg('finished wxMaskedNumCtrl::_SetValue', indent=0)
+        dbg('finished MaskedNumCtrl::_SetValue', indent=0)
 
     def _CheckInsertionPoint(self):
         # If current insertion point is before the end of the integer and
         # its before the 1st digit, place it just after the sign position:
-        dbg('wxMaskedNumCtrl::CheckInsertionPoint', indent=1)
+        dbg('MaskedNumCtrl::CheckInsertionPoint', indent=1)
         sel_start, sel_to = self._GetSelection()
         text = self._GetValue()
         if sel_to < self._fields[0]._extent[1] and text[sel_to] in (' ', '-', '('):
@@ -966,16 +1053,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         grouping characters auto selects the digit before or after the
         grouping character, so that the erasure does the right thing.
         """
-        dbg('wxMaskedNumCtrl::_OnErase', indent=1)
+        dbg('MaskedNumCtrl::_OnErase', indent=1)
 
         #if grouping digits, make sure deletes next to group char always
         # delete next digit to appropriate side:
         if self._groupDigits:
             key = event.GetKeyCode()
-            value = wxMaskedTextCtrl.GetValue(self)
+            value = BaseMaskedTextCtrl.GetValue(self)
             sel_start, sel_to = self._GetSelection()
 
-            if key == WXK_BACK:
+            if key == wx.WXK_BACK:
                 # if 1st selected char is group char, select to previous digit
                 if sel_start > 0 and sel_start < len(self._mask) and value[sel_start:sel_to] == self._groupChar:
                     self.SetInsertionPoint(sel_start-1)
@@ -986,7 +1073,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                     self.SetInsertionPoint(sel_start-2)
                     self.SetSelection(sel_start-2, sel_to)
 
-            elif key == WXK_DELETE:
+            elif key == wx.WXK_DELETE:
                 if( sel_to < len(self._mask) - 2 + (1 *self._useParens)
                     and sel_start == sel_to
                     and value[sel_to] == self._groupChar ):
@@ -998,7 +1085,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                     self.SetInsertionPoint(sel_start)
                     self.SetSelection(sel_start, sel_to+1)
 
-        wxMaskedTextCtrl._OnErase(self, event)
+        BaseMaskedTextCtrl._OnErase(self, event)
         dbg(indent=0)
 
 
@@ -1011,8 +1098,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         text events.  So we check for actual changes to the text
         before passing the events on.
         """
-        dbg('wxMaskedNumCtrl::OnTextChange', indent=1)
-        if not wxMaskedTextCtrl._OnTextChange(self, event):
+        dbg('MaskedNumCtrl::OnTextChange', indent=1)
+        if not BaseMaskedTextCtrl._OnTextChange(self, event):
             dbg(indent=0)
             return
 
@@ -1022,7 +1109,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         if value != self._oldvalue:
             try:
                 self.GetEventHandler().ProcessEvent(
-                    wxMaskedNumNumberUpdatedEvent( self.GetId(), self.GetValue(), self ) )
+                    MaskedNumNumberUpdatedEvent( self.GetId(), self.GetValue(), self ) )
             except ValueError:
                 dbg(indent=0)
                 return
@@ -1033,17 +1120,17 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
     def _GetValue(self):
         """
-        Override of wxMaskedTextCtrl to allow amixin to get the raw text value of the
+        Override of BaseMaskedTextCtrl to allow mixin to get the raw text value of the
         control with this function.
         """
-        return wxTextCtrl.GetValue(self)
+        return wx.TextCtrl.GetValue(self)
 
 
     def GetValue(self):
         """
         Returns the current numeric value of the control.
         """
-        return self._fromGUI( wxMaskedTextCtrl.GetValue(self) )
+        return self._fromGUI( BaseMaskedTextCtrl.GetValue(self) )
 
     def SetValue(self, value):
         """
@@ -1054,16 +1141,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         A ValueError exception will be raised if an invalid value
         is specified.
         """
-        wxMaskedTextCtrl.SetValue( self, self._toGUI(value) )
+        BaseMaskedTextCtrl.SetValue( self, self._toGUI(value) )
 
 
     def SetIntegerWidth(self, value):
-        self.SetCtrlParameters(integerWidth=value)
+        self.SetParameters(integerWidth=value)
     def GetIntegerWidth(self):
         return self._integerWidth
 
     def SetFractionWidth(self, value):
-        self.SetCtrlParameters(fractionWidth=value)
+        self.SetParameters(fractionWidth=value)
     def GetFractionWidth(self):
         return self._fractionWidth
 
@@ -1085,7 +1172,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         If min > the max value allowed by the width of the control,
         the function will return False, and the min will not be set.
         """
-        dbg('wxMaskedNumCtrl::SetMin(%s)' % repr(min), indent=1)
+        dbg('MaskedNumCtrl::SetMin(%s)' % repr(min), indent=1)
         if( self._max is None
             or min is None
             or (self._max is not None and self._max >= min) ):
@@ -1208,7 +1295,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             except ValueError, e:
                 dbg('error getting NumValue(self._toGUI(value)):', e, indent=0)
                 return False
-            if value == '':
+            if value.strip() == '':
                 value = None
             elif self._fractionWidth:
                 value = float(value)
@@ -1281,6 +1368,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
     def GetSelectOnEntry(self):
         return self._selectOnEntry
 
+    def SetAutoSize(self, value):
+        self.SetParameters(autoSize=value)
+    def GetAutoSize(self):
+        return self._autoSize
+
+
     # (Other parameter accessors are inherited from base class)
 
 
@@ -1290,7 +1383,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         type and bounds checking and raises ValueError if argument is
         not a valid value.
         """
-        dbg('wxMaskedNumCtrl::_toGUI(%s)' % repr(value), indent=1)
+        dbg('MaskedNumCtrl::_toGUI(%s)' % repr(value), indent=1)
         if value is None and self.IsNoneAllowed():
             dbg(indent=0)
             return self._template
@@ -1298,6 +1391,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         elif type(value) in (types.StringType, types.UnicodeType):
             value = self._GetNumValue(value)
             dbg('cleansed num value: "%s"' % value)
+            if value == "":
+                if self.IsNoneAllowed():
+                    dbg(indent=0)
+                    return self._template
+                else:
+                    dbg('exception raised:', e, indent=0)
+                    raise ValueError ('wxMaskedNumCtrl requires numeric value, passed %s'% repr(value) )
+            # else...
             try:
                 if self._fractionWidth or value.find('.') != -1:
                     value = float(value)
@@ -1305,12 +1406,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                     value = long(value)
             except Exception, e:
                 dbg('exception raised:', e, indent=0)
-                raise ValueError ('wxMaskedNumCtrl requires numeric value, passed %s'% repr(value) )
+                raise ValueError ('MaskedNumCtrl requires numeric value, passed %s'% repr(value) )
 
         elif type(value) not in (types.IntType, types.LongType, types.FloatType):
             dbg(indent=0)
             raise ValueError (
-                'wxMaskedNumCtrl requires numeric value, passed %s'% repr(value) )
+                'MaskedNumCtrl requires numeric value, passed %s'% repr(value) )
 
         if not self._allowNegative and value < 0:
             raise ValueError (
@@ -1360,14 +1461,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         Conversion function used in getting the value of the control.
         """
         dbg(suspend=0)
-        dbg('wxMaskedNumCtrl::_fromGUI(%s)' % value, indent=1)
+        dbg('MaskedNumCtrl::_fromGUI(%s)' % value, indent=1)
         # One or more of the underlying text control implementations
         # issue an intermediate EVT_TEXT when replacing the control's
         # value, where the intermediate value is an empty string.
         # So, to ensure consistency and to prevent spurious ValueErrors,
         # we make the following test, and react accordingly:
         #
-        if value == '':
+        if value.strip() == '':
             if not self.IsNoneAllowed():
                 dbg('empty value; not allowed,returning 0', indent = 0)
                 if self._fractionWidth:
@@ -1413,7 +1514,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         Preprocessor for base control paste; if value needs to be right-justified
         to fit in control, do so prior to paste:
         """
-        dbg('wxMaskedNumCtrl::_Paste (value = "%s")' % value)
+        dbg('MaskedNumCtrl::_Paste (value = "%s")' % value)
         if value is None:
             paste_text = self._getClipboardContents()
         else:
@@ -1425,7 +1526,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             paste_text = self._toGUI(paste_text)
             self._SetSelection(0, len(self._mask))
 
-        return wxMaskedEditMixin._Paste(self,
+        return MaskedEditMixin._Paste(self,
                                         paste_text,
                                         raise_on_invalid=raise_on_invalid,
                                         just_return_value=just_return_value)
@@ -1438,48 +1539,46 @@ if __name__ == '__main__':
 
     import traceback
 
-    class myDialog(wxDialog):
+    class myDialog(wx.Dialog):
         def __init__(self, parent, id, title,
-            pos = wxPyDefaultPosition, size = wxPyDefaultSize,
-            style = wxDEFAULT_DIALOG_STYLE ):
-            wxDialog.__init__(self, parent, id, title, pos, size, style)
+            pos = wx.DefaultPosition, size = wx.DefaultSize,
+            style = wx.DEFAULT_DIALOG_STYLE ):
+            wx.Dialog.__init__(self, parent, id, title, pos, size, style)
 
-            self.int_ctrl = wxMaskedNumCtrl(self, wxNewId(), size=(55,20))
-            self.OK = wxButton( self, wxID_OK, "OK")
-            self.Cancel = wxButton( self, wxID_CANCEL, "Cancel")
+            self.int_ctrl = MaskedNumCtrl(self, wx.NewId(), size=(55,20))
+            self.OK = wx.Button( self, wx.ID_OK, "OK")
+            self.Cancel = wx.Button( self, wx.ID_CANCEL, "Cancel")
 
-            vs = wxBoxSizer( wxVERTICAL )
-            vs.AddWindow( self.int_ctrl, 0, wxALIGN_CENTRE|wxALL, 5 )
-            hs = wxBoxSizer( wxHORIZONTAL )
-            hs.AddWindow( self.OK, 0, wxALIGN_CENTRE|wxALL, 5 )
-            hs.AddWindow( self.Cancel, 0, wxALIGN_CENTRE|wxALL, 5 )
-            vs.AddSizer(hs, 0, wxALIGN_CENTRE|wxALL, 5 )
+            vs = wx.BoxSizer( wx.VERTICAL )
+            vs.Add( self.int_ctrl, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+            hs = wx.BoxSizer( wx.HORIZONTAL )
+            hs.Add( self.OK, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+            hs.Add( self.Cancel, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+            vs.Add(hs, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
 
             self.SetAutoLayout( True )
             self.SetSizer( vs )
             vs.Fit( self )
             vs.SetSizeHints( self )
-            EVT_MASKEDNUM(self, self.int_ctrl.GetId(), self.OnChange)
+            self.Bind(EVT_MASKEDNUM, self.OnChange, self.int_ctrl)
 
         def OnChange(self, event):
             print 'value now', event.GetValue()
 
-    class TestApp(wxApp):
+    class TestApp(wx.App):
         def OnInit(self):
             try:
-                self.frame = wxFrame(NULL, -1, "Test",
-                                     wxPoint(20,20), wxSize(120,100)  )
-                self.panel = wxPanel(self.frame, -1)
-                button = wxButton(self.panel, 10, "Push Me",
-                                  wxPoint(20, 20))
-                EVT_BUTTON(self, 10, self.OnClick)
+                self.frame = wx.Frame(None, -1, "Test", (20,20), (120,100)  )
+                self.panel = wx.Panel(self.frame, -1)
+                button = wx.Button(self.panel, -1, "Push Me", (20, 20))
+                self.Bind(wx.EVT_BUTTON, self.OnClick, button)
             except:
                 traceback.print_exc()
                 return False
             return True
 
         def OnClick(self, event):
-            dlg = myDialog(self.panel, -1, "test wxMaskedNumCtrl")
+            dlg = myDialog(self.panel, -1, "test MaskedNumCtrl")
             dlg.int_ctrl.SetValue(501)
             dlg.int_ctrl.SetInsertionPoint(1)
             dlg.int_ctrl.SetSelection(1,2)
@@ -1503,3 +1602,12 @@ i=0
 ## =============================##
 ##   1. Add support for printf-style format specification.
 ##   2. Add option for repositioning on 'illegal' insertion point.
+##
+## Version 1.1
+##   1. Fixed .SetIntegerWidth() and .SetFractionWidth() functions.
+##   2. Added autoSize parameter, to allow manual sizing of the control.
+##   3. Changed inheritance to use wxBaseMaskedTextCtrl, to remove exposure of
+##      nonsensical parameter methods from the control, so it will work
+##      properly with Boa.
+##   4. Fixed allowNone bug found by user sameerc1@grandecom.net
+