From b0d6892bc57ba5eb9cf1676a9db70b3fe6ede71f Mon Sep 17 00:00:00 2001
From: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
Date: Thu, 21 Mar 2013 14:31:10 +0100
Subject: [PATCH] ExclusiveGroup: Allow Actions as children

Support is minimal, but increases the API elegance significantly.
Other controls, such as MenuItem, still need to have their exclusiveGroup
property set.

Change-Id: I31c4321c18dc788091e572fb15eb14c0cbb33520
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
---
 examples/gallery/main.qml         | 38 +++++++--------
 src/controls/qtexclusivegroup.cpp | 81 ++++++++++++++++++++++++-------
 src/controls/qtexclusivegroup_p.h |  9 ++++
 3 files changed, 91 insertions(+), 37 deletions(-)

diff --git a/examples/gallery/main.qml b/examples/gallery/main.qml
index 113772049..ee25dc91e 100644
--- a/examples/gallery/main.qml
+++ b/examples/gallery/main.qml
@@ -129,29 +129,27 @@ ApplicationWindow {
             onTriggered: lastFocusObject.paste()
         }
 
-        ExclusiveGroup { id: textFormatGroup }
+        ExclusiveGroup {
+            id: textFormatGroup
 
-        Action {
-            id: a1
-            text: "Align Left"
-            checkable: true
-
-            Component.onCompleted: checked = true
-            exclusiveGroup: textFormatGroup
-        }
+            Action {
+                id: a1
+                text: "Align Left"
+                checkable: true
+                Component.onCompleted: checked = true
+            }
 
-        Action {
-            id: a2
-            text: "Center"
-            checkable: true
-            exclusiveGroup: textFormatGroup
-        }
+            Action {
+                id: a2
+                text: "Center"
+                checkable: true
+            }
 
-        Action {
-            id: a3
-            text: "Align Right"
-            checkable: true
-            exclusiveGroup: textFormatGroup
+            Action {
+                id: a3
+                text: "Align Right"
+                checkable: true
+            }
         }
 
         Menu {
diff --git a/src/controls/qtexclusivegroup.cpp b/src/controls/qtexclusivegroup.cpp
index b076836e8..11f84dd5e 100644
--- a/src/controls/qtexclusivegroup.cpp
+++ b/src/controls/qtexclusivegroup.cpp
@@ -43,6 +43,7 @@
 
 #include <qvariant.h>
 #include <qdebug.h>
+#include "qtaction_p.h"
 
 #define CHECKED_PROPERTY "checked"
 
@@ -66,34 +67,69 @@ static bool isChecked(const QObject *o)
     \qmltype ExclusiveGroup
     \instantiates QtExclusiveGroup
     \inqmlmodule QtQuick.Controls 1.0
-    \ingroup containers
     \brief ExclusiveGroup provides a way to declare several checkable controls as mutually exclusive.
 
+    ExclusiveGroup can contain several \l Action items, and those will automatically get their
+    \l Action::exclusiveGroup property assigned.
+
     \code
-    ExclusiveGroup { id: radioInputGroup }
+    ExclusiveGroup {
+        id: radioInputGroup
 
-    Action {
-        id: dabRadioInput
-        text: "DAB"
-        exclusiveGroup: radioInputGroup
-    }
+        Action {
+            id: dabRadioInput
+            text: "DAB"
+            checkable: true
+        }
 
-    Action {
-        id: fmRadioInput
-        text: "FM"
-        exclusiveGroup: radioInputGroup
-    }
+        Action {
+            id: fmRadioInput
+            text: "FM"
+            checkable: true
+        }
 
-    Action {
-        id: amRadioInput
-        text: "AM"
-        exclusiveGroup: radioInputGroup
+        Action {
+            id: amRadioInput
+            text: "AM"
+            checkable: true
+        }
     }
-
     \endcode
 
     Several controls already support \l ExclusiveGroup, e.g. \l Action, \l MenuItem, \l Button, and \l RadioButton.
 
+    Since \l ExclusiveGroup only supports \l Action as child items, we need to manually assign the \c exclusiveGroup
+    property for other objects.
+
+    \code
+    ExclusiveGroup { id: textAlignmentGroup }
+
+    Menu {
+        MenuItem {
+            text: "Alignt Left"
+            checkable: true
+            exclusiveGroup: textAlignmentGroup
+        }
+        MenuItem {
+            text: "Alignt Right"
+            checkable: true
+            exclusiveGroup: textAlignmentGroup
+        }
+        MenuItem {
+            text: "Center"
+            checkable: true
+            exclusiveGroup: textAlignmentGroup
+        }
+        MenuItem {
+            text: "Justify"
+            checkable: true
+            exclusiveGroup: textAlignmentGroup
+        }
+    }
+    \endcode
+
+    \section1 Adding support to ExclusiveGroup
+
     It is possible to add support for \l ExclusiveGroup for an object, or control. It should have a \c checked
     property, and either a \c checkedChanged, \c toggled(), or \c toggled(bool) signal. It also needs
     to be bound with \l ExclusiveGroup::bindCheckable(object) when its \l ExclusiveGroup ty[ped property is set.
@@ -149,6 +185,17 @@ QtExclusiveGroup::QtExclusiveGroup(QObject *parent)
     m_updateCurrentMethod = metaObject()->method(index);
 }
 
+QQmlListProperty<QtAction> QtExclusiveGroup::actions()
+{
+    return QQmlListProperty<QtAction>(this, 0, &QtExclusiveGroup::append_actions, 0, 0, 0);
+}
+
+void QtExclusiveGroup::append_actions(QQmlListProperty<QtAction> *list, QtAction *action)
+{
+    if (QtExclusiveGroup *eg = qobject_cast<QtExclusiveGroup *>(list->object))
+        action->setExclusiveGroup(eg);
+}
+
 void QtExclusiveGroup::setCurrent(QObject * o)
 {
     if (m_current == o)
diff --git a/src/controls/qtexclusivegroup_p.h b/src/controls/qtexclusivegroup_p.h
index eab96a27a..04109b068 100644
--- a/src/controls/qtexclusivegroup_p.h
+++ b/src/controls/qtexclusivegroup_p.h
@@ -44,14 +44,19 @@
 
 #include <QtCore/qobject.h>
 #include <QtCore/qmetaobject.h>
+#include <QtQml/qqmllist.h>
 
 QT_BEGIN_NAMESPACE
 
+class QtAction;
+
 class QtExclusiveGroup : public QObject
 {
     Q_OBJECT
 
     Q_PROPERTY(QObject *current READ current WRITE setCurrent NOTIFY currentChanged)
+    Q_PROPERTY(QQmlListProperty<QtAction> __actions READ actions)
+    Q_CLASSINFO("DefaultProperty", "__actions")
 
 public:
     explicit QtExclusiveGroup(QObject *parent = 0);
@@ -59,6 +64,8 @@ public:
     QObject *current() const { return m_current; }
     void setCurrent(QObject * o);
 
+    QQmlListProperty<QtAction> actions();
+
 public Q_SLOTS:
     void bindCheckable(QObject *o);
     void unbindCheckable(QObject *o);
@@ -70,6 +77,8 @@ private Q_SLOTS:
     void updateCurrent();
 
 private:
+    static void append_actions(QQmlListProperty<QtAction> *list, QtAction *action);
+
     QObject * m_current;
     QMetaMethod m_updateCurrentMethod;
 };
-- 
GitLab