From 10b35c22f5d6081866c857d70a524f7cf8ec11c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Feb 2019 14:29:06 +0100 Subject: [PATCH 1/4] Remove unnecessary "protected:" from wx/qt/radiobut.h No real changes, just remove an empty protected section. --- include/wx/qt/radiobut.h | 2 -- 1 file changed, 2 deletions(-) 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; From d403c9eccee5950b80023ca09735d6832866c2a3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Feb 2019 14:50:31 +0100 Subject: [PATCH 2/4] Slightly simplify radio buttons creation in the unit test No real changes, just add a temporary variable for the parent and use more useful (and shorter) labels for the buttons. --- tests/controls/radiobuttontest.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/tests/controls/radiobuttontest.cpp b/tests/controls/radiobuttontest.cpp index 649775b294..690bffcf1a 100644 --- a/tests/controls/radiobuttontest.cpp +++ b/tests/controls/radiobuttontest.cpp @@ -105,22 +105,20 @@ 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"); g1radio0->SetValue(true); g2radio0->SetValue(true); From a913393147a8249d16d0d2d47b59ba1727fa31e5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Feb 2019 14:51:29 +0100 Subject: [PATCH 3/4] Test that controls between radio buttons don't break grouping Add a test checking that even not directly consecutive radio buttons are still treated as being part of the same radio group. --- tests/controls/radiobuttontest.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/controls/radiobuttontest.cpp b/tests/controls/radiobuttontest.cpp index 690bffcf1a..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" @@ -120,6 +121,11 @@ void RadioButtonTestCase::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); @@ -136,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); @@ -148,6 +159,8 @@ void RadioButtonTestCase::Group() wxDELETE(g1radio1); wxDELETE(g2radio0); wxDELETE(g2radio1); + wxDELETE(g2radio2); + wxDELETE(text); } void RadioButtonTestCase::Single() From 27f1c8f4452c0935ce987bef766e9fcb25190573 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 Feb 2019 15:04:16 +0100 Subject: [PATCH 4/4] Fix wxRadioButton grouping in wxQt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create QButtonGroup as needed to honour wxRB_GROUP and wxRB_SINGLE styles. Co-Authored-By: Cătălin Răceanu Co-Authored-By: liamtreacy --- src/qt/radiobut.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/src/qt/radiobut.cpp b/src/qt/radiobut.cpp index 1a389997da..28af80b56c 100644 --- a/src/qt/radiobut.cpp +++ b/src/qt/radiobut.cpp @@ -12,6 +12,53 @@ #include "wx/qt/private/converter.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 wxRadioButton::wxRadioButton() : m_qtRadioButton(NULL) @@ -42,7 +89,27 @@ bool wxRadioButton::Create( wxWindow *parent, m_qtRadioButton = new QRadioButton( parent->GetHandle() ); 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)