Patches to the masked edit control from Will Sadkin:
## 1. Fixed .SetValue() to replace the current value, rather than the current ## selection. Also changed it to generate ValueError if presented with ## either a value which doesn't follow the format or won't fit. Also made ## set value adjust numeric and date controls as if user entered the value. ## Expanded doc explaining how SetValue() works. ## 2. Fixed EUDATE* autoformats, fixed IsDateType mask list, and added ability to ## use 3-char months for dates, and EUDATETIME, and EUDATEMILTIME autoformats. ## 3. Made all date autoformats automatically pick implied "datestyle". ## 4. Added IsModified override, since base wxTextCtrl never reports modified if ## .SetValue used to change the value, which is what the masked edit controls ## use internally. ## 5. Fixed bug in date position adjustment on 2 to 4 digit date conversion when ## using tab to "leave field" and auto-adjust. ## 6. Fixed bug in _isCharAllowed() for negative number insertion on pastes, ## and bug in ._Paste() that didn't account for signs in signed masks either. ## 7. Fixed issues with _adjustPos for right-insert fields causing improper ## selection/replacement of values ## 8. Fixed _OnHome handler to properly handle extending current selection to ## beginning of control. ## 9. Exposed all (valid) autoformats to demo, binding descriptions to ## autoformats. ## 10. Fixed a couple of bugs in email regexp. ## 11. Modified autoformats to be more amenable to international use. ## 12. Clarified meaning of '-' formatcode in doc. ## 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. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@20549 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
from wxPython.wx import *
|
||||
from wxPython.lib.maskededit import Field, wxMaskedTextCtrl, wxMaskedComboBox, wxIpAddrCtrl, states, months
|
||||
from wxPython.lib.maskededit import __doc__ as overviewdoc
|
||||
from wxPython.lib.maskededit import autoformats
|
||||
from wxPython.lib.scrolledpanel import wxScrolledPanel
|
||||
import string
|
||||
import string, sys, traceback
|
||||
|
||||
class demoMixin:
|
||||
"""
|
||||
@@ -12,7 +13,7 @@ class demoMixin:
|
||||
description = wxStaticText( self, -1, "Description", )
|
||||
mask = wxStaticText( self, -1, "Mask Value" )
|
||||
formatcode = wxStaticText( self, -1, "Format" )
|
||||
regex = wxStaticText( self, -1, "Regexp\nValidator(opt.)" )
|
||||
regex = wxStaticText( self, -1, "Regexp Validator(opt.)" )
|
||||
ctrl = wxStaticText( self, -1, "wxMaskedEdit Ctrl" )
|
||||
|
||||
description.SetFont( wxFont(9, wxSWISS, wxNORMAL, wxBOLD))
|
||||
@@ -72,13 +73,12 @@ class demoPage1(wxScrolledPanel, demoMixin):
|
||||
|
||||
label = wxStaticText( self, -1, """\
|
||||
Here are some basic wxMaskedTextCtrls to give you an idea of what you can do
|
||||
with this control. Note that all controls have been auto-sized by including
|
||||
F in the format code.
|
||||
with this control. Note that all controls have been auto-sized by including 'F' in
|
||||
the format codes.
|
||||
|
||||
Try entering nonsensical or partial values in validated fields to see what
|
||||
happens. Note that the State and Last Name fields are list-limited (valid
|
||||
last names are: Smith, Jones, Williams). Signs on numbers can be toggled
|
||||
with the minus key.
|
||||
Try entering nonsensical or partial values in validated fields to see what happens.
|
||||
Note that the State and Last Name fields are list-limited (valid last names are:
|
||||
Smith, Jones, Williams). Signs on numbers can be toggled with the minus key.
|
||||
""")
|
||||
label.SetForegroundColour( "Blue" )
|
||||
header = wxBoxSizer( wxHORIZONTAL )
|
||||
@@ -113,6 +113,7 @@ with the minus key.
|
||||
("Zip plus 4", "#{5}-#{4}", "", 'F', "\d{5}-(\s{4}|\d{4})", '','',''),
|
||||
("Customer No", "\CAA-###", "", 'F!', "C[A-Z]{2}-\d{3}", '','',''),
|
||||
("Invoice Total", "#{9}.##", "", 'F-_,', "", '','',''),
|
||||
("Integer", "#{9}", "", 'F-_', "", '','',''),
|
||||
]
|
||||
|
||||
self.layoutGeneralTable(controls, grid)
|
||||
@@ -137,6 +138,50 @@ with the minus key.
|
||||
|
||||
|
||||
class demoPage2(wxScrolledPanel, demoMixin):
|
||||
def __init__( self, parent, log ):
|
||||
self.log = log
|
||||
wxScrolledPanel.__init__( self, parent, -1 )
|
||||
self.sizer = wxBoxSizer( wxVERTICAL )
|
||||
|
||||
label = wxStaticText( self, -1, """\
|
||||
All these controls have been created by passing a single parameter, the autoformat code.
|
||||
The class contains an internal dictionary of types and formats (autoformats).
|
||||
Many of these already do complicated validation; To see some examples, try
|
||||
29 Feb 2002 vs. 2004 for the date formats, or email address validation.
|
||||
""")
|
||||
|
||||
label.SetForegroundColour( "Blue" )
|
||||
self.sizer.Add( label, 0, wxALIGN_LEFT|wxALL, 5 )
|
||||
|
||||
description = wxStaticText( self, -1, "Description")
|
||||
autofmt = wxStaticText( self, -1, "AutoFormat Code")
|
||||
ctrl = wxStaticText( self, -1, "wxMaskedEdit Control")
|
||||
|
||||
description.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
autofmt.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
ctrl.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
|
||||
grid = wxFlexGridSizer( 0, 3, vgap=10, hgap=5 )
|
||||
grid.Add( description, 0, wxALIGN_LEFT )
|
||||
grid.Add( autofmt, 0, wxALIGN_LEFT )
|
||||
grid.Add( ctrl, 0, wxALIGN_LEFT )
|
||||
|
||||
for autoformat, desc in autoformats:
|
||||
grid.Add( wxStaticText( self, -1, desc), 0, wxALIGN_LEFT )
|
||||
grid.Add( wxStaticText( self, -1, autoformat), 0, wxALIGN_LEFT )
|
||||
grid.Add( wxMaskedTextCtrl( self, -1, "",
|
||||
autoformat = autoformat,
|
||||
demo = True,
|
||||
name = autoformat),
|
||||
0, wxALIGN_LEFT )
|
||||
|
||||
self.sizer.Add( grid, 0, wxALIGN_LEFT|wxALL, border=5 )
|
||||
self.SetSizer( self.sizer )
|
||||
self.SetAutoLayout( 1 )
|
||||
self.SetupScrolling()
|
||||
|
||||
|
||||
class demoPage3(wxScrolledPanel, demoMixin):
|
||||
def __init__(self, parent, log):
|
||||
self.log = log
|
||||
wxScrolledPanel.__init__(self, parent, -1)
|
||||
@@ -182,76 +227,7 @@ has a legal range specified.
|
||||
self.changeControlParams( event, "validRequired", True, False )
|
||||
|
||||
|
||||
|
||||
class demoPage3( wxScrolledPanel, demoMixin ):
|
||||
def __init__( self, parent, log ):
|
||||
self.log = log
|
||||
wxScrolledPanel.__init__( self, parent, -1 )
|
||||
self.sizer = wxBoxSizer( wxVERTICAL )
|
||||
|
||||
label = wxStaticText( self, -1, """\
|
||||
All these controls have been created by passing a single parameter, the autoformat code.
|
||||
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.""")
|
||||
|
||||
label.SetForegroundColour( "Blue" )
|
||||
self.sizer.Add( label, 0, wxALIGN_LEFT|wxALL, 5 )
|
||||
|
||||
description = wxStaticText( self, -1, "Description")
|
||||
autofmt = wxStaticText( self, -1, "AutoFormat Code")
|
||||
ctrl = wxStaticText( self, -1, "wxMaskedEdit Control")
|
||||
|
||||
description.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
autofmt.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
ctrl.SetFont( wxFont( 9, wxSWISS, wxNORMAL, wxBOLD ) )
|
||||
|
||||
grid = wxFlexGridSizer( 0, 3, vgap=10, hgap=5 )
|
||||
grid.Add( description, 0, wxALIGN_LEFT )
|
||||
grid.Add( autofmt, 0, wxALIGN_LEFT )
|
||||
grid.Add( ctrl, 0, wxALIGN_LEFT )
|
||||
|
||||
controls = [
|
||||
#description autoformat code
|
||||
("Phone No w/opt. ext","USPHONEFULLEXT"),
|
||||
("Phone No only", "USPHONEFULL"),
|
||||
("US Date + Time","USDATETIMEMMDDYYYY/HHMMSS"),
|
||||
("US Date + Time\n(without seconds)","USDATETIMEMMDDYYYY/HHMM"),
|
||||
("US Date + Military Time","USDATEMILTIMEMMDDYYYY/HHMMSS"),
|
||||
("US Date + Military Time\n(without seconds)","USDATEMILTIMEMMDDYYYY/HHMM"),
|
||||
("US Date MMDDYYYY","USDATEMMDDYYYY/"),
|
||||
("Time", "TIMEHHMMSS"),
|
||||
("Time\n(without seconds)", "TIMEHHMM"),
|
||||
("Military Time", "MILTIMEHHMMSS"),
|
||||
("Military Time\n(without seconds)", "MILTIMEHHMM"),
|
||||
("European Date", "EUDATEYYYYMMDD/"),
|
||||
("Social Sec#","USSOCIALSEC"),
|
||||
("Credit Card","CREDITCARD"),
|
||||
("Expiration MM/YY","EXPDATEMMYY"),
|
||||
("Percentage","PERCENT"),
|
||||
("Person's Age","AGE"),
|
||||
("US State", "USSTATE"),
|
||||
("US Zip Code","USZIP"),
|
||||
("US Zip+4","USZIPPLUS4"),
|
||||
("Age", "AGE"),
|
||||
("Email Address","EMAIL"),
|
||||
]
|
||||
for control in controls:
|
||||
grid.Add( wxStaticText( self, -1, control[0]), 0, wxALIGN_LEFT )
|
||||
grid.Add( wxStaticText( self, -1, control[1]), 0, wxALIGN_LEFT )
|
||||
grid.Add( wxMaskedTextCtrl( self, -1, "",
|
||||
autoformat = control[1],
|
||||
demo = True,
|
||||
name = control[1]),
|
||||
0, wxALIGN_LEFT )
|
||||
|
||||
self.sizer.Add( grid, 0, wxALIGN_LEFT|wxALL, border=5 )
|
||||
self.SetSizer( self.sizer )
|
||||
self.SetAutoLayout( 1 )
|
||||
self.SetupScrolling()
|
||||
|
||||
|
||||
class demoPage4( wxScrolledPanel, demoMixin ):
|
||||
class demoPage4(wxScrolledPanel, demoMixin):
|
||||
def __init__( self, parent, log ):
|
||||
self.log = log
|
||||
wxScrolledPanel.__init__( self, parent, -1 )
|
||||
@@ -344,14 +320,14 @@ Page Up and Shift-Up arrow will similarly cycle backwards through the list.
|
||||
self.SetupScrolling()
|
||||
|
||||
|
||||
class demoPage5( wxScrolledPanel, demoMixin ):
|
||||
class demoPage5(wxScrolledPanel, demoMixin):
|
||||
def __init__( self, parent, log ):
|
||||
self.log = log
|
||||
wxScrolledPanel.__init__( self, parent, -1 )
|
||||
self.sizer = wxBoxSizer( wxVERTICAL )
|
||||
label = wxStaticText( self, -1, """\
|
||||
These are examples of wxMaskedComboBox and wxIpAddrCtrl, and a more
|
||||
useful configuration of a wxMaskedTextCtrl for floating point input.
|
||||
These are examples of wxMaskedComboBox and wxIpAddrCtrl, and more useful
|
||||
configurations of a wxMaskedTextCtrl for integer and floating point input.
|
||||
""")
|
||||
label.SetForegroundColour( "Blue" )
|
||||
self.sizer.Add( label, 0, wxALIGN_LEFT|wxALL, 5 )
|
||||
@@ -420,13 +396,24 @@ of form: 10. (1|2) . (129..255) . (0..255)""")
|
||||
ip_addr3.SetFieldParameters(1, validRange=(129,255), validRequired=False )
|
||||
|
||||
text7 = wxStaticText( self, -1, """\
|
||||
A right-insert integer entry control:""")
|
||||
intctrl = wxMaskedTextCtrl(self, -1, name='intctrl', mask="#{9}", formatcodes = '_-r,F')
|
||||
|
||||
text8 = wxStaticText( self, -1, """\
|
||||
A floating point entry control
|
||||
with right-insert for ordinal:""")
|
||||
floatctrl = wxMaskedTextCtrl(self, -1, mask="#{9}.#{2}", formatcodes="F_-R")
|
||||
floatctrl.SetFieldParameters(0, formatcodes='r,<', validRequired=True) # right-insert, allow commas, require explicit cursor movement to change fields
|
||||
floatctrl.SetFieldParameters(1, defaultValue='00') # don't allow blank fraction
|
||||
self.floatctrl = wxMaskedTextCtrl(self, -1, name='floatctrl', mask="#{9}.#{2}", formatcodes="F,_-R")
|
||||
self.floatctrl.SetFieldParameters(0, formatcodes='r<', validRequired=True) # right-insert, require explicit cursor movement to change fields
|
||||
self.floatctrl.SetFieldParameters(1, defaultValue='00') # don't allow blank fraction
|
||||
|
||||
grid = wxFlexGridSizer( 0, 2, vgap=20, hgap = 5 )
|
||||
text9 = wxStaticText( self, -1, """\
|
||||
Use this control to programmatically set
|
||||
the value of the above float control:""")
|
||||
number_combo = wxComboBox(self, -1, choices = [ '', '111', '222.22', '-3', '54321.666666666', '-1353.978',
|
||||
'1234567', '-1234567', '123456789', '-123456789.1',
|
||||
'1234567890.', '-1234567890.1' ])
|
||||
|
||||
grid = wxFlexGridSizer( 0, 2, vgap=10, hgap = 5 )
|
||||
grid.Add( text1, 0, wxALIGN_LEFT )
|
||||
grid.Add( fraction, 0, wxALIGN_LEFT )
|
||||
grid.Add( text2, 0, wxALIGN_LEFT )
|
||||
@@ -440,7 +427,11 @@ with right-insert for ordinal:""")
|
||||
grid.Add( text6, 0, wxALIGN_LEFT )
|
||||
grid.Add( ip_addr3, 0, wxALIGN_LEFT )
|
||||
grid.Add( text7, 0, wxALIGN_LEFT )
|
||||
grid.Add( floatctrl, 0, wxALIGN_LEFT )
|
||||
grid.Add( intctrl, 0, wxALIGN_LEFT )
|
||||
grid.Add( text8, 0, wxALIGN_LEFT )
|
||||
grid.Add( self.floatctrl, 0, wxALIGN_LEFT )
|
||||
grid.Add( text9, 0, wxALIGN_LEFT )
|
||||
grid.Add( number_combo, 0, wxALIGN_LEFT )
|
||||
|
||||
self.sizer.Add( grid, 0, wxALIGN_LEFT|wxALL, border=5 )
|
||||
self.SetSizer( self.sizer )
|
||||
@@ -457,7 +448,9 @@ with right-insert for ordinal:""")
|
||||
EVT_TEXT( self, ip_addr1.GetId(), self.OnIpAddrChange )
|
||||
EVT_TEXT( self, ip_addr2.GetId(), self.OnIpAddrChange )
|
||||
EVT_TEXT( self, ip_addr3.GetId(), self.OnIpAddrChange )
|
||||
EVT_TEXT( self, floatctrl.GetId(), self.OnTextChange )
|
||||
EVT_TEXT( self, intctrl.GetId(), self.OnTextChange )
|
||||
EVT_TEXT( self, self.floatctrl.GetId(), self.OnTextChange )
|
||||
EVT_COMBOBOX( self, number_combo.GetId(), self.OnNumberSelect )
|
||||
|
||||
|
||||
def OnComboChange( self, event ):
|
||||
@@ -465,7 +458,6 @@ with right-insert for ordinal:""")
|
||||
if not ctl.IsValid():
|
||||
self.log.write('current value not a valid choice')
|
||||
|
||||
|
||||
def OnIpAddrChange( self, event ):
|
||||
ip_addr = self.FindWindowById( event.GetId() )
|
||||
if ip_addr.IsValid():
|
||||
@@ -476,6 +468,21 @@ with right-insert for ordinal:""")
|
||||
if ctl.IsValid():
|
||||
self.log.write('new value = %s\n' % ctl.GetValue() )
|
||||
|
||||
def OnNumberSelect( self, event ):
|
||||
value = event.GetString()
|
||||
# Format choice to fit into format for #{9}.#{2}, with sign position reserved:
|
||||
# (ordinal + fraction == 11 + decimal point + sign == 13)
|
||||
if value:
|
||||
floattext = "%13.2f" % float(value)
|
||||
else:
|
||||
floattext = value # clear the value again
|
||||
try:
|
||||
self.floatctrl.SetValue(floattext)
|
||||
except:
|
||||
type, value, tb = sys.exc_info()
|
||||
for line in traceback.format_exception_only(type, value):
|
||||
self.log.write(line)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
class TestMaskedTextCtrls(wxNotebook):
|
||||
def __init__(self, parent, id, log):
|
||||
@@ -486,10 +493,10 @@ class TestMaskedTextCtrls(wxNotebook):
|
||||
self.AddPage(win, "General examples")
|
||||
|
||||
win = demoPage2(self, log)
|
||||
self.AddPage(win, "Using default values")
|
||||
self.AddPage(win, 'Auto-formatted controls')
|
||||
|
||||
win = demoPage3(self, log)
|
||||
self.AddPage(win, 'Auto-formatted controls')
|
||||
self.AddPage(win, "Using default values")
|
||||
|
||||
win = demoPage4(self, log)
|
||||
self.AddPage(win, 'Using auto-complete fields')
|
||||
|
Reference in New Issue
Block a user