# masked.TimeCtrl, and masked.IpAddrCtrl.
#
#----------------------------------------------------------------------------
+"""
+Provides a generic, fully configurable masked edit text control, as well as
+a base class from which you can derive masked controls tailored to a specific
+function. See maskededit module overview for how to configure the control.
+"""
+
import wx
from wx.lib.masked import *
# 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
-dbg = Logger()
-##dbg(enable=0)
-
-# ## 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.
-# ##
+##dbg = Logger()
+##dbg(enable=1)
+
class BaseMaskedTextCtrl( wx.TextCtrl, MaskedEditMixin ):
"""
This is the primary derivation from MaskedEditMixin. It provides
a general masked text control that can be configured with different
- 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.
+ masks.
+
+ However, this is done with an extra level of inheritance, so that
+ "general" classes like masked.TextCtrl can have all possible attributes,
+ while derived classes, like masked.TimeCtrl and masked.NumCtrl
+ 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::
+
+ masked.TextCtrl(BaseMaskedTextCtrl, MaskedEditAccessorsMixin).
+
+ This allows us to then derive::
+
+ masked.NumCtrl( BaseMaskedTextCtrl )
+
+ and not have to expose all the same accessor functions for the
+ derived control when they don't all make sense for it.
+
+ In practice, BaseMaskedTextCtrl should never be instantiated directly,
+ but should only be used in derived classes.
"""
def __init__( self, parent, id=-1, value = '',
style=style, validator=validator,
name=name)
+ self._PostInit(setupEventHandling = setupEventHandling,
+ name=name, value=value,**kwargs )
+
+
+ def _PostInit(self,setupEventHandling=True,
+ name='maskedTextCtrl' , value='', **kwargs):
+
self.controlInitialized = True
MaskedEditMixin.__init__( self, name, **kwargs )
#### 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...
- """
+## def SetSelection(self, sel_start, sel_to):
+## """
+## This is just for debugging...
+## """
## dbg("MaskedTextCtrl::SetSelection(%(sel_start)d, %(sel_to)d)" % locals())
- wx.TextCtrl.SetSelection(self, sel_start, sel_to)
+## wx.TextCtrl.SetSelection(self, sel_start, sel_to)
def _GetInsertionPoint(self):
#### dbg("MaskedTextCtrl::_SetInsertionPoint(%(pos)d)" % locals())
self.SetInsertionPoint(pos)
- def SetInsertionPoint(self, pos):
- """
- This is just for debugging...
- """
+## def SetInsertionPoint(self, pos):
+## """
+## This is just for debugging...
+## """
## dbg("MaskedTextCtrl::SetInsertionPoint(%(pos)d)" % locals())
- wx.TextCtrl.SetInsertionPoint(self, pos)
+## wx.TextCtrl.SetInsertionPoint(self, pos)
def _GetValue(self):
"""
return self.GetValue()
+
def _SetValue(self, value):
"""
Allow mixin to set the raw value of the control with this function.
def SetValue(self, value):
"""
- This function redefines the externally accessible .SetValue to be
+ This function redefines the externally accessible .SetValue() to be
a smart "paste" of the text in question, so as not to corrupt the
masked control. NOTE: this must be done in the class derived
from the base wx control.
# make SetValue behave the same as if you had typed the value in:
try:
- value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
+ value, replace_to = self._Paste(value, raise_on_invalid=True, just_return_value=True)
if self._isFloat:
self._isNeg = False # (clear current assumptions)
value = self._adjustFloat(value)
dateparts[0] = self._adjustDate(dateparts[0], fixcentury=True)
value = string.join(dateparts, ' ')
## dbg('adjusted value: "%s"' % value)
- value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
+ value, replace_to = self._Paste(value, raise_on_invalid=True, just_return_value=True)
else:
## dbg('exception thrown', indent=0)
raise
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('queuing insertion after .SetValue', replace_to)
+ # set selection to last char replaced by paste
+ wx.CallAfter(self._SetInsertionPoint, replace_to)
+ wx.CallAfter(self._SetSelection, replace_to, replace_to)
## dbg(indent=0)
+ def SetFont(self, *args, **kwargs):
+ """ Set the font, then recalculate control size, if appropriate. """
+ wx.TextCtrl.SetFont(self, *args, **kwargs)
+ if self._autofit:
+## dbg('calculated size:', self._CalcSize())
+ self.SetClientSize(self._CalcSize())
+ width = self.GetSize().width
+ height = self.GetBestSize().height
+## dbg('setting client size to:', (width, height))
+ self.SetBestFittingSize((width, height))
+
+
def Clear(self):
""" Blanks the current control value by replacing it with the default value."""
## dbg("MaskedTextCtrl::Clear - value reset to default value (template)")
def IsModified(self):
"""
- This function overrides the raw wxTextCtrl method, because the
+ This function overrides the raw wx.TextCtrl method, because the
masked edit mixin uses SetValue to change the value, which doesn't
- modify the state of this attribute. So, we keep track on each
- keystroke to see if the value changes, and if so, it's been
+ modify the state of this attribute. So, the derived control keeps track
+ on each keystroke to see if the value changes, and if so, it's been
modified.
"""
return wx.TextCtrl.IsModified(self) or self.modified
class TextCtrl( 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.
+ The "user-visible" masked text control; it is identical to the
+ BaseMaskedTextCtrl class it's derived from.
+ (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.)
+ See BaseMaskedTextCtrl for available methods.
"""
pass
+class PreMaskedTextCtrl( BaseMaskedTextCtrl, MaskedEditAccessorsMixin ):
+ """
+ This class exists to support the use of XRC subclassing.
+ """
+ # This should really be wx.EVT_WINDOW_CREATE but it is not
+ # currently delivered for native controls on all platforms, so
+ # we'll use EVT_SIZE instead. It should happen shortly after the
+ # control is created as the control is set to its "best" size.
+ _firstEventType = wx.EVT_SIZE
+
+ def __init__(self):
+ pre = wx.PreTextCtrl()
+ self.PostCreate(pre)
+ self.Bind(self._firstEventType, self.OnCreate)
+
+
+ def OnCreate(self, evt):
+ self.Unbind(self._firstEventType)
+ self._PostInit()
+
+__i=0
+## CHANGELOG:
+## ====================
+## Version 1.2
+## - Converted docstrings to reST format, added doc for ePyDoc.
+## removed debugging override functions.
+##
+## Version 1.1
+## 1. Added .SetFont() method that properly resizes control
+## 2. Modified control to support construction via XRC mechanism.