Quantcast

Customizing wxTextValidator

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Customizing wxTextValidator

Andreas Falkenhahn
I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX constants aren't
enough as I need to run a custom algorithm on the string to say whether or not it is
valid.

So I need to create a custom wxValidator class but I'm not sure whether I should just
subclass wxTextValidator or whether I need to subclass wxValidator. I guess the
latter but I'm not sure... is it enough to subclass wxTextValidator and override
its Validate() or do I need to subclass wxValidator instead?

Thanks.

--
Best regards,
 Andreas Falkenhahn                          mailto:[hidden email]

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Andreas Falkenhahn
Also, what I don't understand about wxTextValidator is this: Why are there two methods
to check for valid contents? There is OnChar() which is called when the user presses
a key but there is also Validate() which validates the whole string.

If I create a custom version of wxTextValidator, can I just leave out OnChar()? A
single char is not enough for my custom algorithm to say whether the contents of
the wxTextCtrl are valid or not. I need the algorithm to operate on the whole
string and then decide whether the string is good or not.

But I don't see how to fit this concept to the OnChar() handler that is in wxTextValidator
because it only checks for single keys, whereas I need to check the full string.
Validate() seems to be able to do the trick but I don't understand why there is both -
OnChar() *and* Validate()! This looks somewhat redundant to me... can anyone explain
why it is like that?

On 06.04.2017 at 18:46 Andreas Falkenhahn wrote:

> I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX constants aren't
> enough as I need to run a custom algorithm on the string to say whether or not it is
> valid.

> So I need to create a custom wxValidator class but I'm not sure whether I should just
> subclass wxTextValidator or whether I need to subclass wxValidator. I guess the
> latter but I'm not sure... is it enough to subclass wxTextValidator and override
> its Validate() or do I need to subclass wxValidator instead?

> Thanks.

> --
> Best regards,
>  Andreas Falkenhahn                          mailto:[hidden email]



--
Best regards,
 Andreas Falkenhahn                            mailto:[hidden email]

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Fulvio Senore


Il 06/04/2017 20:44, Andreas Falkenhahn ha scritto:

> Also, what I don't understand about wxTextValidator is this: Why are there two methods
> to check for valid contents? There is OnChar() which is called when the user presses
> a key but there is also Validate() which validates the whole string.
>
> If I create a custom version of wxTextValidator, can I just leave out OnChar()? A
> single char is not enough for my custom algorithm to say whether the contents of
> the wxTextCtrl are valid or not. I need the algorithm to operate on the whole
> string and then decide whether the string is good or not.
>
> But I don't see how to fit this concept to the OnChar() handler that is in wxTextValidator
> because it only checks for single keys, whereas I need to check the full string.
> Validate() seems to be able to do the trick but I don't understand why there is both -
> OnChar() *and* Validate()! This looks somewhat redundant to me... can anyone explain
> why it is like that?
>

I suppose that OnChar lets you validate keys as soon as the user presses
them. For example you can ignore unwanted keys. Of course it is better
to ignore a key when it is pressed than allowing it and complaining
about it when the user moves the focus to another control.

On the other hand there are situation where you cannot know if a key is
valid until the full text is entered. Validate() can be used to check
the whole string where each char can be checked against all others.

Fulvio Senore

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Fulvio Senore
In reply to this post by Andreas Falkenhahn

Il 06/04/2017 18:46, Andreas Falkenhahn ha scritto:
> I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX constants aren't
> enough as I need to run a custom algorithm on the string to say whether or not it is
> valid.
>
> So I need to create a custom wxValidator class but I'm not sure whether I should just
> subclass wxTextValidator or whether I need to subclass wxValidator. I guess the
> latter but I'm not sure... is it enough to subclass wxTextValidator and override
> its Validate() or do I need to subclass wxValidator instead?
>

I had the same problem and I did not have time to waste making
experiments, so I ended up cloning wxTextValidator and changing its
name. Then I changed my copy to suit my needs.
Not a very elegant solution but it worked immediately.

Fulvio Senore

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Andreas Falkenhahn
On 06.04.2017 at 21:51 Fulvio Senore wrote:


> Il 06/04/2017 18:46, Andreas Falkenhahn ha scritto:
>> I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX constants aren't
>> enough as I need to run a custom algorithm on the string to say whether or not it is
>> valid.

>> So I need to create a custom wxValidator class but I'm not sure whether I should just
>> subclass wxTextValidator or whether I need to subclass wxValidator. I guess the
>> latter but I'm not sure... is it enough to subclass wxTextValidator and override
>> its Validate() or do I need to subclass wxValidator instead?


> I had the same problem and I did not have time to waste making
> experiments, so I ended up cloning wxTextValidator and changing its
> name. Then I changed my copy to suit my needs.
> Not a very elegant solution but it worked immediately.

So when is Validate() called? Is it only called when the entry widget loses
the focus? That would be quite an awkward user experience then. I'd expect
Validate() to be called whenever text is to be copied into the widget, either
through a keypress or by pasting from the clipboard. From your previous description
it sounds like only OnChar() is called immediately and Validate() is called
when the widget loses focus... is that right?

--
Best regards,
 Andreas Falkenhahn                            mailto:[hidden email]

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Fulvio Senore
Il 06/04/2017 21:59, Andreas Falkenhahn ha scritto:

> On 06.04.2017 at 21:51 Fulvio Senore wrote:
>
>
>> Il 06/04/2017 18:46, Andreas Falkenhahn ha scritto:
>>> I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX constants aren't
>>> enough as I need to run a custom algorithm on the string to say whether or not it is
>>> valid.
>
>>> So I need to create a custom wxValidator class but I'm not sure whether I should just
>>> subclass wxTextValidator or whether I need to subclass wxValidator. I guess the
>>> latter but I'm not sure... is it enough to subclass wxTextValidator and override
>>> its Validate() or do I need to subclass wxValidator instead?
>
>
>> I had the same problem and I did not have time to waste making
>> experiments, so I ended up cloning wxTextValidator and changing its
>> name. Then I changed my copy to suit my needs.
>> Not a very elegant solution but it worked immediately.
>
> So when is Validate() called? Is it only called when the entry widget loses
> the focus? That would be quite an awkward user experience then. I'd expect
> Validate() to be called whenever text is to be copied into the widget, either
> through a keypress or by pasting from the clipboard. From your previous description
> it sounds like only OnChar() is called immediately and Validate() is called
> when the widget loses focus... is that right?
>

I don't know when Validate() is called. My changes were only in
OnChar(), I did not care about Validate(). Anyway, it should not be too
difficult to answer to your question: either look at the code or set a
breakpoint in Validate() and use the control.

Fulvio

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Vadim Zeitlin-4
In reply to this post by Andreas Falkenhahn
On Thu, 6 Apr 2017 18:46:36 +0200 Andreas Falkenhahn wrote:

AF> I need fine-tuned control over wxTextValidator, i.e. the wxFILTER_XXX
AF> constants aren't enough as I need to run a custom algorithm on the
AF> string to say whether or not it is valid.
AF>
AF> So I need to create a custom wxValidator class but I'm not sure whether
AF> I should just subclass wxTextValidator or whether I need to subclass
AF> wxValidator.

 I think it can still be useful to inherit from wxTextValidator, if only
for its handy GetTextEntry() method. And Transfer{To,From}Window() are
useful too, even if they're trivial. However you will certainly need to
override Validate() and live with quite a few methods (SetXXX()) which
don't really make sense for your class.

 FWIW I think this class really needs to be refactored into some
wxTextValidatorBase, containing just those "uncontroversial" parts, without
all the weird filter stuff.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re[2]: Customizing wxTextValidator

Vadim Zeitlin-4
In reply to this post by Andreas Falkenhahn
On Thu, 6 Apr 2017 20:44:16 +0200 Andreas Falkenhahn wrote:

AF> But I don't see how to fit this concept to the OnChar() handler that is
AF> in wxTextValidator because it only checks for single keys, whereas I
AF> need to check the full string. Validate() seems to be able to do the
AF> trick but I don't understand why there is both - OnChar() and
AF> Validate()! This looks somewhat redundant to me... can anyone explain
AF> why it is like that?

 In many cases you want to validate the whole control contents when the
user is done with editing it and OnChar() doesn't allow you to do it. You
may still need to use OnChar() to prevent entering the characters that are
never valid in the control however.

 Notice that Validate() is _not_ called on focus loss, at least not
automatically. It's only called when the dialog containing the control is
closed -- or if you call it explicitly, of course, including from your own
wxEVT_KILL_FOCUS handler.

 FWIW, in my own code I typically do call it from wxEVT_KILL_FOCUS handler
and show any errors in some less intrusive way than by popping up a message
box, as the default version does. It would be really nice if there was a
way to configure a validator to do this automatically, but I have never
found the time to do this in wxWidgets itself...

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Andreas Falkenhahn
On 06.04.2017 at 22:57 Vadim Zeitlin wrote:

> On Thu, 6 Apr 2017 20:44:16 +0200 Andreas Falkenhahn wrote:

AF>> But I don't see how to fit this concept to the OnChar() handler that is
AF>> in wxTextValidator because it only checks for single keys, whereas I
AF>> need to check the full string. Validate() seems to be able to do the
AF>> trick but I don't understand why there is both - OnChar() and
AF>> Validate()! This looks somewhat redundant to me... can anyone explain
AF>> why it is like that?

>  In many cases you want to validate the whole control contents when the
> user is done with editing it and OnChar() doesn't allow you to do it. You
> may still need to use OnChar() to prevent entering the characters that are
> never valid in the control however.

>  Notice that Validate() is _not_ called on focus loss, at least not
> automatically. It's only called when the dialog containing the control is
> closed -- or if you call it explicitly, of course, including from your own
> wxEVT_KILL_FOCUS handler.

Hmm, then wxValidator is probably not even up for the job that I planned.
As I said, I planned to have string-based validation right at the time
the user types or pastes something.

It probably could be hacked into OnChar() by getting the current control
text and the cursor position and then composing the character into that
string and then decide if the string is valid and reject the key press
in case it isn't but such a solution looks really ugly and it also won't
solve the problem that the user could just hit CTRL-V to paste a whole
string into the control to skip OnChar() validation entirely.

So I guess what I want to do here is not possible with wxWidgets at
the moment.

I guess I'm a little spoiled by UIKit on the Mac where there is an
NSFormatter class whose is​Partial​String​Valid() method allows me to
validate all proposed changes of the control's text (either through
key press or through paste) *before* they are actually shown in the
control. This class allows me to do all kinds of funky stuff but I
guess wxValidator isn't that advanced, probably because the native
text controls on MSW and GTK don't support it.

--
Best regards,
 Andreas Falkenhahn                            mailto:[hidden email]

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re[2]: Customizing wxTextValidator

Vadim Zeitlin-4
On Sun, 9 Apr 2017 14:11:21 +0200 Andreas Falkenhahn wrote:

AF> Hmm, then wxValidator is probably not even up for the job that I planned.
AF> As I said, I planned to have string-based validation right at the time
AF> the user types or pastes something.

 FWIW I still don't think it's a good idea (it is often useful to be able
to enter invalid data into a control _temporarily_), but it is possible to
do, just not very simple, because

AF> It probably could be hacked into OnChar() by getting the current control
AF> text and the cursor position and then composing the character into that
AF> string and then decide if the string is valid and reject the key press

... you would have to do this.

AF> in case it isn't but such a solution looks really ugly and it also won't
AF> solve the problem that the user could just hit CTRL-V to paste a whole
AF> string into the control to skip OnChar() validation entirely.

And you would also have to handle wxEVT_TEXT_PASTE.

AF> I guess I'm a little spoiled by UIKit on the Mac where there is an
AF> NSFormatter class whose is​Partial​String​Valid() method allows me to
AF> validate all proposed changes of the control's text (either through
AF> key press or through paste) before they are actually shown in the
AF> control. This class allows me to do all kinds of funky stuff but I
AF> guess wxValidator isn't that advanced, probably because the native
AF> text controls on MSW and GTK don't support it.

 I do think we need something like this in wx to though and we've discussed
it several times in the past. It's probably also related to good IME
support (which can't be mapped well to simple wxEVT_CHAR neither), which is
another thing being discussed from time to time...

 Regards,
--
Vadim Zeitlin (Technical Director) | email: [hidden email]
TT-Solutions SARL                  | web: http://www.tt-solutions.com/
141, rue des Côtes                 | phone: +33-6-62-94-06-85
78600 Le Mesnil-le-Roi, France     | fax: +33-9-55-57-75-07

attachment0 (188 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Aliket
In reply to this post by Andreas Falkenhahn
Hi Andreas

I'll share with you my hack on customizing wxTextValidator to suit your needs...

1) grab (valtext.h and valtext.cpp) from wx source tree and make these changes:

*** valtext.h changes ***

include <wx/regex.h>

static const long wxFILTER_SPACE = 0x400; // allow you enter spaces and not filter them out.
                        // works reliably in conjunction with wxFILTER_REGEX only, unfortunately
static const long wxFILTER_REGEX = 0x800;

// we need to save flags in this struct
// because wxRegEx is not copyable
// so we can recompile the wxRegEx obj from
// pattern & flags when we need to copy it
// in wxTextValidator2::Copy()
struct wxRegexPattern
{
    wxRegexPattern()
    {
        flags = wxRE_DEFAULT;
    }

    wxRegexPattern(const wxString& pattern_,
                   const wxString& purpose_ = wxEmptyString)
    : pattern( pattern_ ), purpose( purpose_ )
    {
        flags = wxRE_DEFAULT;
    }

    long     flags;
    wxString pattern;
    wxString purpose;
};

wxTextValidator2 ctor will look like this:

wxTextValidator2(long style = wxFILTER_NONE, wxString *val = NULL,
                 const wxRegexPattern& exprs = wxRegexPattern());

and add this overload:

bool HasFlag(long style) const
    { return (m_validatorStyle & style) != 0; }

finaly add this to the protected data members:

protected:

    struct // anonymous
    {
        wxRegEx          m_regex;
        wxRegexPattern   m_exprs;
    };

I'll post the rest if you are interested...

Regards

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Customizing wxTextValidator

Aliket
Hi again

I tweaked my wxTextValidator2::IsValid() a little bit to allow wxFILTER_SPACE to work with
wxFILTER_ALPHA, wxFILTER_ALPHANUMERIC and wxFILTER_DIGITS

As i said wxFILTER_SPACE is intended to allow spaces between words or digits in a the control

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Loading...