QRegularExpression: add QObject::findChildren overload
authorGiuseppe D'Angelo <dangelog@gmail.com>
Tue, 13 Mar 2012 05:30:17 +0000 (05:30 +0000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 21 Mar 2012 10:43:38 +0000 (11:43 +0100)
This actually involved tiding up QObject sources a little bit
to clearly separate QString / QRegExp overloads of findChildren.

The corresponding qFindChildren overload for MSVC 6 compatibiltiy
was *not* added.

Change-Id: I84826b3df9275a9bda03608a5b66756890eda6f8
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/corelib/kernel/qobject.cpp
src/corelib/kernel/qobject.h
tests/auto/corelib/kernel/qobject/tst_qobject.cpp

index 914441f..a2f18ee 100644 (file)
@@ -50,6 +50,7 @@
 #include "qvariant.h"
 #include "qmetaobject.h"
 #include <qregexp.h>
+#include <qregularexpression.h>
 #include <qthread.h>
 #include <private/qthread_p.h>
 #include <qdebug.h>
@@ -1558,7 +1559,21 @@ void QObject::killTimer(int id)
     Returns the children of this object that can be cast to type T
     and that have names matching the regular expression \a regExp,
     or an empty list if there are no such objects.
-    The search is performed recursively.
+    The search is performed recursively, unless \a options specifies the
+    option FindDirectChildrenOnly.
+*/
+
+/*!
+    \fn QList<T> QObject::findChildren(const QRegularExpression &re, Qt::FindChildOptions options) const
+    \overload findChildren()
+
+    \since 5.0
+
+    Returns the children of this object that can be cast to type T
+    and that have names matching the regular expression \a re,
+    or an empty list if there are no such objects.
+    The search is performed recursively, unless \a options specifies the
+    option FindDirectChildrenOnly.
 */
 
 /*!
@@ -1611,7 +1626,7 @@ void QObject::killTimer(int id)
 /*!
     \internal
 */
-void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
+void qt_qFindChildren_helper(const QObject *parent, const QString &name,
                              const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
 {
     if (!parent || !list)
@@ -1621,18 +1636,59 @@ void qt_qFindChildren_helper(const QObject *parent, const QString &name, const Q
     for (int i = 0; i < children.size(); ++i) {
         obj = children.at(i);
         if (mo.cast(obj)) {
-            if (re) {
-                if (re->indexIn(obj->objectName()) != -1)
-                    list->append(obj);
-            } else {
-                if (name.isNull() || obj->objectName() == name)
-                    list->append(obj);
-            }
+            if (name.isNull() || obj->objectName() == name)
+                list->append(obj);
+        }
+        if (options & Qt::FindChildrenRecursively)
+            qt_qFindChildren_helper(obj, name, mo, list, options);
+    }
+}
+
+#ifndef QT_NO_REGEXP
+/*!
+    \internal
+*/
+void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
+                             const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
+{
+    if (!parent || !list)
+        return;
+    const QObjectList &children = parent->children();
+    QObject *obj;
+    for (int i = 0; i < children.size(); ++i) {
+        obj = children.at(i);
+        if (mo.cast(obj) && re.indexIn(obj->objectName()) != -1)
+            list->append(obj);
+
+        if (options & Qt::FindChildrenRecursively)
+            qt_qFindChildren_helper(obj, re, mo, list, options);
+    }
+}
+#endif // QT_NO_REGEXP
+
+#ifndef QT_NO_REGEXP
+/*!
+    \internal
+*/
+void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
+                             const QMetaObject &mo, QList<void*> *list, Qt::FindChildOptions options)
+{
+    if (!parent || !list)
+        return;
+    const QObjectList &children = parent->children();
+    QObject *obj;
+    for (int i = 0; i < children.size(); ++i) {
+        obj = children.at(i);
+        if (mo.cast(obj)) {
+            QRegularExpressionMatch m = re.match(obj->objectName());
+            if (m.hasMatch())
+                list->append(obj);
         }
         if (options & Qt::FindChildrenRecursively)
-            qt_qFindChildren_helper(obj, name, re, mo, list, options);
+            qt_qFindChildren_helper(obj, re, mo, list, options);
     }
 }
+#endif // QT_NO_REGEXP
 
 /*! \internal
  */
index 9f09617..37057be 100644 (file)
@@ -73,13 +73,20 @@ class QWidget;
 #ifndef QT_NO_REGEXP
 class QRegExp;
 #endif
+#ifndef QT_NO_REGEXP
+class QRegularExpression;
+#endif
 #ifndef QT_NO_USERDATA
 class QObjectUserData;
 #endif
 
 typedef QList<QObject*> QObjectList;
 
-Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name, const QRegExp *re,
+Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QString &name,
+                                           const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
+Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegExp &re,
+                                           const QMetaObject &mo, QList<void *> *list, Qt::FindChildOptions options);
+Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegularExpression &re,
                                            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);
 
@@ -163,7 +170,7 @@ public:
             QList<void *> *voidList;
         } u;
         u.typedList = &list;
-        qt_qFindChildren_helper(this, aName, 0, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
+        qt_qFindChildren_helper(this, aName, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
         return list;
     }
 
@@ -177,7 +184,22 @@ public:
             QList<void *> *voidList;
         } u;
         u.typedList = &list;
-        qt_qFindChildren_helper(this, QString(), &re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
+        qt_qFindChildren_helper(this, re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
+        return list;
+    }
+#endif
+
+#ifndef QT_NO_REGEXP
+    template<typename T>
+    inline QList<T> findChildren(const QRegularExpression &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
+    {
+        QList<T> list;
+        union {
+            QList<T> *typedList;
+            QList<void *> *voidList;
+        } u;
+        u.typedList = &list;
+        qt_qFindChildren_helper(this, re, reinterpret_cast<T>(0)->staticMetaObject, u.voidList, options);
         return list;
     }
 #endif
index c6667ff..c2ded70 100644 (file)
@@ -45,6 +45,7 @@
 #include <qpointer.h>
 #include <qtimer.h>
 #include <qregexp.h>
+#include <qregularexpression.h>
 #include <qmetaobject.h>
 #include <qvariant.h>
 #include <QTcpServer>
@@ -656,6 +657,26 @@ void tst_QObject::findChildren()
     l = qFindChildren<QObject*>(&o, QRegExp("harry"));
     QCOMPARE(l.size(), 0);
 
+    l = o.findChildren<QObject*>(QRegularExpression("o.*"));
+    QCOMPARE(l.size(), 5);
+    QVERIFY(l.contains(&o1));
+    QVERIFY(l.contains(&o2));
+    QVERIFY(l.contains(&o11));
+    QVERIFY(l.contains(&o12));
+    QVERIFY(l.contains(&o111));
+    l = o.findChildren<QObject*>(QRegularExpression("t.*"));
+    QCOMPARE(l.size(), 2);
+    QVERIFY(l.contains(&t1));
+    QVERIFY(l.contains(&t121));
+    tl = o.findChildren<QTimer*>(QRegularExpression(".*"));
+    QCOMPARE(tl.size(), 3);
+    QVERIFY(tl.contains(&t1));
+    QVERIFY(tl.contains(&t121));
+    tl = o.findChildren<QTimer*>(QRegularExpression("o.*"));
+    QCOMPARE(tl.size(), 0);
+    l = o.findChildren<QObject*>(QRegularExpression("harry"));
+    QCOMPARE(l.size(), 0);
+
     // empty and null string check
     op = qFindChild<QObject*>(&o);
     QCOMPARE(op, &o1);