More patches to the masked edit control from Will Sadkin

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@20551 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-05-08 21:42:47 +00:00
parent 14ca9dc4b0
commit 346573fc95

View File

@@ -54,14 +54,29 @@ mask=
Allowed mask characters and function:
Character Function
# Allow numeric only (0-9)
N Allow letters (a-z,A-Z) and numbers (0-9)
A Allow uppercase letters only (A-Z)
a Allow lowercase letters only (a-z)
X Allow any typeable character
C Allow any letter, upper or lower (a-z,A-Z)
N Allow letters and numbers (0-9)
A Allow uppercase letters only
a Allow lowercase letters only
C Allow any letter, upper or lower
X Allow string.letters, string.punctuation, string.digits
Using these characters, a variety of template masks can be built. See the
demo for some other common examples include date+time, social security
Note:
These controls define these sets of characters using string.letters,
string.uppercase, etc. These sets are affected by the system locale
setting, so in order to have the masked controls accept characters
that are specific to your users' language, your application should
set the locale.
For example, to allow international characters to be used in the
above masks, you can place the following in your code as part of
your application's initialization code:
import locale
locale.setlocale(locale.LC_ALL, '')
Using these mask characters, a variety of template masks can be built. See
the demo for some other common examples include date+time, social security
number, etc. If any of these characters are needed as template rather
than mask characters, they can be escaped with \, ie. \N means "literal N".
(use \\ for literal backslash, as in: r'CCC\\NNN'.)
@@ -561,22 +576,13 @@ control = (WXK_BACK, WXK_DELETE, WXK_CTRL_A, WXK_CTRL_C, WXK_CTRL_S, WXK_CTRL_V,
## Constants for masking. This is where mask characters
## are defined.
## maskchars used to identify valid mask characters from all others
## masktran used to replace mask chars with spaces
## maskchardict used to defined allowed character sets for each mask char
## #- allow numeric 0-9 only
## A- allow uppercase only. Combine with forceupper to force lowercase to upper
## a- allow lowercase only. Combine with forcelower to force upper to lowercase
## X- allow any character (letters, punctuation, digits)
## X- allow any character (string.letters, string.punctuation, string.digits)
## Note: locale settings affect what "uppercase", lowercase, etc comprise.
##
maskchars = ("#","A","a","X","C","N")
maskchardict = {
"#": string.digits,
"A": string.uppercase,
"a": string.lowercase,
"X": string.letters + string.punctuation + string.digits,
"C": string.letters,
"N": string.letters + string.digits
}
months = '(01|02|03|04|05|06|07|08|09|10|11|12)'
charmonths = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)'
@@ -1018,6 +1024,19 @@ class wxMaskedEditMixin:
self._nav = list(nav)
self._control = list(control)
## Dynamically evaluate and store string constants for mask chars
## so that locale settings can be made after this module is imported
## and the controls created after that is done can allow the
## appropriate characters:
self.maskchardict = {
"#": string.digits,
"A": string.uppercase,
"a": string.lowercase,
"X": string.letters + string.punctuation + string.digits,
"C": string.letters,
"N": string.letters + string.digits
}
## self._ignoreChange is used by wxMaskedComboBox, because
## of the hack necessary to determine the selection; it causes
## EVT_TEXT messages from the combobox to be ignored if set.
@@ -2978,7 +2997,7 @@ class wxMaskedEditMixin:
mask character plus control options
"""
maskChar = self.maskdict[pos]
okchars = maskchardict[maskChar] ## entry, get mask approved characters
okchars = self.maskchardict[maskChar] ## entry, get mask approved characters
field = self._FindField(pos)
if okchars and field._okSpaces: ## Allow spaces?
okchars += " "
@@ -3952,15 +3971,26 @@ class wxMaskedTextCtrl( wxTextCtrl, wxMaskedEditMixin ):
self._SetSelection(0, len(self._mask))
# make SetValue behave the same as if you had typed the value in:
value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
if self._isDec:
self._isNeg = False # (clear current assumptions)
value = self._adjustDec(value)
elif self._isInt:
self._isNeg = False # (clear current assumptions)
value = self._adjustInt(value)
elif self._isDate:
value = self._adjustDate(value)
try:
value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
if self._isDec:
self._isNeg = False # (clear current assumptions)
value = self._adjustDec(value)
elif self._isInt:
self._isNeg = False # (clear current assumptions)
value = self._adjustInt(value)
elif self._isDate and not self.IsValid(value) and self._4digityear:
value = self._adjustDate(value, fixcentury=true)
except ValueError:
# If date, year might be 2 digits vs. 4; try adjusting it:
if self._isDate and self._4digityear:
dateparts = value.split(' ')
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)
else:
raise
self._SetValue(value)
dbg(indent=0)
@@ -4193,15 +4223,26 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
self._SetSelection(0, len(self._mask))
# make SetValue behave the same as if you had typed the value in:
value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
if self._isDec:
self._isNeg = False # (clear current assumptions)
value = self._adjustDec(value)
elif self._isInt:
self._isNeg = False # (clear current assumptions)
value = self._adjustInt(value)
elif self._isDate:
value = self._adjustDate(value)
try:
value = self._Paste(value, raise_on_invalid=True, just_return_value=True)
if self._isDec:
self._isNeg = False # (clear current assumptions)
value = self._adjustDec(value)
elif self._isInt:
self._isNeg = False # (clear current assumptions)
value = self._adjustInt(value)
elif self._isDate and not self.IsValid(value) and self._4digityear:
value = self._adjustDate(value, fixcentury=true)
except ValueError:
# If date, year might be 2 digits vs. 4; try adjusting it:
if self._isDate and self._4digityear:
dateparts = value.split(' ')
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)
else:
raise
self._SetValue(value)
@@ -4311,8 +4352,7 @@ class wxMaskedComboBox( wxComboBox, wxMaskedEditMixin ):
self._ignoreChange = False # tell _OnTextChange() to pay attn again
dbg('computed selection:', sel_start, sel_to, indent=0)
dbg(suspend=0) # resume regular debugging
dbg('computed selection:', sel_start, sel_to, indent=0, suspend=0)
return sel_start, sel_to
@@ -4455,6 +4495,45 @@ class wxIpAddrCtrl( wxMaskedTextCtrl ):
print "value:", self.GetAddress()
return False
def SetValue(self, value):
dbg('wxIpAddrCtrl::SetValue(%s)' % str(value), indent=1)
if type(value) != types.StringType:
raise ValueError('%s must be a string', str(value))
bValid = True # assume true
parts = value.split('.')
if len(parts) != 4:
bValid = False
else:
for i in range(4):
part = parts[i]
if not 0 <= len(part) <= 3:
bValid = False
break
elif part.strip(): # non-empty part
try:
j = string.atoi(part)
if not 0 <= j <= 255:
bValid = False
break
else:
parts[i] = '%3d' % j
except:
bValid = False
break
else:
# allow empty sections for SetValue (will result in "invalid" value,
# but this may be useful for initializing the control:
parts[i] = ' ' # convert empty field to 3-char length
if not bValid:
dbg(indent=0)
raise ValueError('value (%s) must be a string of form n.n.n.n where n is empty or in range 0-255' % str(value))
else:
dbg('parts:', parts)
value = string.join(parts, '.')
wxMaskedTextCtrl.SetValue(self, value)
dbg(indent=0)
## ---------- ---------- ---------- ---------- ---------- ---------- ----------
@@ -4891,11 +4970,13 @@ i=1
## 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.
## 11. Made maskchardict an instance var, to make mask chars 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.
## 15. Added validation to wxIpAddrCtrl.SetValue().
##
## Version 1.1
## 1. Changed calling interface to use boolean "useFixedWidthFont" (True by default)