[Ktutorial-commits] SF.net SVN: ktutorial:[354] trunk/ktutorial/ktutorial-library
Status: Alpha
Brought to you by:
danxuliu
|
From: <dan...@us...> - 2012-07-05 18:19:12
|
Revision: 354
http://ktutorial.svn.sourceforge.net/ktutorial/?rev=354&view=rev
Author: danxuliu
Date: 2012-07-05 18:19:04 +0000 (Thu, 05 Jul 2012)
Log Message:
-----------
Refactor to extract object finding logic from KTutorial to its own class, ObjectFinder.
Modified Paths:
--------------
trunk/ktutorial/ktutorial-library/src/CMakeLists.txt
trunk/ktutorial/ktutorial-library/src/KTutorial.cpp
trunk/ktutorial/ktutorial-library/src/KTutorial.h
trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt
Added Paths:
-----------
trunk/ktutorial/ktutorial-library/src/ObjectFinder.cpp
trunk/ktutorial/ktutorial-library/src/ObjectFinder.h
trunk/ktutorial/ktutorial-library/tests/ObjectFinderTest.cpp
Removed Paths:
-------------
trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp
Modified: trunk/ktutorial/ktutorial-library/src/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/src/CMakeLists.txt 2012-07-05 12:38:07 UTC (rev 353)
+++ trunk/ktutorial/ktutorial-library/src/CMakeLists.txt 2012-07-05 18:19:04 UTC (rev 354)
@@ -17,6 +17,7 @@
set(ktutorial_LIB_SRCS
KTutorial.cpp
+ ObjectFinder.cpp
Option.cpp
Step.cpp
Tutorial.cpp
@@ -49,6 +50,7 @@
set(ktutorial_LIB_HEADERS
ktutorial_export.h
KTutorial.h
+ ObjectFinder.h
Option.h
Step.h
Tutorial.h
Modified: trunk/ktutorial/ktutorial-library/src/KTutorial.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/KTutorial.cpp 2012-07-05 12:38:07 UTC (rev 353)
+++ trunk/ktutorial/ktutorial-library/src/KTutorial.cpp 2012-07-05 18:19:04 UTC (rev 354)
@@ -96,146 +96,6 @@
KTutorial* KTutorial::sSelf = new KTutorial();
-QList<QObject*> KTutorial::getBestMatches(const QString& name,
- QList< QList<QObject*> > objectPaths) const {
- if (name.isEmpty() || objectPaths.isEmpty()) {
- return QList<QObject*>();
- }
-
- if (name.indexOf('/') == -1) {
- QList< QList<QObject*> > filteredObjectPaths =
- filterObjectPaths(name, objectPaths);
-
- QList<QObject*> filteredObjects;
- foreach (QList<QObject*> filteredObjectPath, filteredObjectPaths) {
- filteredObjects.append(filteredObjectPath.first());
- }
-
- return filteredObjects;
- }
-
- QRegExp slashPattern("/+");
- QString ancestorName = name.left(name.indexOf(slashPattern));
- QString descendantName = name.mid(ancestorName.length() +
- slashPattern.matchedLength());
-
- return getBestMatches(descendantName, filterObjectPaths(ancestorName,
- objectPaths));
-}
-
-QList< QList<QObject*> > KTutorial::filterObjectPaths(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const {
- QList< QList<QObject*> > filteredPaths = filterDirectChildren(name,
- objectPaths);
- if (filteredPaths.size() > 0) {
- return filteredPaths;
- }
-
- filteredPaths = filterNestedChildrenWithUnnamedAncestors(name, objectPaths);
- if (filteredPaths.size() > 0) {
- return filteredPaths;
- }
-
- return filterNestedChildren(name, objectPaths);
-}
-
-QList< QList<QObject*> > KTutorial::filterDirectChildren(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const {
- QList< QList<QObject*> > filteredPaths;
-
- foreach (QList<QObject*> objectPath, objectPaths) {
- if (objectPath.size() >= 2 && objectPath[1]->objectName() == name) {
- objectPath.removeAt(0);
- filteredPaths.append(objectPath);
- }
- }
-
- return filteredPaths;
-}
-
-QList< QList<QObject*> > KTutorial::filterNestedChildrenWithUnnamedAncestors(
- const QString& name,
- const QList< QList<QObject*> >& objectPaths) const {
- QList< QList<QObject*> > candidatePaths;
-
- //No need to use std::numeric_limits, as there would never be a 100000
- //levels deep object.
- int minimumNumberOfUnnamedAncestors = 100000;
- foreach (QList<QObject*> objectPath, objectPaths) {
- objectPath.removeAt(0);
-
- int unnamedAncestorCount = 0;
- while (objectPath.size() > unnamedAncestorCount &&
- objectPath[unnamedAncestorCount]->objectName() == "") {
- unnamedAncestorCount++;
- }
-
- if (unnamedAncestorCount > 0 &&
- objectPath.size() > unnamedAncestorCount &&
- objectPath[unnamedAncestorCount]->objectName() == name) {
- candidatePaths.append(objectPath);
-
- if (unnamedAncestorCount < minimumNumberOfUnnamedAncestors) {
- minimumNumberOfUnnamedAncestors = unnamedAncestorCount;
- }
- }
- }
-
- QList< QList<QObject*> > filteredPaths;
-
- foreach (QList<QObject*> candidatePath, candidatePaths) {
- if (candidatePath[minimumNumberOfUnnamedAncestors]->objectName() ==
- name) {
- for (int i=0; i<minimumNumberOfUnnamedAncestors; ++i) {
- candidatePath.removeAt(0);
- }
- filteredPaths.append(candidatePath);
- }
- }
-
- return filteredPaths;
-}
-
-QList< QList<QObject*> > KTutorial::filterNestedChildren(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const {
- QList< QList<QObject*> > candidatePaths;
-
- //No need to use std::numeric_limits, as there would never be a 100000
- //levels deep object.
- int minimumNumberOfAncestors = 100000;
- foreach (QList<QObject*> objectPath, objectPaths) {
- objectPath.removeAt(0);
-
- int ancestorCount = 0;
- while (objectPath.size() > ancestorCount &&
- objectPath[ancestorCount]->objectName() != name) {
- ancestorCount++;
- }
-
- if (ancestorCount > 0 && objectPath.size() > ancestorCount &&
- objectPath[ancestorCount]->objectName() == name) {
- candidatePaths.append(objectPath);
-
- if (ancestorCount < minimumNumberOfAncestors) {
- minimumNumberOfAncestors = ancestorCount;
- }
- }
- }
-
- QList< QList<QObject*> > filteredPaths;
-
- foreach (QList<QObject*> candidatePath, candidatePaths) {
- if (candidatePath[minimumNumberOfAncestors]->objectName() == name) {
- for (int i=0; i<minimumNumberOfAncestors; ++i) {
- candidatePath.removeAt(0);
- }
- filteredPaths.append(candidatePath);
- }
- }
-
- return filteredPaths;
-}
-
//private slots:
void KTutorial::showTutorialManagerDialog() const {
Modified: trunk/ktutorial/ktutorial-library/src/KTutorial.h
===================================================================
--- trunk/ktutorial/ktutorial-library/src/KTutorial.h 2012-07-05 12:38:07 UTC (rev 353)
+++ trunk/ktutorial/ktutorial-library/src/KTutorial.h 2012-07-05 18:19:04 UTC (rev 354)
@@ -23,6 +23,7 @@
#include "ktutorial_export.h"
+#include "ObjectFinder.h"
#include "TutorialManager.h"
class KAction;
@@ -171,18 +172,7 @@
*/
template <typename T>
T findObject(const QString& name) const {
- QList<T> candidateObjects;
- findObjects<T>(name, mParent, candidateObjects);
-
- if (candidateObjects.isEmpty()) {
- return 0;
- }
-
- if (candidateObjects.count() == 1) {
- return candidateObjects.first();
- }
-
- return getBestMatch(name, candidateObjects);
+ return mObjectFinder->findObject<T>(name, mParent);
}
private:
@@ -207,6 +197,8 @@
*/
KAction* mTutorialsAction;
+ ObjectFinder* mObjectFinder;
+
/**
* Creates a new KTutorial.
* Private to avoid classes other than self to create instances.
@@ -216,174 +208,9 @@
mTutorialmanager->setParent(this);
mTutorialsAction = 0;
mParent = 0;
+ mObjectFinder = new ObjectFinder(this);
}
- /**
- * Adds to the foundObjects list the objects with the specified name that
- * are descendant of the given ancestor, if any.
- * The name of the objects can contain ancestor names separated by "/". Note
- * that ancestors are not necessarily direct parents.
- *
- * @param name The name of the objects to find.
- * @param ancestor The ancestor to look the objects in.
- * @param foundObjects The list to add to the objects with the specified
- * name to.
- */
- template <typename T>
- void findObjects(const QString& name, const QObject* ancestor,
- QList<T>& foundObjects) const {
- if (name.isEmpty() || ancestor == 0) {
- return;
- }
-
- if (name.indexOf('/') == -1) {
- foundObjects.append(ancestor->findChildren<T>(name));
- return;
- }
-
- QRegExp slashPattern("/+");
- QString ancestorName = name.left(name.indexOf(slashPattern));
- QString descendantName = name.mid(ancestorName.length() +
- slashPattern.matchedLength());
-
- QList<QObject*> namedAncestors =
- ancestor->findChildren<QObject*>(ancestorName);
- foreach (QObject* namedAncestor, namedAncestors) {
- findObjects<T>(descendantName, namedAncestor, foundObjects);
- }
- }
-
- /**
- * Resolves the ambiguity between several objects that match the given name.
- * The ambiguity resolving rules are those specified in
- * findObject(const QString&).
- *
- * @param name The name of the object to find.
- * @param candidateObjects A list with objects that match the given name.
- * @return The object that matches the best the given name.
- */
- template <typename T>
- T getBestMatch(const QString& name, QList<T> candidateObjects) const {
- QList< QList<QObject*> > objectPaths = getObjectPaths(candidateObjects);
-
- QList<QObject*> bestMatches = getBestMatches(name, objectPaths);
-
- //Should not happen, but just in case
- if (bestMatches.isEmpty()) {
- return 0;
- }
-
- return static_cast<T>(bestMatches[0]);
- }
-
- /**
- * Returns a list with the paths to the given objects.
- * Each path is a list that contains the object and all its ancestors. The
- * first object in the list is the more distant ancestor, and the last
- * object is the object itself.
- *
- * @param objects The objects to get their paths.
- * @return A list with the paths to the given objects.
- */
- template <typename T>
- QList< QList<QObject*> > getObjectPaths(const QList<T> objects) const {
- QList< QList<QObject*> > objectPaths;
-
- foreach (T candidateObject, objects) {
- QList<QObject*> objectPath;
-
- QObject* ancestor = candidateObject;
- while (ancestor) {
- objectPath.prepend(ancestor);
- ancestor = ancestor->parent();
- }
-
- objectPaths.append(objectPath);
- }
-
- return objectPaths;
- }
-
- /**
- * Gets the objects from the given object paths that match the best the
- * given name.
- * The name can contain ancestor names. The ambiguity resolving rules are
- * applied recursively for each component of the name, so the object paths
- * used to find each component are the ones filtered with the name of its
- * ancestor.
- *
- * @param name The name of the object to get.
- * @param objectPaths The paths to get the object from.
- * @return The list of objects that match the best the given name.
- */
- QList<QObject*> getBestMatches(const QString& name,
- QList< QList<QObject*> > objectPaths) const;
-
- /**
- * Returns the object paths that contain a descendant of the base object
- * with the given name.
- * If direct children are found, their path is used. If not, if descendants
- * without named objects between them and the base object are found, their
- * path is used. If not, the path of the shallower descendants is used.
- * The name must be a single object name, without any ancestor name.
- * The returned paths are trimmed to make the object with the given name the
- * new base object of the path.
- *
- * @param name The name of the descendant to find.
- * @param objectPaths The paths to search the object in.
- * @return The filtered and trimmed object paths.
- */
- QList< QList<QObject*> > filterObjectPaths(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const;
-
- /**
- * Returns the object paths that contain a direct child from the base object
- * with the given name.
- * The name must be a single object name, without any ancestor name.
- * The returned paths are trimmed to make the object with the given name the
- * new base object of the path.
- *
- * @param name The name of the direct child to find.
- * @param objectPaths The paths to search the object in.
- * @return The filtered and trimmed object paths.
- */
- QList< QList<QObject*> > filterDirectChildren(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const;
-
- /**
- * Returns the object paths that contain a descendant from the base object
- * with the given name.
- * All the objects between the base object and the descendant with the given
- * name must have no name.
- * If there is more than one descendant with the given name, only the
- * shallower ones are taken into account.
- * The name must be a single object name, without any ancestor name.
- * The returned paths are trimmed to make the object with the given name the
- * new base object of the path.
- *
- * @param name The name of the descendant to find.
- * @param objectPaths The paths to search the object in.
- * @return The filtered and trimmed object paths.
- */
- QList< QList<QObject*> > filterNestedChildrenWithUnnamedAncestors(
- const QString& name, const QList< QList<QObject*> >& objectPaths) const;
-
- /**
- * Returns the object paths that contain a descendant from the base object
- * with the given name.
- * If there is more than one descendant with the given name, only the
- * shallower ones are taken into account.
- * The name must be a single object name, without any ancestor name.
- * The returned paths are trimmed to make the object with the given name the
- * new base object of the path.
- *
- * @param name The name of the descendant to find.
- * @param objectPaths The paths to search the object in.
- * @return The filtered and trimmed object paths.
- */
- QList< QList<QObject*> > filterNestedChildren(const QString& name,
- const QList< QList<QObject*> >& objectPaths) const;
-
private slots:
/**
Added: trunk/ktutorial/ktutorial-library/src/ObjectFinder.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/src/ObjectFinder.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/ObjectFinder.cpp 2012-07-05 18:19:04 UTC (rev 354)
@@ -0,0 +1,161 @@
+/***************************************************************************
+ * Copyright (C) 2012 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "ObjectFinder.h"
+
+//private:
+
+QList<QObject*> ObjectFinder::getBestMatches(const QString& name,
+ QList< QList<QObject*> > objectPaths) const {
+ if (name.isEmpty() || objectPaths.isEmpty()) {
+ return QList<QObject*>();
+ }
+
+ if (name.indexOf('/') == -1) {
+ QList< QList<QObject*> > filteredObjectPaths =
+ filterObjectPaths(name, objectPaths);
+
+ QList<QObject*> filteredObjects;
+ foreach (QList<QObject*> filteredObjectPath, filteredObjectPaths) {
+ filteredObjects.append(filteredObjectPath.first());
+ }
+
+ return filteredObjects;
+ }
+
+ QRegExp slashPattern("/+");
+ QString ancestorName = name.left(name.indexOf(slashPattern));
+ QString descendantName = name.mid(ancestorName.length() +
+ slashPattern.matchedLength());
+
+ return getBestMatches(descendantName, filterObjectPaths(ancestorName,
+ objectPaths));
+}
+
+QList< QList<QObject*> > ObjectFinder::filterObjectPaths(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const {
+ QList< QList<QObject*> > filteredPaths = filterDirectChildren(name,
+ objectPaths);
+ if (filteredPaths.size() > 0) {
+ return filteredPaths;
+ }
+
+ filteredPaths = filterNestedChildrenWithUnnamedAncestors(name, objectPaths);
+ if (filteredPaths.size() > 0) {
+ return filteredPaths;
+ }
+
+ return filterNestedChildren(name, objectPaths);
+}
+
+QList< QList<QObject*> > ObjectFinder::filterDirectChildren(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const {
+ QList< QList<QObject*> > filteredPaths;
+
+ foreach (QList<QObject*> objectPath, objectPaths) {
+ if (objectPath.size() >= 2 && objectPath[1]->objectName() == name) {
+ objectPath.removeAt(0);
+ filteredPaths.append(objectPath);
+ }
+ }
+
+ return filteredPaths;
+}
+
+QList< QList<QObject*> > ObjectFinder::filterNestedChildrenWithUnnamedAncestors(
+ const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const {
+ QList< QList<QObject*> > candidatePaths;
+
+ //No need to use std::numeric_limits, as there would never be a 100000
+ //levels deep object.
+ int minimumNumberOfUnnamedAncestors = 100000;
+ foreach (QList<QObject*> objectPath, objectPaths) {
+ objectPath.removeAt(0);
+
+ int unnamedAncestorCount = 0;
+ while (objectPath.size() > unnamedAncestorCount &&
+ objectPath[unnamedAncestorCount]->objectName() == "") {
+ unnamedAncestorCount++;
+ }
+
+ if (unnamedAncestorCount > 0 &&
+ objectPath.size() > unnamedAncestorCount &&
+ objectPath[unnamedAncestorCount]->objectName() == name) {
+ candidatePaths.append(objectPath);
+
+ if (unnamedAncestorCount < minimumNumberOfUnnamedAncestors) {
+ minimumNumberOfUnnamedAncestors = unnamedAncestorCount;
+ }
+ }
+ }
+
+ QList< QList<QObject*> > filteredPaths;
+
+ foreach (QList<QObject*> candidatePath, candidatePaths) {
+ if (candidatePath[minimumNumberOfUnnamedAncestors]->objectName() ==
+ name) {
+ for (int i=0; i<minimumNumberOfUnnamedAncestors; ++i) {
+ candidatePath.removeAt(0);
+ }
+ filteredPaths.append(candidatePath);
+ }
+ }
+
+ return filteredPaths;
+}
+
+QList< QList<QObject*> > ObjectFinder::filterNestedChildren(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const {
+ QList< QList<QObject*> > candidatePaths;
+
+ //No need to use std::numeric_limits, as there would never be a 100000
+ //levels deep object.
+ int minimumNumberOfAncestors = 100000;
+ foreach (QList<QObject*> objectPath, objectPaths) {
+ objectPath.removeAt(0);
+
+ int ancestorCount = 0;
+ while (objectPath.size() > ancestorCount &&
+ objectPath[ancestorCount]->objectName() != name) {
+ ancestorCount++;
+ }
+
+ if (ancestorCount > 0 && objectPath.size() > ancestorCount &&
+ objectPath[ancestorCount]->objectName() == name) {
+ candidatePaths.append(objectPath);
+
+ if (ancestorCount < minimumNumberOfAncestors) {
+ minimumNumberOfAncestors = ancestorCount;
+ }
+ }
+ }
+
+ QList< QList<QObject*> > filteredPaths;
+
+ foreach (QList<QObject*> candidatePath, candidatePaths) {
+ if (candidatePath[minimumNumberOfAncestors]->objectName() == name) {
+ for (int i=0; i<minimumNumberOfAncestors; ++i) {
+ candidatePath.removeAt(0);
+ }
+ filteredPaths.append(candidatePath);
+ }
+ }
+
+ return filteredPaths;
+}
Property changes on: trunk/ktutorial/ktutorial-library/src/ObjectFinder.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/ktutorial/ktutorial-library/src/ObjectFinder.h
===================================================================
--- trunk/ktutorial/ktutorial-library/src/ObjectFinder.h (rev 0)
+++ trunk/ktutorial/ktutorial-library/src/ObjectFinder.h 2012-07-05 18:19:04 UTC (rev 354)
@@ -0,0 +1,242 @@
+/***************************************************************************
+ * Copyright (C) 2012 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef OBJECTFINDER_H
+#define OBJECTFINDER_H
+
+#include <QObject>
+#include <QRegExp>
+
+#include "ktutorial_export.h"
+
+/**
+ * Helper class to find objects.
+ * This class is not intended to be used directly. Instead, use
+ * KTutorial::findObject(const QString&).
+ */
+class KTUTORIAL_EXPORT ObjectFinder: public QObject {
+Q_OBJECT
+public:
+
+ /**
+ * Creates a new ObjectFinder with the given parent.
+ *
+ * @param parent The parent object.
+ */
+ ObjectFinder(QObject* parent): QObject(parent) {
+ }
+
+ /**
+ * Returns the object with the specified name, if any.
+ * Objects are searched in the children of the given base object.
+ *
+ * For details please refer to KTutorial::findObject(const QString&)
+ * documentation.
+ *
+ * @param name The name of the object to find.
+ * @param baseObject The base object to search from.
+ * @return The object with the specified name, or null if there is none.
+ * @see KTutorial::findObject(const QString&)
+ */
+ template <typename T>
+ T findObject(const QString& name, const QObject* baseObject) const {
+ QList<T> candidateObjects;
+ findObjects<T>(name, baseObject, candidateObjects);
+
+ if (candidateObjects.isEmpty()) {
+ return 0;
+ }
+
+ if (candidateObjects.count() == 1) {
+ return candidateObjects.first();
+ }
+
+ return getBestMatch(name, candidateObjects);
+ }
+
+private:
+
+ /**
+ * Adds to the foundObjects list the objects with the specified name that
+ * are descendant of the given ancestor, if any.
+ * The name of the objects can contain ancestor names separated by "/". Note
+ * that ancestors are not necessarily direct parents.
+ *
+ * @param name The name of the objects to find.
+ * @param ancestor The ancestor to look the objects in.
+ * @param foundObjects The list to add to the objects with the specified
+ * name to.
+ */
+ template <typename T>
+ void findObjects(const QString& name, const QObject* ancestor,
+ QList<T>& foundObjects) const {
+ if (name.isEmpty() || ancestor == 0) {
+ return;
+ }
+
+ if (name.indexOf('/') == -1) {
+ foundObjects.append(ancestor->findChildren<T>(name));
+ return;
+ }
+
+ QRegExp slashPattern("/+");
+ QString ancestorName = name.left(name.indexOf(slashPattern));
+ QString descendantName = name.mid(ancestorName.length() +
+ slashPattern.matchedLength());
+
+ QList<QObject*> namedAncestors =
+ ancestor->findChildren<QObject*>(ancestorName);
+ foreach (QObject* namedAncestor, namedAncestors) {
+ findObjects<T>(descendantName, namedAncestor, foundObjects);
+ }
+ }
+
+ /**
+ * Resolves the ambiguity between several objects that match the given name.
+ * The ambiguity resolving rules are those specified in
+ * findObject(const QString&).
+ *
+ * @param name The name of the object to find.
+ * @param candidateObjects A list with objects that match the given name.
+ * @return The object that matches the best the given name.
+ */
+ template <typename T>
+ T getBestMatch(const QString& name, QList<T> candidateObjects) const {
+ QList< QList<QObject*> > objectPaths = getObjectPaths(candidateObjects);
+
+ QList<QObject*> bestMatches = getBestMatches(name, objectPaths);
+
+ //Should not happen, but just in case
+ if (bestMatches.isEmpty()) {
+ return 0;
+ }
+
+ return static_cast<T>(bestMatches[0]);
+ }
+
+ /**
+ * Returns a list with the paths to the given objects.
+ * Each path is a list that contains the object and all its ancestors. The
+ * first object in the list is the more distant ancestor, and the last
+ * object is the object itself.
+ *
+ * @param objects The objects to get their paths.
+ * @return A list with the paths to the given objects.
+ */
+ template <typename T>
+ QList< QList<QObject*> > getObjectPaths(const QList<T> objects) const {
+ QList< QList<QObject*> > objectPaths;
+
+ foreach (T candidateObject, objects) {
+ QList<QObject*> objectPath;
+
+ QObject* ancestor = candidateObject;
+ while (ancestor) {
+ objectPath.prepend(ancestor);
+ ancestor = ancestor->parent();
+ }
+
+ objectPaths.append(objectPath);
+ }
+
+ return objectPaths;
+ }
+
+ /**
+ * Gets the objects from the given object paths that match the best the
+ * given name.
+ * The name can contain ancestor names. The ambiguity resolving rules are
+ * applied recursively for each component of the name, so the object paths
+ * used to find each component are the ones filtered with the name of its
+ * ancestor.
+ *
+ * @param name The name of the object to get.
+ * @param objectPaths The paths to get the object from.
+ * @return The list of objects that match the best the given name.
+ */
+ QList<QObject*> getBestMatches(const QString& name,
+ QList< QList<QObject*> > objectPaths) const;
+
+ /**
+ * Returns the object paths that contain a descendant of the base object
+ * with the given name.
+ * If direct children are found, their path is used. If not, if descendants
+ * without named objects between them and the base object are found, their
+ * path is used. If not, the path of the shallower descendants is used.
+ * The name must be a single object name, without any ancestor name.
+ * The returned paths are trimmed to make the object with the given name the
+ * new base object of the path.
+ *
+ * @param name The name of the descendant to find.
+ * @param objectPaths The paths to search the object in.
+ * @return The filtered and trimmed object paths.
+ */
+ QList< QList<QObject*> > filterObjectPaths(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const;
+
+ /**
+ * Returns the object paths that contain a direct child from the base object
+ * with the given name.
+ * The name must be a single object name, without any ancestor name.
+ * The returned paths are trimmed to make the object with the given name the
+ * new base object of the path.
+ *
+ * @param name The name of the direct child to find.
+ * @param objectPaths The paths to search the object in.
+ * @return The filtered and trimmed object paths.
+ */
+ QList< QList<QObject*> > filterDirectChildren(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const;
+
+ /**
+ * Returns the object paths that contain a descendant from the base object
+ * with the given name.
+ * All the objects between the base object and the descendant with the given
+ * name must have no name.
+ * If there is more than one descendant with the given name, only the
+ * shallower ones are taken into account.
+ * The name must be a single object name, without any ancestor name.
+ * The returned paths are trimmed to make the object with the given name the
+ * new base object of the path.
+ *
+ * @param name The name of the descendant to find.
+ * @param objectPaths The paths to search the object in.
+ * @return The filtered and trimmed object paths.
+ */
+ QList< QList<QObject*> > filterNestedChildrenWithUnnamedAncestors(
+ const QString& name, const QList< QList<QObject*> >& objectPaths) const;
+
+ /**
+ * Returns the object paths that contain a descendant from the base object
+ * with the given name.
+ * If there is more than one descendant with the given name, only the
+ * shallower ones are taken into account.
+ * The name must be a single object name, without any ancestor name.
+ * The returned paths are trimmed to make the object with the given name the
+ * new base object of the path.
+ *
+ * @param name The name of the descendant to find.
+ * @param objectPaths The paths to search the object in.
+ * @return The filtered and trimmed object paths.
+ */
+ QList< QList<QObject*> > filterNestedChildren(const QString& name,
+ const QList< QList<QObject*> >& objectPaths) const;
+
+};
+
+#endif
Property changes on: trunk/ktutorial/ktutorial-library/src/ObjectFinder.h
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2012-07-05 12:38:07 UTC (rev 353)
+++ trunk/ktutorial/ktutorial-library/tests/CMakeLists.txt 2012-07-05 18:19:04 UTC (rev 354)
@@ -26,7 +26,7 @@
ENDMACRO(UNIT_TESTS)
unit_tests(
- KTutorial
+ ObjectFinder
Option
Step
Tutorial
@@ -51,7 +51,7 @@
ENDMACRO(MEM_TESTS)
mem_tests(
- KTutorial
+ ObjectFinder
Option
Step
Tutorial
Deleted: trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp 2012-07-05 12:38:07 UTC (rev 353)
+++ trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp 2012-07-05 18:19:04 UTC (rev 354)
@@ -1,454 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2011-2012 by Daniel Calviño Sánchez *
- * dan...@gm... *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-#include <QtTest>
-
-#include <QAction>
-
-#include "KTutorial.h"
-
-class KTutorialTest: public QObject {
-Q_OBJECT
-
-private slots:
-
- void initTestCase();
- void cleanupTestCase();
-
- void testFindObjectSingleName();
- void testFindObjectSingleNameUnknown();
- void testFindObjectComplexNameDirectChild();
- void testFindObjectComplexNameNestedChild();
- void testFindObjectComplexNameAncestorNameNotUnique();
- void testFindObjectComplexNameUnknownParent();
-
- void testFindObjectAmbiguousSingleNameDirectChild();
- void testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestors();
- void testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestorsDeeperThanNamed();
- void testFindObjectAmbiguousSingleNameNestedChildNamedAncestors();
- void testFindObjectAmbiguousSingleNameNestedChildNamedAncestorsSameDeepThanMixed();
- void testFindObjectAmbiguousSingleNameNestedChildMixedAncestorsSameDeepThanNamed();
- void testFindObjectAmbiguousComplexName();
- void testFindObjectAmbiguousComplexNameUniqueAncestor();
- void testFindObjectComplexNameDifferentAncestorIfSolvingAmbiguity();
-
- void testFindObjectEmptyName();
- void testFindObjectSingleSlash();
- void testFindObjectSlashEndedName();
- void testFindObjectSeveralSlashes();
-
-private:
-
- KXmlGuiWindow* mMainWindow;
- QObject* mObject1_1_1;
- QAction* mAction1_1_2;
- QObject* mObject1_2_1;
- QObject* mObject2_1_1;
- QObject* mObject2_1_2;
- QAction* mAction2_1_3;
- QAction* mAction2_1_4;
- QObject* mObject3_1_1;
- QObject* mObject3_2_1_1;
- QAction* mAction3_3_1_1;
- QObject* mAmbiguousObject5;
- QObject* mAmbiguousObject8_1_2;
- QObject* mAmbiguousObject10_1;
- QObject* mAmbiguousObject11_1_2;
- QObject* mAmbiguousObject12_1;
- QObject* mAmbiguousObject12_2_3;
- QObject* mObject14_1_2;
- QObject* mAmbiguousObject15_2_2_1;
- QObject* mAmbiguousObject16_2_1_1_1;
-
- void assertFindObject(const QString& objectName, QObject* object) const;
- void assertFindAction(const QString& objectName, QAction* action) const;
-
-};
-
-void KTutorialTest::initTestCase() {
- mMainWindow = new KXmlGuiWindow();
- KTutorial::self()->setup(mMainWindow);
-
- //-Grand parent1
- // |-Parent1
- // | |-The object
- // | |-The action
- // |-Parent2
- // |-The object
- //-Grand parent2
- // |-Parent1
- // |-The object
- // |-Another object
- // |-The action
- // |-Another action
- //-Grand parent3
- // |-Parent1
- // | |-The object
- // |-Nested parent
- // | |-Another object
- // |-Nested timer
- // |-Another action
- QObject* grandParent1 = new QObject(mMainWindow);
- grandParent1->setObjectName("Grand parent1");
- QObject* parent1_1 = new QObject(grandParent1);
- parent1_1->setObjectName("Parent1");
- mObject1_1_1 = new QObject(parent1_1);
- mObject1_1_1->setObjectName("The object");
- mAction1_1_2 = new QAction(parent1_1);
- mAction1_1_2->setObjectName("The action");
-
- QObject* parent1_2 = new QObject(grandParent1);
- parent1_2->setObjectName("Parent2");
- mObject1_2_1 = new QObject(parent1_2);
- mObject1_2_1->setObjectName("The object");
-
- QObject* grandParent2 = new QObject(mMainWindow);
- grandParent2->setObjectName("Grand parent2");
- QObject* parent2_1 = new QObject(grandParent2);
- parent2_1->setObjectName("Parent1");
- mObject2_1_1 = new QObject(parent2_1);
- mObject2_1_1->setObjectName("The object");
- mObject2_1_2 = new QObject(parent2_1);
- mObject2_1_2->setObjectName("Another object");
- mAction2_1_3 = new QAction(parent2_1);
- mAction2_1_3->setObjectName("The action");
- mAction2_1_4 = new QAction(parent2_1);
- mAction2_1_4->setObjectName("Another action");
-
- QObject* grandParent3 = new QObject(mMainWindow);
- grandParent3->setObjectName("Grand parent3");
- QObject* parent3_1 = new QObject(grandParent3);
- parent3_1->setObjectName("Parent1");
- mObject3_1_1 = new QObject(parent3_1);
- mObject3_1_1->setObjectName("The object");
-
- QObject* parent3_2 = new QObject(grandParent3);
- parent3_2->setObjectName("Nested parent");
- QObject* parent3_2_1 = new QObject(parent3_2);
- mObject3_2_1_1 = new QObject(parent3_2_1);
- mObject3_2_1_1->setObjectName("Another object");
-
- QTimer* parent3_3 = new QTimer(grandParent3);
- parent3_3->setObjectName("Nested timer");
- QTimer* parent3_3_1 = new QTimer(parent3_3);
- mAction3_3_1_1 = new QAction(parent3_3_1);
- mAction3_3_1_1->setObjectName("Another action");
-
- //-???
- // |-???
- // | |-Ambiguous object
- // |-Ambiguous object
- //-Ambiguous object
- //-Object 6
- // |-Ambiguous object
- // |-Object 6_2
- // |-Ambiguous object
- //-Ambiguous object
- QObject* unnamedObject4 = new QObject(mMainWindow);
- QObject* unnamedObject4_1 = new QObject(unnamedObject4);
- QObject* ambiguousObject4_1_1 = new QObject(unnamedObject4_1);
- ambiguousObject4_1_1->setObjectName("Ambiguous object");
- QObject* ambiguousObject4_2 = new QObject(unnamedObject4);
- ambiguousObject4_2->setObjectName("Ambiguous object");
-
- mAmbiguousObject5 = new QObject(mMainWindow);
- mAmbiguousObject5->setObjectName("Ambiguous object");
-
- QObject* namedObject6 = new QObject(mMainWindow);
- namedObject6->setObjectName("Object 6");
- QObject* ambiguousObject6_1 = new QObject(namedObject6);
- ambiguousObject6_1->setObjectName("Ambiguous object");
- QObject* namedObject6_2 = new QObject(namedObject6);
- namedObject6_2->setObjectName("Object 6_2");
- QObject* ambiguousObject6_2_1 = new QObject(namedObject6_2);
- ambiguousObject6_2_1->setObjectName("Ambiguous object");
-
- QObject* ambiguousObject7 = new QObject(mMainWindow);
- ambiguousObject7->setObjectName("Ambiguous object");
-
- //-???
- // |-???
- // | |-Ambiguous object2
- // | |-Ambiguous object3
- //-Object 9
- // |-Ambiguous object2
- // |-Object 9_2
- // | |-Ambiguous object2
- // |-Ambiguous object3
- //-???
- // |-Ambiguous object2
- // |-Ambiguous object2
- QObject* unnamedObject8 = new QObject(mMainWindow);
- QObject* unnamedObject8_1 = new QObject(unnamedObject8);
- QObject* ambiguousObject8_1_1 = new QObject(unnamedObject8_1);
- ambiguousObject8_1_1->setObjectName("Ambiguous object2");
- mAmbiguousObject8_1_2 = new QObject(unnamedObject8_1);
- mAmbiguousObject8_1_2->setObjectName("Ambiguous object3");
-
- QObject* namedObject9 = new QObject(mMainWindow);
- namedObject9->setObjectName("Object 9");
- QObject* ambiguousObject9_1 = new QObject(namedObject9);
- ambiguousObject9_1->setObjectName("Ambiguous object2");
- QObject* namedObject9_2 = new QObject(namedObject9);
- namedObject9_2->setObjectName("Object 9_2");
- QObject* ambiguousObject9_2_1 = new QObject(namedObject9_2);
- ambiguousObject9_2_1->setObjectName("Ambiguous object2");
- QObject* ambiguousObject9_3 = new QObject(namedObject9);
- ambiguousObject9_3->setObjectName("Ambiguous object3");
-
- QObject* unnamedObject10 = new QObject(mMainWindow);
- mAmbiguousObject10_1 = new QObject(unnamedObject10);
- mAmbiguousObject10_1->setObjectName("Ambiguous object2");
- QObject* ambiguousObject10_2 = new QObject(unnamedObject10);
- ambiguousObject10_2->setObjectName("Ambiguous object2");
-
- //-Object 11
- // |-Object 11_1
- // |-Ambiguous object4
- // |-Ambiguous object5
- //-Object 12
- // |-Ambiguous object4
- // |-???
- // |-Ambiguous object4
- // |-Ambiguous object5
- // |-Ambiguous object6
- //-Object 13
- // |-Ambiguous object4
- // |-Object 13_2
- // |-Ambiguous object6
- QObject* namedObject11 = new QObject(mMainWindow);
- namedObject11->setObjectName("Object 11");
- QObject* namedObject11_1 = new QObject(namedObject11);
- namedObject11_1->setObjectName("Object 11_1");
- QObject* ambiguousObject11_1_1 = new QObject(namedObject11_1);
- ambiguousObject11_1_1->setObjectName("Ambiguous object4");
- mAmbiguousObject11_1_2 = new QObject(namedObject11_1);
- mAmbiguousObject11_1_2->setObjectName("Ambiguous object5");
-
- QObject* namedObject12 = new QObject(mMainWindow);
- namedObject12->setObjectName("Object 12");
- mAmbiguousObject12_1 = new QObject(namedObject12);
- mAmbiguousObject12_1->setObjectName("Ambiguous object4");
- QObject* unnamedObject12_2 = new QObject(namedObject12);
- QObject* ambiguousObject12_2_1 = new QObject(unnamedObject12_2);
- ambiguousObject12_2_1->setObjectName("Ambiguous object4");
- QObject* ambiguousObject12_2_2 = new QObject(unnamedObject12_2);
- ambiguousObject12_2_2->setObjectName("Ambiguous object5");
- mAmbiguousObject12_2_3 = new QObject(unnamedObject12_2);
- mAmbiguousObject12_2_3->setObjectName("Ambiguous object6");
-
- QObject* namedObject13 = new QObject(mMainWindow);
- namedObject13->setObjectName("Object 13");
- QObject* ambiguousObject13_1 = new QObject(namedObject13);
- ambiguousObject13_1->setObjectName("Ambiguous object4");
- QObject* namedObject13_2 = new QObject(namedObject13);
- namedObject13_2->setObjectName("Object 13_2");
- QObject* ambiguousObject13_2_1 = new QObject(namedObject13_2);
- ambiguousObject13_2_1->setObjectName("Ambiguous object6");
-
- //-Object 14
- // |-Ambiguous ancestor
- // |-Ambiguous object7
- // |-The object
- //-???
- // |-Ambiguous ancestor
- // | |-Object 15_1_1
- // | |-Ambiguous object7
- // |-Unique ancestor
- // |-Object 15_2_1
- // | |-Ambiguous object7
- // |-???
- // |-Ambiguous object7
- //-???
- // |-???
- // | |-Ambiguous ancestor
- // | |-Ambiguous object7
- // |-Ambiguous ancestor
- // |-???
- // | |-???
- // | |-Ambiguous object7
- // |-Object 16_2_2
- // |-Ambiguous object7
- QObject* namedObject14 = new QObject(mMainWindow);
- namedObject14->setObjectName("Object 14");
- QObject* ambiguousAncestor14_1 = new QObject(namedObject14);
- ambiguousAncestor14_1->setObjectName("Ambiguous ancestor");
- QObject* ambiguousObject14_1_1 = new QObject(ambiguousAncestor14_1);
- ambiguousObject14_1_1->setObjectName("Ambiguous object7");
- mObject14_1_2 = new QObject(ambiguousAncestor14_1);
- mObject14_1_2->setObjectName("The object");
-
- QObject* unnamedObject15 = new QObject(mMainWindow);
- QObject* ambiguousAncestor15_1 = new QObject(unnamedObject15);
- ambiguousAncestor15_1->setObjectName("Ambiguous ancestor");
- QObject* namedObject15_1_1 = new QObject(ambiguousAncestor15_1);
- namedObject15_1_1->setObjectName("Object 15_1_1");
- QObject* ambiguousObject15_1_1_1 = new QObject(namedObject15_1_1);
- ambiguousObject15_1_1_1->setObjectName("Ambiguous object7");
- QObject* uniqueAncestor15_2 = new QObject(unnamedObject15);
- uniqueAncestor15_2->setObjectName("Unique ancestor");
- QObject* namedObject15_2_1 = new QObject(uniqueAncestor15_2);
- namedObject15_2_1->setObjectName("Object 15_2_1");
- QObject* ambiguousObject15_2_1_1 = new QObject(namedObject15_2_1);
- ambiguousObject15_2_1_1->setObjectName("Ambiguous object7");
- QObject* unnamedObject15_2_2 = new QObject(uniqueAncestor15_2);
- mAmbiguousObject15_2_2_1 = new QObject(unnamedObject15_2_2);
- mAmbiguousObject15_2_2_1->setObjectName("Ambiguous object7");
-
- QObject* unnamedObject16 = new QObject(mMainWindow);
- QObject* unnamedObject16_1 = new QObject(unnamedObject16);
- QObject* ambiguousAncestor16_1_1 = new QObject(unnamedObject16_1);
- ambiguousAncestor16_1_1->setObjectName("Ambiguous ancestor");
- QObject* ambiguousObject16_1_1_1 = new QObject(ambiguousAncestor16_1_1);
- ambiguousObject16_1_1_1->setObjectName("Ambiguous object7");
- QObject* ambiguousAncestor16_2 = new QObject(unnamedObject16);
- ambiguousAncestor16_2->setObjectName("Ambiguous ancestor");
- QObject* unnamedObject16_2_1 = new QObject(ambiguousAncestor16_2);
- QObject* unnamedObject16_2_1_1 = new QObject(unnamedObject16_2_1);
- mAmbiguousObject16_2_1_1_1 = new QObject(unnamedObject16_2_1_1);
- mAmbiguousObject16_2_1_1_1->setObjectName("Ambiguous object7");
- QObject* namedObject16_2_2 = new QObject(ambiguousAncestor16_2);
- namedObject16_2_2->setObjectName("Object 16_2_2");
- QObject* ambiguousObject16_2_2_1 = new QObject(namedObject16_2_2);
- ambiguousObject16_2_2_1->setObjectName("Ambiguous object7");
-}
-
-void KTutorialTest::cleanupTestCase() {
- delete mMainWindow;
-}
-
-void KTutorialTest::testFindObjectSingleName() {
- assertFindObject("The object", mObject1_1_1);
-}
-
-void KTutorialTest::testFindObjectSingleNameUnknown() {
- assertFindObject("Unknown object", 0);
-}
-
-void KTutorialTest::testFindObjectComplexNameDirectChild() {
- assertFindObject("Grand parent1/Parent1/The object", mObject1_1_1);
- assertFindObject("Grand parent1/Parent2/The object", mObject1_2_1);
- assertFindObject("Grand parent2/Parent1/The object", mObject2_1_1);
-
- assertFindAction("Grand parent1/Parent1/The action", mAction1_1_2);
- assertFindAction("Grand parent2/Parent1/The action", mAction2_1_3);
-}
-
-void KTutorialTest::testFindObjectComplexNameNestedChild() {
- assertFindObject("Grand parent2/The object", mObject2_1_1);
- assertFindObject("Nested parent/Another object", mObject3_2_1_1);
-
- assertFindAction("Grand parent2/The action", mAction2_1_3);
- assertFindAction("Nested timer/Another action", mAction3_3_1_1);
-}
-
-void KTutorialTest::testFindObjectComplexNameAncestorNameNotUnique() {
- //The ancestor name is not unique, but the full path is
- assertFindObject("Parent1/Another object", mObject2_1_2);
-
- assertFindAction("Parent1/Another action", mAction2_1_4);
-}
-
-void KTutorialTest::testFindObjectComplexNameUnknownParent() {
- assertFindObject("Unknown grand parent/The object", 0);
- assertFindObject("Grand parent1/Unknown parent/The object", 0);
-}
-
-void KTutorialTest::testFindObjectAmbiguousSingleNameDirectChild() {
- assertFindObject("Ambiguous object", mAmbiguousObject5);
-}
-
-void KTutorialTest::
-testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestors() {
- assertFindObject("Ambiguous object2", mAmbiguousObject10_1);
-}
-
-void KTutorialTest::
-testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestorsDeeperThanNamed() {
- assertFindObject("Ambiguous object3", mAmbiguousObject8_1_2);
-}
-
-void KTutorialTest::
-testFindObjectAmbiguousSingleNameNestedChildNamedAncestors() {
- assertFindObject("Ambiguous object4", mAmbiguousObject12_1);
-}
-
-void KTutorialTest::
-testFindObjectAmbiguousSingleNameNestedChildNamedAncestorsSameDeepThanMixed() {
- assertFindObject("Ambiguous object5", mAmbiguousObject11_1_2);
-}
-
-void KTutorialTest::
-testFindObjectAmbiguousSingleNameNestedChildMixedAncestorsSameDeepThanNamed() {
- assertFindObject("Ambiguous object6", mAmbiguousObject12_2_3);
-}
-
-void KTutorialTest::testFindObjectAmbiguousComplexName() {
- //The ancestor is selected by the rule of shallower unnamed ancestors. The
- //object is selected by the rule of unnamed ancestor even if there are
- //shallower objects, but with named ancestors.
- assertFindObject("Ambiguous ancestor/Ambiguous object7",
- mAmbiguousObject16_2_1_1_1);
-}
-
-void KTutorialTest::testFindObjectAmbiguousComplexNameUniqueAncestor() {
- //The ancestor is unique, although the object itself is ambiguous (even
- //among the descendants of that unique ancestor).
- assertFindObject("Unique ancestor/Ambiguous object7",
- mAmbiguousObject15_2_2_1);
-}
-
-void KTutorialTest::
-testFindObjectComplexNameDifferentAncestorIfSolvingAmbiguity() {
- //The full name is unique, but if the rules to resolve ambiguity were
- //applied no object would be found, as the "Ambiguous ancestor" found using
- //the ambiguity resolving rules have no "The object" descendants.
- assertFindObject("Ambiguous ancestor/The object", mObject14_1_2);
-}
-
-void KTutorialTest::testFindObjectEmptyName() {
- assertFindObject("", 0);
-}
-
-void KTutorialTest::testFindObjectSingleSlash() {
- assertFindObject("/", 0);
-}
-
-void KTutorialTest::testFindObjectSlashEndedName() {
- assertFindObject("Parent/", 0);
-}
-
-void KTutorialTest::testFindObjectSeveralSlashes() {
- assertFindObject("Parent1///The object", mObject1_1_1);
-}
-
-/////////////////////////////////Helpers////////////////////////////////////////
-
-void KTutorialTest::assertFindObject(const QString& objectName,
- QObject* object) const {
- QCOMPARE(KTutorial::self()->findObject<QObject*>(objectName), object);
-}
-
-void KTutorialTest::assertFindAction(const QString& objectName,
- QAction* action) const {
- QCOMPARE(KTutorial::self()->findObject<QAction*>(objectName), action);
-}
-
-QTEST_MAIN(KTutorialTest)
-
-#include "KTutorialTest.moc"
Copied: trunk/ktutorial/ktutorial-library/tests/ObjectFinderTest.cpp (from rev 353, trunk/ktutorial/ktutorial-library/tests/KTutorialTest.cpp)
===================================================================
--- trunk/ktutorial/ktutorial-library/tests/ObjectFinderTest.cpp (rev 0)
+++ trunk/ktutorial/ktutorial-library/tests/ObjectFinderTest.cpp 2012-07-05 18:19:04 UTC (rev 354)
@@ -0,0 +1,457 @@
+/***************************************************************************
+ * Copyright (C) 2011-2012 by Daniel Calviño Sánchez *
+ * dan...@gm... *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include <QtTest>
+
+#include <QAction>
+
+#include <KXmlGuiWindow>
+
+#include "ObjectFinder.h"
+
+class ObjectFinderTest: public QObject {
+Q_OBJECT
+
+private slots:
+
+ void initTestCase();
+ void cleanupTestCase();
+
+ void testFindObjectSingleName();
+ void testFindObjectSingleNameUnknown();
+ void testFindObjectComplexNameDirectChild();
+ void testFindObjectComplexNameNestedChild();
+ void testFindObjectComplexNameAncestorNameNotUnique();
+ void testFindObjectComplexNameUnknownParent();
+
+ void testFindObjectAmbiguousSingleNameDirectChild();
+ void testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestors();
+ void testFindObjectAmbiguousSingleNameNestedChildUnnamedAncestorsDeeperThanNamed();
+ void testFindObjectAmbiguousSingleNameNestedChildNamedAncestors();
+ void testFindObjectAmbiguousSingleNameNestedChildNamedAncestorsSameDeepThanMixed();
+ void testFindObjectAmbiguousSingleNameNestedChildMixedAncestorsSameDeepThanNamed();
+ void testFindObjectAmbiguousComplexName();
+ void testFindObjectAmbiguousComplexNameUniqueAncestor();
+ void testFindObjectComplexNameDifferentAncestorIfSolvingAmbiguity();
+
+ void testFindObjectEmptyName();
+ void testFindObjectSingleSlash();
+ void testFindObjectSlashEndedName();
+ void testFindObjectSeveralSlashes();
+
+private:
+
+ KXmlGuiWindow* mMainWindow;
+ QObject* mObject1_1_1;
+ QAction* mAction1_1_2;
+ QObject* mObject1_2_1;
+ QObject* mObject2_1_1;
+ QObject* mObject2_1_2;
+ QAction* mAction2_1_3;
+ QAction* mAction2_1_4;
+ QObject* mObject3_1_1;
+ QObject* mObject3_2_1_1;
+ QAction* mAction3_3_1_1;
+ QObject* mAmbiguousObject5;
+ QObject* mAmbiguousObject8_1_2;
+ QObject* mAmbiguousObject10_1;
+ QObject* mAmbiguousObject11_1_2;
+ QObject* mAmbiguousObject12_1;
+ QObject* mAmbiguousObject12_2_3;
+ QObject* mObject14_1_2;
+ QObject* mAmbiguousObject15_2_2_1;
+ QObject* mAmbiguousObject16_2_1_1_1;
+
+ void assertFindObject(const QString& objectName, QObject* object) const;
+ void assertFindAction(const QString& objectName, QAction* action) const;
+
+};
+
+void ObjectFinderTest::initTestCase() {
+ mMainWindow = new KXmlGuiWindow();
+
+ //-Grand parent1
+ // |-Parent1
+ // | |-The object
+ // | |-The action
+ // |-Parent2
+ // |-The object
+ //-Grand parent2
+ // |-Parent1
+ // |-The object
+ // |-Another object
+ // |-The action
+ // |-Another action
+ //-Grand parent3
+ // |-Parent1
+ // | |-The object
+ // |-Nested parent
+ // | |-Another object
+ // |-Nested timer
+ // |-Another action
+ QObject* grandParent1 = new QObject(mMainWindow);
+ grandParent1->setObjectName("Grand parent1");
+ QObject* parent1_1 = new QObject(grandParent1);
+ parent1_1->setObjectName("Parent1");
+ mObject1_1_1 = new QObject(parent1_1);
+ mObject1_1_1->setObjectName("The object");
+ mAction1_1_2 = new QAction(parent1_1);
+ mAction1_1_2->setObjectName("The action");
+
+ QObject* parent1_2 = new QObject(grandParent1);
+ parent1_2->setObjectName("Parent2");
+ mObject1_2_1 = new QObject(parent1_2);
+ mObject1_2_1->setObjectName("The object");
+
+ QObject* grandParent2 = new QObject(mMainWindow);
+ grandParent2->setObjectName("Grand parent2");
+ QObject* parent2_1 = new QObject(grandParent2);
+ parent2_1->setObjectName("Parent1");
+ mObject2_1_1 = new QObject(parent2_1);
+ mObject2_1_1->setObjectName("The object");
+ mObject2_1_2 = new QObject(parent2_1);
+ mObject2_1_2->setObjectName("Another object");
+ mAction2_1_3 = new QAction(parent2_1);
+ mAction2_1_3->setObjectName("The action");
+ mAction2_1_4 = new QAction(parent2_1);
+ mAction2_1_4->setObjectName("Another action");
+
+ QObject* grandParent3 = new QObject(mMainWindow);
+ grandParent3->setObjectName("Grand parent3");
+ QObject* parent3_1 = new QObject(grandParent3);
+ parent3_1->setObjectName("Parent1");
+ mObject3_1_1 = new QObject(parent3_1);
+ mObject3_1_1->setObjectName("The object");
+
+ QObject* parent3_2 = new QObject(grandParent3);
+ parent3_2->setObjectName("Nested parent");
+ QObject* parent3_2_1 = new QObject(parent3_2);
+ mObject3_2_1_1 = new QObject(parent3_2_1);
+ mObject3_2_1_1->setObjectName("Another object");
+
+ QTimer* parent3_3 = new QTimer(grandParent3);
+ parent3_3->setObjectName("Nested timer");
+ QTimer* parent3_3_1 = new QTimer(parent3_3);
+ mAction3_3_1_1 = new QAction(parent3_3_1);
+ mAction3_3_1_1->setObjectName("Another action");
+
+ //-???
+ // |-???
+ // | |-Ambiguous object
+ // |-Ambiguous object
+ //-Ambiguous object
+ //-Object 6
+ // |-Ambiguous object
+ // |-Object 6_2
+ // |-Ambiguous object
+ //-Ambiguous object
+ QObject* unnamedObject4 = new QObject(mMainWindow);
+ QObject* unnamedObject4_1 = new QObject(unnamedObject4);
+ QObject* ambiguousObject4_1_1 = new QObject(unnamedObject4_1);
+ ambiguousObject4_1_1->setObjectName("Ambiguous object");
+ QObject* ambiguousObject4_2 = new QObject(unnamedObject4);
+ ambiguousObject4_2->setObjectName("Ambiguous object");
+
+ mAmbiguousObject5 = new QObject(mMainWindow);
+ mAmbiguousObject5->setObjectName("Ambiguous object");
+
+ QObject* namedObject6 = new QObject(mMainWindow);
+ namedObject6->setObjectName("Object 6");
+ QObject* ambiguousObject6_1 = new QObject(namedObject6);
+ ambiguousObject6_1->setObjectName("Ambiguous object");
+ QObject* namedObject6_2 = new QObject(namedObject6);
+ namedObject6_2->setObjectName("Object 6_2");
+ QObject* ambiguousObject6_2_1 = new QObject(namedObject6_2);
+ ambiguousObject6_2_1->setObjectName("Ambiguous object");
+
+ QObject* ambiguousObject7 = new QObject(mMainWindow);
+ ambiguousObject7->setObjectName("Ambiguous object");
+
+ //-???
+ // |-???
+ // | |-Ambiguous object2
+ // | |-Ambiguous object3
+ //-Object 9
+ // |-Ambiguous object2
+ // |-Object 9_2
+ // | |-Ambiguous object2
+ // |-Ambiguous object3
+ //-???
+ // |-Ambiguous object2
...
[truncated message content] |