diff --git a/include/wx/qt/radiobut.h b/include/wx/qt/radiobut.h index 6679be6d04..56864e9094 100644 --- a/include/wx/qt/radiobut.h +++ b/include/wx/qt/radiobut.h @@ -37,8 +37,6 @@ public: virtual QWidget *GetHandle() const; -protected: - private: QRadioButton *m_qtRadioButton; diff --git a/src/qt/radiobut.cpp b/src/qt/radiobut.cpp index 57d71bb95b..4e9de1cdf5 100644 --- a/src/qt/radiobut.cpp +++ b/src/qt/radiobut.cpp @@ -13,6 +13,53 @@ #include "wx/qt/private/winevent.h" #include +#include + +namespace +{ + +// Tiny helper applying a safe cast to return the handle of wxRadioButton as +// its actual type. +inline +QRadioButton* QtGetRadioButton(wxRadioButton* radioBtn) +{ + return static_cast(radioBtn->GetHandle()); +} + +void QtStartNewGroup(QRadioButton* qtRadioButton) +{ + // Note that the QButtonGroup created here will be deallocated when its + // parent // QRadioButton is destroyed. + QButtonGroup* qtButtonGroup = new QButtonGroup(qtRadioButton); + qtButtonGroup->addButton(qtRadioButton); +} + +bool QtTryJoiningExistingGroup(wxRadioButton* radioBtnThis) +{ + for ( wxWindow* previous = radioBtnThis->GetPrevSibling(); + previous; + previous = previous->GetPrevSibling() ) + { + if ( wxRadioButton* radioBtn = wxDynamicCast(previous, wxRadioButton) ) + { + // We should never join the exclusive group of wxRB_SINGLE button. + if ( !radioBtn->HasFlag(wxRB_SINGLE) ) + { + if ( QButtonGroup *qtGroup = QtGetRadioButton(radioBtn)->group() ) + { + qtGroup->addButton(QtGetRadioButton(radioBtnThis)); + return true; + } + } + + break; + } + } + + return false; +} + +} // anonymous namespace class wxQtRadioButton : public wxQtEventSignalHandler< QRadioButton, wxRadioButton > { @@ -65,7 +112,27 @@ bool wxRadioButton::Create( wxWindow *parent, m_qtRadioButton = new wxQtRadioButton( parent, this ); m_qtRadioButton->setText( wxQtConvertString( label )); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + if ( !QtCreateControl(parent, id, pos, size, style, validator, name) ) + return false; + + // Check if we need to create a new button group: this must be done when + // explicitly requested to do so (wxRB_GROUP) but also for wxRB_SINGLE + // buttons to prevent them implicitly becoming part of an existing group. + if ( (style & wxRB_GROUP) || (style & wxRB_SINGLE) ) + { + QtStartNewGroup(m_qtRadioButton); + } + else + { + // Otherwise try to join an already existing group. Currently we don't + // do anything if joining it fails, i.e. if there is no current group + // yet, because the radio buttons not explicitly associated with some + // group still work as if they were part of one, so we just ignore the + // return value of this function. + QtTryJoiningExistingGroup(this); + } + + return true; } void wxRadioButton::SetValue(bool value) diff --git a/tests/controls/radiobuttontest.cpp b/tests/controls/radiobuttontest.cpp index 649775b294..df50b969f5 100644 --- a/tests/controls/radiobuttontest.cpp +++ b/tests/controls/radiobuttontest.cpp @@ -17,6 +17,7 @@ #ifndef WX_PRECOMP #include "wx/app.h" #include "wx/radiobut.h" + #include "wx/stattext.h" #endif // WX_PRECOMP #include "wx/uiaction.h" @@ -105,22 +106,25 @@ void RadioButtonTestCase::Value() void RadioButtonTestCase::Group() { - //Add another button to the first group and create another of two buttons - wxRadioButton* g1radio0 = new wxRadioButton(wxTheApp->GetTopWindow(), - wxID_ANY, "wxRadioButton", - wxDefaultPosition, - wxDefaultSize, wxRB_GROUP); + wxWindow* const parent = wxTheApp->GetTopWindow(); - wxRadioButton* g1radio1 = new wxRadioButton(wxTheApp->GetTopWindow(), - wxID_ANY, "wxRadioButton"); + // Create two different radio groups. + wxRadioButton* g1radio0 = new wxRadioButton(parent, wxID_ANY, "radio 1.0", + wxDefaultPosition, wxDefaultSize, + wxRB_GROUP); - wxRadioButton* g2radio0 = new wxRadioButton(wxTheApp->GetTopWindow(), - wxID_ANY, "wxRadioButton", - wxDefaultPosition, - wxDefaultSize, wxRB_GROUP); + wxRadioButton* g1radio1 = new wxRadioButton(parent, wxID_ANY, "radio 1.1"); - wxRadioButton* g2radio1 = new wxRadioButton(wxTheApp->GetTopWindow(), - wxID_ANY, "wxRadioButton"); + wxRadioButton* g2radio0 = new wxRadioButton(parent, wxID_ANY, "radio 2.0", + wxDefaultPosition, wxDefaultSize, + wxRB_GROUP); + + wxRadioButton* g2radio1 = new wxRadioButton(parent, wxID_ANY, "radio 2.1"); + + // Check that having another control between radio buttons doesn't break + // grouping. + wxStaticText* text = new wxStaticText(parent, wxID_ANY, "Label"); + wxRadioButton* g2radio2 = new wxRadioButton(parent, wxID_ANY, "radio 2.1"); g1radio0->SetValue(true); g2radio0->SetValue(true); @@ -138,6 +142,11 @@ void RadioButtonTestCase::Group() CPPUNIT_ASSERT(!g2radio0->GetValue()); CPPUNIT_ASSERT(g2radio1->GetValue()); + g2radio2->SetValue(true); + CPPUNIT_ASSERT(!g2radio0->GetValue()); + CPPUNIT_ASSERT(!g2radio1->GetValue()); + CPPUNIT_ASSERT(g2radio2->GetValue()); + g1radio0->SetValue(true); g2radio0->SetValue(true); @@ -150,6 +159,8 @@ void RadioButtonTestCase::Group() wxDELETE(g1radio1); wxDELETE(g2radio0); wxDELETE(g2radio1); + wxDELETE(g2radio2); + wxDELETE(text); } void RadioButtonTestCase::Single()