TransferToWindow and TransferFromWindow isn't called in custom validator  [SOLVED]

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
usernameak
In need of some credit
In need of some credit
Posts: 5
Joined: Thu Jul 12, 2018 11:13 am

TransferToWindow and TransferFromWindow isn't called in custom validator

Postby usernameak » Thu Jul 12, 2018 11:15 am

TransferToWindow and TransferFromWindow isn't called in custom validator.
The validator:

Code: Select all

#pragma once

#include <wx/wx.h>

template <typename T> class WDEdCBBitValidator : public wxValidator {
    T *val;
    T bitmask;
public:
    WDEdCBBitValidator(T *val, T bitmask) : wxValidator(), val(val), bitmask(bitmask) {
        wxPrintf("Validator init\n");
    };

    virtual wxObject *Clone() const {
        wxPrintf("Validator Clone %p %p\n", m_validatorWindow, val);
        return new WDEdCBBitValidator<T>(*this);
    }

    // Called when the value in the window must be validated: this is not used
    // by this class
    virtual bool Validate(wxWindow * WXUNUSED(parent)) {
        return true;
    }

    // Called to transfer data to the window
    virtual bool TransferToWindow() {
        wxPrintf("TransferToWindow %p %p\n", m_validatorWindow, val);
        if(!m_validatorWindow || !val) return false;
        wxCheckBox *cb = (wxCheckBox *) m_validatorWindow;
        cb->SetValue((*val & bitmask) ? true : false);
        return true;
    }

    // Called to transfer data from the window
    virtual bool TransferFromWindow() {
        wxPrintf("TransferFromWindow %p %p\n", m_validatorWindow, val);
        if(!m_validatorWindow || !val) return false;
        wxCheckBox *cb = (wxCheckBox *) m_validatorWindow;
        if(cb->GetValue()) {
            *val |= bitmask;
        } else {
            *val &= ~bitmask;
        }
        return true;
    }
};

User avatar
doublemax
Moderator
Moderator
Posts: 12423
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby doublemax » Thu Jul 12, 2018 12:22 pm

At first sight i don't see anything obviously wrong. Where/how do you use it? TransferToWindow() will only be called automatically inside wxDialog(s), not inside wxFrame(s).

http://docs.wxwidgets.org/trunk/overview_validator.html
Use the source, Luke!

usernameak
In need of some credit
In need of some credit
Posts: 5
Joined: Thu Jul 12, 2018 11:13 am

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby usernameak » Thu Jul 12, 2018 12:25 pm

I use it in a wxDialog:

Code: Select all

template <typename T> WDEdPropertiesDialog *AddBitCheckboxGroup(wxString name, T *value, std::initializer_list<WDEdBitCheckboxProperties<T> > props) {
        AddGroup(name);
        int i = 0;
        int j = sizer->GetRows();
        for(auto &prop : props) {

            sizer->Add(new wxCheckBox(panel,
                                      wxID_ANY,
                                      prop.name,
                                      wxDefaultPosition, wxDefaultSize,
                                      0L,
                                      WDEdCBBitValidator<T>(value, prop.bitmask)
                                     ), wxGBPosition(j, i++));
            if(i != i % 4) {
                j++;
                i = i % 4;
            }
        }
        return this;
    }
Last edited by usernameak on Thu Jul 12, 2018 1:10 pm, edited 1 time in total.

Manolo
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 576
Joined: Mon Apr 30, 2012 11:07 pm

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby Manolo » Thu Jul 12, 2018 12:28 pm

Your validator code seems good. You don't post the code where the validator is bound or used, so hard to find an issue.

Transfer to/from window only happens automatically for dialogs, not other windows like a wxFrame.
You may call those functions as a response to some user action, e.g. the control loses focus.

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1586
Joined: Sun Jan 03, 2010 5:45 pm

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby PB » Thu Jul 12, 2018 2:26 pm

"Is not called in custom validator" implies that it works with a built-in one (wxGenericValidator)? This is quite important distinction to see whether the issue is with validation of your dialog in general or the custom validator only.

As usual, an SSCCE would be great to have...

Edit
Seems to works for me (as in both methods are getting called) with current master on MSW:

Code: Select all

#include <wx/wx.h>

template <typename T> class WDEdCBBitValidator : public wxValidator {
    T *val;
    T bitmask;
public:
    WDEdCBBitValidator(T *val, T bitmask) : wxValidator(), val(val), bitmask(bitmask) {
        wxLogMessage("Validator init\n");
    };

    virtual wxObject *Clone() const {
        wxLogMessage("Validator Clone %p %p\n", m_validatorWindow, val);
        return new WDEdCBBitValidator<T>(*this);
    }

    // Called when the value in the window must be validated: this is not used
    // by this class
    virtual bool Validate(wxWindow * WXUNUSED(parent)) {
        return true;
    }

    // Called to transfer data to the window
    virtual bool TransferToWindow() {
        wxLogMessage("TransferToWindow %p %p\n", m_validatorWindow, val);
        if(!m_validatorWindow || !val) return false;
        wxCheckBox *cb = (wxCheckBox *) m_validatorWindow;
        cb->SetValue((*val & bitmask) ? true : false);
        return true;
    }

    // Called to transfer data from the window
    virtual bool TransferFromWindow() {
        wxLogMessage("TransferFromWindow %p %p\n", m_validatorWindow, val);
        if(!m_validatorWindow || !val) return false;
        wxCheckBox *cb = (wxCheckBox *) m_validatorWindow;
        if(cb->GetValue()) {
            *val |= bitmask;
        } else {
            *val &= ~bitmask;
        }
        return true;
    }
};

class MyDialog : public wxDialog
{
public:
    MyDialog(int& value) : wxDialog(NULL, wxID_ANY, _("Test"))
    {       
        wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);

        wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);       
        wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));   

        wxCheckBox* cb = new wxCheckBox(this, wxID_ANY, "Checkbox",
                            wxDefaultPosition, wxDefaultSize, 0L,
                            WDEdCBBitValidator<int>(&value,  0xFFFF));
       
        bSizer->Add(cb, 0);
        bSizer->Add(logCtrl, 1, wxEXPAND | wxALL, 5);               
        bSizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxALL, 5);

        wxLogMessage("Value is %d", value);

        SetSizer(bSizer);
    }   
};

class MyApp : public wxApp
{
public:
    virtual bool OnInit()
    {
        int value = 1;
       
        if ( MyDialog(value).ShowModal() == wxID_OK )
            wxMessageBox(wxString::Format("New value is %d", value));

        return false;
    }
}; wxIMPLEMENT_APP(MyApp);


I assume the issue is not something silly like using older wxWidgets and not setting wxWS_EX_VALIDATE_RECURSIVELY where necessary...

usernameak
In need of some credit
In need of some credit
Posts: 5
Joined: Thu Jul 12, 2018 11:13 am

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby usernameak » Thu Jul 12, 2018 2:57 pm

PB wrote:"Is not called in custom validator" implies that it works with a built-in one (wxGenericValidator)? This is quite important distinction to see whether the issue is with validation of your dialog in general or the custom validator only.
I assume the issue is not something silly like using older wxWidgets and not setting wxWS_EX_VALIDATE_RECURSIVELY where necessary...

It works with wxIntegerValidator.
My version is 3.0.4

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1586
Joined: Sun Jan 03, 2010 5:45 pm

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby PB » Thu Jul 12, 2018 3:38 pm

Does the code from my previous post work on your setup, i.e., the method are called?

usernameak
In need of some credit
In need of some credit
Posts: 5
Joined: Thu Jul 12, 2018 11:13 am

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby usernameak » Thu Jul 12, 2018 6:49 pm

PB wrote:Does the code from my previous post work on your setup, i.e., the method are called?

It does.

usernameak
In need of some credit
In need of some credit
Posts: 5
Joined: Thu Jul 12, 2018 11:13 am

Re: TransferToWindow and TransferFromWindow isn't called in custom validator  [SOLVED]

Postby usernameak » Thu Jul 12, 2018 6:56 pm

wxWS_EX_VALIDATE_RECURSIVELY fixed the problem

PB
Part Of The Furniture
Part Of The Furniture
Posts: 1586
Joined: Sun Jan 03, 2010 5:45 pm

Re: TransferToWindow and TransferFromWindow isn't called in custom validator

Postby PB » Thu Jul 12, 2018 7:31 pm

usernameak wrote:It works with wxIntegerValidator.
usernameak wrote:wxWS_EX_VALIDATE_RECURSIVELY fixed the problem


This is odd, no validator should have worked without the flag. Well, I guess all's well that ends well...


Return to “C++ Development”

Who is online

Users browsing this forum: Google [Bot] and 11 guests