[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] |