]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/maskednumctrl.py
Add wxRTTI info and set bestSize
[wxWidgets.git] / wxPython / wx / lib / maskednumctrl.py
index c8e7e4bb838f409a8e0d045efee628a5ca83e539..9a3d234793026dbb8dc4ce3021da0656fee3f626 100644 (file)
@@ -4,15 +4,15 @@
 # Created:      09/06/2003
 # Copyright:   (c) 2003 by Will Sadkin
 # RCS-ID:      $Id$
 # 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.
 #----------------------------------------------------------------------------
 # 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.
 #
 #   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.
 #   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.
 #
 #   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.
 #
 #   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
 # 
 #   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>
 
 """<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>
 <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>
 <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>
 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,
          parent, id = -1,
          <B>value</B> = 0,
-         pos = wxDefaultPosition,
-         size = wxDefaultSize,
+         pos = wx.DefaultPosition,
+         size = wx.DefaultSize,
          style = 0,
          style = 0,
-         validator = wxDefaultValidator,
+         validator = wx.DefaultValidator,
          name = "maskednumber",
          <B>integerWidth</B> = 10,
          <B>fractionWidth</B> = 0,
          name = "maskednumber",
          <B>integerWidth</B> = 10,
          <B>fractionWidth</B> = 0,
@@ -80,6 +87,7 @@ Here's the API:
          <B>emptyBackgroundColour</B> = "White",
          <B>validBackgroundColour</B> = "White",
          <B>invalidBackgroundColour</B> = "Yellow",
          <B>emptyBackgroundColour</B> = "White",
          <B>validBackgroundColour</B> = "White",
          <B>invalidBackgroundColour</B> = "Yellow",
+         <B>autoSize</B> = True         
          )
 </PRE>
 <UL>
          )
 </PRE>
 <UL>
@@ -170,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.
     <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>
 </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.)
 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.)
@@ -346,6 +363,12 @@ within the control.  (The default is True.)
 the field values on entry.
 <BR>
 <BR>
 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>
 """
 </DL>
 </body></html>
 """
@@ -361,8 +384,7 @@ MAXINT = maxint     # (constants should be in upper case)
 MININT = -maxint-1
 
 from wx.tools.dbg import Logger
 MININT = -maxint-1
 
 from wx.tools.dbg import Logger
-from wx.lib.maskededit import wxMaskedEditMixin, wxMaskedTextCtrl, Field
-
+from wx.lib.maskededit import MaskedEditMixin, BaseMaskedTextCtrl, Field
 dbg = Logger()
 dbg(enable=0)
 
 dbg = Logger()
 dbg(enable=0)
 
@@ -373,7 +395,7 @@ EVT_MASKEDNUM = wx.PyEventBinder(wxEVT_COMMAND_MASKED_NUMBER_UPDATED, 1)
 
 #----------------------------------------------------------------------------
 
 
 #----------------------------------------------------------------------------
 
-class wxMaskedNumNumberUpdatedEvent(wx.PyCommandEvent):
+class MaskedNumNumberUpdatedEvent(wx.PyCommandEvent):
     def __init__(self, id, value = 0, object=None):
         wx.PyCommandEvent.__init__(self, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, id)
 
     def __init__(self, id, value = 0, object=None):
         wx.PyCommandEvent.__init__(self, wxEVT_COMMAND_MASKED_NUMBER_UPDATED, id)
 
@@ -387,16 +409,55 @@ class wxMaskedNumNumberUpdatedEvent(wx.PyCommandEvent):
 
 
 #----------------------------------------------------------------------------
 
 
 #----------------------------------------------------------------------------
+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
 
     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
         '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,
         'groupChar': ',',                   # by default, use ',' for grouping
         'min': None,                        # by default, no bounds set
         'max': None,
@@ -408,7 +469,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         'emptyBackgroundColour': "White",
         'validBackgroundColour': "White",
         'invalidBackgroundColour': "Yellow",
         '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        
         }
 
 
         }
 
 
@@ -419,21 +481,21 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                 name = "maskednum",
                 **kwargs ):
 
                 name = "maskednum",
                 **kwargs ):
 
-        dbg('wxMaskedNumCtrl::__init__', indent=1)
+        dbg('MaskedNumCtrl::__init__', indent=1)
 
         # Set defaults for control:
         dbg('setting defaults:')
 
         # 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:
             # 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')
         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
                 raise AttributeError('invalid keyword argument "%s"' % key)
             else:
                 init_args[key] = param_value
@@ -481,6 +543,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         del init_args['integerWidth']
         del init_args['fractionWidth']
 
         del init_args['integerWidth']
         del init_args['fractionWidth']
 
+        self._autoSize = init_args['autoSize']
+        if self._autoSize:
+            formatcodes = 'FR<'
+        else:
+            formatcodes = 'R<'
+
 
         mask = intmask+fracmask
 
 
         mask = intmask+fracmask
 
@@ -490,11 +558,11 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         self._typedSign = False
 
         # Construct the base control:
         self._typedSign = False
 
         # Construct the base control:
-        wxMaskedTextCtrl.__init__(
+        BaseMaskedTextCtrl.__init__(
                 self, parent, id, '',
                 pos, size, style, validator, name,
                 mask = mask,
                 self, parent, id, '',
                 pos, size, style, validator, name,
                 mask = mask,
-                formatcodes = 'FR<',
+                formatcodes = formatcodes,
                 fields = fields,
                 validFunc=self.IsInBounds,
                 setupEventHandling = False)
                 fields = fields,
                 validFunc=self.IsInBounds,
                 setupEventHandling = False)
@@ -517,21 +585,22 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         # Ensure proper coloring:
         self.Refresh()
 
         # 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:
         """
 
 
     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)
         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 = {}
 
 
             fields = {}
 
@@ -596,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')
         # 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)
                 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)
                 setattr(self, '_' + key, param_value)
             elif key in ('mask', 'autoformat'): # disallow explicit setting of mask
                 raise AttributeError('invalid keyword argument "%s"' % key)
@@ -607,7 +676,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         dbg('kwargs:', kwargs)
 
         # reprocess existing format codes to ensure proper resulting format:
         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 += '-'
         if kwargs.has_key('allowNegative'):
             if kwargs['allowNegative'] and '-' not in formatcodes:
                 formatcodes += '-'
@@ -634,6 +703,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                 formatcodes = formatcodes.replace('S','')
                 maskededit_kwargs['formatcodes'] = formatcodes
 
                 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
         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
@@ -641,6 +720,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             formatcodes = formatcodes.replace('r', '')
             maskededit_kwargs['formatcodes'] = formatcodes
 
             formatcodes = formatcodes.replace('r', '')
             maskededit_kwargs['formatcodes'] = formatcodes
 
+
         if kwargs.has_key('limited'):
             if kwargs['limited'] and not self._limited:
                 maskededit_kwargs['validRequired'] = True
         if kwargs.has_key('limited'):
             if kwargs['limited'] and not self._limited:
                 maskededit_kwargs['validRequired'] = True
@@ -654,6 +734,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         # Record end of integer and place cursor there:
         integerEnd = self._fields[0]._extent[1]
 
         # Record end of integer and place cursor there:
         integerEnd = self._fields[0]._extent[1]
+        self.SetInsertionPoint(0)
         self.SetInsertionPoint(integerEnd)
         self.SetSelection(integerEnd, integerEnd)
 
         self.SetInsertionPoint(integerEnd)
         self.SetSelection(integerEnd, integerEnd)
 
@@ -726,7 +807,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             dbg('abs(value):', value)
             self._isNeg = False
 
             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:
             if self._min > 0:
                 value = self._min
             else:
@@ -746,7 +827,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             sel_start, sel_to = self.GetSelection()
             self._SetValue(self._toGUI(value))
         self.Refresh() # recolor as appropriate
             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)
 
 
 
 
 
 
@@ -768,7 +849,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         else:
             fracstart, fracend = self._fields[1]._extent
             if candidate is None:
         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()
             else:
                 value = self._toGUI(candidate)
             fracstring = value[fracstart:fracend].strip()
@@ -778,14 +859,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                 return string.atof(fracstring)
 
     def _OnChangeSign(self, event):
                 return string.atof(fracstring)
 
     def _OnChangeSign(self, event):
-        dbg('wxMaskedNumCtrl::_OnChangeSign', indent=1)
+        dbg('MaskedNumCtrl::_OnChangeSign', indent=1)
         self._typedSign = True
         self._typedSign = True
-        wxMaskedEditMixin._OnChangeSign(self, event)
+        MaskedEditMixin._OnChangeSign(self, event)
         dbg(indent=0)
 
 
     def _disallowValue(self):
         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
         # limited and -1 is out of bounds
         if self._typedSign:
             self._isNeg = False
@@ -805,7 +886,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         by the user.
         """
 
         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) ) :
 
         if( (self._fractionWidth and value.find(self._decimalChar) == -1) or
             (self._fractionWidth == 0 and value.find(self._decimalChar) != -1) ) :
@@ -817,8 +898,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
         if numvalue == "":
             if self._allowNone:
 
         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():
                 self.Refresh()
                 return
             elif self._min > 0 and self.IsLimited():
@@ -918,7 +999,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             # reasonable instead:
             dbg('setting replacement value:', replacement)
             self._SetValue(self._toGUI(replacement))
             # 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))
             wx.CallAfter(self.SetInsertionPoint, sel_start)
             sel_to = sel_start + len(str(abs(replacement)))
             dbg('queuing selection of (%d, %d)' %(sel_start, sel_to))
             wx.CallAfter(self.SetInsertionPoint, sel_start)
@@ -944,18 +1025,18 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
 
         sel_start, sel_to = self._GetSelection()     # record current insertion point
 
 
         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:
         wx.CallAfter(self._CheckInsertionPoint)
 
         # After all actions so far scheduled, check that resulting cursor
         # position is appropriate, and move if not:
         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:
 
     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 (' ', '-', '('):
         sel_start, sel_to = self._GetSelection()
         text = self._GetValue()
         if sel_to < self._fields[0]._extent[1] and text[sel_to] in (' ', '-', '('):
@@ -972,13 +1053,13 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         grouping characters auto selects the digit before or after the
         grouping character, so that the erasure does the right thing.
         """
         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()
 
         #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 == wx.WXK_BACK:
             sel_start, sel_to = self._GetSelection()
 
             if key == wx.WXK_BACK:
@@ -1004,7 +1085,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                     self.SetInsertionPoint(sel_start)
                     self.SetSelection(sel_start, sel_to+1)
 
                     self.SetInsertionPoint(sel_start)
                     self.SetSelection(sel_start, sel_to+1)
 
-        wxMaskedTextCtrl._OnErase(self, event)
+        BaseMaskedTextCtrl._OnErase(self, event)
         dbg(indent=0)
 
 
         dbg(indent=0)
 
 
@@ -1017,8 +1098,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         text events.  So we check for actual changes to the text
         before passing the events on.
         """
         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
 
             dbg(indent=0)
             return
 
@@ -1028,7 +1109,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         if value != self._oldvalue:
             try:
                 self.GetEventHandler().ProcessEvent(
         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
             except ValueError:
                 dbg(indent=0)
                 return
@@ -1039,7 +1120,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
 
     def _GetValue(self):
         """
 
     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 wx.TextCtrl.GetValue(self)
         control with this function.
         """
         return wx.TextCtrl.GetValue(self)
@@ -1049,7 +1130,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         """
         Returns the current numeric value of the control.
         """
         """
         Returns the current numeric value of the control.
         """
-        return self._fromGUI( wxMaskedTextCtrl.GetValue(self) )
+        return self._fromGUI( BaseMaskedTextCtrl.GetValue(self) )
 
     def SetValue(self, value):
         """
 
     def SetValue(self, value):
         """
@@ -1060,16 +1141,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         A ValueError exception will be raised if an invalid value
         is specified.
         """
         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):
 
 
     def SetIntegerWidth(self, value):
-        self.SetCtrlParameters(integerWidth=value)
+        self.SetParameters(integerWidth=value)
     def GetIntegerWidth(self):
         return self._integerWidth
 
     def SetFractionWidth(self, 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
 
     def GetFractionWidth(self):
         return self._fractionWidth
 
@@ -1091,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.
         """
         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) ):
         if( self._max is None
             or min is None
             or (self._max is not None and self._max >= min) ):
@@ -1214,7 +1295,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             except ValueError, e:
                 dbg('error getting NumValue(self._toGUI(value)):', e, indent=0)
                 return False
             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)
                 value = None
             elif self._fractionWidth:
                 value = float(value)
@@ -1287,6 +1368,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
     def GetSelectOnEntry(self):
         return self._selectOnEntry
 
     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)
 
 
     # (Other parameter accessors are inherited from base class)
 
 
@@ -1296,7 +1383,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         type and bounds checking and raises ValueError if argument is
         not a valid value.
         """
         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
         if value is None and self.IsNoneAllowed():
             dbg(indent=0)
             return self._template
@@ -1304,6 +1391,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         elif type(value) in (types.StringType, types.UnicodeType):
             value = self._GetNumValue(value)
             dbg('cleansed num value: "%s"' % value)
         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)
             try:
                 if self._fractionWidth or value.find('.') != -1:
                     value = float(value)
@@ -1311,12 +1406,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
                     value = long(value)
             except Exception, e:
                 dbg('exception raised:', e, indent=0)
                     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 (
 
         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 (
 
         if not self._allowNegative and value < 0:
             raise ValueError (
@@ -1366,14 +1461,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
         Conversion function used in getting the value of the control.
         """
         dbg(suspend=0)
         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:
         #
         # 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:
             if not self.IsNoneAllowed():
                 dbg('empty value; not allowed,returning 0', indent = 0)
                 if self._fractionWidth:
@@ -1419,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:
         """
         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:
         if value is None:
             paste_text = self._getClipboardContents()
         else:
@@ -1431,7 +1526,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
             paste_text = self._toGUI(paste_text)
             self._SetSelection(0, len(self._mask))
 
             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)
                                         paste_text,
                                         raise_on_invalid=raise_on_invalid,
                                         just_return_value=just_return_value)
@@ -1450,7 +1545,7 @@ if __name__ == '__main__':
             style = wx.DEFAULT_DIALOG_STYLE ):
             wx.Dialog.__init__(self, parent, id, title, pos, size, style)
 
             style = wx.DEFAULT_DIALOG_STYLE ):
             wx.Dialog.__init__(self, parent, id, title, pos, size, style)
 
-            self.int_ctrl = wxMaskedNumCtrl(self, wx.NewId(), size=(55,20))
+            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")
 
             self.OK = wx.Button( self, wx.ID_OK, "OK")
             self.Cancel = wx.Button( self, wx.ID_CANCEL, "Cancel")
 
@@ -1483,7 +1578,7 @@ if __name__ == '__main__':
             return True
 
         def OnClick(self, event):
             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)
             dlg.int_ctrl.SetValue(501)
             dlg.int_ctrl.SetInsertionPoint(1)
             dlg.int_ctrl.SetSelection(1,2)
@@ -1507,3 +1602,12 @@ i=0
 ## =============================##
 ##   1. Add support for printf-style format specification.
 ##   2. Add option for repositioning on 'illegal' insertion point.
 ## =============================##
 ##   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
+