Add flag for non-recursive lookup of child qobject(s)
authorDavid Faure <faure@kde.org>
Mon, 15 Aug 2011 11:24:23 +0000 (13:24 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 15 Aug 2011 11:37:49 +0000 (13:37 +0200)
Merge-request: 40
Reviewed-by: olivier
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
Change-Id: I1194ba0d8bba92ece3132171e230cece341ec127
Reviewed-on: http://codereview.qt.nokia.com/2957
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
doc/src/snippets/code/src_corelib_kernel_qobject.cpp
src/corelib/global/qnamespace.h
src/corelib/global/qnamespace.qdoc
src/corelib/kernel/qobject.cpp
src/corelib/kernel/qobject.h
tests/auto/qobject/tst_qobject.cpp

index afb9460..086c628 100644 (file)
@@ -434,6 +434,21 @@ hostNameLabel->setText(tr("Name:"));
 QString example = tr("Example");
 //! [40]
 
+//! [41]
+QPushButton *button = parentWidget->findChild<QPushButton *>("button1", Qt::FindDirectChildOnly);
+//! [41]
+
+
+//! [42]
+QListWidget *list = parentWidget->findChild<QListWidget *>(QString(), Qt::FindDirectChildOnly);
+//! [42]
+
+
+//! [43]
+QList<QPushButton *> childButtons = parentWidget.findChildren<QPushButton *>(QString(), Qt::FindDirectChildOnly);
+//! [43]
+
+
 //! [meta data]
 //: This is a comment for the translator.
 //= qtn_foo_bar
index 4f638e1..9253b19 100644 (file)
@@ -1293,7 +1293,11 @@ public:
         AnchorBottom
     };
 
-
+    enum FindChildOption {
+        FindDirectChildrenOnly = 0x0,
+        FindChildrenRecursively = 0x1
+    };
+    Q_DECLARE_FLAGS(FindChildOptions, FindChildOption)
 
     enum DropAction {
         CopyAction = 0x1,
index 9dd7cda..08df79a 100644 (file)
 */
 
 /*!
+    \enum Qt::FindChildOption
+
+    \value FindDirectChildrenOnly    Looks only at the direct children of the object.
+    \value FindChildrenRecursively   Looks at all children of the object (recursive search).
+*/
+
+/*!
     \enum Qt::DropAction
 
     \value CopyAction       Copy the data to the target.
index 076744e..dce7839 100644 (file)
@@ -1028,8 +1028,8 @@ QObjectPrivate::Connection::~Connection()
 
     \brief the name of this object
 
-    You can find an object by name (and type) using findChild(). You can
-    find a set of objects with findChildren().
+    You can find an object by name (and type) using findChild().
+    You can find a set of objects with findChildren().
 
     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 5
 
@@ -1545,12 +1545,13 @@ void QObject::killTimer(int id)
 
 
 /*!
-    \fn T *QObject::findChild(const QString &name) const
+    \fn T *QObject::findChild(const QString &name, Qt::FindChildOptions options) const
 
     Returns the child of this object that can be cast into type T and
     that is called \a name, or 0 if there is no such object.
     Omitting the \a name argument causes all object names to be matched.
-    The search is performed recursively.
+    The search is performed recursively, unless \a options specifies the
+    option FindDirectChildrenOnly.
 
     If there is more than one child matching the search, the most
     direct ancestor is returned. If there are several direct
@@ -1558,7 +1559,8 @@ void QObject::killTimer(int id)
     case, findChildren() should be used.
 
     This example returns a child \l{QPushButton} of \c{parentWidget}
-    named \c{"button1"}:
+    named \c{"button1"}, even if the button isn't a direct child of
+    the parent:
 
     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 10
 
@@ -1566,16 +1568,27 @@ void QObject::killTimer(int id)
 
     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 11
 
+    This example returns a child \l{QPushButton} of \c{parentWidget}
+    (its direct parent) named \c{"button1"}:
+
+    \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 41
+
+    This example returns a \l{QListWidget} child of \c{parentWidget},
+    its direct parent:
+
+    \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 42
+
     \sa findChildren()
 */
 
 /*!
-    \fn QList<T> QObject::findChildren(const QString &name) const
+    \fn QList<T> QObject::findChildren(const QString &name, Qt::FindChildOptions options) const
 
     Returns all children of this object with the given \a name that can be
     cast to type T, or an empty list if there are no such objects.
     Omitting the \a name argument causes all object names to be matched.
-    The search is performed recursively.
+    The search is performed recursively, unless \a options specifies the
+    option FindDirectChildrenOnly.
 
     The following example shows how to find a list of child \l{QWidget}s of
     the specified \c{parentWidget} named \c{widgetname}:
@@ -1586,11 +1599,15 @@ void QObject::killTimer(int id)
 
     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 13
 
+    This example returns all \c{QPushButton}s that are immediate children of \c{parentWidget}:
+
+    \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 43
+
     \sa findChild()
 */
 
 /*!
-    \fn QList<T> QObject::findChildren(const QRegExp &regExp) const
+    \fn QList<T> QObject::findChildren(const QRegExp &regExp, Qt::FindChildOptions options) const
     \overload findChildren()
 
     Returns the children of this object that can be cast to type T
@@ -1650,7 +1667,7 @@ void QObject::killTimer(int id)
     \internal
 */
 void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
-                             const QMetaObject &mo, QList<void*> *list)
+                             const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
 {
     if (!parent || !list)
         return;
@@ -1667,13 +1684,14 @@ void qt_qFindChildren_helper(const QObject *parent, const QString &name, const Q
                     list->append(obj);
             }
         }
-        qt_qFindChildren_helper(obj, name, re, mo, list);
+        if (options & Qt::FindChildrenRecursively)
+            qt_qFindChildren_helper(obj, name, re, mo, list, options);
     }
 }
 
 /*! \internal
  */
-QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo)
+QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options)
 {
     if (!parent)
         return 0;
@@ -1685,10 +1703,12 @@ QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const
         if (mo.cast(obj) && (name.isNull() || obj->objectName() == name))
             return obj;
     }
-    for (i = 0; i < children.size(); ++i) {
-        obj = qt_qFindChild_helper(children.at(i), name, mo);
-        if (obj)
-            return obj;
+    if (options & Qt::FindChildrenRecursively) {
+        for (i = 0; i < children.size(); ++i) {
+            obj = qt_qFindChild_helper(children.at(i), name, mo, options);
+            if (obj)
+                return obj;
+        }
     }
     return 0;
 }
index 0e28fa7..59ff988 100644 (file)
@@ -78,8 +78,8 @@ class QObjectUserData;
 typedef QList<QObject*> QObjectList;
 
 Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
-                                           const QMetaObject &mo, QList<void *> *list);
-Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo);
+                                           const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
+Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options);
 
 class
 #if defined(__INTEL_COMPILER) && defined(Q_OS_WIN)
@@ -155,11 +155,11 @@ public:
     void killTimer(int id);
 
     template<typename T>
-    inline T findChild(const QString &aName = QString()) const
-    { return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject)); }
+    inline T findChild(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
+    { return static_cast<T>(qt_qFindChild_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject, options)); }
 
     template<typename T>
-    inline QList<T> findChildren(const QString &aName = QString()) const
+    inline QList<T> findChildren(const QString &aName = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
     {
         QList<T> list;
         union {
@@ -167,13 +167,13 @@ public:
             QList<void *> *voidList;
         } u;
         u.typedList = &list;
-        qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
+        qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
         return list;
     }
 
 #ifndef QT_NO_REGEXP
     template<typename T>
-    inline QList<T> findChildren(const QRegExp &re) const
+    inline QList<T> findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
     {
         QList<T> list;
         union {
@@ -181,7 +181,7 @@ public:
             QList<void *> *voidList;
         } u;
         u.typedList = &list;
-        qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList);
+        qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
         return list;
     }
 #endif
index 99942d5..3cd4376 100644 (file)
@@ -689,6 +689,101 @@ void tst_QObject::findChildren()
     tl = o.findChildren<QTimer *>("t1");
     QCOMPARE(tl.size(), 1);
     QCOMPARE(tl.at(0), &t1);
+
+    // Find direct child/children
+
+    op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, &o1);
+    op = o.findChild<QObject*>("o2", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, &o2);
+    op = o.findChild<QObject*>("o11", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("o12", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("o111", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("t1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(&t1));
+    op = o.findChild<QObject*>("t121", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QTimer*>("t1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(&t1));
+    op = o.findChild<QTimer*>("t121", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QTimer*>("o12", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("o", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("harry", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+    op = o.findChild<QObject*>("o1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, &o1);
+
+    l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 1);
+    QCOMPARE(l.at(0), &o1);
+    l = o.findChildren<QObject*>("o2", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 1);
+    QCOMPARE(l.at(0), &o2);
+    l = o.findChildren<QObject*>("o11", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    l = o.findChildren<QObject*>("o12", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    l = o.findChildren<QObject*>("o111", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    l = o.findChildren<QObject*>("t1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 1);
+    QCOMPARE(l.at(0), static_cast<QObject *>(&t1));
+    l = o.findChildren<QObject*>("t121", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    tl = o.findChildren<QTimer*>("t1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 1);
+    QCOMPARE(tl.at(0), &t1);
+    tl = o.findChildren<QTimer*>("t121", Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 0);
+    l = o.findChildren<QObject*>("o", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    l = o.findChildren<QObject*>("harry", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+    tl = o.findChildren<QTimer*>("o12", Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 0);
+    l = o.findChildren<QObject*>("o1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 1);
+    QCOMPARE(l.at(0), &o1);
+
+    l = o.findChildren<QObject*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 2);
+    QVERIFY(l.contains(&o1));
+    QVERIFY(l.contains(&o2));
+    l = o.findChildren<QObject*>(QRegExp("t.*"), Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 1);
+    QVERIFY(l.contains(&t1));
+    tl = o.findChildren<QTimer*>(QRegExp(".*"), Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 2);
+    QVERIFY(tl.contains(&t1));
+    tl = o.findChildren<QTimer*>(QRegExp("o.*"), Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 0);
+    l = o.findChildren<QObject*>(QRegExp("harry"), Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+
+    // empty and null string check
+    op = o.findChild<QObject*>(QString(), Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, &o1);
+    op = o.findChild<QObject*>("", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, &unnamed);
+    op = o.findChild<QObject*>("unnamed", Qt::FindDirectChildrenOnly);
+    QCOMPARE(op, static_cast<QObject *>(0));
+
+    l = o.findChildren<QObject*>(QString(), Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 5);
+    l = o.findChildren<QObject*>("", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 2);
+    l = o.findChildren<QObject*>("unnamed", Qt::FindDirectChildrenOnly);
+    QCOMPARE(l.size(), 0);
+
+    tl = o.findChildren<QTimer *>("t1", Qt::FindDirectChildrenOnly);
+    QCOMPARE(tl.size(), 1);
+    QCOMPARE(tl.at(0), &t1);
 }