On Fri, 25 May 2012 01:59:53 +0200 Manolo wrote:
M> I'm thinking of giving wxMaskedEditCtrl a try.
This would be most welcome, it's really a pity to still not have such a
useful control.
M> I found:
M>
http://svn.wxwidgets.org/viewvc/wx/wxWidgets/branches/SOC2010_MASKED_CTRL/interface/wx/maskededit.h
M> and
M>
http://wxpython.org/docs/api/wx.lib.masked.maskededit-module.html
M>
M> After reading those docs, I still have some thoughts and doubts:
M>
M> a) This is not a composite control, just an "edit control" which
M> allows only some kind of inputs.
It was meant to be used as a "decorator" for any text control. I.e. it
would modify the behaviour of an existing control.
M> Something similar to a wxValidator. Or, should it really be a
M> specialized validator?
I don't think it makes sense to make it a validator, it's too different
from the other ones. It also modifies the control appearance which is
something that normal validators never do. It is conceptually similar to
them though.
M> b) It shall work with wxTextCtrl and wxComboBox. I guess, with wxTextEntry.
Yes, and this is why it's a decorator instead of being a control itself.
M> c) The whole string at the control is divided into one or more
M> "fields", with something to
M> separate them. This "something separator" is given in the mask.
M> Example 1: "123.123.123.123" the separator is "."
M> Example 2: "12-mar-2012" the separator is "-"
M> Example 3: "04/10 23:15" with three separators "/", " " and ":"
M> Example 4: "(090)123123" with a prefix "(" and a separator ")"
Yes.
M> d) Mask characters, or "what this control is said to do"
M> # Allow numeric only (0-9)
M> N Allow letters and numbers (0-9)
M> A Allow uppercase letters only
M> a Allow lowercase letters only
M> C Allow any letter, upper or lower
M> It should be advised that uppercase/lowercase works well currently
M> just with latin characters.
M> X Allow string.letters, string.punctuation, string.digits
M> & Allow string.punctuation only (doesn't include all unicode symbols)
M> * Allow any visible character
M> What's intended with "punctuation"? Any other character like @#'<;?
% python -c 'import string; print string.punctuation'
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
M> What is a "visible" character?
My guess would be any character for which isprint() returns true.
M> | Field boundary. Fields are continuous, without separator between them
M> Is this "|" mandatory?
I don't really know.
M> All these "allow" characters mean you can type it, or not. But it lacks
M> a "you must" type it. If I need a four, not other than four, characters
M> field, how is this told in the mask?
I think all characters are required in this control (please consider
checking it with wxPython demo). I.e. if you have "####" mask then you need
to enter 4 digits for IsValid() to return true.
M> e) Literal characters may be set. So, with a mask like "##\a#.###"
M> valid inputs are "12a3.456"
M> or "45a1.900". How many fields are here? two: "12a3" and "456" or
M> three: "12" "a3" and "456"
M> And, if that "." is considered as a field separator, shouldn't that
M> "\a" be a field separator too?
I think it should be, yes. Any non-special character or any special
character escaped by a backslash should be treated the same.
M> Literals, must the user type them?
No.
M> f) Format codes:
M> _ Allow spaces
M> ! Force upper
M> ^ Force lower
M> R Right-align field(s)
M> r Right-insert in field(s) (implies R)
M> < Stay in field until explicit navigation out of it
M> I don't understand this "<"
Me neither. "!" and "^" are weird, for me "^" clearly evokes "force
upper". In any case, none of them is really absolutely needed and it would
be perfectly acceptable to have a first, simple version of the control
without them. In fact I think it would be preferable to have an as simple
as possible first version to make it easier to test it under all platforms
and ensure that at least the basic functionality does work everywhere.
M> > insert/delete/backspace behaviour.
M> As I understand this, delete/backspace-key can delete a char or the
M> whole field.
Probably, don't know. Not indispensable in the first version neither.
M> F Auto-Fit: The control calculate its size from the mask length.
M> What is this needed for? wxWindow::SetMinSize()?
Yes, probably.
M> h) I like the idea of allowing the user to set some validator[s]
M> function[s] on [each] field.
It's interesting but, again, it almost certainly shouldn't be in the first
version.
M> i) Allow/Exclude some characters. Allow/Exclude some strings. Both
M> options defined for each field.
M> With "allow" I really mean "list of only allowed".
I think this would be done with custom validators. We really can't
implement all kinds of possible checks in this class itself, so we should
only implement the most common ones and -- perhaps later -- make it
possible to define custom checks.
M> j) Do a numeric range check.
Same as (i).
M> k) Allow or not and empty field.
I don't think it matters if the field is empty or not. If we want to allow
leaving something empty we must use some indicator for this in the mask.
E.g. if "##" means "2 digits" then we could have "##?" for "1 or 2 digits".
M> l) Replace and empty field with some default.
I really don't think this belongs to this class. It's totally
application-specific.
M> m) Autocomplete. Automatically or with some key (pagedown?). This
M> should be combined with allowed strings.
Nice but let's leave it for later.
M> n) Colors. Both background and foreground.
This OTOH is specific enough to be implemented in the control itself.
M> - Invalid input
M> - valid, although incomplete
M> - Valid
M> - Default colors when nothing is yet typed, although some value is still there.
If you work on this, please define a struct/class containing all these
colours instead of adding separate functions for setting each of them.
M> o) What about retaining focus when, after and invalid paste, some
M> field is invalid?.
Sorry, what about it?
M> p) When should "validation" be done? While typing allows char
M> filtering, but not range check.
I think wxIntegerValidator experiment has successfully shown that
validation during typing is a bad idea. We could set the colours when the
field loses focus but there should be no error messages from the control at
all, leave it to the application code to do it when it wants.
M> q) Navigation. I suppose the idea is that the cursor "jumps" over the
M> separator to the next field when the previous field has been full typed.
M> In a IP field, after typing the third digit, and range
M> check validates its value, the cursor goes on the next field.
Yes, and this is pretty critical for the control usability.
M> But, what should TAB do? next field or next control?
Next field I'd say.
M> Should cursor-keys allow jumping between fields or just inside one?
M> Typing the field separator, should be understood as "jump to next field"?
M> What other navigations keys (home, end, ctrl-up, etc) should do?
I think we shouldn't do anything special (i.e. cursor keys should behave
by default, except that they should skip over fixed characters; typing a
separator should do nothing) at least initially.
M> There are three ways:
M> - Working with existing wxMaskedEditCtrl C++ code
M> - Translating most from current wxPython masked module to C++
M> - Restart from scratch
M>
M> Most of the rules can be done with wxRegEx.
I'm not sure if it's a good idea to use wxRegEx here.
M> Finally, the more I think of it, the more it fits in a validator, not
M> in a control.
M>
M> What do you think?
I don't believe this should be a validator. OTOH more I think about it,
more I become sure that we actually can't implement it as a pure decorator
neither because wxMaskedEditCtrl needs to override some methods. E.g. with
"####-##-##" mask you'd probably expect SetValue("20120525") to show
"2012-05-25" in the text control but how would you make this work without
overriding SetValue()? Well, maybe this is not such a problem if we had
wxMaskedEditCtrl::SetPlainValue() (there is already a GetPlainValue()).
Anyhow, if we can implement it as a decorator -- all the best. If not, the
least bad solution is to have a template wxMaskedEdit<T> class inheriting
from T, so that we could have wxMaskedEdit<wxTextCtrl> or
wxMaskedEdit<wxComboBox> or whatever.
As for the best approach, I think it would be nice to salvage something
from the existing wxMaskedEditCtrl code. However I don't think you can
really reuse much of it without any changes. So I guess I'd recommend
starting from scratch but reusing as much of it as possible.
In any case -- and I really can't emphasize this enough -- it would be an
excellent idea to have a version with as few features as possible but
working well under all platforms first. This would allow us to add it to
wxWidgets and we could proceed to extend it later. If you try to implement
all of the features listed above, it's going to take you years and you'll
probably never finish it and we won't have anything at all in wxWidgets any
time soon so this is definitely a case of "less is more".
Good luck,
VZ