Thread: [Ktutorial-commits] SF.net SVN: ktutorial:[111] trunk/ktutorial/ktutorial-editor
Status: Alpha
Brought to you by:
danxuliu
From: <dan...@us...> - 2010-03-05 23:48:53
|
Revision: 111 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=111&view=rev Author: danxuliu Date: 2010-03-05 23:48:40 +0000 (Fri, 05 Mar 2010) Log Message: ----------- Add TextTreeItem class, that represents a plain string in a TreeModel. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-05 23:48:40 UTC (rev 111) @@ -1,6 +1,7 @@ include_directories(${KDE4_INCLUDES}) set(ktutorial_editor_view_SRCS + TextTreeItem.cpp TreeItem.cpp TreeModel.cpp ) Added: trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp 2010-03-05 23:48:40 UTC (rev 111) @@ -0,0 +1,30 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TextTreeItem.h" + +TextTreeItem::TextTreeItem(TreeItem* parent): TreeItem(parent) { +} + +QString TextTreeItem::text() const { + return mText; +} + +void TextTreeItem::setText(const QString& text) { + mText = text; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.h 2010-03-05 23:48:40 UTC (rev 111) @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TEXTTREEITEM_H +#define TEXTTREEITEM_H + +#include "TreeItem.h" + +/** + * A simple TreeItem that represents a plain string. + */ +class TextTreeItem: public TreeItem { +public: + + /** + * Creates a new TextTreeItem with the given parent. + * + * @param parent The parent TreeItem. + */ + explicit TextTreeItem(TreeItem* parent = 0); + + /** + * The text to be shown for this node of the tree, + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + + /** + * Sets the text of this TextTreeItem. + * + * @param text The text to set. + */ + void setText(const QString& text); + +private: + + /** + * The text to show. + */ + QString mText; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-05 23:48:40 UTC (rev 111) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(TreeItem TreeModel) +unit_tests(TextTreeItem TreeItem TreeModel) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(TreeItem TreeModel) +mem_tests(TextTreeItem TreeItem TreeModel) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp 2010-03-05 23:48:40 UTC (rev 111) @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TextTreeItem.h" + +class TextTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSetText(); + +}; + +void TextTreeItemTest::testConstructor() { + TextTreeItem parent; + TextTreeItem treeItem(&parent); + + QCOMPARE(parent.parent(), (TreeItem*)0); + QCOMPARE(treeItem.parent(), &parent); +} + +void TextTreeItemTest::testSetText() { + TextTreeItem item; + item.setText("Hello world"); + + QCOMPARE(item.text(), QString("Hello world")); +} + +QTEST_MAIN(TextTreeItemTest) + +#include "TextTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-05 23:35:37
|
Revision: 110 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=110&view=rev Author: danxuliu Date: 2010-03-05 23:35:28 +0000 (Fri, 05 Mar 2010) Log Message: ----------- Add the foundations to show a Tutorial in a QTreeView. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/CMakeLists.txt trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h trunk/ktutorial/ktutorial-editor/tests/ trunk/ktutorial/ktutorial-editor/tests/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/runMemcheck.py trunk/ktutorial/ktutorial-editor/tests/unit/view/ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp Modified: trunk/ktutorial/ktutorial-editor/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/CMakeLists.txt 2010-03-05 23:32:03 UTC (rev 109) +++ trunk/ktutorial/ktutorial-editor/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -5,3 +5,4 @@ include(KDE4Defaults) add_subdirectory(src) +add_subdirectory(tests) Modified: trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-05 23:32:03 UTC (rev 109) +++ trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -2,6 +2,8 @@ # In order to work, they must be compiled using -fPIC add_definitions("-fPIC") +add_subdirectory(view) + include_directories(${KDE4_INCLUDES}) set(ktutorial_editor_SRCS @@ -14,6 +16,7 @@ # As everything but a tiny initialization code is in a library, the build system # for the tests can be easily set up. kde4_add_library(ktutorial_editor ${ktutorial_editor_SRCS}) +target_link_libraries(ktutorial_editor ktutorial_editor_view) kde4_add_executable(ktutorial-editor main.cpp) target_link_libraries(ktutorial-editor ktutorial_editor ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS}) Added: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,10 @@ +include_directories(${KDE4_INCLUDES}) + +set(ktutorial_editor_view_SRCS + TreeItem.cpp + TreeModel.cpp +) + +kde4_add_library(ktutorial_editor_view ${ktutorial_editor_view_SRCS}) + +target_link_libraries(ktutorial_editor_view ${KDE4_KDEUI_LIBS}) Property changes on: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeItem.h" + +TreeItem::TreeItem(TreeItem* parent): + mParent(parent) { +} + +TreeItem::~TreeItem() { + qDeleteAll(mChildren); +} + +TreeItem* TreeItem::child(int index) { + return mChildren.value(index); +} + +int TreeItem::childCount() const { + return mChildren.count(); +} + +void TreeItem::appendChild(TreeItem* child) { + Q_ASSERT(!mChildren.contains(child)); + Q_ASSERT(child->parent() == this); + + mChildren.append(child); +} + +void TreeItem::insertChild(TreeItem* child, int index) { + Q_ASSERT(!mChildren.contains(child)); + Q_ASSERT(child->parent() == this); + + mChildren.insert(index, child); +} + +void TreeItem::removeChild(TreeItem* child) { + Q_ASSERT(mChildren.contains(child)); + Q_ASSERT(child->parent() == this); + + mChildren.removeAt(mChildren.indexOf(child)); +} + +TreeItem* TreeItem::parent() { + return mParent; +} + +int TreeItem::childIndex() const { + for (int i = 0; i < mParent->childCount(); ++i) { + if (mParent->child(i) == this) { + return i; + } + } + + return -1; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,133 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TREEITEM_H +#define TREEITEM_H + +#include <QString> +#include <QVariant> + +/** + * An item in a TreeModel. + * TreeItems form tree structures that provide the data to TreeModels. The + * TreeItems act as an adapter between the model and the real data: through + * TreeItem custom subclasses a source of data can be represented as several + * nested TreeItem objects that expose the data in some specific structure. + * + * For example, an object of a Person class with name, age and profession + * attributes can be represented as a tree with a parent TreeItem that contains + * the name of the person and two child TreeItems, one that contains the age and + * one that contains the profession. + * + * TreeItem is an abstract class. Subclasses must implement its text() method, + * that provides the data for that item to the TreeModel when DisplayRole is + * used. + * + * @see TreeModel + */ +class TreeItem { +public: + + /** + * Creates a new TreeItem with the given parent. + * + * @param parent The parent TreeItem. + */ + explicit TreeItem(TreeItem* parent = 0); + + /** + * Destroys this TreeItem and all its children. + */ + virtual ~TreeItem(); + + /** + * The text to be shown for this node of the tree, + * This method must be implemented by subclasses. + * + * @return The text for this TreeItem. + */ + virtual QString text() const = 0; + + /** + * Returns the child tree item with the given index. + * + * @param index The index of the child to get. + * @return The child with the given index. + */ + TreeItem* child(int index); + + /** + * Returns the number of child tree items. + * + * @return The number of children. + */ + int childCount() const; + + /** + * Adds a child at the end of the child list. + * + * @param child The child to add. + */ + void appendChild(TreeItem* child); + + /** + * Inserts a child at the given position of the child list. + * + * @param child The child to insert. + * @param index The position to insert the child into. + */ + void insertChild(TreeItem* child, int index); + + /** + * Removes the given child from the child list. + * + * @param child The child to remove. + */ + void removeChild(TreeItem* child); + + /** + * The parent of this TreeItem. + * + * @return The parent of this TreeItem. + */ + TreeItem* parent(); + + /** + * The index of this TreeItem in the child list of its parent. + * If this TreeItem was not added or was removed from its parent, -1 is + * returned. + * + * @return The index of this TreeItem. + */ + int childIndex() const; + +private: + + /** + * The parent of this TreeItem. + */ + TreeItem* mParent; + + /** + * The children of this TreeItem. + */ + QList<TreeItem*> mChildren; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,116 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeModel.h" + +#include "TreeItem.h" + +//public: + +TreeModel::TreeModel(TreeItem* rootItem, QObject* parent): + QAbstractItemModel(parent), + mRootItem(rootItem) { + Q_ASSERT(rootItem); +} + +TreeModel::~TreeModel() { + delete mRootItem; +} + +QVariant TreeModel::data(const QModelIndex& index, int role) const { + if (!index.isValid()) { + return QVariant(); + } + + if (role != Qt::DisplayRole) { + return QVariant(); + } + + TreeItem* item = static_cast<TreeItem*>(index.internalPointer()); + + return item->text(); +} + +Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const { + if (!index.isValid()) { + return Qt::NoItemFlags; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant TreeModel::headerData(int section, Qt::Orientation orientation, + int role) const { + if (section == 0 && orientation == Qt::Horizontal && + role == Qt::DisplayRole) { + return mRootItem->text(); + } + + return QVariant(); +} + +QModelIndex TreeModel::index(int row, int column, + const QModelIndex& parent) const { + if (!hasIndex(row, column, parent)) { + return QModelIndex(); + } + + TreeItem* parentItem; + + if (!parent.isValid()) { + parentItem = mRootItem; + } else { + parentItem = static_cast<TreeItem*>(parent.internalPointer()); + } + + TreeItem* childItem = parentItem->child(row); + + return createIndex(row, column, childItem); +} + +QModelIndex TreeModel::parent(const QModelIndex& index) const { + if (!index.isValid()) { + return QModelIndex(); + } + + TreeItem* childItem = static_cast<TreeItem*>(index.internalPointer()); + TreeItem* parentItem = childItem->parent(); + + if (parentItem == mRootItem) { + return QModelIndex(); + } + + return createIndex(parentItem->childIndex(), 0, parentItem); +} + +int TreeModel::rowCount(const QModelIndex& parent) const { + TreeItem* parentItem; + if (!parent.isValid()) { + parentItem = mRootItem; + } else { + parentItem = static_cast<TreeItem*>(parent.internalPointer()); + } + + return parentItem->childCount(); +} + +int TreeModel::columnCount(const QModelIndex& parent) const { + Q_UNUSED(parent); + + return 1; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TREEMODEL_H +#define TREEMODEL_H + +#include <QAbstractItemModel> + +class TreeItem; + +/** + * A read only model to represent nested data in a single column tree. + * The model gets its data from a tree structure made of TreeItems. The root + * item provides the data for the header and its children (and the children of + * its children, and the children of the children of...) the data for the + * contents. + * + * TreeItem objects are mapped one to one to items in the model. Each TreeItem + * (but the root item) has its own index in the model. Top level items (direct + * children of root item) have no parent indexes. For child items, their parent + * index is the index of its parent item. The row count for any index is the + * number of children of its TreeItem. There is only one column in any index (as + * it is a single column tree). + * + * Each TreeItem provides the data to be shown by its associated model item. + * Display role shows the text of the TreeItem. + * + * @see TreeItem + */ +class TreeModel: public QAbstractItemModel { +Q_OBJECT +public: + + /** + * Creates a new TreeModel for the given root TreeItem. + * + * @param rootItem The root of the tree. + * @param parent The parent object. + */ + explicit TreeModel(TreeItem* rootItem, QObject* parent = 0); + + /** + * Destroys this TreeModel and its tree of items. + */ + virtual ~TreeModel(); + + /** + * Returns the data for the given index and role. + * Display role with valid index returns the text of the TreeItem referred + * to by the index. An invalid variant is returned otherwise. + * + * @param index The index. + * @param role The role. + * @return The data for the given index and role, or an invalid variant if + * there is no data. + */ + virtual QVariant data(const QModelIndex& index, + int role = Qt::DisplayRole) const; + + /** + * Returns the flags for the given index. + * If the index is valid, the flags enable the item and allow it to be + * selected. + * + * @return The flags for the given index. + */ + virtual Qt::ItemFlags flags(const QModelIndex& index) const; + + /** + * Returns the data for the given role and section in the header with the + * specified orientation. + * Display role in section 0 and horizontal orientation returns the text of + * the root item. An invalid variant is returned otherwise. + * + * @param section The section of the header. + * @param orientation The orientation of the header. + * @param role The role of the header. + * @return The data for the header. + */ + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + /** + * Returns the index of the item in the model specified by the given row, + * column and parent index. + * If the row or column is out of bounds for the given parent, an invalid + * index is returned. + * + * @param row The row of the index. + * @param column The column of the index. + * @param parent The parent of the index. + * @return The index for the given row, column and parent. + */ + virtual QModelIndex index(int row, int column, + const QModelIndex& parent = QModelIndex()) const; + + /** + * Returns the index for the parent of the model item with the given index. + * If the index has no parent (it is invalid, or a top level index), an + * invalid index is returned. + * + * @param index The index to get its parent. + * @return The parent index of the given index. + */ + virtual QModelIndex parent(const QModelIndex& index) const; + + /** + * Returns the number of rows under the given parent. + * It is the number of children of the TreeItem referred to by the index. If + * the index is invalid, it is the number of top level items. + * + * @param parent The parent index. + * @return The number of child rows. + */ + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + + /** + * Returns the number of columns for the children of the given parent. + * As this model is a single column model, it always returns 1. + * + * @param parent The parent index. + * @return The number of columns for the children. + */ + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; + +private: + + /** + * The root item. + */ + TreeItem* mRootItem; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1 @@ +add_subdirectory(unit) Property changes on: trunk/ktutorial/ktutorial-editor/tests/CMakeLists.txt ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1 @@ +add_subdirectory(view) Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/runMemcheck.py =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/runMemcheck.py (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/runMemcheck.py 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,173 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# run valgrind's memory error checker on all tests. +# filter uninteresting errors and known false positives +# eg staticly initialized memory from libraries like libfontconfig +# + + +# Modified from Coverage plugin tests for KDevelop 4 +# http://websvn.kde.org/trunk/KDE/kdevelop/tools/coverage/tests/runMemcheck.py?revision=926694&view=markup +# which is licensed under GPL 2 or later +# http://websvn.kde.org/trunk/KDE/kdevelop/tools/coverage/coverageplugin.cpp?revision=926694&view=markup + + +from os import system, remove +from sys import exit, stdout +from subprocess import Popen, PIPE +from xml.dom.minidom import parse, parseString + +def garbage(line): + ''' filter for valgridn output''' + return not line.startswith('<unknown program name>') and \ + not line.startswith('profiling:') and \ + line.find('</valgrindoutput>') # problem is that valgrind erroneously puts multiple of these end-document entries if processes are spawned _inside_ the exe under investigation + +def memcheck(test): + ''' run valgrind-memcheck on test in testdir. return xml output as string ''' + #proc = Popen("valgrind --tool=memcheck --leak-check=full --xml=yes " + test, stdout=PIPE, stderr=PIPE, shell=True, executable="/bin/bash") + #proc.wait() + #out = proc.stderr.readlines() + system("valgrind --tool=memcheck --leak-check=full --xml=yes --xml-file=.memcheck.tmp --num-callers=50 " + test + " 1>/dev/null") + out = open(".memcheck.tmp").readlines() + remove(".memcheck.tmp") + out = filter(garbage, out) + return ''.join(out) + "\n</valgrindoutput>\n" + +def xml_child_data(dom,tag): + ''' extract child data for tag. return None if not found''' + elem = dom.getElementsByTagName(tag) + val = None + if len(elem) != 0: + val = elem[0].firstChild.data + return val + +class Frame: + ''' single entry in a memory error backtrace ''' + def __init__(self, dom_frame): + '''<frame> + <ip>0x62ACDBF</ip> + <obj>/home/nix/KdeDev/kde4/lib/libkdevplatformlanguage.so.1.0.0</obj> + <fn>KDevelop::ParamIterator::ParamIterator(QString, QString, int)</fn> + <dir>/home/nix/KdeDev/kdevplatform/language/duchain</dir> + <file>stringhelpers.cpp</file> + <line>292</line> + </frame>''' + self.obj = xml_child_data(dom_frame, 'obj') + self.func = xml_child_data(dom_frame, 'fn') + self.sfile = xml_child_data(dom_frame, 'file') + self.sline = xml_child_data(dom_frame, 'line') + + def __str__(self): + out = "" + if self.func: + out += "\t" + self.func + if self.sfile and self.sline: + out += " (" + self.sfile + ":" + self.sline + ")" + #if self.obj: + #out += "\t" + self.obj + "\n" + out += "\n" + return out + +class BackTrace: + ''' valgrind memcheck stack trace ''' + def __init__(self, errordom): + self.dom = errordom + self.kind = self.dom.getElementsByTagName('kind')[0].firstChild.data + stack = self.dom.getElementsByTagName('frame') + self.stack = [] + for frame in stack: + if xml_child_data(frame, 'fn'): # filter anonymous frames out + self.stack.append(Frame(frame)) + self.what = xml_child_data(self.dom, 'what') + if self.dom.getElementsByTagName('xwhat').length > 0: + self.what = xml_child_data(self.dom.getElementsByTagName('xwhat')[0], 'text') + + def is_definitely_lost(self): + return self.kind == u'Leak_DefinitelyLost' + + def is_qtest(self): + is_interesting = False + for frame in self.stack: + if frame.func: + if frame.func.find("QTest") != -1 or frame.func.find("Veritas") != -1: + is_interesting = True + if frame.func.find('XcursorXcFileLoadImages') != -1: + return False # something deep in X server, not interested in this + if frame.func.find('XRegisterIMInstantiateCallback') != -1: + return False # X-related static memory allocation, no leak + if frame.func.find('FcDefaultSubstitute') != -1: + return False # something Qt-Font related, not interested in this + if frame.func.find('__nss_database_lookup') != -1: + return False # more crap + if frame.sfile: + if frame.sfile.find("xtest") != -1 or frame.sfile.find("veritas") != -1: + is_interesting = True + return is_interesting + + def __str__(self): + out = self.what + "\n" + for frame in self.stack: + out += str(frame) + return out + +def parse_errors(out): + ''' extract the interesting memcheck errors from the xml-string input 'out'. + return these as a list ''' + xmldoc = parseString(out) + errors = xmldoc.getElementsByTagName('error') + errors_ = [] + for error in errors: + bt = BackTrace(error) + if bt.is_definitely_lost() and bt.is_qtest(): + errors_.append(bt) + return errors_ + +def run_single_test(exe_name): + print ">> running valgrind memcheck on " + exe_name + system("export LD_LIBRARY_PATH="+sys.argv[2]+"/lib/:$LD_LIBRARY_PATH") + count = 0 + import xml + while count < 5: + try: + out = memcheck(exe_name) + errors = parse_errors(out) + if len(errors) == 0: + print "PASS" + exit(0) + else: + for trace in errors: + print trace, + print "---------------------------------------------------" + exit(-1) + except xml.parsers.expat.ExpatError: + print "Valgrind fooked up, retry" + count += 1 + pass + print "5 retries, no luck: aborting :(" + exit(-1) + +################### ENTRY #################################################### + + +def isValgrind3_5OrHigher(): + process = Popen("valgrind --version", stdout=PIPE, shell=True) + process.wait() + valgrindOutput = process.stdout.read().strip() + + import re, string + version = re.search("[0-9]+(.[0-9]+)*", valgrindOutput).group(0) + version = string.split(version, ".") + + if map(int, version) < [3, 5]: + return False + else: + return True + +if __name__ == '__main__': + if not isValgrind3_5OrHigher(): + print "Valgrind 3.5.0 or higher is needed. No mem check will be run." + exit(-1) + + import sys + run_single_test(sys.argv[1]) Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/runMemcheck.py ___________________________________________________________________ Added: svn:executable + * Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,27 @@ +# Used by kde4_add_unit_test to set the full path to test executables +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CMAKE_CURRENT_BINARY_DIR} ${ktutorial-editor_SOURCE_DIR}/src/view ${ktutorial-editor_BINARY_DIR}/src/view ${KDE4_INCLUDES}) + +# Since Qt 4.6.0, this definition is needed for GUI testing. +# It is backwards compatible with previous Qt versions, unlike the alternative +# which is to add #include <QTestGui> in the test files. +add_definitions(-DQT_GUI_LIB) + +MACRO(UNIT_TESTS) + FOREACH(_className ${ARGN}) + set(_testName ${_className}Test) + kde4_add_unit_test(${_testName} TESTNAME ktutorial-editor-unit-${_testName} ${_testName}.cpp) + target_link_libraries(${_testName} ktutorial_editor_view ${QT_QTTEST_LIBRARY}) + ENDFOREACH(_className) +ENDMACRO(UNIT_TESTS) + +unit_tests(TreeItem TreeModel) + +MACRO(MEM_TESTS) + FOREACH(_testname ${ARGN}) + add_test(ktutorial-editor-unit-mem-${_testname} ${CMAKE_CURRENT_SOURCE_DIR}/../runMemcheck.py ${CMAKE_CURRENT_BINARY_DIR}/${_testname}Test ${CMAKE_CURRENT_BINARY_DIR}) + ENDFOREACH(_testname) +ENDMACRO(MEM_TESTS) + +mem_tests(TreeItem TreeModel) Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,188 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeItem.h" + +class TreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testAppendChild(); + void testAppendChildSeveralChildren(); + + void testInsertChild(); + void testInsertChildSeveralChildren(); + + void testRemoveChild(); + void testRemoveChildSeveralChildren(); + +}; + +class StubTreeItem: public TreeItem { +public: + + QString mText; + + StubTreeItem(TreeItem* parent = 0): TreeItem(parent) { + } + + virtual QString text() const { + return mText; + } + +}; + +void TreeItemTest::testConstructor() { + StubTreeItem parent; + StubTreeItem treeItem(&parent); + + QCOMPARE(parent.parent(), (TreeItem*)0); + QCOMPARE(treeItem.parent(), &parent); +} + +void TreeItemTest::testAppendChild() { + StubTreeItem treeItem; + TreeItem* child = new StubTreeItem(&treeItem); + + treeItem.appendChild(child); + + QCOMPARE(treeItem.childCount(), 1); + QCOMPARE(treeItem.child(0), child); + QCOMPARE(child->childIndex(), 0); + QCOMPARE(child->parent(), &treeItem); +} + +void TreeItemTest::testAppendChildSeveralChildren() { + StubTreeItem treeItem; + TreeItem* child1 = new StubTreeItem(&treeItem); + TreeItem* child2 = new StubTreeItem(&treeItem); + TreeItem* child3 = new StubTreeItem(&treeItem); + + treeItem.appendChild(child1); + treeItem.appendChild(child2); + treeItem.appendChild(child3); + + QCOMPARE(treeItem.childCount(), 3); + QCOMPARE(treeItem.child(0), child1); + QCOMPARE(treeItem.child(1), child2); + QCOMPARE(treeItem.child(2), child3); + QCOMPARE(child1->childIndex(), 0); + QCOMPARE(child1->parent(), &treeItem); + QCOMPARE(child2->childIndex(), 1); + QCOMPARE(child2->parent(), &treeItem); + QCOMPARE(child3->childIndex(), 2); + QCOMPARE(child3->parent(), &treeItem); +} + +void TreeItemTest::testInsertChild() { + StubTreeItem treeItem; + TreeItem* child = new StubTreeItem(&treeItem); + + treeItem.insertChild(child, 0); + + QCOMPARE(treeItem.childCount(), 1); + QCOMPARE(treeItem.child(0), child); + QCOMPARE(child->childIndex(), 0); + QCOMPARE(child->parent(), &treeItem); +} + +void TreeItemTest::testInsertChildSeveralChildren() { + StubTreeItem treeItem; + TreeItem* child1 = new StubTreeItem(&treeItem); + TreeItem* child2 = new StubTreeItem(&treeItem); + TreeItem* child3 = new StubTreeItem(&treeItem); + TreeItem* child4 = new StubTreeItem(&treeItem); + + treeItem.insertChild(child2, 0); + treeItem.insertChild(child1, 0); + treeItem.insertChild(child4, 2); + treeItem.insertChild(child3, 2); + + QCOMPARE(treeItem.childCount(), 4); + QCOMPARE(treeItem.child(0), child1); + QCOMPARE(treeItem.child(1), child2); + QCOMPARE(treeItem.child(2), child3); + QCOMPARE(treeItem.child(3), child4); + QCOMPARE(child1->childIndex(), 0); + QCOMPARE(child1->parent(), &treeItem); + QCOMPARE(child2->childIndex(), 1); + QCOMPARE(child2->parent(), &treeItem); + QCOMPARE(child3->childIndex(), 2); + QCOMPARE(child3->parent(), &treeItem); + QCOMPARE(child4->childIndex(), 3); + QCOMPARE(child4->parent(), &treeItem); +} + +void TreeItemTest::testRemoveChild() { + StubTreeItem treeItem; + //It will be removed and not deleted by parent TreeItem, so it is created in + //stack + StubTreeItem child(&treeItem); + + treeItem.appendChild(&child); + treeItem.removeChild(&child); + + QCOMPARE(treeItem.childCount(), 0); + QCOMPARE(child.childIndex(), -1); + QCOMPARE(child.parent(), &treeItem); +} + +void TreeItemTest::testRemoveChildSeveralChildren() { + StubTreeItem treeItem; + //They will be removed and not deleted by parent TreeItem, so they are + //created in stack + StubTreeItem child1(&treeItem); + StubTreeItem child2(&treeItem); + StubTreeItem child3(&treeItem); + + treeItem.appendChild(&child1); + treeItem.appendChild(&child2); + treeItem.appendChild(&child3); + + treeItem.removeChild(&child2); + + QCOMPARE(treeItem.childCount(), 2); + QCOMPARE(treeItem.child(0), &child1); + QCOMPARE(treeItem.child(1), &child3); + QCOMPARE(child1.childIndex(), 0); + QCOMPARE(child1.parent(), &treeItem); + QCOMPARE(child2.childIndex(), -1); + QCOMPARE(child2.parent(), &treeItem); + QCOMPARE(child3.childIndex(), 1); + QCOMPARE(child3.parent(), &treeItem); + + treeItem.removeChild(&child1); + treeItem.removeChild(&child3); + + QCOMPARE(treeItem.childCount(), 0); + QCOMPARE(child1.childIndex(), -1); + QCOMPARE(child1.parent(), &treeItem); + QCOMPARE(child2.childIndex(), -1); + QCOMPARE(child2.parent(), &treeItem); + QCOMPARE(child3.childIndex(), -1); + QCOMPARE(child3.parent(), &treeItem); +} + +QTEST_MAIN(TreeItemTest) + +#include "TreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp 2010-03-05 23:35:28 UTC (rev 110) @@ -0,0 +1,295 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeModel.h" + +#include "TreeItem.h" + +class TreeModelTest: public QObject { +Q_OBJECT + +private slots: + + void init(); + void cleanup(); + + void testConstructorEmptyRootItem(); + void testConstructorSingleItem(); + void testConstructorSeveralFlatItems(); + void testConstructorSingleNestedItem(); + void testConstructorSeveralNestedItems(); + + void testDataWithInvalidIndex(); + void testDataWithInvalidRole(); + + void testFlagsWithInvalidIndex(); + + void testHeaderDataWithInvalidSection(); + void testHeaderDataWithInvalidOrientation(); + void testHeaderDataWithInvalidRole(); + + void testIndexOutOfBounds(); + + void testParentWithInvalidIndex(); + +private: + + TreeItem* mEmptyRootItem; + TreeItem* mSingleItem; + TreeItem* mSeveralFlatItems; + TreeItem* mSingleNestedItem; + TreeItem* mSeveralNestedItems; + + void assertItem(const QModelIndex& index, const QString& displayRoleData, + int childrenCount, const QModelIndex& parent) const; + +}; + +class StubTreeItem: public TreeItem { +public: + + QString mText; + + StubTreeItem(QString text, TreeItem* parent = 0): + TreeItem(parent), + mText(text) { + } + + virtual QString text() const { + return mText; + } + +}; + +void TreeModelTest::init() { + mEmptyRootItem = new StubTreeItem("root"); + + mSingleItem = new StubTreeItem("root"); + TreeItem* parent = mSingleItem; + mSingleItem->appendChild(new StubTreeItem("root-1", parent)); + + mSeveralFlatItems = new StubTreeItem("root"); + parent = mSeveralFlatItems; + mSeveralFlatItems->appendChild(new StubTreeItem("root-1", parent)); + mSeveralFlatItems->appendChild(new StubTreeItem("root-2", parent)); + mSeveralFlatItems->appendChild(new StubTreeItem("root-3", parent)); + + mSingleNestedItem = new StubTreeItem("root"); + parent = mSingleNestedItem; + mSingleNestedItem->appendChild(new StubTreeItem("root-1", parent)); + parent = mSingleNestedItem->child(0); + mSingleNestedItem->child(0)->appendChild(new StubTreeItem("root-1-1", parent)); + + mSeveralNestedItems = new StubTreeItem("root"); + parent = mSeveralNestedItems; + mSeveralNestedItems->appendChild(new StubTreeItem("root-1", parent)); + parent = mSeveralNestedItems->child(0); + mSeveralNestedItems->child(0)->appendChild(new StubTreeItem("root-1-1", parent)); + parent = mSeveralNestedItems; + mSeveralNestedItems->appendChild(new StubTreeItem("root-2", parent)); + mSeveralNestedItems->appendChild(new StubTreeItem("root-3", parent)); + parent = mSeveralNestedItems->child(2); + mSeveralNestedItems->child(2)->appendChild(new StubTreeItem("root-3-1", parent)); + mSeveralNestedItems->child(2)->appendChild(new StubTreeItem("root-3-2", parent)); +} + +void TreeModelTest::cleanup() { + delete mEmptyRootItem; + delete mSingleItem; + delete mSeveralFlatItems; + delete mSingleNestedItem; + delete mSeveralNestedItems; +} + +void TreeModelTest::testConstructorEmptyRootItem() { + TreeModel model(mEmptyRootItem); + mEmptyRootItem = 0; + + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); +} + +void TreeModelTest::testConstructorSingleItem() { + TreeModel model(mSingleItem); + mSingleItem = 0; + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 0, QModelIndex()); +} + +void TreeModelTest::testConstructorSeveralFlatItems() { + TreeModel model(mSeveralFlatItems); + mSeveralFlatItems = 0; + + QCOMPARE(model.rowCount(), 3); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 0, QModelIndex()); + + index = model.index(1, 0); + assertItem(index, "root-2", 0, QModelIndex()); + + index = model.index(2, 0); + assertItem(index, "root-3", 0, QModelIndex()); +} + +void TreeModelTest::testConstructorSingleNestedItem() { + TreeModel model(mSingleNestedItem); + mSingleNestedItem = 0; + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 1, QModelIndex()); + + QModelIndex parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1", 0, parent); +} + +void TreeModelTest::testConstructorSeveralNestedItems() { + TreeModel model(mSeveralNestedItems); + mSeveralNestedItems = 0; + + QCOMPARE(model.rowCount(), 3); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 1, QModelIndex()); + + QModelIndex parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1", 0, parent); + + index = model.index(1, 0); + assertItem(index, "root-2", 0, QModelIndex()); + + index = model.index(2, 0); + assertItem(index, "root-3", 2, QModelIndex()); + + parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-3-1", 0, parent); + + index = model.index(1, 0, parent); + assertItem(index, "root-3-2", 0, parent); +} + +void TreeModelTest::testDataWithInvalidIndex() { + TreeModel model(mSingleItem); + mSingleItem = 0; + + QCOMPARE(model.data(QModelIndex()), QVariant()); +} + +void TreeModelTest::testDataWithInvalidRole() { + TreeModel model(mSingleItem); + mSingleItem = 0; + + QCOMPARE(model.data(model.index(0, 0), Qt::DecorationRole), QVariant()); + QCOMPARE(model.data(model.index(0, 0), Qt::EditRole), QVariant()); + QCOMPARE(model.data(model.index(0, 0), Qt::ToolTipRole), QVariant()); + QCOMPARE(model.data(model.index(0, 0), Qt::StatusTipRole), QVariant()); + QCOMPARE(model.data(model.index(0, 0), Qt::WhatsThisRole), QVariant()); + QCOMPARE(model.data(model.index(0, 0), Qt::SizeHintRole), QVariant()); +} + +void TreeModelTest::testFlagsWithInvalidIndex() { + TreeModel model(mSingleItem); + mSingleItem = 0; + + QCOMPARE(model.flags(QModelIndex()), Qt::NoItemFlags); +} + +void TreeModelTest::testHeaderDataWithInvalidSection() { + TreeModel model(mEmptyRootItem); + mEmptyRootItem = 0; + + QCOMPARE(model.headerData(1, Qt::Horizontal), QVariant()); +} + +void TreeModelTest::testHeaderDataWithInvalidOrientation() { + TreeModel model(mEmptyRootItem); + mEmptyRootItem = 0; + + QCOMPARE(model.headerData(0, Qt::Vertical), QVariant()); +} + +void TreeModelTest::testHeaderDataWithInvalidRole() { + TreeModel model(mEmptyRootItem); + mEmptyRootItem = 0; + + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::DecorationRole), QVariant()); + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::EditRole), QVariant()); + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::ToolTipRole), QVariant()); + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::StatusTipRole), QVariant()); + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::WhatsThisRole), QVariant()); + QCOMPARE(model.headerData(0, Qt::Horizontal, Qt::SizeHintRole), QVariant()); +} + +void TreeModelTest::testIndexOutOfBounds() { + TreeModel model(mSingleNestedItem); + mSingleNestedItem = 0; + + QCOMPARE(model.index(0, 1), QModelIndex()); + QCOMPARE(model.index(1, 0), QModelIndex()); + + QModelIndex parent = model.index(0, 0); + QVERIFY(parent.isValid()); + QCOMPARE(model.index(0, 1, parent), QModelIndex()); + QCOMPARE(model.index(1, 0, parent), QModelIndex()); +} + +void TreeModelTest::testParentWithInvalidIndex() { + TreeModel model(mSingleItem); + mSingleItem = 0; + + QCOMPARE(model.parent(QModelIndex()), QModelIndex()); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void TreeModelTest::assertItem(const QModelIndex& index, + const QString& displayRoleData, + int childrenCount, + const QModelIndex& parent) const { + const QAbstractItemModel* model = index.model(); + + QVERIFY(index.isValid()); + QCOMPARE(model->data(index).toString(), displayRoleData); + QCOMPARE(model->flags(index), Qt::ItemIsEnabled | Qt::ItemIsSelectable); + QCOMPARE(model->parent(index), parent); + QCOMPARE(model->rowCount(index), childrenCount); + QCOMPARE(model->columnCount(index), 1); +} + +QTEST_MAIN(TreeModelTest) + +#include "TreeModelTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-06 17:11:33
|
Revision: 112 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=112&view=rev Author: danxuliu Date: 2010-03-06 17:11:26 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Emit signals when the structure or data of a TreeItem is modified, so the TreeModel can watch those signals and notify its views to be updated. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp 2010-03-05 23:48:40 UTC (rev 111) +++ trunk/ktutorial/ktutorial-editor/src/view/TextTreeItem.cpp 2010-03-06 17:11:26 UTC (rev 112) @@ -27,4 +27,6 @@ void TextTreeItem::setText(const QString& text) { mText = text; + + emit dataChanged(this); } Modified: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp 2010-03-05 23:48:40 UTC (rev 111) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItem.cpp 2010-03-06 17:11:26 UTC (rev 112) @@ -38,21 +38,33 @@ Q_ASSERT(!mChildren.contains(child)); Q_ASSERT(child->parent() == this); + emit childAboutToBeInserted(child, mChildren.count()); + mChildren.append(child); + + emit childInserted(child); } void TreeItem::insertChild(TreeItem* child, int index) { Q_ASSERT(!mChildren.contains(child)); Q_ASSERT(child->parent() == this); + emit childAboutToBeInserted(child, index); + mChildren.insert(index, child); + + emit childInserted(child); } void TreeItem::removeChild(TreeItem* child) { Q_ASSERT(mChildren.contains(child)); Q_ASSERT(child->parent() == this); + emit childAboutToBeRemoved(child); + mChildren.removeAt(mChildren.indexOf(child)); + + emit childRemoved(child); } TreeItem* TreeItem::parent() { Modified: trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h 2010-03-05 23:48:40 UTC (rev 111) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItem.h 2010-03-06 17:11:26 UTC (rev 112) @@ -34,13 +34,19 @@ * the name of the person and two child TreeItems, one that contains the age and * one that contains the profession. * + * The structure of a tree can be modified after being added to a TreeModel. + * Changes in the layout (adding or removing child items) or the data are + * notified to the TreeModel, which notifies the views to be updated as needed. + * * TreeItem is an abstract class. Subclasses must implement its text() method, * that provides the data for that item to the TreeModel when DisplayRole is - * used. + * used. They also have to emit dataChanged(TreeItem*) signal when the data to + * be shown is modified. * * @see TreeModel */ -class TreeItem { +class TreeItem: public QObject { +Q_OBJECT public: /** @@ -116,6 +122,52 @@ */ int childIndex() const; +Q_SIGNALS: + + /** + * Emitted just before a child is inserted or appended. + * It is used to notify the TreeModel in order to update the views. + * + * @param child The child to be added. + * @param index The position to insert it (if the item is appended, the + * index is equal to the child count). + */ + void childAboutToBeInserted(TreeItem* child, int index); + + /** + * Emitted after a child is inserted or appended. + * It is used to notify the TreeModel in order to update the views. + * + * @param child The child added. + */ + void childInserted(TreeItem* child); + + /** + * Emitted just before a child is removed. + * It is used to notify the TreeModel in order to update the views. + * + * @param child The child to be removed. + */ + void childAboutToBeRemoved(TreeItem* child); + + /** + * Emitted after a child is removed. + * It is used to notify the TreeModel in order to update the views. + * + * @param child The child removed. + */ + void childRemoved(TreeItem* child); + + /** + * Emitted when the data to be used by the TreeModel changes. + * It is used to notify the TreeModel in order to update the views. + * + * It must be emitted by subclasses as needed. + * + * @param item This TreeItem. + */ + void dataChanged(TreeItem* item); + private: /** Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp 2010-03-05 23:48:40 UTC (rev 111) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TextTreeItemTest.cpp 2010-03-06 17:11:26 UTC (rev 112) @@ -39,11 +39,23 @@ QCOMPARE(treeItem.parent(), &parent); } +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + void TextTreeItemTest::testSetText() { TextTreeItem item; + + //TreeItem* must be registered in order to be used with QSignalSpy + int treeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + item.setText("Hello world"); QCOMPARE(item.text(), QString("Hello world")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), treeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), &item); } QTEST_MAIN(TextTreeItemTest) Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp 2010-03-05 23:48:40 UTC (rev 111) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemTest.cpp 2010-03-06 17:11:26 UTC (rev 112) @@ -25,6 +25,8 @@ private slots: + void initTestCase(); + void testConstructor(); void testAppendChild(); @@ -36,6 +38,15 @@ void testRemoveChild(); void testRemoveChildSeveralChildren(); +private: + + int mTreeItemStarType; + + void assertAboutToBeInsertedSignal(const QSignalSpy& spy, int index, + TreeItem* item, int itemIndex) const; + + void assertSignal(const QSignalSpy& spy, int index, TreeItem* item) const; + }; class StubTreeItem: public TreeItem { @@ -52,6 +63,11 @@ }; +void TreeItemTest::initTestCase() { + //TreeItem* must be registered in order to be used with QSignalSpy + mTreeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); +} + void TreeItemTest::testConstructor() { StubTreeItem parent; StubTreeItem treeItem(&parent); @@ -60,16 +76,32 @@ QCOMPARE(treeItem.parent(), &parent); } +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + void TreeItemTest::testAppendChild() { StubTreeItem treeItem; TreeItem* child = new StubTreeItem(&treeItem); + QSignalSpy aboutToBeInsertedSpy(&treeItem, + SIGNAL(childAboutToBeInserted(TreeItem*, int))); + QSignalSpy insertedSpy(&treeItem, SIGNAL(childInserted(TreeItem*))); + treeItem.appendChild(child); QCOMPARE(treeItem.childCount(), 1); QCOMPARE(treeItem.child(0), child); QCOMPARE(child->childIndex(), 0); QCOMPARE(child->parent(), &treeItem); + + //The proper way to check this would be asserting not only that the signals + //were emitted, but that when they were emitted the item wasn't and was + //already added (depending on the signal). However, that is too much effort + //for little gain. + QCOMPARE(aboutToBeInsertedSpy.count(), 1); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 0, child, 0); + QCOMPARE(insertedSpy.count(), 1); + assertSignal(insertedSpy, 0, child); } void TreeItemTest::testAppendChildSeveralChildren() { @@ -78,6 +110,10 @@ TreeItem* child2 = new StubTreeItem(&treeItem); TreeItem* child3 = new StubTreeItem(&treeItem); + QSignalSpy aboutToBeInsertedSpy(&treeItem, + SIGNAL(childAboutToBeInserted(TreeItem*, int))); + QSignalSpy insertedSpy(&treeItem, SIGNAL(childInserted(TreeItem*))); + treeItem.appendChild(child1); treeItem.appendChild(child2); treeItem.appendChild(child3); @@ -92,18 +128,36 @@ QCOMPARE(child2->parent(), &treeItem); QCOMPARE(child3->childIndex(), 2); QCOMPARE(child3->parent(), &treeItem); + + QCOMPARE(aboutToBeInsertedSpy.count(), 3); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 0, child1, 0); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 1, child2, 1); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 2, child3, 2); + QCOMPARE(insertedSpy.count(), 3); + assertSignal(insertedSpy, 0, child1); + assertSignal(insertedSpy, 1, child2); + assertSignal(insertedSpy, 2, child3); } void TreeItemTest::testInsertChild() { StubTreeItem treeItem; TreeItem* child = new StubTreeItem(&treeItem); + QSignalSpy aboutToBeInsertedSpy(&treeItem, + SIGNAL(childAboutToBeInserted(TreeItem*, int))); + QSignalSpy insertedSpy(&treeItem, SIGNAL(childInserted(TreeItem*))); + treeItem.insertChild(child, 0); QCOMPARE(treeItem.childCount(), 1); QCOMPARE(treeItem.child(0), child); QCOMPARE(child->childIndex(), 0); QCOMPARE(child->parent(), &treeItem); + + QCOMPARE(aboutToBeInsertedSpy.count(), 1); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 0, child, 0); + QCOMPARE(insertedSpy.count(), 1); + assertSignal(insertedSpy, 0, child); } void TreeItemTest::testInsertChildSeveralChildren() { @@ -113,6 +167,10 @@ TreeItem* child3 = new StubTreeItem(&treeItem); TreeItem* child4 = new StubTreeItem(&treeItem); + QSignalSpy aboutToBeInsertedSpy(&treeItem, + SIGNAL(childAboutToBeInserted(TreeItem*, int))); + QSignalSpy insertedSpy(&treeItem, SIGNAL(childInserted(TreeItem*))); + treeItem.insertChild(child2, 0); treeItem.insertChild(child1, 0); treeItem.insertChild(child4, 2); @@ -131,6 +189,17 @@ QCOMPARE(child3->parent(), &treeItem); QCOMPARE(child4->childIndex(), 3); QCOMPARE(child4->parent(), &treeItem); + + QCOMPARE(aboutToBeInsertedSpy.count(), 4); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 0, child2, 0); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 1, child1, 0); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 2, child4, 2); + assertAboutToBeInsertedSignal(aboutToBeInsertedSpy, 3, child3, 2); + QCOMPARE(insertedSpy.count(), 4); + assertSignal(insertedSpy, 0, child2); + assertSignal(insertedSpy, 1, child1); + assertSignal(insertedSpy, 2, child4); + assertSignal(insertedSpy, 3, child3); } void TreeItemTest::testRemoveChild() { @@ -139,12 +208,21 @@ //stack StubTreeItem child(&treeItem); + QSignalSpy aboutToBeRemovedSpy(&treeItem, + SIGNAL(childAboutToBeRemoved(TreeItem*))); + QSignalSpy removedSpy(&treeItem, SIGNAL(childRemoved(TreeItem*))); + treeItem.appendChild(&child); treeItem.removeChild(&child); QCOMPARE(treeItem.childCount(), 0); QCOMPARE(child.childIndex(), -1); QCOMPARE(child.parent(), &treeItem); + + QCOMPARE(aboutToBeRemovedSpy.count(), 1); + assertSignal(aboutToBeRemovedSpy, 0, &child); + QCOMPARE(removedSpy.count(), 1); + assertSignal(removedSpy, 0, &child); } void TreeItemTest::testRemoveChildSeveralChildren() { @@ -155,6 +233,10 @@ StubTreeItem child2(&treeItem); StubTreeItem child3(&treeItem); + QSignalSpy aboutToBeRemovedSpy(&treeItem, + SIGNAL(childAboutToBeRemoved(TreeItem*))); + QSignalSpy removedSpy(&treeItem, SIGNAL(childRemoved(TreeItem*))); + treeItem.appendChild(&child1); treeItem.appendChild(&child2); treeItem.appendChild(&child3); @@ -171,6 +253,11 @@ QCOMPARE(child3.childIndex(), 1); QCOMPARE(child3.parent(), &treeItem); + QCOMPARE(aboutToBeRemovedSpy.count(), 1); + assertSignal(aboutToBeRemovedSpy, 0, &child2); + QCOMPARE(removedSpy.count(), 1); + assertSignal(removedSpy, 0, &child2); + treeItem.removeChild(&child1); treeItem.removeChild(&child3); @@ -181,8 +268,40 @@ QCOMPARE(child2.parent(), &treeItem); QCOMPARE(child3.childIndex(), -1); QCOMPARE(child3.parent(), &treeItem); + + QCOMPARE(aboutToBeRemovedSpy.count(), 3); + assertSignal(aboutToBeRemovedSpy, 1, &child1); + assertSignal(aboutToBeRemovedSpy, 2, &child3); + QCOMPARE(removedSpy.count(), 3); + assertSignal(removedSpy, 1, &child1); + assertSignal(removedSpy, 2, &child3); } +/////////////////////////////////// Helpers //////////////////////////////////// + +void TreeItemTest::assertAboutToBeInsertedSignal(const QSignalSpy& spy, + int index, TreeItem* item, + int itemIndex) const { + QCOMPARE(spy.at(index).count(), 2); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); + + argument = spy.at(index).at(1); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), itemIndex); +} + +void TreeItemTest::assertSignal(const QSignalSpy& spy, int index, + TreeItem* item) const { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); +} + QTEST_MAIN(TreeItemTest) #include "TreeItemTest.moc" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-06 17:12:55
|
Revision: 113 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=113&view=rev Author: danxuliu Date: 2010-03-06 17:12:46 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Watch the signals emitted by the TreeItems added to a TreeModel and notify the views to be updated as needed. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp 2010-03-06 17:11:26 UTC (rev 112) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp 2010-03-06 17:12:46 UTC (rev 113) @@ -26,6 +26,8 @@ QAbstractItemModel(parent), mRootItem(rootItem) { Q_ASSERT(rootItem); + + registerTreeItemForUpdates(rootItem); } TreeModel::~TreeModel() { @@ -114,3 +116,79 @@ return 1; } + +//private: + +void TreeModel::registerTreeItemForUpdates(TreeItem* item) { + connect(item, SIGNAL(childAboutToBeInserted(TreeItem*, int)), + this, SLOT(treeItemAboutToBeInserted(TreeItem*, int))); + connect(item, SIGNAL(childInserted(TreeItem*)), + this, SLOT(treeItemInserted(TreeItem*))); + connect(item, SIGNAL(childAboutToBeRemoved(TreeItem*)), + this, SLOT(treeItemAboutToBeRemoved(TreeItem*))); + connect(item, SIGNAL(childRemoved(TreeItem*)), + this, SLOT(treeItemRemoved(TreeItem*))); + connect(item, SIGNAL(dataChanged(TreeItem*)), + this, SLOT(treeItemDataChanged(TreeItem*))); + + for (int i=0; i<item->childCount(); ++i) { + registerTreeItemForUpdates(item->child(i)); + } +} + +void TreeModel::deregisterTreeItemFromUpdates(TreeItem* item) { + disconnect(item, SIGNAL(childAboutToBeInserted(TreeItem*, int)), + this, SLOT(treeItemAboutToBeInserted(TreeItem*, int))); + disconnect(item, SIGNAL(childInserted(TreeItem*)), + this, SLOT(treeItemInserted(TreeItem*))); + disconnect(item, SIGNAL(childAboutToBeRemoved(TreeItem*)), + this, SLOT(treeItemAboutToBeRemoved(TreeItem*))); + disconnect(item, SIGNAL(childRemoved(TreeItem*)), + this, SLOT(treeItemRemoved(TreeItem*))); + disconnect(item, SIGNAL(dataChanged(TreeItem*)), + this, SLOT(treeItemDataChanged(TreeItem*))); + + for (int i=0; i<item->childCount(); ++i) { + deregisterTreeItemFromUpdates(item->child(i)); + } +} + +QModelIndex TreeModel::getParentIndex(TreeItem* item) { + QModelIndex parent; + + if (item->parent() != mRootItem) { + parent = createIndex(item->parent()->childIndex(), 0, item->parent()); + } + + return parent; +} + +//private slots: + +void TreeModel::treeItemAboutToBeInserted(TreeItem* item, int treeItemIndex) { + beginInsertRows(getParentIndex(item), treeItemIndex, treeItemIndex); +} + +void TreeModel::treeItemInserted(TreeItem* item) { + endInsertRows(); + + registerTreeItemForUpdates(item); +} + +void TreeModel::treeItemAboutToBeRemoved(TreeItem* item) { + int treeItemIndex = item->childIndex(); + + beginRemoveRows(getParentIndex(item), treeItemIndex, treeItemIndex); +} + +void TreeModel::treeItemRemoved(TreeItem* item) { + deregisterTreeItemFromUpdates(item); + + endRemoveRows(); +} + +void TreeModel::treeItemDataChanged(TreeItem* item) { + QModelIndex index = createIndex(item->childIndex(), 0, item); + + emit dataChanged(index, index); +} Modified: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h 2010-03-06 17:11:26 UTC (rev 112) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeModel.h 2010-03-06 17:12:46 UTC (rev 113) @@ -40,6 +40,9 @@ * Each TreeItem provides the data to be shown by its associated model item. * Display role shows the text of the TreeItem. * + * Changes in the tree layout or data provided by the TreeItems are notified to + * the views, so they can be updated as needed. + * * @see TreeItem */ class TreeModel: public QAbstractItemModel { @@ -145,6 +148,70 @@ */ TreeItem* mRootItem; + /** + * Starts watching changes in the given item and its children. + * When something change in a registered item (the data is modified, a child + * is added or a child is removed), the views are notified so they can be + * updated as needed. + * + * @param item The item to register. + */ + void registerTreeItemForUpdates(TreeItem* item); + + /** + * Stops watching changes in the given item and its children. + * + * @param item The item to deregister. + */ + void deregisterTreeItemFromUpdates(TreeItem* item); + + /** + * Returns the index for the parent of the given item. + * + * @param item The item to get the index of its parent. + * @return The parent index. + */ + QModelIndex getParentIndex(TreeItem* item); + +private Q_SLOTS: + + /** + * Notifies the views that the given item is going to be added. + * + * @param item The item that is going to be added. + * @param treeItemIndex The index in the parent item where the item is going + * to be added. + */ + void treeItemAboutToBeInserted(TreeItem* item, int treeItemIndex); + + /** + * Notifies the views that the given item has been added, + * + * @param item The item added. + */ + void treeItemInserted(TreeItem* item); + + /** + * Notifies the views that the given item is going to be removed. + * + * @param item The item that is going to be removed. + */ + void treeItemAboutToBeRemoved(TreeItem* item); + + /** + * Notifies the views that the given item has been removed. + * + * @param item The item removed. + */ + void treeItemRemoved(TreeItem* item); + + /** + * Notifies the views about a change in the data of the given item. + * + * @param item The item that changed. + */ + void treeItemDataChanged(TreeItem* item); + }; #endif Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp 2010-03-06 17:11:26 UTC (rev 112) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp 2010-03-06 17:12:46 UTC (rev 113) @@ -27,6 +27,8 @@ private slots: + void initTestCase(); + void init(); void cleanup(); @@ -36,6 +38,18 @@ void testConstructorSingleNestedItem(); void testConstructorSeveralNestedItems(); + void testAppendTopLevelItem(); + void testInsertTopLevelItem(); + void testRemoveTopLevelItem(); + + void testChangeChildrenOfNestedItemAddedBeforeConstructor(); + void testChangeChildrenOfNestedItemAddedAfterConstructor(); + + void testChangeChildrenOfRemovedItem(); + void testChangeChildrenOfRemovedNestedItem(); + + void testChangeItemData(); + void testDataWithInvalidIndex(); void testDataWithInvalidRole(); @@ -51,6 +65,8 @@ private: + int mModelIndexType; + TreeItem* mEmptyRootItem; TreeItem* mSingleItem; TreeItem* mSeveralFlatItems; @@ -60,9 +76,13 @@ void assertItem(const QModelIndex& index, const QString& displayRoleData, int childrenCount, const QModelIndex& parent) const; + void assertSignal(const QSignalSpy& spy, int signalIndex, + const QModelIndex& index, int row) const; + }; class StubTreeItem: public TreeItem { +Q_OBJECT public: QString mText; @@ -76,8 +96,19 @@ return mText; } + void setText(const QString& text) { + mText = text; + + emit dataChanged(this); + } + }; +void TreeModelTest::initTestCase() { + //QModelIndex must be registered in order to be used with QSignalSpy + mModelIndexType = qRegisterMetaType<QModelIndex>("QModelIndex"); +} + void TreeModelTest::init() { mEmptyRootItem = new StubTreeItem("root"); @@ -202,6 +233,289 @@ assertItem(index, "root-3-2", 0, parent); } +//QModelIndex must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(QModelIndex); + +void TreeModelTest::testAppendTopLevelItem() { + TreeItem* rootItem = mEmptyRootItem; + mEmptyRootItem = 0; + + TreeModel model(rootItem); + + QSignalSpy aboutToSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + + rootItem->appendChild(new StubTreeItem("root-1", rootItem)); + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 0, QModelIndex()); + + //The proper way to check this would be asserting not only that the signals + //were emitted, but that when they were emitted the item wasn't and was + //already added (depending on the signal). However, that is too much effort + //for little gain. + QCOMPARE(aboutToSpy.count(), 1); + assertSignal(aboutToSpy, 0, QModelIndex(), 0); + QCOMPARE(insertedSpy.count(), 1); + assertSignal(insertedSpy, 0, QModelIndex(), 0); +} + +void TreeModelTest::testInsertTopLevelItem() { + TreeItem* rootItem = mSeveralFlatItems; + mSeveralFlatItems = 0; + + TreeModel model(rootItem); + + QSignalSpy aboutToSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + + rootItem->insertChild(new StubTreeItem("root-2new", rootItem), 1); + + QCOMPARE(model.rowCount(), 4); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 0, QModelIndex()); + + index = model.index(1, 0); + assertItem(index, "root-2new", 0, QModelIndex()); + + index = model.index(2, 0); + assertItem(index, "root-2", 0, QModelIndex()); + + index = model.index(3, 0); + assertItem(index, "root-3", 0, QModelIndex()); + + QCOMPARE(aboutToSpy.count(), 1); + assertSignal(aboutToSpy, 0, QModelIndex(), 1); + QCOMPARE(insertedSpy.count(), 1); + assertSignal(insertedSpy, 0, QModelIndex(), 1); +} + +void TreeModelTest::testRemoveTopLevelItem() { + TreeItem* rootItem = mSeveralFlatItems; + mSeveralFlatItems = 0; + + TreeModel model(rootItem); + + QSignalSpy aboutToSpy(&model, + SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int))); + QSignalSpy removedSpy(&model, SIGNAL(rowsRemoved(QModelIndex, int, int))); + + TreeItem* itemToBeRemoved = rootItem->child(1); + rootItem->removeChild(itemToBeRemoved); + delete itemToBeRemoved; + + QCOMPARE(model.rowCount(), 2); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 0, QModelIndex()); + + index = model.index(1, 0); + assertItem(index, "root-3", 0, QModelIndex()); + + QCOMPARE(aboutToSpy.count(), 1); + assertSignal(aboutToSpy, 0, QModelIndex(), 1); + QCOMPARE(removedSpy.count(), 1); + assertSignal(removedSpy, 0, QModelIndex(), 1); +} + + +void TreeModelTest::testChangeChildrenOfNestedItemAddedBeforeConstructor() { + TreeItem* rootItem = mSingleNestedItem; + mSingleNestedItem = 0; + + TreeModel model(rootItem); + TreeItem* item = rootItem->child(0)->child(0); + + QSignalSpy aboutToInsertSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + QSignalSpy aboutToRemoveSpy(&model, + SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int))); + QSignalSpy removedSpy(&model, SIGNAL(rowsRemoved(QModelIndex, int, int))); + + StubTreeItem childToBeRemoved("root-1-1-3", item); + item->appendChild(new StubTreeItem("root-1-1-1", item)); + item->appendChild(&childToBeRemoved); + item->insertChild(new StubTreeItem("root-1-1-2", item), 1); + item->removeChild(&childToBeRemoved); + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 1, QModelIndex()); + + QModelIndex parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1", 2, parent); + + parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1-1", 0, parent); + + index = model.index(1, 0, parent); + assertItem(index, "root-1-1-2", 0, parent); + + QCOMPARE(aboutToInsertSpy.count(), 3); + assertSignal(aboutToInsertSpy, 0, parent, 0); + assertSignal(aboutToInsertSpy, 1, parent, 1); + assertSignal(aboutToInsertSpy, 2, parent, 1); + QCOMPARE(insertedSpy.count(), 3); + assertSignal(insertedSpy, 0, parent, 0); + assertSignal(insertedSpy, 1, parent, 1); + assertSignal(insertedSpy, 2, parent, 1); + QCOMPARE(aboutToRemoveSpy.count(), 1); + assertSignal(aboutToRemoveSpy, 0, parent, 2); + QCOMPARE(removedSpy.count(), 1); + assertSignal(removedSpy, 0, parent, 2); +} + +void TreeModelTest::testChangeChildrenOfNestedItemAddedAfterConstructor() { + TreeItem* rootItem = mEmptyRootItem; + mEmptyRootItem = 0; + + TreeModel model(rootItem); + rootItem->appendChild(new StubTreeItem("root-1", rootItem)); + + TreeItem* item = new StubTreeItem("root-1-1", rootItem->child(0)); + rootItem->child(0)->appendChild(item); + + QSignalSpy aboutToInsertSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + QSignalSpy aboutToRemoveSpy(&model, + SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int))); + QSignalSpy removedSpy(&model, SIGNAL(rowsRemoved(QModelIndex, int, int))); + + StubTreeItem childToBeRemoved("root-1-1-3", item); + item->appendChild(new StubTreeItem("root-1-1-1", item)); + item->appendChild(&childToBeRemoved); + item->insertChild(new StubTreeItem("root-1-1-2", item), 1); + item->removeChild(&childToBeRemoved); + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1", 1, QModelIndex()); + + QModelIndex parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1", 2, parent); + + parent = index; + index = model.index(0, 0, parent); + assertItem(index, "root-1-1-1", 0, parent); + + index = model.index(1, 0, parent); + assertItem(index, "root-1-1-2", 0, parent); + + QCOMPARE(aboutToInsertSpy.count(), 3); + assertSignal(aboutToInsertSpy, 0, parent, 0); + assertSignal(aboutToInsertSpy, 1, parent, 1); + assertSignal(aboutToInsertSpy, 2, parent, 1); + QCOMPARE(insertedSpy.count(), 3); + assertSignal(insertedSpy, 0, parent, 0); + assertSignal(insertedSpy, 1, parent, 1); + assertSignal(insertedSpy, 2, parent, 1); + QCOMPARE(aboutToRemoveSpy.count(), 1); + assertSignal(aboutToRemoveSpy, 0, parent, 2); + QCOMPARE(removedSpy.count(), 1); + assertSignal(removedSpy, 0, parent, 2); +} + +void TreeModelTest::testChangeChildrenOfRemovedItem() { + TreeItem* rootItem = mEmptyRootItem; + mEmptyRootItem = 0; + + TreeModel model(rootItem); + + StubTreeItem item("root-1", rootItem); + rootItem->appendChild(&item); + rootItem->removeChild(&item); + + QSignalSpy aboutToSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + + item.appendChild(new StubTreeItem("root-1-1", &item)); + + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QCOMPARE(aboutToSpy.count(), 0); + QCOMPARE(insertedSpy.count(), 0); +} + +void TreeModelTest::testChangeChildrenOfRemovedNestedItem() { + TreeItem* rootItem = mEmptyRootItem; + mEmptyRootItem = 0; + + TreeModel model(rootItem); + + StubTreeItem item("root-1", rootItem); + TreeItem* nestedItem = new StubTreeItem("root-1-1", &item); + item.appendChild(nestedItem); + rootItem->appendChild(&item); + rootItem->removeChild(&item); + + QSignalSpy aboutToSpy(&model, + SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int))); + QSignalSpy insertedSpy(&model, SIGNAL(rowsInserted(QModelIndex, int, int))); + + nestedItem->appendChild(new StubTreeItem("root-1-1-1", nestedItem)); + + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QCOMPARE(aboutToSpy.count(), 0); + QCOMPARE(insertedSpy.count(), 0); +} + +void TreeModelTest::testChangeItemData() { + TreeItem* rootItem = mEmptyRootItem; + mEmptyRootItem = 0; + + StubTreeItem* item = new StubTreeItem("root-1", rootItem); + rootItem->appendChild(item); + TreeModel model(rootItem); + + QSignalSpy dataChangedSpy(&model, + SIGNAL(dataChanged(QModelIndex, QModelIndex))); + + item->setText("root-1modified"); + + QCOMPARE(model.rowCount(), 1); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("root")); + + QModelIndex index = model.index(0, 0); + assertItem(index, "root-1modified", 0, QModelIndex()); + + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), mModelIndexType); + QCOMPARE(qvariant_cast<QModelIndex>(argument), index); + argument = dataChangedSpy.at(0).at(1); + QCOMPARE(argument.userType(), mModelIndexType); + QCOMPARE(qvariant_cast<QModelIndex>(argument), index); +} + void TreeModelTest::testDataWithInvalidIndex() { TreeModel model(mSingleItem); mSingleItem = 0; @@ -290,6 +604,23 @@ QCOMPARE(model->columnCount(index), 1); } +void TreeModelTest::assertSignal(const QSignalSpy& spy, int signalIndex, + const QModelIndex& index, int row) const { + QCOMPARE(spy.at(signalIndex).count(), 3); + + QVariant argument = spy.at(signalIndex).at(0); + QCOMPARE(argument.userType(), mModelIndexType); + QCOMPARE(qvariant_cast<QModelIndex>(argument), index); + + argument = spy.at(signalIndex).at(1); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), row); + + argument = spy.at(signalIndex).at(2); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), row); +} + QTEST_MAIN(TreeModelTest) #include "TreeModelTest.moc" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-06 20:52:36
|
Revision: 114 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=114&view=rev Author: danxuliu Date: 2010-03-06 20:52:29 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Add basic version of Tutorial class to store the data of a tutorial. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp trunk/ktutorial/ktutorial-editor/src/Tutorial.h trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-06 17:12:46 UTC (rev 113) +++ trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-06 20:52:29 UTC (rev 114) @@ -8,6 +8,7 @@ set(ktutorial_editor_SRCS KTutorialEditor.cpp + Tutorial.cpp ) # Instead of compiling the executable directly from the sources, the sources are Added: trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-06 20:52:29 UTC (rev 114) @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "Tutorial.h" + +#include <QStringList> + +//public: + +Tutorial::Tutorial(QObject* parent) { +} + +QString Tutorial::id() const { + return toLowerCamelCase(mName); +} + +QString Tutorial::name() const { + return mName; +} + +void Tutorial::setName(const QString& name) { + mName = name; + + emit dataChanged(this); +} + +QString Tutorial::description() const { + return mDescription; +} + +void Tutorial::setDescription(const QString& description) { + mDescription = description; + + emit dataChanged(this); +} + +QString Tutorial::licenseText() const { + return mLicenseText; +} + +void Tutorial::setLicenseText(const QString& licenseText) { + mLicenseText = licenseText; + + emit dataChanged(this); +} + +QString Tutorial::customSetupCode() const { + return mCustomSetupCode; +} + +void Tutorial::setCustomSetupCode(const QString& code) { + mCustomSetupCode = code; + + emit dataChanged(this); +} + +QString Tutorial::customTearDownCode() const { + return mCustomTearDownCode; +} + +void Tutorial::setCustomTearDownCode(const QString& code) { + mCustomTearDownCode = code; + + emit dataChanged(this); +} + +//private: + +QString Tutorial::toLowerCamelCase(const QString& text) const { + QStringList words = text.split(' ', QString::SkipEmptyParts); + + QString lowerCamelCase; + words[0][0] = words[0][0].toLower(); + lowerCamelCase += words[0]; + + for (int i=1; i<words.count(); ++i) { + words[i][0] = words[i][0].toUpper(); + lowerCamelCase += words[i]; + } + + return lowerCamelCase; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/Tutorial.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.h 2010-03-06 20:52:29 UTC (rev 114) @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TUTORIAL_H +#define TUTORIAL_H + +#include <QObject> + +/** + * Container for tutorial data. + * It stores the data used in KTutorial tutorials, but it has nothing to do with + * it (they don't even know each other). Its purpose is store the data needed to + * generate the code to create a true KTutorial::Tutorial. + * + * When any attribute is modified, dataChanged(Tutorial*) signal is emitted. + */ +class Tutorial: public QObject { +Q_OBJECT +public: + + Tutorial(QObject* parent = 0); + + /** + * Returns the id of this Tutorial. + * The id is a lowerCamelCase version of the name. + * + * @return The id of this Tutorial. + */ + QString id() const; + + QString name() const; + void setName(const QString& name); + + QString description() const; + void setDescription(const QString& description); + + QString licenseText() const; + void setLicenseText(const QString& licenseText); + + QString customSetupCode() const; + void setCustomSetupCode(const QString& code); + + QString customTearDownCode() const; + void setCustomTearDownCode(const QString& code); + +Q_SIGNALS: + + /** + * Emitted when any data in the tutorial changed. + * + * @param tutorial This tutorial. + */ + void dataChanged(Tutorial* tutorial); + +private: + + QString mName; + QString mDescription; + QString mLicenseText; + QString mCustomSetupCode; + QString mCustomTearDownCode; + + /** + * Returns the lowerCamelCase version of the given text. + * + * @param text The string to get its lowerCamelCase version. + * @return The lowerCamelCase version of the text. + */ + QString toLowerCamelCase(const QString& text) const; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/Tutorial.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-06 17:12:46 UTC (rev 113) +++ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-06 20:52:29 UTC (rev 114) @@ -1 +1,25 @@ add_subdirectory(view) + +# Used by kde4_add_unit_test to set the full path to test executables +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}) + +# include_directories(${CMAKE_CURRENT_BINARY_DIR} ${ktutorial-editor_SOURCE_DIR}/src/view ${ktutorial-editor_BINARY_DIR}/src/view ${KDE4_INCLUDES}) +include_directories(${ktutorial-editor_SOURCE_DIR}/src/ ${KDE4_INCLUDES}) + +MACRO(UNIT_TESTS) + FOREACH(_className ${ARGN}) + set(_testName ${_className}Test) + kde4_add_unit_test(${_testName} TESTNAME ktutorial-editor-unit-${_testName} ${_testName}.cpp) + target_link_libraries(${_testName} ktutorial_editor ${QT_QTTEST_LIBRARY}) + ENDFOREACH(_className) +ENDMACRO(UNIT_TESTS) + +unit_tests(Tutorial) + +MACRO(MEM_TESTS) + FOREACH(_testname ${ARGN}) + add_test(ktutorial-editor-unit-mem-${_testname} ${CMAKE_CURRENT_SOURCE_DIR}/../runMemcheck.py ${CMAKE_CURRENT_BINARY_DIR}/${_testname}Test ${CMAKE_CURRENT_BINARY_DIR}) + ENDFOREACH(_testname) +ENDMACRO(MEM_TESTS) + +mem_tests(Tutorial) Added: trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-06 20:52:29 UTC (rev 114) @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "Tutorial.h" + +class TutorialTest: public QObject { +Q_OBJECT + +private slots: + + void testId(); + + void testSetName(); + + void testSetDescription(); + + void testSetLicenseText(); + + void testSetCustomSetupCode(); + + void testSetCustomTearDownCode(); + +}; + +void TutorialTest::testId() { + Tutorial tutorial; + tutorial.setName("ThE name of a tutoRial"); + + QCOMPARE(tutorial.id(), QString("thENameOfATutoRial")); +} + +//Tutorial* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(Tutorial*); + +void TutorialTest::testSetName() { + Tutorial tutorial; + + //Tutorial* must be registered in order to be used with QSignalSpy + int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + QSignalSpy dataChangedSpy(&tutorial, SIGNAL(dataChanged(Tutorial*))); + + tutorial.setName("The name"); + + QCOMPARE(tutorial.name(), QString("The name")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), tutorialStarType); + QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); +} + +void TutorialTest::testSetDescription() { + Tutorial tutorial; + + //Tutorial* must be registered in order to be used with QSignalSpy + int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + QSignalSpy dataChangedSpy(&tutorial, SIGNAL(dataChanged(Tutorial*))); + + tutorial.setDescription("The description"); + + QCOMPARE(tutorial.description(), QString("The description")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), tutorialStarType); + QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); +} + +void TutorialTest::testSetLicenseText() { + Tutorial tutorial; + + //Tutorial* must be registered in order to be used with QSignalSpy + int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + QSignalSpy dataChangedSpy(&tutorial, SIGNAL(dataChanged(Tutorial*))); + + tutorial.setLicenseText("The license text"); + + QCOMPARE(tutorial.licenseText(), QString("The license text")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), tutorialStarType); + QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); +} + +void TutorialTest::testSetCustomSetupCode() { + Tutorial tutorial; + + //Tutorial* must be registered in order to be used with QSignalSpy + int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + QSignalSpy dataChangedSpy(&tutorial, SIGNAL(dataChanged(Tutorial*))); + + tutorial.setCustomSetupCode("The setup code"); + + QCOMPARE(tutorial.customSetupCode(), QString("The setup code")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), tutorialStarType); + QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); +} + +void TutorialTest::testSetCustomTearDownCode() { + Tutorial tutorial; + + //Tutorial* must be registered in order to be used with QSignalSpy + int tutorialStarType = qRegisterMetaType<Tutorial*>("Tutorial*"); + QSignalSpy dataChangedSpy(&tutorial, SIGNAL(dataChanged(Tutorial*))); + + tutorial.setCustomTearDownCode("The tear down code"); + + QCOMPARE(tutorial.customTearDownCode(), QString("The tear down code")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), tutorialStarType); + QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); +} + +QTEST_MAIN(TutorialTest) + +#include "TutorialTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-06 22:53:00
|
Revision: 115 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=115&view=rev Author: danxuliu Date: 2010-03-06 22:52:52 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Fix crash when an empty string or a spaces only string is converted to lowerCamelCase. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-06 20:52:29 UTC (rev 114) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-06 22:52:52 UTC (rev 115) @@ -84,6 +84,10 @@ QString Tutorial::toLowerCamelCase(const QString& text) const { QStringList words = text.split(' ', QString::SkipEmptyParts); + if (words.count() == 0) { + return ""; + } + QString lowerCamelCase; words[0][0] = words[0][0].toLower(); lowerCamelCase += words[0]; Modified: trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-06 20:52:29 UTC (rev 114) +++ trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-06 22:52:52 UTC (rev 115) @@ -26,6 +26,8 @@ private slots: void testId(); + void testIdWithEmptyName(); + void testIdWithSpaceName(); void testSetName(); @@ -46,6 +48,20 @@ QCOMPARE(tutorial.id(), QString("thENameOfATutoRial")); } +void TutorialTest::testIdWithEmptyName() { + Tutorial tutorial; + tutorial.setName(""); + + QCOMPARE(tutorial.id(), QString("")); +} + +void TutorialTest::testIdWithSpaceName() { + Tutorial tutorial; + tutorial.setName(" "); + + QCOMPARE(tutorial.id(), QString("")); +} + //Tutorial* must be declared as a metatype to be used in qvariant_cast Q_DECLARE_METATYPE(Tutorial*); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-07 07:21:24
|
Revision: 117 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=117&view=rev Author: danxuliu Date: 2010-03-07 07:21:18 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Add TutorialTreeItem class to show a Tutorial in a TreeModel. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-07 06:21:19 UTC (rev 116) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-07 07:21:18 UTC (rev 117) @@ -4,8 +4,9 @@ TextTreeItem.cpp TreeItem.cpp TreeModel.cpp + TutorialTreeItem.cpp ) kde4_add_library(ktutorial_editor_view ${ktutorial_editor_view_SRCS}) -target_link_libraries(ktutorial_editor_view ${KDE4_KDEUI_LIBS}) +target_link_libraries(ktutorial_editor_view ktutorial_editor ${KDE4_KDEUI_LIBS}) Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp 2010-03-07 07:21:18 UTC (rev 117) @@ -0,0 +1,150 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialTreeItem.h" + +#include <KLocalizedString> + +#include "TextTreeItem.h" +#include "../Tutorial.h" + +//public: + +TutorialTreeItem::TutorialTreeItem(Tutorial* tutorial, TreeItem* parent): + TreeItem(parent) { + Q_ASSERT(tutorial); + + mNameItem = 0; + mDescriptionItem = 0; + mLicenseItem = 0; + mSetupItem = 0; + mTearDownItem = 0; + + update(tutorial); + connect(tutorial, SIGNAL(dataChanged(Tutorial*)), + this, SLOT(update(Tutorial*))); +} + +QString TutorialTreeItem::text() const { + if (mTutorialId.isEmpty()) { + return i18nc("@item", "Tutorial"); + } + + return i18nc("@item", "Tutorial %1", mTutorialId); +} + +//private slots: + +void TutorialTreeItem::update(Tutorial* tutorial) { + int childIndex = 0; + + if (tutorial->name().isEmpty()) { + removeFlatItemIfNeeded(mNameItem); + + if (!mTutorialId.isEmpty()) { + mTutorialId = QString(); + emit dataChanged(this); + } + } else { + addFlatItemIfNeeded(mNameItem, childIndex); + mNameItem->setText(i18nc("@item", "Name: %1", tutorial->name())); + + mTutorialId = tutorial->id(); + emit dataChanged(this); + + childIndex++; + } + + if (tutorial->description().isEmpty()) { + removeFlatItemIfNeeded(mDescriptionItem); + } else { + addFlatItemIfNeeded(mDescriptionItem, childIndex); + mDescriptionItem->setText(i18nc("@item", "Description: %1", + tutorial->description())); + + childIndex++; + } + + if (tutorial->licenseText().isEmpty()) { + removeNestedItemIfNeeded(mLicenseItem); + } else { + addNestedItemIfNeeded(mLicenseItem, childIndex, + i18nc("@item", "License:")); + mLicenseItem->setText(tutorial->licenseText()); + + childIndex++; + } + + if (tutorial->customSetupCode().isEmpty()) { + removeNestedItemIfNeeded(mSetupItem); + } else { + addNestedItemIfNeeded(mSetupItem, childIndex, + i18nc("@item", "Setup:")); + mSetupItem->setText(tutorial->customSetupCode()); + + childIndex++; + } + + if (tutorial->customTearDownCode().isEmpty()) { + removeNestedItemIfNeeded(mTearDownItem); + } else { + addNestedItemIfNeeded(mTearDownItem, childIndex, + i18nc("@item", "Tear down:")); + mTearDownItem->setText(tutorial->customTearDownCode()); + + childIndex++; + } +} + +void TutorialTreeItem::addFlatItemIfNeeded(TextTreeItem*& item, + int childIndex) { + if (item == 0) { + item = new TextTreeItem(this); + insertChild(item, childIndex); + } +} + +void TutorialTreeItem::removeFlatItemIfNeeded(TextTreeItem*& item) { + if (item != 0) { + removeChild(item); + delete item; + item = 0; + } +} + +void TutorialTreeItem::addNestedItemIfNeeded(TextTreeItem*& item, + int childIndex, + const QString& parentText) { + if (item == 0) { + TextTreeItem* parentItem = new TextTreeItem(this); + parentItem->setText(parentText); + + item = new TextTreeItem(parentItem); + parentItem->appendChild(item); + + insertChild(parentItem, childIndex); + } +} + +void TutorialTreeItem::removeNestedItemIfNeeded(TextTreeItem*& item) { + if (item != 0) { + removeChild(item->parent()); + delete item->parent(); + item = 0; + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h 2010-03-07 07:21:18 UTC (rev 117) @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TUTORIALTREEITEM_H +#define TUTORIALTREEITEM_H + +#include "TreeItem.h" + +class TextTreeItem; +class Tutorial; + +/** + * A TreeItem that represents a Tutorial. + * The tree representation of a tutorial is: + * Tutorial theId + * |-Name: the name + * |-Description: the description + * |-License: + * | -The license text + * |-Setup: + * | -The custom setup code + * --Tear down: + * -The custom tear down code + * + * The items only appear if they have some data to show. For example, if only + * the name of the Tutorial is set, its representation is: + * Tutorial theId + * -Name: the name + * + * Note that composed elements like license don't appear at all, not even the + * parent item with just "License:". + * + * Whenever the tutorial data changes, the TutorialTreeItem and its child items + * are updated as needed. + * + * Also note that the order of the child elements is always the same. Even if, + * for example, the setup code is set first and then the name, the name item + * will appear first and then the setup code item. + */ +class TutorialTreeItem: public TreeItem { +Q_OBJECT +public: + + /** + * Creates a new TutorialTreeItem for the given Tutorial and with the given + * parent. + * + * @param tutorial The tutorial to represent. + * @param parent The parent TreeItem. + */ + explicit TutorialTreeItem(Tutorial* tutorial, TreeItem* parent = 0); + + /** + * Returns "Tutorial " and the id of the tutorial, or just "Tutorial" if + * there is no id. + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + +private: + + /** + * The id of the tutorial. + */ + QString mTutorialId; + + /** + * The child item containing the name. + */ + TextTreeItem* mNameItem; + + /** + * The child item containing the description. + */ + TextTreeItem* mDescriptionItem; + + /** + * The child item containing the license. + * This is a nested item. Its parent (and the direct child of this + * TutorialTreeItem) contains the "License:" text. + */ + TextTreeItem* mLicenseItem; + + /** + * The child item containing the custom setup code. + * This is a nested item. Its parent (and the direct child of this + * TutorialTreeItem) contains the "Setup:" text. + */ + TextTreeItem* mSetupItem; + + /** + * The child item containing the custom tear down code. + * This is a nested item. Its parent (and the direct child of this + * TutorialTreeItem) contains the "Tear down:" text. + */ + TextTreeItem* mTearDownItem; + +private Q_SLOTS: + + /** + * Updates this TutorialTreeItem when the data of its tutorial changed. + * If a child item is needed to show some data, it is inserted or updated + * (depending on whether it existed previously or not). + * If the child item is no longer needed, it is removed. + * + * Items may be flat or nested, depending on the data to show. + * + * @param tutorial The tutorial. + */ + void update(Tutorial* tutorial); + + /** + * If there is no item, inserts a new TextTreeItem at the given childIndex + * in this TutorialTreeItem. + * The new TextTreeItem is stored in the given item. + * + * @param item The item to check and the place to store the new item. + * @param childIndex The index in this TutorialTreeItem to add the item. + */ + void addFlatItemIfNeeded(TextTreeItem*& item, int childIndex); + + /** + * If there is an item, it is removed from this TutorialTreeItem. + * The given item is set to null after deleting it. + * + * @param item The item to remove, delete and clean. + */ + void removeFlatItemIfNeeded(TextTreeItem*& item); + + /** + * If there is no item, inserts a new nested TextTreeItem at the given + * childIndex in this TutorialTreeItem. + * A TextTreeItem is inserted with the given parentText, and a new + * TextTreeItem child is appended to that parent. + * The child is stored in the given item. + * + * @param item The item to check and the place to store the new item. + * @param childIndex The index in this TutorialTreeItem to add the item. + */ + void addNestedItemIfNeeded(TextTreeItem*& item, int childIndex, + const QString& parentText); + + /** + * If there is an item, its parent is removed from this TutorialTreeItem. + * The given item is set to null after its parent is deleted. + * + * @param item The item to clean after removing and deleting its parent. + */ + void removeNestedItemIfNeeded(TextTreeItem*& item); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-07 06:21:19 UTC (rev 116) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-07 07:21:18 UTC (rev 117) @@ -12,11 +12,11 @@ FOREACH(_className ${ARGN}) set(_testName ${_className}Test) kde4_add_unit_test(${_testName} TESTNAME ktutorial-editor-unit-${_testName} ${_testName}.cpp) - target_link_libraries(${_testName} ktutorial_editor_view ${QT_QTTEST_LIBRARY}) + target_link_libraries(${_testName} ktutorial_editor ktutorial_editor_view ${QT_QTTEST_LIBRARY}) ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(TextTreeItem TreeItem TreeModel) +unit_tests(TextTreeItem TreeItem TreeModel TutorialTreeItem) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(TextTreeItem TreeItem TreeModel) +mem_tests(TextTreeItem TreeItem TreeModel TutorialTreeItem) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp 2010-03-07 07:21:18 UTC (rev 117) @@ -0,0 +1,462 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialTreeItem.h" + +#include <KLocalizedString> + +#include "../Tutorial.h" + +class TutorialTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + void testConstructorFullTutorial(); + + void testTutorialSetName(); + void testTutorialSetNameChange(); + void testTutorialSetNameEmpty(); + + void testTutorialSetDescription(); + void testTutorialSetDescriptionChange(); + void testTutorialSetDescriptionEmpty(); + + void testTutorialSetLicenseText(); + void testTutorialSetLicenseTextChange(); + void testTutorialSetLicenseTextEmpty(); + + void testTutorialSetCustomSetupCode(); + void testTutorialSetCustomSetupCodeChange(); + void testTutorialSetCustomSetupCodeEmpty(); + + void testTutorialSetCustomTearDownCode(); + void testTutorialSetCustomTearDownCodeChange(); + void testTutorialSetCustomTearDownCodeEmpty(); + + void testChildOrderWhenSettingDataInTutorial(); + void testChildOrderWhenUnsettingDataInTutorial(); + +private: + + int mTreeItemStarType; + + void assertName(TreeItem* nameItem, const QString& name) const; + void assertDescription(TreeItem* descriptionItem, + const QString& description) const; + void assertLicenseText(TreeItem* licenseItem, + const QString& licenseText) const; + void assertCustomSetupCode(TreeItem* setupItem, const QString& code) const; + void assertCustomTearDownCode(TreeItem* tearDownItem, + const QString& code) const; + + void assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const; + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void TutorialTreeItemTest::initTestCase() { + //TreeItem* must be registered in order to be used with QSignalSpy + mTreeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); +} + +void TutorialTreeItemTest::testConstructor() { + Tutorial tutorial; + + StubTreeItem parent; + TutorialTreeItem item(&tutorial, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 0); +} + +void TutorialTreeItemTest::testConstructorFullTutorial() { + Tutorial tutorial; + tutorial.setName("The name"); + tutorial.setDescription("The description"); + tutorial.setLicenseText("The license text"); + tutorial.setCustomSetupCode("The setup code"); + tutorial.setCustomTearDownCode("The tear down code"); + + StubTreeItem parent; + TutorialTreeItem item(&tutorial, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 5); + assertName(item.child(0), "The name"); + assertDescription(item.child(1), "The description"); + assertLicenseText(item.child(2), "The license text"); + assertCustomSetupCode(item.child(3), "The setup code"); + assertCustomTearDownCode(item.child(4), "The tear down code"); +} + +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + +void TutorialTreeItemTest::testTutorialSetName() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + //Setting the name changes the data returned by text() in the + //TutorialTreeItem itself, as the id is based on the name + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + tutorial.setName("The name"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 1); + assertName(item.child(0), "The name"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void TutorialTreeItemTest::testTutorialSetNameChange() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setName("The name"); + + QSignalSpy dataChangedRootSpy(&item, SIGNAL(dataChanged(TreeItem*))); + QSignalSpy dataChangedSpy(item.child(0), SIGNAL(dataChanged(TreeItem*))); + + tutorial.setName("The name changed"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theNameChanged")); + QCOMPARE(item.childCount(), 1); + assertName(item.child(0), "The name changed"); + QCOMPARE(dataChangedRootSpy.count(), 1); + assertDataChanged(dataChangedRootSpy, 0, &item); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)); +} + +void TutorialTreeItemTest::testTutorialSetNameEmpty() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setName("The name"); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + tutorial.setName(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 0); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void TutorialTreeItemTest::testTutorialSetDescription() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setDescription("The description"); + + QCOMPARE(item.childCount(), 1); + assertDescription(item.child(0), "The description"); +} + +void TutorialTreeItemTest::testTutorialSetDescriptionChange() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setDescription("The description"); + + QSignalSpy dataChangedSpy(item.child(0), SIGNAL(dataChanged(TreeItem*))); + + tutorial.setDescription("The description changed"); + + QCOMPARE(item.childCount(), 1); + assertDescription(item.child(0), "The description changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)); +} + +void TutorialTreeItemTest::testTutorialSetDescriptionEmpty() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setDescription("The description"); + tutorial.setDescription(""); + + QCOMPARE(item.childCount(), 0); +} + +void TutorialTreeItemTest::testTutorialSetLicenseText() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setLicenseText("The license text"); + + QCOMPARE(item.childCount(), 1); + assertLicenseText(item.child(0), "The license text"); +} + +void TutorialTreeItemTest::testTutorialSetLicenseTextChange() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setLicenseText("The license text"); + + QSignalSpy dataChangedSpy(item.child(0)->child(0), + SIGNAL(dataChanged(TreeItem*))); + + tutorial.setLicenseText("The license text changed"); + + QCOMPARE(item.childCount(), 1); + assertLicenseText(item.child(0), "The license text changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)->child(0)); +} + +void TutorialTreeItemTest::testTutorialSetLicenseTextEmpty() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setLicenseText("The license text"); + tutorial.setLicenseText(""); + + QCOMPARE(item.childCount(), 0); +} + +void TutorialTreeItemTest::testTutorialSetCustomSetupCode() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomSetupCode("The setup code"); + + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); +} + +void TutorialTreeItemTest::testTutorialSetCustomSetupCodeChange() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomSetupCode("The setup code"); + + QSignalSpy dataChangedSpy(item.child(0)->child(0), + SIGNAL(dataChanged(TreeItem*))); + + tutorial.setCustomSetupCode("The setup code changed"); + + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)->child(0)); +} + +void TutorialTreeItemTest::testTutorialSetCustomSetupCodeEmpty() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomSetupCode("The setup code"); + tutorial.setCustomSetupCode(""); + + QCOMPARE(item.childCount(), 0); +} + +void TutorialTreeItemTest::testTutorialSetCustomTearDownCode() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomTearDownCode("The tear down code"); + + QCOMPARE(item.childCount(), 1); + assertCustomTearDownCode(item.child(0), "The tear down code"); +} + +void TutorialTreeItemTest::testTutorialSetCustomTearDownCodeChange() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomTearDownCode("The tear down code"); + + QSignalSpy dataChangedSpy(item.child(0)->child(0), + SIGNAL(dataChanged(TreeItem*))); + + tutorial.setCustomTearDownCode("The tear down code changed"); + + QCOMPARE(item.childCount(), 1); + assertCustomTearDownCode(item.child(0), "The tear down code changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)->child(0)); +} + +void TutorialTreeItemTest::testTutorialSetCustomTearDownCodeEmpty() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomTearDownCode("The tear down code"); + tutorial.setCustomTearDownCode(""); + + QCOMPARE(item.childCount(), 0); +} + +void TutorialTreeItemTest::testChildOrderWhenSettingDataInTutorial() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + tutorial.setCustomSetupCode("The setup code"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); + + tutorial.setDescription("The description"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 2); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + + tutorial.setCustomTearDownCode("The tear down code"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 3); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + + tutorial.setName("The name"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 4); + assertName(item.child(0), "The name"); + assertDescription(item.child(1), "The description"); + assertCustomSetupCode(item.child(2), "The setup code"); + assertCustomTearDownCode(item.child(3), "The tear down code"); + + tutorial.setLicenseText("The license text"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 5); + assertName(item.child(0), "The name"); + assertDescription(item.child(1), "The description"); + assertLicenseText(item.child(2), "The license text"); + assertCustomSetupCode(item.child(3), "The setup code"); + assertCustomTearDownCode(item.child(4), "The tear down code"); +} + +void TutorialTreeItemTest::testChildOrderWhenUnsettingDataInTutorial() { + Tutorial tutorial; + tutorial.setName("The name"); + tutorial.setDescription("The description"); + tutorial.setLicenseText("The license text"); + tutorial.setCustomSetupCode("The setup code"); + tutorial.setCustomTearDownCode("The tear down code"); + + TutorialTreeItem item(&tutorial); + + tutorial.setLicenseText(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 4); + assertName(item.child(0), "The name"); + assertDescription(item.child(1), "The description"); + assertCustomSetupCode(item.child(2), "The setup code"); + assertCustomTearDownCode(item.child(3), "The tear down code"); + + tutorial.setName(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 3); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + + tutorial.setCustomTearDownCode(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 2); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + + tutorial.setDescription(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); + + tutorial.setCustomSetupCode(""); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 0); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void TutorialTreeItemTest::assertName(TreeItem* nameItem, + const QString& name) const { + QCOMPARE(nameItem->text(), i18nc("@item", "Name: %1", name)); +} + +void TutorialTreeItemTest::assertDescription(TreeItem* descriptionItem, + const QString& description) const { + QCOMPARE(descriptionItem->text(), + i18nc("@item", "Description: %1", description)); +} + +void TutorialTreeItemTest::assertLicenseText(TreeItem* licenseItem, + const QString& licenseText) const { + QCOMPARE(licenseItem->text(), i18nc("@item", "License:")); + QCOMPARE(licenseItem->childCount(), 1); + QCOMPARE(licenseItem->child(0)->text(), + i18nc("@item", licenseText.toAscii())); +} + +void TutorialTreeItemTest::assertCustomSetupCode(TreeItem* setupItem, + const QString& code) const { + QCOMPARE(setupItem->text(), i18nc("@item", "Setup:")); + QCOMPARE(setupItem->childCount(), 1); + QCOMPARE(setupItem->child(0)->text(), i18nc("@item", code.toAscii())); +} + +void TutorialTreeItemTest::assertCustomTearDownCode(TreeItem* tearDownItem, + const QString& code) const { + QCOMPARE(tearDownItem->text(), i18nc("@item", "Tear down:")); + QCOMPARE(tearDownItem->childCount(), 1); + QCOMPARE(tearDownItem->child(0)->text(), i18nc("@item", code.toAscii())); +} + +void TutorialTreeItemTest::assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); +} + +QTEST_MAIN(TutorialTreeItemTest) + +#include "TutorialTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-07 07:39:04
|
Revision: 118 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=118&view=rev Author: danxuliu Date: 2010-03-07 07:38:57 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Add basic version of Step class to store the data of a step. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/Step.cpp trunk/ktutorial/ktutorial-editor/src/Step.h trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-07 07:21:18 UTC (rev 117) +++ trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-07 07:38:57 UTC (rev 118) @@ -8,6 +8,7 @@ set(ktutorial_editor_SRCS KTutorialEditor.cpp + Step.cpp Tutorial.cpp ) Added: trunk/ktutorial/ktutorial-editor/src/Step.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Step.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/Step.cpp 2010-03-07 07:38:57 UTC (rev 118) @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "Step.h" + +//public: + +Step::Step(QObject* parent) { +} + +QString Step::id() const { + return mId; +} + +void Step::setId(const QString& id) { + mId = id; + + emit dataChanged(this); +} + +QString Step::text() const { + return mText; +} + +void Step::setText(const QString& text) { + mText = text; + + emit dataChanged(this); +} + +QString Step::customSetupCode() const { + return mCustomSetupCode; +} + +void Step::setCustomSetupCode(const QString& code) { + mCustomSetupCode = code; + + emit dataChanged(this); +} + +QString Step::customTearDownCode() const { + return mCustomTearDownCode; +} + +void Step::setCustomTearDownCode(const QString& code) { + mCustomTearDownCode = code; + + emit dataChanged(this); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/Step.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/Step.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Step.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/Step.h 2010-03-07 07:38:57 UTC (rev 118) @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2010 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 STEP_H +#define STEP_H + +#include <QObject> + +/** + * Container for step data. + * It stores the data used in KTutorial steps, but it has nothing to do with + * them (they don't even know each other). Its purpose is store the data needed to + * generate the code to create a true KTutorial::Step. + * + * When any attribute is modified, dataChanged(Step*) signal is emitted. + */ +class Step: public QObject { +Q_OBJECT +public: + + Step(QObject* parent = 0); + + QString id() const; + void setId(const QString& id); + + QString text() const; + void setText(const QString& text); + + QString customSetupCode() const; + void setCustomSetupCode(const QString& code); + + QString customTearDownCode() const; + void setCustomTearDownCode(const QString& code); + +Q_SIGNALS: + + /** + * Emitted when any data in the step changed. + * + * @param step This step. + */ + void dataChanged(Step* step); + +private: + + QString mId; + QString mText; + QString mCustomSetupCode; + QString mCustomTearDownCode; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/Step.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-07 07:21:18 UTC (rev 117) +++ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-07 07:38:57 UTC (rev 118) @@ -14,7 +14,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(Tutorial) +unit_tests(Step Tutorial) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -22,4 +22,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(Tutorial) +mem_tests(Step Tutorial) Added: trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp 2010-03-07 07:38:57 UTC (rev 118) @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "Step.h" + +class StepTest: public QObject { +Q_OBJECT + +private slots: + + void testSetId(); + + void testSetText(); + + void testSetCustomSetupCode(); + + void testSetCustomTearDownCode(); + +}; + +//Step* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(Step*); + +void StepTest::testSetId() { + Step step; + + //Step* must be registered in order to be used with QSignalSpy + int stepStarType = qRegisterMetaType<Step*>("Step*"); + QSignalSpy dataChangedSpy(&step, SIGNAL(dataChanged(Step*))); + + step.setId("The id"); + + QCOMPARE(step.id(), QString("The id")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), stepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), &step); +} + +void StepTest::testSetText() { + Step step; + + //Step* must be registered in order to be used with QSignalSpy + int stepStarType = qRegisterMetaType<Step*>("Step*"); + QSignalSpy dataChangedSpy(&step, SIGNAL(dataChanged(Step*))); + + step.setText("The text"); + + QCOMPARE(step.text(), QString("The text")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), stepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), &step); +} + +void StepTest::testSetCustomSetupCode() { + Step step; + + //Step* must be registered in order to be used with QSignalSpy + int stepStarType = qRegisterMetaType<Step*>("Step*"); + QSignalSpy dataChangedSpy(&step, SIGNAL(dataChanged(Step*))); + + step.setCustomSetupCode("The setup code"); + + QCOMPARE(step.customSetupCode(), QString("The setup code")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), stepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), &step); +} + +void StepTest::testSetCustomTearDownCode() { + Step step; + + //Step* must be registered in order to be used with QSignalSpy + int stepStarType = qRegisterMetaType<Step*>("Step*"); + QSignalSpy dataChangedSpy(&step, SIGNAL(dataChanged(Step*))); + + step.setCustomTearDownCode("The tear down code"); + + QCOMPARE(step.customTearDownCode(), QString("The tear down code")); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), stepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), &step); +} + +QTEST_MAIN(StepTest) + +#include "StepTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-07 18:50:44
|
Revision: 119 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=119&view=rev Author: danxuliu Date: 2010-03-07 18:50:37 +0000 (Sun, 07 Mar 2010) Log Message: ----------- -Add StepTreeItem class to show a Step in a TreeModel. -Extract common methods from TutorialTreeItem and StepTreeItem to TreeItemUtil class. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.cpp trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.h trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemUtilTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-07 07:38:57 UTC (rev 118) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-07 18:50:37 UTC (rev 119) @@ -1,8 +1,10 @@ include_directories(${KDE4_INCLUDES}) set(ktutorial_editor_view_SRCS + StepTreeItem.cpp TextTreeItem.cpp TreeItem.cpp + TreeItemUtil.cpp TreeModel.cpp TutorialTreeItem.cpp ) Added: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepTreeItem.h" + +#include <KLocalizedString> + +#include "TextTreeItem.h" +#include "TreeItemUtil.h" +#include "../Step.h" + +//public: + +StepTreeItem::StepTreeItem(Step* step, TreeItem* parent): + TreeItem(parent) { + Q_ASSERT(step); + + mTextItem = 0; + mSetupItem = 0; + mTearDownItem = 0; + + update(step); + connect(step, SIGNAL(dataChanged(Step*)), + this, SLOT(update(Step*))); +} + +QString StepTreeItem::text() const { + if (mStepId.isEmpty()) { + return i18nc("@item", "Step"); + } + + return i18nc("@item", "Step %1", mStepId); +} + +//private slots: + +void StepTreeItem::update(Step* step) { + int childIndex = 0; + + if (step->id().isEmpty()) { + if (!mStepId.isEmpty()) { + mStepId = QString(); + emit dataChanged(this); + } + } else { + mStepId = step->id(); + emit dataChanged(this); + } + + if (step->text().isEmpty()) { + TreeItemUtil::removeFlatItemIfNeeded(mTextItem); + } else { + TreeItemUtil::addFlatItemIfNeeded(this, mTextItem, childIndex); + mTextItem->setText(i18nc("@item", "Text: %1", step->text())); + + childIndex++; + } + + if (step->customSetupCode().isEmpty()) { + TreeItemUtil::removeNestedItemIfNeeded(mSetupItem); + } else { + TreeItemUtil::addNestedItemIfNeeded(this, mSetupItem, childIndex, + i18nc("@item", "Setup:")); + mSetupItem->setText(step->customSetupCode()); + + childIndex++; + } + + if (step->customTearDownCode().isEmpty()) { + TreeItemUtil::removeNestedItemIfNeeded(mTearDownItem); + } else { + TreeItemUtil::addNestedItemIfNeeded(this, mTearDownItem, childIndex, + i18nc("@item", "Tear down:")); + mTearDownItem->setText(step->customTearDownCode()); + + childIndex++; + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2010 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 STEPTREEITEM_H +#define STEPTREEITEM_H + +#include "TreeItem.h" + +class Step; +class TextTreeItem; + +/** + * A TreeItem that represents a Step. + * The tree representation of a step is: + * Step theId + * |-Text: the text + * |-Setup: + * | -The custom setup code + * --Tear down: + * -The custom tear down code + * + * The items only appear if they have some data to show. For example, if only + * the text of the Step is set, its representation is: + * Step + * -The text + * + * Note that composed elements like custom setup code don't appear at all, not + * even the parent item with just "Setup:". + * + * Whenever the step data changes, the StepTreeItem and its child items + * are updated as needed. + * + * Also note that the order of the child elements is always the same. Even if, + * for example, the setup code is set first and then the text, the text item + * will appear first and then the setup code item. + */ +class StepTreeItem: public TreeItem { +Q_OBJECT +public: + + /** + * Creates a new StepTreeItem for the given Step and with the given + * parent. + * + * @param step The step to represent. + * @param parent The parent TreeItem. + */ + explicit StepTreeItem(Step* step, TreeItem* parent = 0); + + /** + * Returns "Step " and the id of the step, or just "Step" if + * there is no id. + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + +private: + + /** + * The id of the step. + */ + QString mStepId; + + /** + * The child item containing the text. + */ + TextTreeItem* mTextItem; + + /** + * The child item containing the custom setup code. + * This is a nested item. Its parent (and the direct child of this + * StepTreeItem) contains the "Setup:" text. + */ + TextTreeItem* mSetupItem; + + /** + * The child item containing the custom tear down code. + * This is a nested item. Its parent (and the direct child of this + * StepTreeItem) contains the "Tear down:" text. + */ + TextTreeItem* mTearDownItem; + +private Q_SLOTS: + + /** + * Updates this StepTreeItem when the data of its step changed. + * If a child item is needed to show some data, it is inserted or updated + * (depending on whether it existed previously or not). + * If the child item is no longer needed, it is removed. + * + * Items may be flat or nested, depending on the data to show. + * + * @param step The step. + */ + void update(Step* step); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.cpp 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeItemUtil.h" + +#include "TextTreeItem.h" + +//public: + +void TreeItemUtil::addFlatItemIfNeeded(TreeItem* root, TextTreeItem*& item, + int index) { + if (item == 0) { + item = new TextTreeItem(root); + root->insertChild(item, index); + } +} + +void TreeItemUtil::removeFlatItemIfNeeded(TextTreeItem*& item) { + if (item != 0) { + item->parent()->removeChild(item); + delete item; + item = 0; + } +} + +void TreeItemUtil::addNestedItemIfNeeded(TreeItem* root, TextTreeItem*& item, + int index, const QString& parentText) { + if (item == 0) { + TextTreeItem* parentItem = new TextTreeItem(root); + parentItem->setText(parentText); + + item = new TextTreeItem(parentItem); + parentItem->appendChild(item); + + root->insertChild(parentItem, index); + } +} + +void TreeItemUtil::removeNestedItemIfNeeded(TextTreeItem*& item) { + if (item != 0) { + item->parent()->parent()->removeChild(item->parent()); + delete item->parent(); + item = 0; + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.h 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TREEITEMUTIL_H +#define TREEITEMUTIL_H + +#include "TreeItem.h" + +class TextTreeItem; + +/** + * Utility class for TreeItems. + * It provides some static methods to modify the structure of TreeItems, adding + * or removing children. + */ +class TreeItemUtil { +public: + + /** + * If there is no item, inserts a new TextTreeItem at the given index in the + * root item. + * The new TextTreeItem is stored in the given item. + * + * @param root The root item to add the item to. + * @param item The item to check and the variable to store the new item in. + * @param index The index in the root item to add the item. + */ + static void addFlatItemIfNeeded(TreeItem* root, TextTreeItem*& item, + int index); + + /** + * If there is an item, it is removed from its parent item. + * The given item is set to null after deleting it. + * + * @param item The item to remove, delete and clean. + */ + static void removeFlatItemIfNeeded(TextTreeItem*& item); + + /** + * If there is no item, inserts a new nested TextTreeItem at the given index + * in the root item. + * A TextTreeItem is inserted with the given parentText, and a new + * TextTreeItem child is appended to that parent. + * The child is stored in the given item. + * + * @param root The root item to add the parent item to. + * @param item The item to check and the place to store the new item. + * @param index The index in the root item to add the parent item. + * @param parentText The text to set in the added parent item. + */ + static void addNestedItemIfNeeded(TreeItem* root, TextTreeItem*& item, + int index, const QString& parentText); + + /** + * If there is an item, its parent is removed from its parent item. + * The given item is set to null after its parent is deleted. + * + * @param item The item to clean after removing and deleting its parent. + */ + static void removeNestedItemIfNeeded(TextTreeItem*& item); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TreeItemUtil.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp 2010-03-07 07:38:57 UTC (rev 118) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp 2010-03-07 18:50:37 UTC (rev 119) @@ -21,6 +21,7 @@ #include <KLocalizedString> #include "TextTreeItem.h" +#include "TreeItemUtil.h" #include "../Tutorial.h" //public: @@ -54,14 +55,14 @@ int childIndex = 0; if (tutorial->name().isEmpty()) { - removeFlatItemIfNeeded(mNameItem); + TreeItemUtil::removeFlatItemIfNeeded(mNameItem); if (!mTutorialId.isEmpty()) { mTutorialId = QString(); emit dataChanged(this); } } else { - addFlatItemIfNeeded(mNameItem, childIndex); + TreeItemUtil::addFlatItemIfNeeded(this, mNameItem, childIndex); mNameItem->setText(i18nc("@item", "Name: %1", tutorial->name())); mTutorialId = tutorial->id(); @@ -71,9 +72,9 @@ } if (tutorial->description().isEmpty()) { - removeFlatItemIfNeeded(mDescriptionItem); + TreeItemUtil::removeFlatItemIfNeeded(mDescriptionItem); } else { - addFlatItemIfNeeded(mDescriptionItem, childIndex); + TreeItemUtil::addFlatItemIfNeeded(this, mDescriptionItem, childIndex); mDescriptionItem->setText(i18nc("@item", "Description: %1", tutorial->description())); @@ -81,70 +82,32 @@ } if (tutorial->licenseText().isEmpty()) { - removeNestedItemIfNeeded(mLicenseItem); + TreeItemUtil::removeNestedItemIfNeeded(mLicenseItem); } else { - addNestedItemIfNeeded(mLicenseItem, childIndex, - i18nc("@item", "License:")); + TreeItemUtil::addNestedItemIfNeeded(this, mLicenseItem, childIndex, + i18nc("@item", "License:")); mLicenseItem->setText(tutorial->licenseText()); childIndex++; } if (tutorial->customSetupCode().isEmpty()) { - removeNestedItemIfNeeded(mSetupItem); + TreeItemUtil::removeNestedItemIfNeeded(mSetupItem); } else { - addNestedItemIfNeeded(mSetupItem, childIndex, - i18nc("@item", "Setup:")); + TreeItemUtil::addNestedItemIfNeeded(this, mSetupItem, childIndex, + i18nc("@item", "Setup:")); mSetupItem->setText(tutorial->customSetupCode()); childIndex++; } if (tutorial->customTearDownCode().isEmpty()) { - removeNestedItemIfNeeded(mTearDownItem); + TreeItemUtil::removeNestedItemIfNeeded(mTearDownItem); } else { - addNestedItemIfNeeded(mTearDownItem, childIndex, - i18nc("@item", "Tear down:")); + TreeItemUtil::addNestedItemIfNeeded(this, mTearDownItem, childIndex, + i18nc("@item", "Tear down:")); mTearDownItem->setText(tutorial->customTearDownCode()); childIndex++; } } - -void TutorialTreeItem::addFlatItemIfNeeded(TextTreeItem*& item, - int childIndex) { - if (item == 0) { - item = new TextTreeItem(this); - insertChild(item, childIndex); - } -} - -void TutorialTreeItem::removeFlatItemIfNeeded(TextTreeItem*& item) { - if (item != 0) { - removeChild(item); - delete item; - item = 0; - } -} - -void TutorialTreeItem::addNestedItemIfNeeded(TextTreeItem*& item, - int childIndex, - const QString& parentText) { - if (item == 0) { - TextTreeItem* parentItem = new TextTreeItem(this); - parentItem->setText(parentText); - - item = new TextTreeItem(parentItem); - parentItem->appendChild(item); - - insertChild(parentItem, childIndex); - } -} - -void TutorialTreeItem::removeNestedItemIfNeeded(TextTreeItem*& item) { - if (item != 0) { - removeChild(item->parent()); - delete item->parent(); - item = 0; - } -} Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h 2010-03-07 07:38:57 UTC (rev 118) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h 2010-03-07 18:50:37 UTC (rev 119) @@ -125,45 +125,6 @@ */ void update(Tutorial* tutorial); - /** - * If there is no item, inserts a new TextTreeItem at the given childIndex - * in this TutorialTreeItem. - * The new TextTreeItem is stored in the given item. - * - * @param item The item to check and the place to store the new item. - * @param childIndex The index in this TutorialTreeItem to add the item. - */ - void addFlatItemIfNeeded(TextTreeItem*& item, int childIndex); - - /** - * If there is an item, it is removed from this TutorialTreeItem. - * The given item is set to null after deleting it. - * - * @param item The item to remove, delete and clean. - */ - void removeFlatItemIfNeeded(TextTreeItem*& item); - - /** - * If there is no item, inserts a new nested TextTreeItem at the given - * childIndex in this TutorialTreeItem. - * A TextTreeItem is inserted with the given parentText, and a new - * TextTreeItem child is appended to that parent. - * The child is stored in the given item. - * - * @param item The item to check and the place to store the new item. - * @param childIndex The index in this TutorialTreeItem to add the item. - */ - void addNestedItemIfNeeded(TextTreeItem*& item, int childIndex, - const QString& parentText); - - /** - * If there is an item, its parent is removed from this TutorialTreeItem. - * The given item is set to null after its parent is deleted. - * - * @param item The item to clean after removing and deleting its parent. - */ - void removeNestedItemIfNeeded(TextTreeItem*& item); - }; #endif Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-07 07:38:57 UTC (rev 118) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-07 18:50:37 UTC (rev 119) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(TextTreeItem TreeItem TreeModel TutorialTreeItem) +unit_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(TextTreeItem TreeItem TreeModel TutorialTreeItem) +mem_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,372 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepTreeItem.h" + +#include <KLocalizedString> + +#include "../Step.h" + +class StepTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + void testConstructorFullStep(); + + void testStepSetId(); + void testStepSetIdChange(); + void testStepSetIdEmpty(); + + void testStepSetText(); + void testStepSetTextChange(); + void testStepSetTextEmpty(); + + void testStepSetCustomSetupCode(); + void testStepSetCustomSetupCodeChange(); + void testStepSetCustomSetupCodeEmpty(); + + void testStepSetCustomTearDownCode(); + void testStepSetCustomTearDownCodeChange(); + void testStepSetCustomTearDownCodeEmpty(); + + void testChildOrderWhenSettingDataInStep(); + void testChildOrderWhenUnsettingDataInStep(); + +private: + + int mTreeItemStarType; + + void assertText(TreeItem* textItem, const QString& licenseText) const; + void assertCustomSetupCode(TreeItem* setupItem, const QString& code) const; + void assertCustomTearDownCode(TreeItem* tearDownItem, + const QString& code) const; + + void assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const; + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void StepTreeItemTest::initTestCase() { + //TreeItem* must be registered in order to be used with QSignalSpy + mTreeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); +} + +void StepTreeItemTest::testConstructor() { + Step step; + + StubTreeItem parent; + StepTreeItem item(&step, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 0); +} + +void StepTreeItemTest::testConstructorFullStep() { + Step step; + step.setId("The id"); + step.setText("The text"); + step.setCustomSetupCode("The setup code"); + step.setCustomTearDownCode("The tear down code"); + + StubTreeItem parent; + StepTreeItem item(&step, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.childCount(), 3); + assertText(item.child(0), "The text"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); +} + +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + +void StepTreeItemTest::testStepSetId() { + Step step; + StepTreeItem item(&step); + + //Setting the id changes the data returned by text() in the + //StepTreeItem itself + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + step.setId("The id"); + + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.childCount(), 0); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void StepTreeItemTest::testStepSetIdChange() { + Step step; + StepTreeItem item(&step); + + step.setId("The id"); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + step.setId("The id changed"); + + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id changed")); + QCOMPARE(item.childCount(), 0); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void StepTreeItemTest::testStepSetIdEmpty() { + Step step; + StepTreeItem item(&step); + + step.setId("The id"); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + step.setId(""); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 0); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void StepTreeItemTest::testStepSetText() { + Step step; + StepTreeItem item(&step); + + step.setText("The text"); + + QCOMPARE(item.childCount(), 1); + assertText(item.child(0), "The text"); +} + +void StepTreeItemTest::testStepSetTextChange() { + Step step; + StepTreeItem item(&step); + + step.setText("The text"); + + QSignalSpy dataChangedSpy(item.child(0), SIGNAL(dataChanged(TreeItem*))); + + step.setText("The text changed"); + + QCOMPARE(item.childCount(), 1); + assertText(item.child(0), "The text changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)); +} + +void StepTreeItemTest::testStepSetTextEmpty() { + Step step; + StepTreeItem item(&step); + + step.setText("The text"); + step.setText(""); + + QCOMPARE(item.childCount(), 0); +} + +void StepTreeItemTest::testStepSetCustomSetupCode() { + Step step; + StepTreeItem item(&step); + + step.setCustomSetupCode("The setup code"); + + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); +} + +void StepTreeItemTest::testStepSetCustomSetupCodeChange() { + Step step; + StepTreeItem item(&step); + + step.setCustomSetupCode("The setup code"); + + QSignalSpy dataChangedSpy(item.child(0)->child(0), + SIGNAL(dataChanged(TreeItem*))); + + step.setCustomSetupCode("The setup code changed"); + + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)->child(0)); +} + +void StepTreeItemTest::testStepSetCustomSetupCodeEmpty() { + Step step; + StepTreeItem item(&step); + + step.setCustomSetupCode("The setup code"); + step.setCustomSetupCode(""); + + QCOMPARE(item.childCount(), 0); +} + +void StepTreeItemTest::testStepSetCustomTearDownCode() { + Step step; + StepTreeItem item(&step); + + step.setCustomTearDownCode("The tear down code"); + + QCOMPARE(item.childCount(), 1); + assertCustomTearDownCode(item.child(0), "The tear down code"); +} + +void StepTreeItemTest::testStepSetCustomTearDownCodeChange() { + Step step; + StepTreeItem item(&step); + + step.setCustomTearDownCode("The tear down code"); + + QSignalSpy dataChangedSpy(item.child(0)->child(0), + SIGNAL(dataChanged(TreeItem*))); + + step.setCustomTearDownCode("The tear down code changed"); + + QCOMPARE(item.childCount(), 1); + assertCustomTearDownCode(item.child(0), "The tear down code changed"); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, item.child(0)->child(0)); +} + +void StepTreeItemTest::testStepSetCustomTearDownCodeEmpty() { + Step step; + StepTreeItem item(&step); + + step.setCustomTearDownCode("The tear down code"); + step.setCustomTearDownCode(""); + + QCOMPARE(item.childCount(), 0); +} + +void StepTreeItemTest::testChildOrderWhenSettingDataInStep() { + Step step; + StepTreeItem item(&step); + + step.setCustomSetupCode("The setup code"); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); + + step.setText("The text"); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 2); + assertText(item.child(0), "The text"); + assertCustomSetupCode(item.child(1), "The setup code"); + + step.setCustomTearDownCode("The tear down code"); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 3); + assertText(item.child(0), "The text"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + + step.setId("The id"); + + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.childCount(), 3); + assertText(item.child(0), "The text"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); +} + +void StepTreeItemTest::testChildOrderWhenUnsettingDataInStep() { + Step step; + step.setId("The id"); + step.setText("The text"); + step.setCustomSetupCode("The setup code"); + step.setCustomTearDownCode("The tear down code"); + + StepTreeItem item(&step); + + step.setText(""); + + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.childCount(), 2); + assertCustomSetupCode(item.child(0), "The setup code"); + assertCustomTearDownCode(item.child(1), "The tear down code"); + + step.setCustomTearDownCode(""); + + QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); + + step.setId(""); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 1); + assertCustomSetupCode(item.child(0), "The setup code"); + + step.setCustomSetupCode(""); + + QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.childCount(), 0); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void StepTreeItemTest::assertText(TreeItem* textItem, + const QString& name) const { + QCOMPARE(textItem->text(), i18nc("@item", "Text: %1", name)); +} + +void StepTreeItemTest::assertCustomSetupCode(TreeItem* setupItem, + const QString& code) const { + QCOMPARE(setupItem->text(), i18nc("@item", "Setup:")); + QCOMPARE(setupItem->childCount(), 1); + QCOMPARE(setupItem->child(0)->text(), i18nc("@item", code.toAscii())); +} + +void StepTreeItemTest::assertCustomTearDownCode(TreeItem* tearDownItem, + const QString& code) const { + QCOMPARE(tearDownItem->text(), i18nc("@item", "Tear down:")); + QCOMPARE(tearDownItem->childCount(), 1); + QCOMPARE(tearDownItem->child(0)->text(), i18nc("@item", code.toAscii())); +} + +void StepTreeItemTest::assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); +} + +QTEST_MAIN(StepTreeItemTest) + +#include "StepTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemUtilTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemUtilTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemUtilTest.cpp 2010-03-07 18:50:37 UTC (rev 119) @@ -0,0 +1,191 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TreeItemUtil.h" + +#include "TextTreeItem.h" + +class TreeItemUtilTest: public QObject { +Q_OBJECT + +private slots: + + void testAddFlatItem(); + void testAddFlatItemAlreadyAdded(); + + void testRemoveFlatItem(); + void testRemoveFlatItemAlreadyRemoved(); + + void testAddNestedItem(); + void testAddNestedItemAlreadyAdded(); + + void testRemoveNestedItem(); + void testRemoveNestedItemAlreadyRemoved(); + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void TreeItemUtilTest::testAddFlatItem() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = 0; + + TreeItemUtil::addFlatItemIfNeeded(&parent, item, 0); + + QVERIFY(item); + QCOMPARE(item->parent(), &parent); + QCOMPARE(parent.childCount(), 2); + QCOMPARE(parent.child(0), item); + QCOMPARE(parent.child(1), lastItem); +} + +void TreeItemUtilTest::testAddFlatItemAlreadyAdded() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = 0; + + TreeItemUtil::addFlatItemIfNeeded(&parent, item, 0); + TreeItemUtil::addFlatItemIfNeeded(&parent, item, 0); + + QVERIFY(item); + QCOMPARE(item->parent(), &parent); + QCOMPARE(parent.childCount(), 2); + QCOMPARE(parent.child(0), item); + QCOMPARE(parent.child(1), lastItem); +} + +void TreeItemUtilTest::testRemoveFlatItem() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = new TextTreeItem(&parent); + parent.insertChild(item, 0); + + TreeItemUtil::removeFlatItemIfNeeded(item); + + QVERIFY(!item); + QCOMPARE(parent.childCount(), 1); + QCOMPARE(parent.child(0), lastItem); +} + +void TreeItemUtilTest::testRemoveFlatItemAlreadyRemoved() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = new TextTreeItem(&parent); + parent.insertChild(item, 0); + + TreeItemUtil::removeFlatItemIfNeeded(item); + TreeItemUtil::removeFlatItemIfNeeded(item); + + QVERIFY(!item); + QCOMPARE(parent.childCount(), 1); + QCOMPARE(parent.child(0), lastItem); +} + +void TreeItemUtilTest::testAddNestedItem() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = 0; + + TreeItemUtil::addNestedItemIfNeeded(&parent, item, 0, "Parent text"); + + QVERIFY(item); + QCOMPARE(parent.childCount(), 2); + QCOMPARE(item->parent(), parent.child(0)); + QCOMPARE(parent.child(0)->parent(), &parent); + QCOMPARE(parent.child(0)->text(), QString("Parent text")); + QCOMPARE(parent.child(0)->childCount(), 1); + QCOMPARE(parent.child(0)->child(0), item); + QCOMPARE(parent.child(1), lastItem); +} + +void TreeItemUtilTest::testAddNestedItemAlreadyAdded() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = 0; + + TreeItemUtil::addNestedItemIfNeeded(&parent, item, 0, "Parent text"); + TreeItemUtil::addNestedItemIfNeeded(&parent, item, 0, "Parent text2"); + + QVERIFY(item); + QCOMPARE(parent.childCount(), 2); + QCOMPARE(item->parent(), parent.child(0)); + QCOMPARE(parent.child(0)->parent(), &parent); + QCOMPARE(parent.child(0)->text(), QString("Parent text")); + QCOMPARE(parent.child(0)->childCount(), 1); + QCOMPARE(parent.child(0)->child(0), item); + QCOMPARE(parent.child(1), lastItem); +} + +void TreeItemUtilTest::testRemoveNestedItem() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = new TextTreeItem(&parent); + parent.insertChild(item, 0); + TextTreeItem* childItem = new TextTreeItem(item); + item->appendChild(childItem); + + TreeItemUtil::removeNestedItemIfNeeded(childItem); + + QVERIFY(!childItem); + QCOMPARE(parent.childCount(), 1); + QCOMPARE(parent.child(0), lastItem); +} + +void TreeItemUtilTest::testRemoveNestedItemAlreadyRemoved() { + StubTreeItem parent; + TreeItem* lastItem = new TextTreeItem(&parent); + parent.appendChild(lastItem); + + TextTreeItem* item = new TextTreeItem(&parent); + parent.insertChild(item, 0); + TextTreeItem* childItem = new TextTreeItem(item); + item->appendChild(childItem); + + TreeItemUtil::removeNestedItemIfNeeded(childItem); + TreeItemUtil::removeNestedItemIfNeeded(childItem); + + QVERIFY(!childItem); + QCOMPARE(parent.childCount(), 1); + QCOMPARE(parent.child(0), lastItem); +} + +QTEST_MAIN(TreeItemUtilTest) + +#include "TreeItemUtilTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeItemUtilTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-07 22:50:22
|
Revision: 120 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=120&view=rev Author: danxuliu Date: 2010-03-07 22:50:16 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Include a list of steps in tutorial. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp trunk/ktutorial/ktutorial-editor/src/Tutorial.h trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -20,11 +20,17 @@ #include <QStringList> +#include "Step.h" + //public: Tutorial::Tutorial(QObject* parent) { } +Tutorial::~Tutorial() { + qDeleteAll(mSteps); +} + QString Tutorial::id() const { return toLowerCamelCase(mName); } @@ -79,6 +85,26 @@ emit dataChanged(this); } +void Tutorial::addStep(Step* step) { + Q_ASSERT(!mSteps.contains(step)); + + mSteps.append(step); + + emit stepAdded(step); +} + +QList<Step*> Tutorial::steps() const { + return mSteps; +} + +void Tutorial::removeStep(Step* step) { + Q_ASSERT(mSteps.contains(step)); + + mSteps.removeOne(step); + + emit stepRemoved(step); +} + //private: QString Tutorial::toLowerCamelCase(const QString& text) const { Modified: trunk/ktutorial/ktutorial-editor/src/Tutorial.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.h 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.h 2010-03-07 22:50:16 UTC (rev 120) @@ -19,8 +19,11 @@ #ifndef TUTORIAL_H #define TUTORIAL_H +#include <QList> #include <QObject> +class Step; + /** * Container for tutorial data. * It stores the data used in KTutorial tutorials, but it has nothing to do with @@ -28,6 +31,8 @@ * generate the code to create a true KTutorial::Tutorial. * * When any attribute is modified, dataChanged(Tutorial*) signal is emitted. + * When steps are added or removed, stepAdded(Step*) and stepRemoved(Step*) are + * emitted. */ class Tutorial: public QObject { Q_OBJECT @@ -36,6 +41,11 @@ Tutorial(QObject* parent = 0); /** + * Destroys this Tutorial and all its steps. + */ + virtual ~Tutorial(); + + /** * Returns the id of this Tutorial. * The id is a lowerCamelCase version of the name. * @@ -58,6 +68,24 @@ QString customTearDownCode() const; void setCustomTearDownCode(const QString& code); + /** + * Adds a new step to this Tutorial. + * The Tutorial gets ownership of the Step, so it is deleted when the + * Tutorial is deleted. + * + * @param step The step to add. + */ + void addStep(Step* step); + QList<Step*> steps() const; + + /** + * Removes a step from this Tutorial. + * The Step must be deleted explicitly. + * + * @param step The step to remove. + */ + void removeStep(Step* step); + Q_SIGNALS: /** @@ -67,6 +95,20 @@ */ void dataChanged(Tutorial* tutorial); + /** + * Emitted when the step is added to the tutorial. + * + * @param step The step added. + */ + void stepAdded(Step* step); + + /** + * Emitted when the step is removed from the tutorial. + * + * @param step The step removed. + */ + void stepRemoved(Step* step); + private: QString mName; @@ -74,6 +116,7 @@ QString mLicenseText; QString mCustomSetupCode; QString mCustomTearDownCode; + QList<Step*> mSteps; /** * Returns the lowerCamelCase version of the given text. Modified: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -27,7 +27,8 @@ //public: StepTreeItem::StepTreeItem(Step* step, TreeItem* parent): - TreeItem(parent) { + TreeItem(parent), + mStep(step) { Q_ASSERT(step); mTextItem = 0; @@ -47,6 +48,10 @@ return i18nc("@item", "Step %1", mStepId); } +Step* StepTreeItem::step() const { + return mStep; +} + //private slots: void StepTreeItem::update(Step* step) { Modified: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h 2010-03-07 22:50:16 UTC (rev 120) @@ -70,9 +70,21 @@ */ virtual QString text() const; + /** + * Returns the Step. + * + * @return The Step. + */ + Step* step() const; + private: /** + * The Step. + */ + Step* mStep; + + /** * The id of the step. */ QString mStepId; Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -20,6 +20,7 @@ #include <KLocalizedString> +#include "StepTreeItem.h" #include "TextTreeItem.h" #include "TreeItemUtil.h" #include "../Tutorial.h" @@ -39,6 +40,14 @@ update(tutorial); connect(tutorial, SIGNAL(dataChanged(Tutorial*)), this, SLOT(update(Tutorial*))); + + foreach(Step* step, tutorial->steps()) { + addStep(step); + } + connect(tutorial, SIGNAL(stepAdded(Step*)), + this, SLOT(addStep(Step*))); + connect(tutorial, SIGNAL(stepRemoved(Step*)), + this, SLOT(removeStep(Step*))); } QString TutorialTreeItem::text() const { @@ -49,6 +58,18 @@ return i18nc("@item", "Tutorial %1", mTutorialId); } +//private: + +StepTreeItem* TutorialTreeItem::stepTreeItemForStep(Step* step) { + foreach (StepTreeItem* stepTreeItem, mStepTreeItems) { + if (stepTreeItem->step() == step) { + return stepTreeItem; + } + } + + return 0; +} + //private slots: void TutorialTreeItem::update(Tutorial* tutorial) { @@ -111,3 +132,35 @@ childIndex++; } } + +void TutorialTreeItem::addStep(Step* step) { + TreeItem* rootStepItem; + + if (mStepTreeItems.isEmpty()) { + TextTreeItem* textRootStepItem = new TextTreeItem(this); + textRootStepItem->setText(i18nc("@item", "Steps:")); + appendChild(textRootStepItem); + + rootStepItem = textRootStepItem; + } else { + rootStepItem = mStepTreeItems.at(0)->parent(); + } + + StepTreeItem* stepTreeItem = new StepTreeItem(step, rootStepItem); + rootStepItem->appendChild(stepTreeItem); + mStepTreeItems.append(stepTreeItem); +} + +void TutorialTreeItem::removeStep(Step* step) { + StepTreeItem* stepTreeItem = stepTreeItemForStep(step); + TreeItem* rootStepItem = stepTreeItem->parent(); + + rootStepItem->removeChild(stepTreeItem); + mStepTreeItems.removeOne(stepTreeItem); + delete stepTreeItem; + + if (mStepTreeItems.isEmpty()) { + removeChild(rootStepItem); + delete rootStepItem; + } +} Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeItem.h 2010-03-07 22:50:16 UTC (rev 120) @@ -21,6 +21,8 @@ #include "TreeItem.h" +class Step; +class StepTreeItem; class TextTreeItem; class Tutorial; @@ -34,8 +36,14 @@ * | -The license text * |-Setup: * | -The custom setup code - * --Tear down: - * -The custom tear down code + * |-Tear down: + * | -The custom tear down code + * --Steps: + * -Step first step added + * ... + * -Step second step added + * ... + * ... * * The items only appear if they have some data to show. For example, if only * the name of the Tutorial is set, its representation is: @@ -51,6 +59,8 @@ * Also note that the order of the child elements is always the same. Even if, * for example, the setup code is set first and then the name, the name item * will appear first and then the setup code item. + * + * @see StepTreeItem */ class TutorialTreeItem: public TreeItem { Q_OBJECT @@ -111,6 +121,19 @@ */ TextTreeItem* mTearDownItem; + /** + * The StepTreeItems for each Step in the Tutorial. + */ + QList<StepTreeItem*> mStepTreeItems; + + /** + * Returns the StepTreeItem for the given Step. + * + * @param step The Step to get its StepTreeItem. + * @return The StepTreeItem. + */ + StepTreeItem* stepTreeItemForStep(Step* step); + private Q_SLOTS: /** @@ -125,6 +148,22 @@ */ void update(Tutorial* tutorial); + /** + * Adds a new StepTreeItem when a Step is added in the tutorial. + * If there were no other steps yet, the parent "Steps:" item is also added. + * + * @param step The Step added in the Tutorial. + */ + void addStep(Step* step); + + /** + * Removes the StepTreeItem for the Step removed in the tutorial. + * If there are no other steps, the parent "Steps:" item is also removed. + * + * @param step The Step removed in the Tutorial. + */ + void removeStep(Step* step); + }; #endif Modified: trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -19,12 +19,15 @@ #include <QtTest> #include "Tutorial.h" +#include "Step.h" class TutorialTest: public QObject { Q_OBJECT private slots: + void initTestCase(); + void testId(); void testIdWithEmptyName(); void testIdWithSpaceName(); @@ -39,8 +42,22 @@ void testSetCustomTearDownCode(); + void testAddStep(); + void testRemoveStep(); + +private: + + int mStepStarType; + + void assertStepSignal(const QSignalSpy& spy, int index, Step* step); + }; +void TutorialTest::initTestCase() { + //Step* must be registered in order to be used with QSignalSpy + mStepStarType = qRegisterMetaType<Tutorial*>("Step*"); +} + void TutorialTest::testId() { Tutorial tutorial; tutorial.setName("ThE name of a tutoRial"); @@ -145,6 +162,74 @@ QCOMPARE(qvariant_cast<Tutorial*>(argument), &tutorial); } +//Step* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(Step*); + +void TutorialTest::testAddStep() { + Tutorial tutorial; + Step* step1 = new Step(); + Step* step2 = new Step(); + Step* step3 = new Step(); + + QSignalSpy stepAddedSpy(&tutorial, SIGNAL(stepAdded(Step*))); + + tutorial.addStep(step1); + tutorial.addStep(step2); + tutorial.addStep(step3); + + QCOMPARE(tutorial.steps().count(), 3); + QCOMPARE(tutorial.steps()[0], step1); + QCOMPARE(tutorial.steps()[1], step2); + QCOMPARE(tutorial.steps()[2], step3); + QCOMPARE(stepAddedSpy.count(), 3); + assertStepSignal(stepAddedSpy, 0, step1); + assertStepSignal(stepAddedSpy, 1, step2); + assertStepSignal(stepAddedSpy, 2, step3); +} + +void TutorialTest::testRemoveStep() { + Tutorial tutorial; + + //They will be removed and not deleted by the Tutorial, so they are created + //in stack + Step step1; + Step step2; + Step step3; + + tutorial.addStep(&step1); + tutorial.addStep(&step2); + tutorial.addStep(&step3); + + QSignalSpy stepRemovedSpy(&tutorial, SIGNAL(stepRemoved(Step*))); + + tutorial.removeStep(&step2); + + QCOMPARE(tutorial.steps().count(), 2); + QCOMPARE(tutorial.steps()[0], &step1); + QCOMPARE(tutorial.steps()[1], &step3); + QCOMPARE(stepRemovedSpy.count(), 1); + assertStepSignal(stepRemovedSpy, 0, &step2); + + tutorial.removeStep(&step1); + tutorial.removeStep(&step3); + + QCOMPARE(tutorial.steps().count(), 0); + QCOMPARE(stepRemovedSpy.count(), 3); + assertStepSignal(stepRemovedSpy, 1, &step1); + assertStepSignal(stepRemovedSpy, 2, &step3); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void TutorialTest::assertStepSignal(const QSignalSpy& spy, int index, + Step* step) { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mStepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), step); +} + QTEST_MAIN(TutorialTest) #include "TutorialTest.moc" Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -87,6 +87,7 @@ QCOMPARE(item.parent(), &parent); QCOMPARE(item.text(), i18nc("@item", "Step")); + QCOMPARE(item.step(), &step); QCOMPARE(item.childCount(), 0); } @@ -102,6 +103,7 @@ QCOMPARE(item.parent(), &parent); QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); + QCOMPARE(item.step(), &step); QCOMPARE(item.childCount(), 3); assertText(item.child(0), "The text"); assertCustomSetupCode(item.child(1), "The setup code"); Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp 2010-03-07 18:50:37 UTC (rev 119) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeItemTest.cpp 2010-03-07 22:50:16 UTC (rev 120) @@ -22,6 +22,8 @@ #include <KLocalizedString> +#include "StepTreeItem.h" +#include "../Step.h" #include "../Tutorial.h" class TutorialTreeItemTest: public QObject { @@ -54,6 +56,10 @@ void testTutorialSetCustomTearDownCodeChange(); void testTutorialSetCustomTearDownCodeEmpty(); + void testTutorialAddStep(); + + void testTutorialRemoveStep(); + void testChildOrderWhenSettingDataInTutorial(); void testChildOrderWhenUnsettingDataInTutorial(); @@ -69,6 +75,8 @@ void assertCustomSetupCode(TreeItem* setupItem, const QString& code) const; void assertCustomTearDownCode(TreeItem* tearDownItem, const QString& code) const; + void assertStep(TreeItem* rootStepItem, int index, + const QString& stepId) const; void assertDataChanged(const QSignalSpy& spy, int index, TreeItem* item) const; @@ -106,17 +114,28 @@ tutorial.setCustomSetupCode("The setup code"); tutorial.setCustomTearDownCode("The tear down code"); + Step* step1 = new Step(); + step1->setId("First step"); + tutorial.addStep(step1); + + Step* step2 = new Step(); + step2->setId("Second step"); + tutorial.addStep(step2); + StubTreeItem parent; TutorialTreeItem item(&tutorial, &parent); QCOMPARE(item.parent(), &parent); QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); - QCOMPARE(item.childCount(), 5); + QCOMPARE(item.childCount(), 6); assertName(item.child(0), "The name"); assertDescription(item.child(1), "The description"); assertLicenseText(item.child(2), "The license text"); assertCustomSetupCode(item.child(3), "The setup code"); assertCustomTearDownCode(item.child(4), "The tear down code"); + QCOMPARE(item.child(5)->childCount(), 2); + assertStep(item.child(5), 0, "First step"); + assertStep(item.child(5), 1, "Second step"); } //TreeItem* must be declared as a metatype to be used in qvariant_cast @@ -322,6 +341,30 @@ QCOMPARE(item.childCount(), 0); } +void TutorialTreeItemTest::testTutorialAddStep() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + Step* step = new Step(); + step->setId("Step id"); + tutorial.addStep(step); + + QCOMPARE(item.childCount(), 1); + assertStep(item.child(0), 0, "Step id"); +} + +void TutorialTreeItemTest::testTutorialRemoveStep() { + Tutorial tutorial; + TutorialTreeItem item(&tutorial); + + Step* step = new Step(); + step->setId("Step id"); + tutorial.addStep(step); + tutorial.removeStep(step); + + QCOMPARE(item.childCount(), 0); +} + void TutorialTreeItemTest::testChildOrderWhenSettingDataInTutorial() { Tutorial tutorial; TutorialTreeItem item(&tutorial); @@ -347,24 +390,55 @@ assertCustomSetupCode(item.child(1), "The setup code"); assertCustomTearDownCode(item.child(2), "The tear down code"); + Step* step1 = new Step(); + step1->setId("First step"); + tutorial.addStep(step1); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 4); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + QCOMPARE(item.child(3)->childCount(), 1); + assertStep(item.child(3), 0, "First step"); + tutorial.setName("The name"); QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); - QCOMPARE(item.childCount(), 4); + QCOMPARE(item.childCount(), 5); assertName(item.child(0), "The name"); assertDescription(item.child(1), "The description"); assertCustomSetupCode(item.child(2), "The setup code"); assertCustomTearDownCode(item.child(3), "The tear down code"); + QCOMPARE(item.child(4)->childCount(), 1); + assertStep(item.child(4), 0, "First step"); - tutorial.setLicenseText("The license text"); + Step* step2 = new Step(); + step2->setId("Second step"); + tutorial.addStep(step2); QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); QCOMPARE(item.childCount(), 5); assertName(item.child(0), "The name"); assertDescription(item.child(1), "The description"); + assertCustomSetupCode(item.child(2), "The setup code"); + assertCustomTearDownCode(item.child(3), "The tear down code"); + QCOMPARE(item.child(4)->childCount(), 2); + assertStep(item.child(4), 0, "First step"); + assertStep(item.child(4), 1, "Second step"); + + tutorial.setLicenseText("The license text"); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); + QCOMPARE(item.childCount(), 6); + assertName(item.child(0), "The name"); + assertDescription(item.child(1), "The description"); assertLicenseText(item.child(2), "The license text"); assertCustomSetupCode(item.child(3), "The setup code"); assertCustomTearDownCode(item.child(4), "The tear down code"); + QCOMPARE(item.child(5)->childCount(), 2); + assertStep(item.child(5), 0, "First step"); + assertStep(item.child(5), 1, "Second step"); } void TutorialTreeItemTest::testChildOrderWhenUnsettingDataInTutorial() { @@ -375,41 +449,78 @@ tutorial.setCustomSetupCode("The setup code"); tutorial.setCustomTearDownCode("The tear down code"); + //They will be removed and not deleted by the Tutorial, so they are created + //in stack + Step step1; + step1.setId("First step"); + tutorial.addStep(&step1); + + Step step2; + step2.setId("Second step"); + tutorial.addStep(&step2); + TutorialTreeItem item(&tutorial); tutorial.setLicenseText(""); QCOMPARE(item.text(), i18nc("@item", "Tutorial %1", "theName")); - QCOMPARE(item.childCount(), 4); + QCOMPARE(item.childCount(), 5); assertName(item.child(0), "The name"); assertDescription(item.child(1), "The description"); assertCustomSetupCode(item.child(2), "The setup code"); assertCustomTearDownCode(item.child(3), "The tear down code"); + QCOMPARE(item.child(4)->childCount(), 2); + assertStep(item.child(4), 0, "First step"); + assertStep(item.child(4), 1, "Second step"); tutorial.setName(""); QCOMPARE(item.text(), i18nc("@item", "Tutorial")); - QCOMPARE(item.childCount(), 3); + QCOMPARE(item.childCount(), 4); assertDescription(item.child(0), "The description"); assertCustomSetupCode(item.child(1), "The setup code"); assertCustomTearDownCode(item.child(2), "The tear down code"); + QCOMPARE(item.child(3)->childCount(), 2); + assertStep(item.child(3), 0, "First step"); + assertStep(item.child(3), 1, "Second step"); + tutorial.removeStep(&step1); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 4); + assertDescription(item.child(0), "The description"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + QCOMPARE(item.child(3)->childCount(), 1); + assertStep(item.child(3), 0, "Second step"); + tutorial.setCustomTearDownCode(""); QCOMPARE(item.text(), i18nc("@item", "Tutorial")); - QCOMPARE(item.childCount(), 2); + QCOMPARE(item.childCount(), 3); assertDescription(item.child(0), "The description"); assertCustomSetupCode(item.child(1), "The setup code"); + QCOMPARE(item.child(2)->childCount(), 1); + assertStep(item.child(2), 0, "Second step"); tutorial.setDescription(""); QCOMPARE(item.text(), i18nc("@item", "Tutorial")); - QCOMPARE(item.childCount(), 1); + QCOMPARE(item.childCount(), 2); assertCustomSetupCode(item.child(0), "The setup code"); + QCOMPARE(item.child(1)->childCount(), 1); + assertStep(item.child(1), 0, "Second step"); tutorial.setCustomSetupCode(""); QCOMPARE(item.text(), i18nc("@item", "Tutorial")); + QCOMPARE(item.childCount(), 1); + QCOMPARE(item.child(0)->childCount(), 1); + assertStep(item.child(0), 0, "Second step"); + + tutorial.removeStep(&step2); + + QCOMPARE(item.text(), i18nc("@item", "Tutorial")); QCOMPARE(item.childCount(), 0); } @@ -448,6 +559,14 @@ QCOMPARE(tearDownItem->child(0)->text(), i18nc("@item", code.toAscii())); } +void TutorialTreeItemTest::assertStep(TreeItem* rootStepItem, int index, + const QString& stepId) const { + QCOMPARE(rootStepItem->text(), i18nc("@item", "Steps:")); + QVERIFY(qobject_cast<StepTreeItem*>(rootStepItem->child(index))); + QCOMPARE(rootStepItem->child(index)->text(), + i18nc("@item", "Step %1", stepId)); +} + void TutorialTreeItemTest::assertDataChanged(const QSignalSpy& spy, int index, TreeItem* item) const { QCOMPARE(spy.at(index).count(), 1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-07 23:11:43
|
Revision: 121 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=121&view=rev Author: danxuliu Date: 2010-03-07 23:11:37 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Fix setting parent QObject in Step and Tutorial classes. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/Step.cpp trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/Step.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Step.cpp 2010-03-07 22:50:16 UTC (rev 120) +++ trunk/ktutorial/ktutorial-editor/src/Step.cpp 2010-03-07 23:11:37 UTC (rev 121) @@ -20,7 +20,7 @@ //public: -Step::Step(QObject* parent) { +Step::Step(QObject* parent): QObject(parent) { } QString Step::id() const { Modified: trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-07 22:50:16 UTC (rev 120) +++ trunk/ktutorial/ktutorial-editor/src/Tutorial.cpp 2010-03-07 23:11:37 UTC (rev 121) @@ -24,7 +24,7 @@ //public: -Tutorial::Tutorial(QObject* parent) { +Tutorial::Tutorial(QObject* parent): QObject(parent) { } Tutorial::~Tutorial() { Modified: trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp 2010-03-07 22:50:16 UTC (rev 120) +++ trunk/ktutorial/ktutorial-editor/tests/unit/StepTest.cpp 2010-03-07 23:11:37 UTC (rev 121) @@ -25,6 +25,8 @@ private slots: + void testConstructor(); + void testSetId(); void testSetText(); @@ -35,6 +37,13 @@ }; +void StepTest::testConstructor() { + QObject parent; + Step* step = new Step(&parent); + + QCOMPARE(step->parent(), &parent); +} + //Step* must be declared as a metatype to be used in qvariant_cast Q_DECLARE_METATYPE(Step*); Modified: trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-07 22:50:16 UTC (rev 120) +++ trunk/ktutorial/ktutorial-editor/tests/unit/TutorialTest.cpp 2010-03-07 23:11:37 UTC (rev 121) @@ -28,6 +28,8 @@ void initTestCase(); + void testConstructor(); + void testId(); void testIdWithEmptyName(); void testIdWithSpaceName(); @@ -58,6 +60,13 @@ mStepStarType = qRegisterMetaType<Tutorial*>("Step*"); } +void TutorialTest::testConstructor() { + QObject parent; + Tutorial* tutorial = new Tutorial(&parent); + + QCOMPARE(tutorial->parent(), &parent); +} + void TutorialTest::testId() { Tutorial tutorial; tutorial.setName("ThE name of a tutoRial"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-08 17:41:12
|
Revision: 123 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=123&view=rev Author: danxuliu Date: 2010-03-08 17:41:03 +0000 (Mon, 08 Mar 2010) Log Message: ----------- Add TutorialTreeSelectionManager class to watch changes in selections and notify when a Step was selected in a TreeModel. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-07 23:13:10 UTC (rev 122) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-08 17:41:03 UTC (rev 123) @@ -7,6 +7,7 @@ TreeItemUtil.cpp TreeModel.cpp TutorialTreeItem.cpp + TutorialTreeSelectionManager.cpp ) kde4_add_library(ktutorial_editor_view ${ktutorial_editor_view_SRCS}) Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp 2010-03-08 17:41:03 UTC (rev 123) @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialTreeSelectionManager.h" + +#include "StepTreeItem.h" +#include "TreeItem.h" + +//public: + +TutorialTreeSelectionManager::TutorialTreeSelectionManager( + QItemSelectionModel* itemSelectionModel) { + connect(itemSelectionModel, + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, + SLOT(handleSelectionChanged(QItemSelection, QItemSelection))); +} + +//private: + +void TutorialTreeSelectionManager::updateStepSelection(TreeItem* selected, + TreeItem* deselected) { + Step* selectedStep = getStepForTreeItem(selected); + Step* deselectedStep = getStepForTreeItem(deselected); + + if (selectedStep && selectedStep != deselectedStep) { + emit stepSelected(selectedStep); + return; + } + + if (!selectedStep && deselectedStep) { + emit stepSelected(0); + return; + } +} + +Step* TutorialTreeSelectionManager::getStepForTreeItem(TreeItem* item) { + if (qobject_cast<StepTreeItem*>(item)) { + return static_cast<StepTreeItem*>(item)->step(); + } + + if (item == 0 || item->parent() == 0) { + return 0; + } + + return getStepForTreeItem(item->parent()); +} + +//private slots: + +void TutorialTreeSelectionManager::handleSelectionChanged( + const QItemSelection& selected, + const QItemSelection& deselected) { + //Only single selections are supported + Q_ASSERT(selected.count() <= 1); + Q_ASSERT(deselected.count() <= 1); + + TreeItem* selectedItem = 0; + TreeItem* deselectedItem = 0; + + if (selected.count() == 1) { + Q_ASSERT(selected.at(0).indexes().count() == 1); + + QModelIndex index = selected.at(0).indexes().at(0); + selectedItem = static_cast<TreeItem*>(index.internalPointer()); + } + + if (deselected.count() == 1) { + Q_ASSERT(deselected.at(0).indexes().count() == 1); + + QModelIndex index = deselected.at(0).indexes().at(0); + deselectedItem = static_cast<TreeItem*>(index.internalPointer()); + } + + updateStepSelection(selectedItem, deselectedItem); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h 2010-03-08 17:41:03 UTC (rev 123) @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TUTORIALTREESELECTIONMANAGER_H +#define TUTORIALTREESELECTIONMANAGER_H + +#include <QItemSelectionModel> +#include <QObject> + +class Step; +class TreeItem; + +/** + * Watches the QItemSelectionModel of a TreeModel for changes in the selection. + * When an item is selected in the TreeModel, it is checked what kind of data it + * represents. If it is a Step, stepSelected(Step*) signal is emitted. + * + * Only single item selections are supported. + */ +class TutorialTreeSelectionManager: public QObject { +Q_OBJECT +public: + + /** + * Creates a new TutorialTreeSelectionManager that watchs the given + * selection model. + * + * @param itemSelectionModel The selection model to watch for changes in the + * selection. + */ + TutorialTreeSelectionManager(QItemSelectionModel* itemSelectionModel); + +Q_SIGNALS: + + /** + * Emitted when a Step (or any of its child items) is selected. + * If the Step is deselected and the new selected item isn't a Step, the + * signal is emitted with a null pointer. + * No signal is emitted if the selected item changes to another item that + * selects the same Step already selected. + * + * @param step The selected Step, or null if it was deselected. + */ + void stepSelected(Step* step); + +private: + + /** + * Emits stepSelected(Step*) signal based on the selected and deselected + * items. + * + * @param selected The selected item, if any. + * @param deselected The deselected item, if any. + */ + void updateStepSelection(TreeItem* selected, TreeItem* deselected); + + /** + * Returns the Step represented by the given item. + * Any recursive child item of a StepTreeItem, or a StepTreeItem itself, + * represents a Step. + * + * If the item doesn't represent a Step or there is no item, a null pointer + * is returned. + * + * @param item The item to get its represented Step. + * @return The Step. + */ + Step* getStepForTreeItem(TreeItem* item); + +private Q_SLOTS: + + /** + * Handles a change in the selection in the watched selection model. + * Signals are emitted as needed based on the selected and deselected items. + * + * @param selected The item selection of selected items. + * @param selected The item selection of deselected items. + */ + void handleSelectionChanged(const QItemSelection& selected, + const QItemSelection& deselected); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-07 23:13:10 UTC (rev 122) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-08 17:41:03 UTC (rev 123) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem) +unit_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem) +mem_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp 2010-03-08 17:41:03 UTC (rev 123) @@ -0,0 +1,328 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialTreeSelectionManager.h" + +#include "TreeModel.h" +#include "TutorialTreeItem.h" +#include "../Step.h" +#include "../Tutorial.h" + +class TutorialTreeSelectionManagerTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + void testSelectTutorialOrChildren(); + + void testSelectStepOrChildrenChangingToOtherItems(); + void testSelectStepOrChildrenWithoutChangingStep(); + void testSelectStepOrChildrenChangingToAnotherStep(); + +private: + + int mStepStarType; + + Tutorial* mTutorial; + Step* mStep1; + Step* mStep2; + TreeModel* mTreeModel; + + QItemSelectionModel* mSelectionModel; + TutorialTreeSelectionManager* mSelectionManager; + QSignalSpy* mStepSelectedSpy; + + void select(const QModelIndex& index); + + void assertStepSignal(const QSignalSpy* spy, int index, Step* step) const; + +}; + +void TutorialTreeSelectionManagerTest::initTestCase() { + //Step* must be registered in order to be used with QSignalSpy + mStepStarType = qRegisterMetaType<Step*>("Step*"); + + mTutorial = new Tutorial(); + mTutorial->setName("The name"); + mTutorial->setDescription("The description"); + mTutorial->setLicenseText("The license text"); + mTutorial->setCustomSetupCode("The setup code"); + mTutorial->setCustomTearDownCode("The tear down code"); + + mStep1 = new Step(); + mStep1->setId("First step"); + mStep1->setText("Text 1"); + mStep1->setCustomSetupCode("Setup 1"); + mStep1->setCustomTearDownCode("Tear down 1"); + mTutorial->addStep(mStep1); + + mStep2 = new Step(); + mStep2->setId("Second step"); + mStep2->setText("Text 2"); + mStep2->setCustomSetupCode("Setup 2"); + mStep2->setCustomTearDownCode("Tear down 2"); + mTutorial->addStep(mStep2); + + mTreeModel = new TreeModel(new TutorialTreeItem(mTutorial)); +} + +void TutorialTreeSelectionManagerTest::init() { + mSelectionModel = new QItemSelectionModel(mTreeModel); + mSelectionManager = new TutorialTreeSelectionManager(mSelectionModel); + + mStepSelectedSpy = new QSignalSpy(mSelectionManager, + SIGNAL(stepSelected(Step*))); +} + +void TutorialTreeSelectionManagerTest::cleanup() { + delete mStepSelectedSpy; + delete mSelectionManager; + delete mSelectionModel; +} + +void TutorialTreeSelectionManagerTest::cleanupTestCase() { + delete mTreeModel; + delete mTutorial; +} + +void TutorialTreeSelectionManagerTest::testSelectTutorialOrChildren() { + //Name + select(mTreeModel->index(0, 0)); + //Description + select(mTreeModel->index(1, 0)); + //License + select(mTreeModel->index(2, 0)); + select(mTreeModel->index(0, 0, mTreeModel->index(2, 0))); + //Setup + select(mTreeModel->index(3, 0)); + select(mTreeModel->index(0, 0, mTreeModel->index(3, 0))); + //Tear down + select(mTreeModel->index(4, 0)); + select(mTreeModel->index(0, 0, mTreeModel->index(4, 0))); + //Steps root + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 0); +} + +void TutorialTreeSelectionManagerTest:: + testSelectStepOrChildrenChangingToOtherItems() { + QModelIndex step1Index = mTreeModel->index(0, 0, mTreeModel->index(5, 0)); + + select(step1Index); + + QCOMPARE(mStepSelectedSpy->count(), 1); + assertStepSignal(mStepSelectedSpy, 0, mStep1); + + //Steps root + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 2); + assertStepSignal(mStepSelectedSpy, 1, 0); + + //Text + select(mTreeModel->index(0, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 3); + assertStepSignal(mStepSelectedSpy, 2, mStep1); + + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 4); + assertStepSignal(mStepSelectedSpy, 3, 0); + + //Setup + select(mTreeModel->index(1, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 5); + assertStepSignal(mStepSelectedSpy, 4, mStep1); + + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 6); + assertStepSignal(mStepSelectedSpy, 5, 0); + + //Setup code + select(mTreeModel->index(0, 0, mTreeModel->index(1, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 7); + assertStepSignal(mStepSelectedSpy, 6, mStep1); + + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 8); + assertStepSignal(mStepSelectedSpy, 7, 0); + + //Tear down + select(mTreeModel->index(2, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 9); + assertStepSignal(mStepSelectedSpy, 8, mStep1); + + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 10); + assertStepSignal(mStepSelectedSpy, 9, 0); + + //Tear down code + select(mTreeModel->index(0, 0, mTreeModel->index(2, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 11); + assertStepSignal(mStepSelectedSpy, 10, mStep1); + + select(mTreeModel->index(5, 0)); + + QCOMPARE(mStepSelectedSpy->count(), 12); + assertStepSignal(mStepSelectedSpy, 11, 0); +} + +void TutorialTreeSelectionManagerTest:: + testSelectStepOrChildrenWithoutChangingStep() { + QModelIndex step1Index = mTreeModel->index(0, 0, mTreeModel->index(5, 0)); + + select(step1Index); + + QCOMPARE(mStepSelectedSpy->count(), 1); + assertStepSignal(mStepSelectedSpy, 0, mStep1); + + //Text + select(mTreeModel->index(0, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 1); + + //Setup + select(mTreeModel->index(1, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 1); + + //Setup code + select(mTreeModel->index(0, 0, mTreeModel->index(1, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 1); + + //Tear down + select(mTreeModel->index(2, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 1); + + //Tear down code + select(mTreeModel->index(0, 0, mTreeModel->index(2, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 1); +} + +void TutorialTreeSelectionManagerTest:: + testSelectStepOrChildrenChangingToAnotherStep() { + QModelIndex step1Index = mTreeModel->index(0, 0, mTreeModel->index(5, 0)); + QModelIndex step2Index = mTreeModel->index(1, 0, mTreeModel->index(5, 0)); + + select(step1Index); + + QCOMPARE(mStepSelectedSpy->count(), 1); + assertStepSignal(mStepSelectedSpy, 0, mStep1); + + select(step2Index); + + QCOMPARE(mStepSelectedSpy->count(), 2); + assertStepSignal(mStepSelectedSpy, 1, mStep2); + + //Text + select(mTreeModel->index(0, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 3); + assertStepSignal(mStepSelectedSpy, 2, mStep1); + + select(mTreeModel->index(0, 0, step2Index)); + + QCOMPARE(mStepSelectedSpy->count(), 4); + assertStepSignal(mStepSelectedSpy, 3, mStep2); + + //Setup + select(mTreeModel->index(1, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 5); + assertStepSignal(mStepSelectedSpy, 4, mStep1); + + select(mTreeModel->index(1, 0, step2Index)); + + QCOMPARE(mStepSelectedSpy->count(), 6); + assertStepSignal(mStepSelectedSpy, 5, mStep2); + + //Setup code + select(mTreeModel->index(0, 0, mTreeModel->index(1, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 7); + assertStepSignal(mStepSelectedSpy, 6, mStep1); + + select(mTreeModel->index(0, 0, mTreeModel->index(1, 0, step2Index))); + + QCOMPARE(mStepSelectedSpy->count(), 8); + assertStepSignal(mStepSelectedSpy, 7, mStep2); + + //Tear down + select(mTreeModel->index(2, 0, step1Index)); + + QCOMPARE(mStepSelectedSpy->count(), 9); + assertStepSignal(mStepSelectedSpy, 8, mStep1); + + select(mTreeModel->index(2, 0, step2Index)); + + QCOMPARE(mStepSelectedSpy->count(), 10); + assertStepSignal(mStepSelectedSpy, 9, mStep2); + + //Tear down code + select(mTreeModel->index(0, 0, mTreeModel->index(2, 0, step1Index))); + + QCOMPARE(mStepSelectedSpy->count(), 11); + assertStepSignal(mStepSelectedSpy, 10, mStep1); + + select(mTreeModel->index(0, 0, mTreeModel->index(2, 0, step2Index))); + + QCOMPARE(mStepSelectedSpy->count(), 12); + assertStepSignal(mStepSelectedSpy, 11, mStep2); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void TutorialTreeSelectionManagerTest::select(const QModelIndex& index) { + mSelectionModel->select(index, QItemSelectionModel::SelectCurrent); +} + +//Step* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(Step*); + +void TutorialTreeSelectionManagerTest::assertStepSignal(const QSignalSpy* spy, + int index, + Step* step) const { + QCOMPARE(spy->at(index).count(), 1); + + QVariant argument = spy->at(index).at(0); + QCOMPARE(argument.userType(), mStepStarType); + QCOMPARE(qvariant_cast<Step*>(argument), step); +} + +QTEST_MAIN(TutorialTreeSelectionManagerTest) + +#include "TutorialTreeSelectionManagerTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 02:18:31
|
Revision: 125 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=125&view=rev Author: danxuliu Date: 2010-03-09 02:18:24 +0000 (Tue, 09 Mar 2010) Log Message: ----------- -Added EditionWidget as base class for widgets that edit data in a tutorial. -Added EditionDialog class that wraps an EditionWidget and provides "Ok" and "Cancel" buttons. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.cpp trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.h trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.h trunk/ktutorial/ktutorial-editor/tests/unit/view/EditionDialogTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-08 18:47:18 UTC (rev 124) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 02:18:24 UTC (rev 125) @@ -1,6 +1,8 @@ include_directories(${KDE4_INCLUDES}) set(ktutorial_editor_view_SRCS + EditionDialog.cpp + EditionWidget.cpp StepTreeItem.cpp TextTreeItem.cpp TreeItem.cpp Added: trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.cpp 2010-03-09 02:18:24 UTC (rev 125) @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "EditionDialog.h" + +#include <KLocalizedString> + +#include "EditionWidget.h" + +//public: + +EditionDialog::EditionDialog(EditionWidget* editionWidget, QWidget* parent): + KDialog(parent), + mEditionWidget(editionWidget) { + + editionWidget->setParent(this); + + setMainWidget(editionWidget); + setWindowTitle(editionWidget->windowTitle()); + + setModal(true); + + setButtons(KDialog::Ok | KDialog::Cancel); +} + +//protected slots: + +void EditionDialog::slotButtonClicked(int button) { + if (button == KDialog::Ok) { + mEditionWidget->saveChanges(); + } + + KDialog::slotButtonClicked(button); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.cpp ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.h 2010-03-09 02:18:24 UTC (rev 125) @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2010 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 EDITIONDIALOG_H +#define EDITIONDIALOG_H + +#include <KDialog> + +class EditionWidget; + +/** + * Wrapper dialog for EditionWidgets that provides Ok and Cancel buttons. + * When the user clicks the "Ok" button, the changes are saved to the object + * being edited by the EditionWidget. + * + * By default, the dialog is modal and gets its window title from the edition + * widget own window title. + * + * @see EditionWidgdet + */ +class EditionDialog: public KDialog { +Q_OBJECT +public: + + /** + * Creates and shows a new TutorialManagerDialog. + * The EditionWidget is reparented to this dialog and destroyed when this + * EditionDialog is destroyed. + * + * @param editionWidget The EditionWidget to wrap. + * @param parent The parent widget of this dialog, defaults to null. + */ + explicit EditionDialog(EditionWidget* editionWidget, QWidget* parent = 0); + +protected Q_SLOTS: + + /** + * Hides the dialog, saving the changes if the button clicked was "Ok" + * button. + * + * @param button The button clicked. + */ + virtual void slotButtonClicked(int button); + +private: + + /** + * The EditionWidget wrapped. + */ + EditionWidget* mEditionWidget; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/EditionDialog.h ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.cpp 2010-03-09 02:18:24 UTC (rev 125) @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "EditionWidget.h" + +//public: + +EditionWidget::EditionWidget(QWidget* parent): QWidget(parent) { +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.h 2010-03-09 02:18:24 UTC (rev 125) @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2010 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 EDITIONWIDGET_H +#define EDITIONWIDGET_H + +#include <QWidget> + +/** + * Base abstract class for edition widgets. + * Widgets mean to edit any data in the tutorial must inherit from this class. + * A generic edition dialog with Ok and Cancel buttons is provided by + * EditionDialog class. The dialog wraps an EditionWidget and saves the changes + * using saveChanges() method when needed. + * + * Subclasses must implement saveChanges method to commit the changes to the + * object being edited. + * + * @see EditionDialog + */ +class EditionWidget: public QWidget { +Q_OBJECT +public: + + /** + * Creates a new EditionWidget with the given parent. + * + * @param parent The parent widget. + */ + EditionWidget(QWidget* parent = 0); + + /** + * Saves the changes to the object being edited. + * This method must be implemented in subclasses. + */ + virtual void saveChanges() = 0; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/EditionWidget.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-08 18:47:18 UTC (rev 124) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 02:18:24 UTC (rev 125) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) +unit_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) +mem_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/EditionDialogTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/EditionDialogTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/EditionDialogTest.cpp 2010-03-09 02:18:24 UTC (rev 125) @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "EditionDialog.h" + +#include <KPushButton> + +#include "EditionWidget.h" + +class EditionDialogTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testOk(); + void testCancel(); + +}; + +class MockEditionWidget: public EditionWidget { +public: + + int mSaveChangesCallCount; + + MockEditionWidget(QWidget* parent = 0): EditionWidget(parent), + mSaveChangesCallCount(0) { + setWindowTitle("The edition widget title"); + } + + virtual void saveChanges() { + mSaveChangesCallCount++; + } + +}; + +void EditionDialogTest::testConstructor() { + EditionWidget* editionWidget = new MockEditionWidget(); + QWidget parentWidget; + EditionDialog* dialog = new EditionDialog(editionWidget, &parentWidget); + + QCOMPARE(dialog->mainWidget(), editionWidget); + QCOMPARE(dialog->mainWidget()->parent(), dialog); + QCOMPARE(dialog->parentWidget(), &parentWidget); + QVERIFY(dialog->isModal()); + QCOMPARE(dialog->windowTitle(), QString("The edition widget title")); + QVERIFY(dialog->button(KDialog::Ok)); + QVERIFY(dialog->button(KDialog::Cancel)); +} + +void EditionDialogTest::testOk() { + MockEditionWidget* editionWidget = new MockEditionWidget(); + EditionDialog dialog(editionWidget); + + dialog.button(KDialog::Ok)->click(); + + QCOMPARE(editionWidget->mSaveChangesCallCount, 1); + QVERIFY(dialog.isHidden()); +} + +void EditionDialogTest::testCancel() { + MockEditionWidget* editionWidget = new MockEditionWidget(); + EditionDialog dialog(editionWidget); + + dialog.button(KDialog::Cancel)->click(); + + QCOMPARE(editionWidget->mSaveChangesCallCount, 0); + QVERIFY(dialog.isHidden()); +} + +QTEST_MAIN(EditionDialogTest) + +#include "EditionDialogTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/EditionDialogTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 03:01:33
|
Revision: 126 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=126&view=rev Author: danxuliu Date: 2010-03-09 03:01:27 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Fix header data update in TreeModel. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp 2010-03-09 02:18:24 UTC (rev 125) +++ trunk/ktutorial/ktutorial-editor/src/view/TreeModel.cpp 2010-03-09 03:01:27 UTC (rev 126) @@ -188,6 +188,11 @@ } void TreeModel::treeItemDataChanged(TreeItem* item) { + if (item == mRootItem) { + emit headerDataChanged(Qt::Horizontal, 0, 0); + return; + } + QModelIndex index = createIndex(item->childIndex(), 0, item); emit dataChanged(index, index); Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp 2010-03-09 02:18:24 UTC (rev 125) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TreeModelTest.cpp 2010-03-09 03:01:27 UTC (rev 126) @@ -49,6 +49,7 @@ void testChangeChildrenOfRemovedNestedItem(); void testChangeItemData(); + void testChangeRootItemData(); void testDataWithInvalidIndex(); void testDataWithInvalidRole(); @@ -516,6 +517,37 @@ QCOMPARE(qvariant_cast<QModelIndex>(argument), index); } +//Qt::Orientation must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(Qt::Orientation); + +void TreeModelTest::testChangeRootItemData() { + StubTreeItem* rootItem = new StubTreeItem("root"); + TreeModel model(rootItem); + + //Qt::Orientation must be registered in order to be used with QSignalSpy + int orientationIndexType = qRegisterMetaType<Qt::Orientation>("Qt::Orientation"); + QSignalSpy headerDataChangedSpy(&model, + SIGNAL(headerDataChanged(Qt::Orientation, int, int))); + + rootItem->setText("root modified"); + + QCOMPARE(model.rowCount(), 0); + QCOMPARE(model.columnCount(), 1); + QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), + QString("root modified")); + + QCOMPARE(headerDataChangedSpy.count(), 1); + QVariant argument = headerDataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), orientationIndexType); + QCOMPARE(qvariant_cast<Qt::Orientation>(argument), Qt::Horizontal); + argument = headerDataChangedSpy.at(0).at(1); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), 0); + argument = headerDataChangedSpy.at(0).at(2); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), 0); +} + void TreeModelTest::testDataWithInvalidIndex() { TreeModel model(mSingleItem); mSingleItem = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 03:41:31
|
Revision: 127 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=127&view=rev Author: danxuliu Date: 2010-03-09 03:41:25 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Add parent argument to TutorialTreeSelectionManager constructor. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp 2010-03-09 03:01:27 UTC (rev 126) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.cpp 2010-03-09 03:41:25 UTC (rev 127) @@ -24,7 +24,8 @@ //public: TutorialTreeSelectionManager::TutorialTreeSelectionManager( - QItemSelectionModel* itemSelectionModel) { + QItemSelectionModel* itemSelectionModel, + QObject* parent): QObject(parent) { connect(itemSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, Modified: trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h 2010-03-09 03:01:27 UTC (rev 126) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialTreeSelectionManager.h 2010-03-09 03:41:25 UTC (rev 127) @@ -42,8 +42,10 @@ * * @param itemSelectionModel The selection model to watch for changes in the * selection. + * @param parent The parent object. */ - TutorialTreeSelectionManager(QItemSelectionModel* itemSelectionModel); + TutorialTreeSelectionManager(QItemSelectionModel* itemSelectionModel, + QObject* parent = 0); Q_SIGNALS: Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp 2010-03-09 03:01:27 UTC (rev 126) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialTreeSelectionManagerTest.cpp 2010-03-09 03:41:25 UTC (rev 127) @@ -35,6 +35,8 @@ void cleanup(); void cleanupTestCase(); + void testConstructor(); + void testSelectTutorialOrChildren(); void testSelectStepOrChildrenChangingToOtherItems(); @@ -107,6 +109,14 @@ delete mTutorial; } +void TutorialTreeSelectionManagerTest::testConstructor() { + QObject parent; + TutorialTreeSelectionManager* selectionManager = + new TutorialTreeSelectionManager(mSelectionModel, &parent); + + QCOMPARE(selectionManager->parent(), &parent); +} + void TutorialTreeSelectionManagerTest::testSelectTutorialOrChildren() { //Name select(mTreeModel->index(0, 0)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 04:33:54
|
Revision: 128 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=128&view=rev Author: danxuliu Date: 2010-03-09 04:33:47 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Add TutorialInformationWidget to edit the name and description of a tutorial. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.h trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.ui trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialInformationWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 03:41:25 UTC (rev 127) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 04:33:47 UTC (rev 128) @@ -8,10 +8,15 @@ TreeItem.cpp TreeItemUtil.cpp TreeModel.cpp + TutorialInformationWidget.cpp TutorialTreeItem.cpp TutorialTreeSelectionManager.cpp ) +kde4_add_ui_files(ktutorial_editor_view_SRCS + TutorialInformationWidget.ui +) + kde4_add_library(ktutorial_editor_view ${ktutorial_editor_view_SRCS}) target_link_libraries(ktutorial_editor_view ktutorial_editor ${KDE4_KDEUI_LIBS}) Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.cpp 2010-03-09 04:33:47 UTC (rev 128) @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialInformationWidget.h" + +#include "ui_TutorialInformationWidget.h" +#include "../Tutorial.h" + +//public: + +TutorialInformationWidget::TutorialInformationWidget(Tutorial* tutorial, + QWidget* parent): + EditionWidget(parent), + mTutorial(tutorial) { + ui = new Ui::TutorialInformationWidgetUi(); + ui->setupUi(this); + + ui->nameLineEdit->setText(tutorial->name()); + ui->descriptionTextEdit->setText(tutorial->description()); +} + +TutorialInformationWidget::~TutorialInformationWidget() { + delete ui; +} + +void TutorialInformationWidget::saveChanges() { + QString name = ui->nameLineEdit->text(); + if (mTutorial->name() != name) { + mTutorial->setName(name); + } + + QString description = ui->descriptionTextEdit->toPlainText(); + if (mTutorial->description() != description) { + mTutorial->setDescription(description); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.h 2010-03-09 04:33:47 UTC (rev 128) @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TUTORIALINFORMATIONWIDGET_H +#define TUTORIALINFORMATIONWIDGET_H + +#include "EditionWidget.h" + +class Tutorial; + +namespace Ui { +class TutorialInformationWidgetUi; +} + +/** + * Edition widget for the name and description of a Tutorial. + */ +class TutorialInformationWidget: public EditionWidget { +Q_OBJECT +public: + + /** + * Creates a new TutorialInformationWidget for the given Tutorial. + * + * @param tutorial The tutorial to edit. + * @param parent The parent QWidget. + */ + explicit TutorialInformationWidget(Tutorial* tutorial, QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~TutorialInformationWidget(); + + /** + * Saves the name and description in the tutorial. + */ + virtual void saveChanges(); + +private: + + /** + * The tutorial to edit. + */ + Tutorial* mTutorial; + + /** + * The Ui Designer generated class. + */ + Ui::TutorialInformationWidgetUi* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialInformationWidget.ui 2010-03-09 04:33:47 UTC (rev 128) @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>TutorialInformationWidgetUi</class> + <widget class="QWidget" name="TutorialInformationWidgetUi"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Set tutorial information</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Set the name and description of the tutorial.</para><para>The name and the description are shown in the dialog where the tutorial to be started is selected.</para></string> + </property> + <layout class="QVBoxLayout" name="tutorialInformationWidgetUiLayout"> + <item> + <widget class="QGroupBox" name="tutorialInformationGroupBox"> + <property name="title"> + <string comment="@title">Tutorial information</string> + </property> + <layout class="QVBoxLayout" name="tutorialInformationGroupBoxLayout"> + <item> + <layout class="QHBoxLayout" name="nameLayout"> + <item> + <widget class="QLabel" name="nameLabel"> + <property name="whatsThis"> + <string comment="@info:whatsthis">The name to set in the tutorial.</string> + </property> + <property name="text"> + <string comment="@label:textbox">Name:</string> + </property> + <property name="buddy"> + <cstring>nameLineEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="KLineEdit" name="nameLineEdit"/> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="descriptionLayout"> + <item> + <widget class="QLabel" name="descriptionLabel"> + <property name="whatsThis"> + <string comment="@info:whatsthis">The description to set in the tutorial.</string> + </property> + <property name="text"> + <string comment="@label:textbox">Description:</string> + </property> + <property name="buddy"> + <cstring>descriptionTextEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="KTextEdit" name="descriptionTextEdit"/> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + <customwidget> + <class>KTextEdit</class> + <extends>QTextEdit</extends> + <header>ktextedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 03:41:25 UTC (rev 127) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 04:33:47 UTC (rev 128) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) +unit_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialTreeItem TutorialTreeSelectionManager) +mem_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialInformationWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialInformationWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialInformationWidgetTest.cpp 2010-03-09 04:33:47 UTC (rev 128) @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialInformationWidget.h" + +#include <KLineEdit> +#include <KTextEdit> + +#include "../Tutorial.h" + +class TutorialInformationWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSaveChanges(); + +private: + + KLineEdit* nameLineEdit(TutorialInformationWidget* widget) const; + KTextEdit* descriptionTextEdit(TutorialInformationWidget* widget) const; + +}; + +void TutorialInformationWidgetTest::testConstructor() { + Tutorial tutorial; + tutorial.setName("The name"); + tutorial.setDescription("The description"); + + QWidget parent; + TutorialInformationWidget* widget = new TutorialInformationWidget(&tutorial, + &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(nameLineEdit(widget)->text(), QString("The name")); + QCOMPARE(descriptionTextEdit(widget)->toPlainText(), + QString("The description")); +} + +void TutorialInformationWidgetTest::testSaveChanges() { + Tutorial tutorial; + tutorial.setName("The name"); + tutorial.setDescription("The description"); + + TutorialInformationWidget widget(&tutorial); + nameLineEdit(&widget)->setText("The new name"); + descriptionTextEdit(&widget)->setText("The new description"); + + widget.saveChanges(); + + QCOMPARE(tutorial.name(), QString("The new name")); + QCOMPARE(tutorial.description(), QString("The new description")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KLineEdit* TutorialInformationWidgetTest::nameLineEdit( + TutorialInformationWidget* widget) const { + return widget->findChild<KLineEdit*>("nameLineEdit"); +} + +KTextEdit* TutorialInformationWidgetTest::descriptionTextEdit( + TutorialInformationWidget* widget) const { + return widget->findChild<KTextEdit*>("descriptionTextEdit"); +} + +QTEST_MAIN(TutorialInformationWidgetTest) + +#include "TutorialInformationWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialInformationWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 05:25:35
|
Revision: 130 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=130&view=rev Author: danxuliu Date: 2010-03-09 05:25:28 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Add StepDataWidget to edit the id and text of a step. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.h trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.ui trunk/ktutorial/ktutorial-editor/tests/unit/view/StepDataWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 04:53:34 UTC (rev 129) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 05:25:28 UTC (rev 130) @@ -3,6 +3,7 @@ set(ktutorial_editor_view_SRCS EditionDialog.cpp EditionWidget.cpp + StepDataWidget.cpp StepTreeItem.cpp TextTreeItem.cpp TreeItem.cpp @@ -14,6 +15,7 @@ ) kde4_add_ui_files(ktutorial_editor_view_SRCS + StepDataWidget.ui TutorialInformationWidget.ui ) Added: trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.cpp 2010-03-09 05:25:28 UTC (rev 130) @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepDataWidget.h" + +#include "ui_StepDataWidget.h" +#include "../Step.h" + +//public: + +StepDataWidget::StepDataWidget(Step* step, QWidget* parent): + EditionWidget(parent), + mStep(step) { + ui = new Ui::StepDataWidget(); + ui->setupUi(this); + + ui->idLineEdit->setText(step->id()); + ui->textTextEdit->setText(step->text()); +} + +StepDataWidget::~StepDataWidget() { + delete ui; +} + +void StepDataWidget::saveChanges() { + QString id = ui->idLineEdit->text(); + if (mStep->id() != id) { + mStep->setId(id); + } + + QString text = ui->textTextEdit->toPlainText(); + if (mStep->text() != text) { + mStep->setText(text); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.h 2010-03-09 05:25:28 UTC (rev 130) @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2010 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 STEPDATAWIDGET_H +#define STEPDATAWIDGET_H + +#include "EditionWidget.h" + +class Step; + +namespace Ui { +class StepDataWidget; +} + +/** + * Edition widget for the id and text of a Step. + */ +class StepDataWidget: public EditionWidget { +Q_OBJECT +public: + + /** + * Creates a new StepDataWidget for the given Step. + * + * @param step The step to edit. + * @param parent The parent QWidget. + */ + explicit StepDataWidget(Step* step, QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~StepDataWidget(); + + /** + * Saves the id and text in the step. + */ + virtual void saveChanges(); + +private: + + /** + * The step to edit. + */ + Step* mStep; + + /** + * The Ui Designer generated class. + */ + Ui::StepDataWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepDataWidget.ui 2010-03-09 05:25:28 UTC (rev 130) @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>StepDataWidget</class> + <widget class="QWidget" name="StepDataWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Set step data</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Set the id and the text of the step</para> +<para>The text is shown to the user when the tutorial changes to that step.</para> +<para>On the other hand, the id is only used internally and never shown to the user. It is used to tell the tutorial which is the next step to change to.</para></string> + </property> + <layout class="QVBoxLayout" name="StepDataWidgetLayout"> + <item> + <widget class="QGroupBox" name="stepDataGroupBox"> + <property name="title"> + <string comment="@title">Step data</string> + </property> + <layout class="QVBoxLayout" name="stepDataGroupBoxLayout"> + <item> + <layout class="QHBoxLayout" name="idLayout"> + <item> + <widget class="QLabel" name="idLabel"> + <property name="text"> + <string comment="@label:textbox">Id:</string> + </property> + <property name="buddy"> + <cstring>idLineEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="KLineEdit" name="idLineEdit"/> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="textLayout"> + <item> + <widget class="QLabel" name="textLabel"> + <property name="text"> + <string comment="@label:textbox">Text:</string> + </property> + <property name="buddy"> + <cstring>textTextEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="KTextEdit" name="textTextEdit"/> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + <customwidget> + <class>KTextEdit</class> + <extends>QTextEdit</extends> + <header>ktextedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 04:53:34 UTC (rev 129) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 05:25:28 UTC (rev 130) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +unit_tests(EditionDialog StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(EditionDialog StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +mem_tests(EditionDialog StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepDataWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/StepDataWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/StepDataWidgetTest.cpp 2010-03-09 05:25:28 UTC (rev 130) @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepDataWidget.h" + +#include <KLineEdit> +#include <KTextEdit> + +#include "../Step.h" + +class StepDataWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSaveChanges(); + +private: + + KLineEdit* idLineEdit(StepDataWidget* widget) const; + KTextEdit* textTextEdit(StepDataWidget* widget) const; + +}; + +void StepDataWidgetTest::testConstructor() { + Step step; + step.setId("The id"); + step.setText("The text"); + + QWidget parent; + StepDataWidget* widget = new StepDataWidget(&step, &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(idLineEdit(widget)->text(), QString("The id")); + QCOMPARE(textTextEdit(widget)->toPlainText(), QString("The text")); +} + +void StepDataWidgetTest::testSaveChanges() { + Step step; + step.setId("The id"); + step.setText("The text"); + + StepDataWidget widget(&step); + idLineEdit(&widget)->setText("The new id"); + textTextEdit(&widget)->setText("The new text"); + + widget.saveChanges(); + + QCOMPARE(step.id(), QString("The new id")); + QCOMPARE(step.text(), QString("The new text")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KLineEdit* StepDataWidgetTest::idLineEdit(StepDataWidget* widget) const { + return widget->findChild<KLineEdit*>("idLineEdit"); +} + +KTextEdit* StepDataWidgetTest::textTextEdit(StepDataWidget* widget) const { + return widget->findChild<KTextEdit*>("textTextEdit"); +} + +QTEST_MAIN(StepDataWidgetTest) + +#include "StepDataWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepDataWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 19:17:07
|
Revision: 135 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=135&view=rev Author: danxuliu Date: 2010-03-09 19:16:53 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Add TutorialCustomCodeWidget and StepCustomCodeWidget widgets to edit the setup and tear down code of tutorials and steps. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/CustomCodeWidget.ui trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.h trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.h trunk/ktutorial/ktutorial-editor/tests/unit/view/StepCustomCodeWidgetTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialCustomCodeWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-09 16:14:46 UTC (rev 134) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-09 19:16:53 UTC (rev 135) @@ -28,8 +28,10 @@ #include "Step.h" #include "Tutorial.h" #include "view/EditionDialog.h" +#include "view/StepCustomCodeWidget.h" #include "view/StepDataWidget.h" #include "view/TreeModel.h" +#include "view/TutorialCustomCodeWidget.h" #include "view/TutorialInformationWidget.h" #include "view/TutorialTreeItem.h" #include "view/TutorialTreeSelectionManager.h" @@ -78,6 +80,20 @@ this, SLOT(setTutorialInformation())); action = new KAction(this); + action->setText(i18nc("@action", "Set setup code...")); + action->setStatusTip(i18nc("@info:status", "Set the custom code to be " +"executed when the tutorial starts.")); + actionCollection()->addAction("setTutorialSetup", action); + connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialSetup())); + + action = new KAction(this); + action->setText(i18nc("@action", "Set tear down code...")); + action->setStatusTip(i18nc("@info:status", "Set the custom code to be " +"executed when the tutorial finishes.")); + actionCollection()->addAction("setTutorialTearDown", action); + connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialTearDown())); + + action = new KAction(this); action->setText(i18nc("@action", "Add step...")); action->setStatusTip(i18nc("@info:status", "Add a new step to the " "tutorial.")); @@ -93,6 +109,23 @@ connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepData())); action = new KAction(this); + action->setText(i18nc("@action", "Set setup code...")); + action->setStatusTip(i18nc("@info:status", "Set the custom code to be " +"executed when the tutorial passes to the currently selected step.")); + action->setEnabled(false); + actionCollection()->addAction("setStepSetup", action); + connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepSetup())); + + action = new KAction(this); + action->setText(i18nc("@action", "Set tear down code...")); + action->setStatusTip(i18nc("@info:status", "Set the custom code to be " +"executed when the tutorial changes from the currently selected step to " +"another step.")); + action->setEnabled(false); + actionCollection()->addAction("setStepTearDown", action); + connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepTearDown())); + + action = new KAction(this); action->setText(i18nc("@action", "Remove step")); action->setStatusTip(i18nc("@info:status", "Removes the currently selected " "step from the tutorial.")); @@ -115,9 +148,13 @@ if (mCurrentStep) { actionCollection()->action("setStepData")->setEnabled(true); + actionCollection()->action("setStepSetup")->setEnabled(true); + actionCollection()->action("setStepTearDown")->setEnabled(true); actionCollection()->action("removeStep")->setEnabled(true); } else { actionCollection()->action("setStepData")->setEnabled(false); + actionCollection()->action("setStepSetup")->setEnabled(false); + actionCollection()->action("setStepTearDown")->setEnabled(false); actionCollection()->action("removeStep")->setEnabled(false); } } @@ -126,6 +163,16 @@ showEditionDialog(new TutorialInformationWidget(mTutorial)); } +void KTutorialEditor::setTutorialSetup() { + showEditionDialog(new TutorialCustomCodeWidget(mTutorial, + TutorialCustomCodeWidget::Setup)); +} + +void KTutorialEditor::setTutorialTearDown() { + showEditionDialog(new TutorialCustomCodeWidget(mTutorial, + TutorialCustomCodeWidget::TearDown)); +} + void KTutorialEditor::addStep() { Step* step = new Step(); mTutorial->addStep(step); @@ -139,6 +186,16 @@ showEditionDialog(new StepDataWidget(mCurrentStep)); } +void KTutorialEditor::setStepSetup() { + showEditionDialog(new StepCustomCodeWidget(mCurrentStep, + StepCustomCodeWidget::Setup)); +} + +void KTutorialEditor::setStepTearDown() { + showEditionDialog(new StepCustomCodeWidget(mCurrentStep, + StepCustomCodeWidget::TearDown)); +} + void KTutorialEditor::removeStep() { Q_ASSERT(mCurrentStep); Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-09 16:14:46 UTC (rev 134) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-09 19:16:53 UTC (rev 135) @@ -91,6 +91,16 @@ void setTutorialInformation(); /** + * Shows a TutorialCustomCodeWidget for the setup code of the tutorial. + */ + void setTutorialSetup(); + + /** + * Shows a TutorialCustomCodeWidget for the tear down code of the tutorial. + */ + void setTutorialTearDown(); + + /** * Adds a new step to the tutorial and shows a StepDataWidget for it. */ void addStep(); @@ -101,6 +111,16 @@ void setStepData(); /** + * Shows a StepCustomCodeWidget for the setup code of the current step. + */ + void setStepSetup(); + + /** + * Shows a StepCustomCodeWidget for the tear down code of the current step. + */ + void setStepTearDown(); + + /** * Removes the current step from the tutorial. */ void removeStep(); Modified: trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc =================================================================== --- trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-09 16:14:46 UTC (rev 134) +++ trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-09 19:16:53 UTC (rev 135) @@ -6,11 +6,15 @@ <Menu name="editTutorials"> <Text context="@item:inmenu">Tutorial</Text> <Action name="setTutorialInformation"/> + <Action name="setTutorialSetup"/> + <Action name="setTutorialTearDown"/> </Menu> <Menu name="editSteps"> <Text context="@item:inmenu">Step</Text> <Action name="addStep"/> <Action name="setStepData"/> + <Action name="setStepSetup"/> + <Action name="setStepTearDown"/> <Action name="removeStep"/> </Menu> </Menu> Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 16:14:46 UTC (rev 134) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 19:16:53 UTC (rev 135) @@ -3,18 +3,21 @@ set(ktutorial_editor_view_SRCS EditionDialog.cpp EditionWidget.cpp + StepCustomCodeWidget.cpp StepDataWidget.cpp StepTreeItem.cpp TextTreeItem.cpp TreeItem.cpp TreeItemUtil.cpp TreeModel.cpp + TutorialCustomCodeWidget.cpp TutorialInformationWidget.cpp TutorialTreeItem.cpp TutorialTreeSelectionManager.cpp ) kde4_add_ui_files(ktutorial_editor_view_SRCS + CustomCodeWidget.ui StepDataWidget.ui TutorialInformationWidget.ui ) Added: trunk/ktutorial/ktutorial-editor/src/view/CustomCodeWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CustomCodeWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/CustomCodeWidget.ui 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CustomCodeWidget</class> + <widget class="QWidget" name="CustomCodeWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Set custom code</string> + </property> + <layout class="QVBoxLayout" name="CustomCodeWidgetLayout"> + <item> + <widget class="QGroupBox" name="customCodeGroupBox"> + <layout class="QVBoxLayout" name="customCodeGroupBoxLayout"> + <item> + <widget class="KTextEdit" name="customCodeTextEdit"/> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KTextEdit</class> + <extends>QTextEdit</extends> + <header>ktextedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Added: trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.cpp 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepCustomCodeWidget.h" + +#include <KLocalizedString> + +#include "ui_CustomCodeWidget.h" +#include "../Step.h" + +//public: + +StepCustomCodeWidget::StepCustomCodeWidget(Step* step, Type type, + QWidget* parent): + EditionWidget(parent), + mStep(step), + mType(type) { + + ui = new Ui::CustomCodeWidget(); + ui->setupUi(this); + + if (type == Setup) { + ui->customCodeTextEdit->setText(step->customSetupCode()); + ui->customCodeGroupBox->setTitle(i18nc("@ŧitle", "Step setup code")); + setWindowTitle(i18nc("@title", "Set the step setup code")); + setWhatsThis(i18nc("@info:whatsthis", "<para>Set the code to be " +"executed when the tutorials passes to the step.</para>" +"<para>The code will be written as is to the setup of the step, after the " +"setup code generated automatically by the editor. This means that the code " +"must be written in the same programming language the tutorial will be " +"exported to.</para>")); + } else { + ui->customCodeTextEdit->setText(step->customTearDownCode()); + ui->customCodeGroupBox->setTitle(i18nc("@ŧitle", + "Step tear down code")); + setWindowTitle(i18nc("@title", "Set the step tear down code")); + setWhatsThis(i18nc("@info:whatsthis", "<para>Set the code to be " +"executed when the tutorial finishes.</para>" +"<para>The code will be written as is to the tear down of the step, before the " +"tear down code generated automatically by the editor. This means that the " +"code must be written in the same programming language the tutorial will be " +"exported to.</para>")); + } +} + +StepCustomCodeWidget::~StepCustomCodeWidget() { + delete ui; +} + +void StepCustomCodeWidget::saveChanges() { + QString customCode = ui->customCodeTextEdit->toPlainText(); + if (mType == Setup && mStep->customSetupCode() != customCode) { + mStep->setCustomSetupCode(customCode); + } + + if (mType == TearDown && mStep->customTearDownCode() != customCode) { + mStep->setCustomTearDownCode(customCode); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.h 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,83 @@ +/*************************************************************************** + * Copyright (C) 2010 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 STEPCUSTOMCODEWIDGET_H +#define STEPCUSTOMCODEWIDGET_H + +#include "EditionWidget.h" + +class Step; + +namespace Ui { +class CustomCodeWidget; +} + +/** + * Edition widget for the setup and tear down code of a Step. + * The code that is edited (setup or tear down) is specified when the widget + * is created. + */ +class StepCustomCodeWidget: public EditionWidget { +Q_OBJECT +public: + + enum Type { + Setup, + TearDown + }; + + /** + * Creates a new StepCustomCodeWidget for the given type of code of the + * given step. + * + * @param step The step to edit its code. + * @param type The type of code to edit. + * @param parent The parent QWidget. + */ + StepCustomCodeWidget(Step* step, Type type, QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~StepCustomCodeWidget(); + + /** + * Saves the code in the step. + */ + virtual void saveChanges(); + +private: + + /** + * The step to set its code. + */ + Step* mStep; + + /** + * The type of custom code to edit. + */ + Type mType; + + /** + * The Ui Designer generated class. + */ + Ui::CustomCodeWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/StepCustomCodeWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.cpp 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialCustomCodeWidget.h" + +#include <KLocalizedString> + +#include "ui_CustomCodeWidget.h" +#include "../Tutorial.h" + +//public: + +TutorialCustomCodeWidget::TutorialCustomCodeWidget(Tutorial* tutorial, + Type type, QWidget* parent): + EditionWidget(parent), + mTutorial(tutorial), + mType(type) { + + ui = new Ui::CustomCodeWidget(); + ui->setupUi(this); + + if (type == Setup) { + ui->customCodeTextEdit->setText(tutorial->customSetupCode()); + ui->customCodeGroupBox->setTitle(i18nc("@ŧitle", + "Tutorial setup code")); + setWindowTitle(i18nc("@title", "Set the tutorial setup code")); + setWhatsThis(i18nc("@info:whatsthis", "<para>Set the code to be " +"executed when the tutorial starts.</para>" +"<para>The code will be written as is to the setup of the tutorial, after the " +"setup code generated automatically by the editor. This means that the code " +"must be written in the same programming language the tutorial will be " +"exported to.</para>")); + } else { + ui->customCodeTextEdit->setText(tutorial->customTearDownCode()); + ui->customCodeGroupBox->setTitle(i18nc("@ŧitle", + "Tutorial tear down code")); + setWindowTitle(i18nc("@title", "Set the tutorial tear down code")); + setWhatsThis(i18nc("@info:whatsthis", "<para>Set the code to be " +"executed when the tutorial finishes.</para>" +"<para>The code will be written as is to the tear down of the tutorial, before " +"the tear down code generated automatically by the editor. This means that the " +"code must be written in the same programming language the tutorial will be " +"exported to.</para>")); + } +} + +TutorialCustomCodeWidget::~TutorialCustomCodeWidget() { + delete ui; +} + +void TutorialCustomCodeWidget::saveChanges() { + QString customCode = ui->customCodeTextEdit->toPlainText(); + if (mType == Setup && mTutorial->customSetupCode() != customCode) { + mTutorial->setCustomSetupCode(customCode); + } + + if (mType == TearDown && mTutorial->customTearDownCode() != customCode) { + mTutorial->setCustomTearDownCode(customCode); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.h 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2010 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 TUTORIALCUSTOMCODEWIDGET_H +#define TUTORIALCUSTOMCODEWIDGET_H + +#include "EditionWidget.h" + +class Tutorial; + +namespace Ui { +class CustomCodeWidget; +} + +/** + * Edition widget for the setup and tear down code of a Tutorial. + * The code that is edited (setup or tear down) is specified when the widget + * is created. + */ +class TutorialCustomCodeWidget: public EditionWidget { +Q_OBJECT +public: + + enum Type { + Setup, + TearDown + }; + + /** + * Creates a new TutorialCustomCodeWidget for the given type of code of the + * given tutorial. + * + * @param tutorial The tutorial to edit its code. + * @param type The type of code to edit. + * @param parent The parent QWidget. + */ + TutorialCustomCodeWidget(Tutorial* tutorial, Type type, + QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~TutorialCustomCodeWidget(); + + /** + * Saves the code in the tutorial. + */ + virtual void saveChanges(); + +private: + + /** + * The tutorial to set its code. + */ + Tutorial* mTutorial; + + /** + * The type of custom code to edit. + */ + Type mType; + + /** + * The Ui Designer generated class. + */ + Ui::CustomCodeWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/TutorialCustomCodeWidget.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 16:14:46 UTC (rev 134) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 19:16:53 UTC (rev 135) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(EditionDialog StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +unit_tests(EditionDialog StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(EditionDialog StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +mem_tests(EditionDialog StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepCustomCodeWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/StepCustomCodeWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/StepCustomCodeWidgetTest.cpp 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "StepCustomCodeWidget.h" + +#include <KLineEdit> +#include <KTextEdit> + +#include "../Step.h" + +class StepCustomCodeWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructorSetup(); + void testConstructorTearDown(); + + void testSaveChangesSetup(); + void testSaveChangesTearDown(); + +private: + + KTextEdit* customCodeTextEdit(StepCustomCodeWidget* widget) const; + +}; + +void StepCustomCodeWidgetTest::testConstructorSetup() { + Step step; + step.setCustomSetupCode("The setup code"); + + QWidget parent; + StepCustomCodeWidget* widget = + new StepCustomCodeWidget(&step, + StepCustomCodeWidget::Setup, + &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(customCodeTextEdit(widget)->toPlainText(), + QString("The setup code")); +} + +void StepCustomCodeWidgetTest::testConstructorTearDown() { + Step step; + step.setCustomTearDownCode("The tear down code"); + + QWidget parent; + StepCustomCodeWidget* widget = + new StepCustomCodeWidget(&step, + StepCustomCodeWidget::TearDown, + &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(customCodeTextEdit(widget)->toPlainText(), + QString("The tear down code")); +} + +void StepCustomCodeWidgetTest::testSaveChangesSetup() { + Step step; + step.setCustomSetupCode("The setup code"); + + StepCustomCodeWidget widget(&step, StepCustomCodeWidget::Setup); + customCodeTextEdit(&widget)->setText("The new setup code"); + + widget.saveChanges(); + + QCOMPARE(step.customSetupCode(), QString("The new setup code")); +} + +void StepCustomCodeWidgetTest::testSaveChangesTearDown() { + Step step; + step.setCustomTearDownCode("The tear down code"); + + StepCustomCodeWidget widget(&step, StepCustomCodeWidget::TearDown); + customCodeTextEdit(&widget)->setText("The new tear down code"); + + widget.saveChanges(); + + QCOMPARE(step.customTearDownCode(), QString("The new tear down code")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KTextEdit* StepCustomCodeWidgetTest::customCodeTextEdit( + StepCustomCodeWidget* widget) const { + return widget->findChild<KTextEdit*>("customCodeTextEdit"); +} + +QTEST_MAIN(StepCustomCodeWidgetTest) + +#include "StepCustomCodeWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepCustomCodeWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialCustomCodeWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialCustomCodeWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialCustomCodeWidgetTest.cpp 2010-03-09 19:16:53 UTC (rev 135) @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "TutorialCustomCodeWidget.h" + +#include <KLineEdit> +#include <KTextEdit> + +#include "../Tutorial.h" + +class TutorialCustomCodeWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructorSetup(); + void testConstructorTearDown(); + + void testSaveChangesSetup(); + void testSaveChangesTearDown(); + +private: + + KTextEdit* customCodeTextEdit(TutorialCustomCodeWidget* widget) const; + +}; + +void TutorialCustomCodeWidgetTest::testConstructorSetup() { + Tutorial tutorial; + tutorial.setCustomSetupCode("The setup code"); + + QWidget parent; + TutorialCustomCodeWidget* widget = + new TutorialCustomCodeWidget(&tutorial, + TutorialCustomCodeWidget::Setup, + &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(customCodeTextEdit(widget)->toPlainText(), + QString("The setup code")); +} + +void TutorialCustomCodeWidgetTest::testConstructorTearDown() { + Tutorial tutorial; + tutorial.setCustomTearDownCode("The tear down code"); + + QWidget parent; + TutorialCustomCodeWidget* widget = + new TutorialCustomCodeWidget(&tutorial, + TutorialCustomCodeWidget::TearDown, + &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(customCodeTextEdit(widget)->toPlainText(), + QString("The tear down code")); +} + +void TutorialCustomCodeWidgetTest::testSaveChangesSetup() { + Tutorial tutorial; + tutorial.setCustomSetupCode("The setup code"); + + TutorialCustomCodeWidget widget(&tutorial, TutorialCustomCodeWidget::Setup); + customCodeTextEdit(&widget)->setText("The new setup code"); + + widget.saveChanges(); + + QCOMPARE(tutorial.customSetupCode(), QString("The new setup code")); +} + +void TutorialCustomCodeWidgetTest::testSaveChangesTearDown() { + Tutorial tutorial; + tutorial.setCustomTearDownCode("The tear down code"); + + TutorialCustomCodeWidget widget(&tutorial, + TutorialCustomCodeWidget::TearDown); + customCodeTextEdit(&widget)->setText("The new tear down code"); + + widget.saveChanges(); + + QCOMPARE(tutorial.customTearDownCode(), QString("The new tear down code")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KTextEdit* TutorialCustomCodeWidgetTest::customCodeTextEdit( + TutorialCustomCodeWidget* widget) const { + return widget->findChild<KTextEdit*>("customCodeTextEdit"); +} + +QTEST_MAIN(TutorialCustomCodeWidgetTest) + +#include "TutorialCustomCodeWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/TutorialCustomCodeWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-09 19:45:51
|
Revision: 136 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=136&view=rev Author: danxuliu Date: 2010-03-09 19:45:44 +0000 (Tue, 09 Mar 2010) Log Message: ----------- Add LicenseWidget to set the license of the tutorial. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.h trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.ui trunk/ktutorial/ktutorial-editor/tests/unit/view/LicenseWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-09 19:16:53 UTC (rev 135) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-09 19:45:44 UTC (rev 136) @@ -28,6 +28,7 @@ #include "Step.h" #include "Tutorial.h" #include "view/EditionDialog.h" +#include "view/LicenseWidget.h" #include "view/StepCustomCodeWidget.h" #include "view/StepDataWidget.h" #include "view/TreeModel.h" @@ -80,6 +81,13 @@ this, SLOT(setTutorialInformation())); action = new KAction(this); + action->setText(i18nc("@action", "Set license...")); + action->setStatusTip(i18nc("@info:status", "Set the license text of the " +"tutorial.")); + actionCollection()->addAction("setTutorialLicense", action); + connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialLicense())); + + action = new KAction(this); action->setText(i18nc("@action", "Set setup code...")); action->setStatusTip(i18nc("@info:status", "Set the custom code to be " "executed when the tutorial starts.")); @@ -163,6 +171,10 @@ showEditionDialog(new TutorialInformationWidget(mTutorial)); } +void KTutorialEditor::setTutorialLicense() { + showEditionDialog(new LicenseWidget(mTutorial)); +} + void KTutorialEditor::setTutorialSetup() { showEditionDialog(new TutorialCustomCodeWidget(mTutorial, TutorialCustomCodeWidget::Setup)); Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-09 19:16:53 UTC (rev 135) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-09 19:45:44 UTC (rev 136) @@ -91,6 +91,11 @@ void setTutorialInformation(); /** + * Shows a LicenseWidget for the tutorial. + */ + void setTutorialLicense(); + + /** * Shows a TutorialCustomCodeWidget for the setup code of the tutorial. */ void setTutorialSetup(); Modified: trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc =================================================================== --- trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-09 19:16:53 UTC (rev 135) +++ trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-09 19:45:44 UTC (rev 136) @@ -6,6 +6,7 @@ <Menu name="editTutorials"> <Text context="@item:inmenu">Tutorial</Text> <Action name="setTutorialInformation"/> + <Action name="setTutorialLicense"/> <Action name="setTutorialSetup"/> <Action name="setTutorialTearDown"/> </Menu> Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 19:16:53 UTC (rev 135) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 19:45:44 UTC (rev 136) @@ -3,6 +3,7 @@ set(ktutorial_editor_view_SRCS EditionDialog.cpp EditionWidget.cpp + LicenseWidget.cpp StepCustomCodeWidget.cpp StepDataWidget.cpp StepTreeItem.cpp @@ -18,6 +19,7 @@ kde4_add_ui_files(ktutorial_editor_view_SRCS CustomCodeWidget.ui + LicenseWidget.ui StepDataWidget.ui TutorialInformationWidget.ui ) Added: trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.cpp 2010-03-09 19:45:44 UTC (rev 136) @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "LicenseWidget.h" + +#include "ui_LicenseWidget.h" +#include "../Tutorial.h" + +//public: + +LicenseWidget::LicenseWidget(Tutorial* tutorial, QWidget* parent): + EditionWidget(parent), + mTutorial(tutorial) { + ui = new Ui::LicenseWidget(); + ui->setupUi(this); + + ui->licenseTextEdit->setText(tutorial->licenseText()); +} + +LicenseWidget::~LicenseWidget() { + delete ui; +} + +void LicenseWidget::saveChanges() { + QString licenseText = ui->licenseTextEdit->toPlainText(); + if (mTutorial->licenseText() != licenseText) { + mTutorial->setLicenseText(licenseText); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.h 2010-03-09 19:45:44 UTC (rev 136) @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2010 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 LICENSEWIDGET_H +#define LICENSEWIDGET_H + +#include "EditionWidget.h" + +class Tutorial; + +namespace Ui { +class LicenseWidget; +} + +/** + * Edition widget for the license of a tutorial. + */ +class LicenseWidget: public EditionWidget { +Q_OBJECT +public: + + /** + * Creates a new LicenseWidget for the given Tutorial. + * + * @param tutorial The tutorial to set its license. + * @param parent The parent QWidget. + */ + explicit LicenseWidget(Tutorial* tutorial, QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~LicenseWidget(); + + /** + * Saves the license in the tutorial. + */ + virtual void saveChanges(); + +private: + + /** + * The tutorial to set its license. + */ + Tutorial* mTutorial; + + /** + * The Ui Designer generated class. + */ + Ui::LicenseWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/LicenseWidget.ui 2010-03-09 19:45:44 UTC (rev 136) @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>LicenseWidget</class> + <widget class="QWidget" name="LicenseWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Set tutorial license</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Set the license of the tutorial.</para> +<para>The license is copied, commented, to the top of the exported tutorial file. That is, you don't have to worry about how comments are written in the programming language the tutorial will be exported to. Just set the pure text of the license, and the editor will take care of adding the necessary characters in each line to mark them as comments instead of source code.</para></string> + </property> + <layout class="QVBoxLayout" name="LicenseWidgetLayout"> + <item> + <widget class="QGroupBox" name="licenseGroupBox"> + <property name="title"> + <string comment="@title">License text</string> + </property> + <layout class="QVBoxLayout" name="customCodeGroupBoxLayout"> + <item> + <widget class="KTextEdit" name="licenseTextEdit"/> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KTextEdit</class> + <extends>QTextEdit</extends> + <header>ktextedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 19:16:53 UTC (rev 135) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 19:45:44 UTC (rev 136) @@ -16,7 +16,7 @@ ENDFOREACH(_className) ENDMACRO(UNIT_TESTS) -unit_tests(EditionDialog StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +unit_tests(EditionDialog LicenseWidget StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) MACRO(MEM_TESTS) FOREACH(_testname ${ARGN}) @@ -24,4 +24,4 @@ ENDFOREACH(_testname) ENDMACRO(MEM_TESTS) -mem_tests(EditionDialog StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) +mem_tests(EditionDialog LicenseWidget StepCustomCodeWidget StepDataWidget StepTreeItem TextTreeItem TreeItem TreeItemUtil TreeModel TutorialCustomCodeWidget TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/LicenseWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/LicenseWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/LicenseWidgetTest.cpp 2010-03-09 19:45:44 UTC (rev 136) @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "LicenseWidget.h" + +#include <KLineEdit> +#include <KTextEdit> + +#include "../Tutorial.h" + +class LicenseWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSaveChanges(); + +private: + + KTextEdit* licenseTextEdit(LicenseWidget* widget) const; + +}; + +void LicenseWidgetTest::testConstructor() { + Tutorial tutorial; + tutorial.setLicenseText("The license"); + + QWidget parent; + LicenseWidget* widget = new LicenseWidget(&tutorial, &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(licenseTextEdit(widget)->toPlainText(), QString("The license")); +} + +void LicenseWidgetTest::testSaveChanges() { + Tutorial tutorial; + tutorial.setLicenseText("The license"); + + LicenseWidget widget(&tutorial); + licenseTextEdit(&widget)->setText("The new license"); + + widget.saveChanges(); + + QCOMPARE(tutorial.licenseText(), QString("The new license")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KTextEdit* LicenseWidgetTest::licenseTextEdit(LicenseWidget* widget) const { + return widget->findChild<KTextEdit*>("licenseTextEdit"); +} + +QTEST_MAIN(LicenseWidgetTest) + +#include "LicenseWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/LicenseWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-10 17:51:03
|
Revision: 141 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=141&view=rev Author: danxuliu Date: 2010-03-10 17:50:56 +0000 (Wed, 10 Mar 2010) Log Message: ----------- Add docks to show the edition actions. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.h trunk/ktutorial/ktutorial-editor/tests/unit/view/ActionListWidgetTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-09 21:12:53 UTC (rev 140) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.cpp 2010-03-10 17:50:56 UTC (rev 141) @@ -18,6 +18,7 @@ #include "KTutorialEditor.h" +#include <QDockWidget> #include <QTreeView> #include <KAction> @@ -27,6 +28,7 @@ #include "Step.h" #include "Tutorial.h" +#include "view/ActionListWidget.h" #include "view/EditionDialog.h" #include "view/LicenseWidget.h" #include "view/StepCustomCodeWidget.h" @@ -46,6 +48,8 @@ setupTutorialToBeEdited(); + setupDocks(); + setupActions(); setupGUI(); @@ -69,9 +73,23 @@ this, SLOT(selectStep(Step*))); } +void KTutorialEditor::setupDocks() { + mTutorialActionDock = new QDockWidget(i18nc("@title", "Edit tutorial"), + this); + mTutorialActionDock->setObjectName("editTutorialDock"); + addDockWidget(Qt::RightDockWidgetArea, mTutorialActionDock); + + mStepActionDock = new QDockWidget(i18nc("@title", "Edit step"), this); + mStepActionDock->setObjectName("editStepDock"); + addDockWidget(Qt::RightDockWidgetArea, mStepActionDock); +} + void KTutorialEditor::setupActions() { KStandardAction::quit(kapp, SLOT(quit()), actionCollection()); + ActionListWidget* actionListWidget = + new ActionListWidget(mTutorialActionDock); + KAction* action = new KAction(this); action->setText(i18nc("@action", "Set information...")); action->setStatusTip(i18nc("@info:status", "Set the name and description " @@ -79,6 +97,7 @@ actionCollection()->addAction("setTutorialInformation", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialInformation())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set license...")); @@ -86,6 +105,7 @@ "tutorial.")); actionCollection()->addAction("setTutorialLicense", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialLicense())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set setup code...")); @@ -93,6 +113,7 @@ "executed when the tutorial starts.")); actionCollection()->addAction("setTutorialSetup", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialSetup())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set tear down code...")); @@ -100,13 +121,18 @@ "executed when the tutorial finishes.")); actionCollection()->addAction("setTutorialTearDown", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setTutorialTearDown())); + actionListWidget->addAction(action); + mTutorialActionDock->setWidget(actionListWidget); + actionListWidget = new ActionListWidget(mStepActionDock); + action = new KAction(this); action->setText(i18nc("@action", "Add step...")); action->setStatusTip(i18nc("@info:status", "Add a new step to the " "tutorial.")); actionCollection()->addAction("addStep", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(addStep())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set data...")); @@ -115,6 +141,7 @@ action->setEnabled(false); actionCollection()->addAction("setStepData", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepData())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set setup code...")); @@ -123,6 +150,7 @@ action->setEnabled(false); actionCollection()->addAction("setStepSetup", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepSetup())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Set tear down code...")); @@ -132,6 +160,7 @@ action->setEnabled(false); actionCollection()->addAction("setStepTearDown", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(setStepTearDown())); + actionListWidget->addAction(action); action = new KAction(this); action->setText(i18nc("@action", "Remove step")); @@ -140,6 +169,14 @@ action->setEnabled(false); actionCollection()->addAction("removeStep", action); connect(action, SIGNAL(triggered(bool)), this, SLOT(removeStep())); + actionListWidget->addAction(action); + + mStepActionDock->setWidget(actionListWidget); + + actionCollection()->addAction("showEditTutorialDock", + mTutorialActionDock->toggleViewAction()); + actionCollection()->addAction("showEditStepDock", + mStepActionDock->toggleViewAction()); } void KTutorialEditor::showEditionDialog(EditionWidget* editionWidget) { Modified: trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-09 21:12:53 UTC (rev 140) +++ trunk/ktutorial/ktutorial-editor/src/KTutorialEditor.h 2010-03-10 17:50:56 UTC (rev 141) @@ -45,8 +45,18 @@ * The main tree view that shows the tutorial. */ QTreeView* mTreeView; - + /** + * Dock with the actions to edit a tutorial. + */ + QDockWidget* mTutorialActionDock; + + /** + * Dock with the actions to edit a step. + */ + QDockWidget* mStepActionDock; + + /** * The tutorial being edited. */ Tutorial* mTutorial; @@ -64,6 +74,11 @@ void setupTutorialToBeEdited(); /** + * Sets up the dock widgets. + */ + void setupDocks(); + + /** * Sets up all the actions used in the application. */ void setupActions(); Modified: trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc =================================================================== --- trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-09 21:12:53 UTC (rev 140) +++ trunk/ktutorial/ktutorial-editor/src/ktutorial-editorui.rc 2010-03-10 17:50:56 UTC (rev 141) @@ -19,5 +19,12 @@ <Action name="removeStep"/> </Menu> </Menu> + <Menu name="view"> + <Menu name="panels"> + <Text context="@title:menu">Panels</Text> + <Action name="showEditTutorialDock"/> + <Action name="showEditStepDock"/> + </Menu> + </Menu> </MenuBar> </gui> Added: trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.cpp 2010-03-10 17:50:56 UTC (rev 141) @@ -0,0 +1,127 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "ActionListWidget.h" + +#include <QAction> +#include <QActionEvent> +#include <QToolButton> +#include <QVBoxLayout> + +/** + * A button which always leave room for an icon, even if there is none, so that + * all button texts are correctly aligned. + * + * Code got from Gwenview's app/sidebar.cpp file, licensed as GPL 2 or later + * (at the time of KDE SVN revision 968729). + */ +class ForcedIconToolButton: public QToolButton { +protected: + + virtual void paintEvent(QPaintEvent* event) { + forceIcon(); + QToolButton::paintEvent(event); + } + +private: + + void forceIcon() { + if (!icon().isNull()) { + return; + } + + // Assign an empty icon to the button if there is no icon associated + // with the action so that all button texts are correctly aligned. + QSize wantedSize = iconSize(); + if (mEmptyIcon.isNull() || + mEmptyIcon.actualSize(wantedSize) != wantedSize) { + QPixmap pix(wantedSize); + pix.fill(Qt::transparent); + mEmptyIcon.addPixmap(pix); + } + setIcon(mEmptyIcon); + } + + QIcon mEmptyIcon; + +}; + +//public: + +ActionListWidget::ActionListWidget(QWidget* parent): QWidget(parent) { + QVBoxLayout* layout = new QVBoxLayout(this); + layout->addStretch(); + layout->setMargin(0); + layout->setSpacing(0); + + setLayout(layout); +} + +//protected: + +void ActionListWidget::actionEvent(QActionEvent* event) { + if (event->type() == QEvent::ActionAdded) { + addToolButtonForAction(event->action(), + toolButtonForAction(event->before())); + return; + } + + if (event->type() == QEvent::ActionRemoved) { + QToolButton* button = toolButtonForAction(event->action()); + layout()->removeWidget(button); + button->deleteLater(); + return; + } +} + +//private: + +QToolButton* ActionListWidget::toolButtonForAction(QAction* action) { + for (int i=0; i<layout()->count(); i++ ) { + QWidget* widget = layout()->itemAt(i)->widget(); + if (widget) { + QToolButton* button = static_cast<QToolButton*>(widget); + if (button->defaultAction() == action) { + return button; + } + } + } + + return 0; +} + +void ActionListWidget::addToolButtonForAction(QAction* action, + QToolButton* before) { + Q_ASSERT(action); + + QToolButton* button = new ForcedIconToolButton(); + button->setDefaultAction(action); + button->setObjectName(action->objectName() + "ToolButton"); + button->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + button->setAutoRaise(true); + button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + + int index; + if (before == 0) { + index = layout()->count() - 1; + } else { + index = layout()->indexOf(before); + } + + static_cast<QVBoxLayout*>(layout())->insertWidget(index, button); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.h 2010-03-10 17:50:56 UTC (rev 141) @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright (C) 2010 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 ACTIONLISTWIDGET_H +#define ACTIONLISTWIDGET_H + +#include <QWidget> + +class QToolButton; + +/** + * QWidget to show the added actions as QToolButtons. + * Standard widgets show the actions added to them in a menu. This widget shows + * them in a list of QToolButtons. Adding, inserting and removing actions is + * supported. + * + * Each QToolButton is named like its action, followed by "ToolButton". + * + * A special tool button subclass, that ensures that there is always an icon + * even if it is empty, is used. When there is an icon, Oxygen and other styles + * align the text with the icon, instead of centering it like it is done when + * there is no icon and a size policy other than fixed is used. A minimum + * expanding size policiy is used for the tool buttons to fill the whole width + * of this widget, instead of having each one its own width. + */ +class ActionListWidget: public QWidget { +Q_OBJECT +public: + + /** + * Creates a new empty ActionListWidget. + * + * @param parent The parent widget. + */ + explicit ActionListWidget(QWidget* parent = 0); + +protected: + + /** + * Handles adding, changing or deleting an action in this ActionListWidget. + * + * @param event The action event. + */ + virtual void actionEvent(QActionEvent* event); + +private: + + /** + * Returns the QToolButton in this widget that shows the given action. + * + * @param action The action to get its QToolButton. + */ + QToolButton* toolButtonForAction(QAction* action); + + /** + * Adds a new QToolButton for the given action. + * + * @param action The action to add a QToolButton for it. + * @param before Add the action before this tool button, or append it if it + * is 0. + */ + void addToolButtonForAction(QAction* action, QToolButton* before); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/ActionListWidget.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-09 21:12:53 UTC (rev 140) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-10 17:50:56 UTC (rev 141) @@ -1,6 +1,7 @@ include_directories(${KDE4_INCLUDES}) set(ktutorial_editor_view_SRCS + ActionListWidget.cpp EditionDialog.cpp EditionWidget.cpp LicenseWidget.cpp Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/ActionListWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/ActionListWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/ActionListWidgetTest.cpp 2010-03-10 17:50:56 UTC (rev 141) @@ -0,0 +1,183 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "ActionListWidget.h" + +#include <QAction> +#include <QLayout> +#include <QToolButton> + +#include <KIcon> + +class ActionListWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testAddAction(); + void testAddActionSeveralActions(); + + void testInsertAction(); + void testInsertActionSeveralActions(); + + void testRemoveAction(); + void testRemoveActionSeveralActions(); + +private: + + QToolButton* toolButton(const ActionListWidget* widget, + const QAction* action) const; + + void assertToolButton(const ActionListWidget* widget, int index, + const QAction* action) const; + +}; + +void ActionListWidgetTest::testConstructor() { + QWidget parent; + ActionListWidget* widget = new ActionListWidget(&parent); + + QCOMPARE(widget->parent(), &parent); + QVERIFY(widget->layout()->itemAt(widget->layout()->count()-1)->spacerItem()); +} + +void ActionListWidgetTest::testAddAction() { + ActionListWidget widget; + QAction* action = new QAction(this); + action->setObjectName("action"); + + widget.addAction(action); + + assertToolButton(&widget, 0, action); + QVERIFY(widget.layout()->itemAt(widget.layout()->count()-1)->spacerItem()); +} + +void ActionListWidgetTest::testAddActionSeveralActions() { + ActionListWidget widget; + QAction* action1 = new QAction(this); + action1->setObjectName("action1"); + QAction* action2 = new QAction(this); + action2->setObjectName("action2"); + QAction* action3 = new QAction(this); + action3->setObjectName("action3"); + action3->setIcon(KIcon("kde")); + + widget.addAction(action1); + widget.addAction(action2); + widget.addAction(action3); + + assertToolButton(&widget, 0, action1); + assertToolButton(&widget, 1, action2); + assertToolButton(&widget, 2, action3); + QVERIFY(widget.layout()->itemAt(widget.layout()->count()-1)->spacerItem()); +} + +void ActionListWidgetTest::testInsertAction() { + ActionListWidget widget; + QAction* action = new QAction(this); + action->setObjectName("action"); + + widget.insertAction(0, action); + + assertToolButton(&widget, 0, action); + QVERIFY(widget.layout()->itemAt(widget.layout()->count()-1)->spacerItem()); +} + +void ActionListWidgetTest::testInsertActionSeveralActions() { + ActionListWidget widget; + QAction* action1 = new QAction(this); + action1->setObjectName("action1"); + QAction* action2 = new QAction(this); + action2->setObjectName("action2"); + QAction* action3 = new QAction(this); + action3->setObjectName("action3"); + action3->setIcon(KIcon("kde")); + + widget.insertAction(0, action3); + widget.insertAction(action3, action1); + widget.insertAction(action3, action2); + + assertToolButton(&widget, 0, action1); + assertToolButton(&widget, 1, action2); + assertToolButton(&widget, 2, action3); + QVERIFY(widget.layout()->itemAt(widget.layout()->count()-1)->spacerItem()); +} + +void ActionListWidgetTest::testRemoveAction() { + ActionListWidget widget; + QAction* action = new QAction(this); + action->setObjectName("action"); + + widget.addAction(action); + widget.removeAction(action); + + QCOMPARE(widget.layout()->count(), 1); + QVERIFY(widget.layout()->itemAt(0)->spacerItem()); +} + +void ActionListWidgetTest::testRemoveActionSeveralActions() { + ActionListWidget widget; + QAction* action1 = new QAction(this); + action1->setObjectName("action1"); + QAction* action2 = new QAction(this); + action2->setObjectName("action2"); + QAction* action3 = new QAction(this); + action3->setObjectName("action3"); + action3->setIcon(KIcon("kde")); + + widget.addAction(action1); + widget.addAction(action2); + widget.addAction(action3); + + widget.removeAction(action2); + + assertToolButton(&widget, 0, action1); + assertToolButton(&widget, 1, action3); + + widget.removeAction(action1); + widget.removeAction(action3); + + QCOMPARE(widget.layout()->count(), 1); + QVERIFY(widget.layout()->itemAt(0)->spacerItem()); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +QToolButton* ActionListWidgetTest::toolButton(const ActionListWidget* widget, + const QAction* action) const { + QString buttonName = action->objectName() + "ToolButton"; + return widget->findChild<QToolButton*>(buttonName); +} + +void ActionListWidgetTest::assertToolButton(const ActionListWidget* widget, + int index, const QAction* action) const { + QToolButton* button = toolButton(widget, action); + + QVERIFY(button); + QCOMPARE(button->parent(), widget); + QCOMPARE(button->defaultAction(), action); + QCOMPARE(widget->layout()->indexOf(button), index); +} + +QTEST_MAIN(ActionListWidgetTest) + +#include "ActionListWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/ActionListWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-09 21:12:53 UTC (rev 140) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-10 17:50:56 UTC (rev 141) @@ -17,6 +17,7 @@ ENDMACRO(UNIT_TESTS) unit_tests( + ActionListWidget EditionDialog LicenseWidget StepCustomCodeWidget @@ -39,6 +40,7 @@ ENDMACRO(MEM_TESTS) mem_tests( + ActionListWidget EditionDialog LicenseWidget StepCustomCodeWidget This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-10 18:47:28
|
Revision: 145 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=145&view=rev Author: danxuliu Date: 2010-03-10 18:47:21 +0000 (Wed, 10 Mar 2010) Log Message: ----------- -Add localization infrastructure. -Add Spanish localization. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/po/ trunk/ktutorial/ktutorial-editor/po/CMakeLists.txt trunk/ktutorial/ktutorial-editor/po/Messages.sh trunk/ktutorial/ktutorial-editor/po/es.po trunk/ktutorial/ktutorial-editor/po/ktutorial-editor.pot Modified: trunk/ktutorial/ktutorial-editor/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/CMakeLists.txt 2010-03-10 18:35:20 UTC (rev 144) +++ trunk/ktutorial/ktutorial-editor/CMakeLists.txt 2010-03-10 18:47:21 UTC (rev 145) @@ -4,5 +4,6 @@ include(KDE4Defaults) +add_subdirectory(po) add_subdirectory(src) add_subdirectory(tests) Added: trunk/ktutorial/ktutorial-editor/po/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/po/CMakeLists.txt (rev 0) +++ trunk/ktutorial/ktutorial-editor/po/CMakeLists.txt 2010-03-10 18:47:21 UTC (rev 145) @@ -0,0 +1,25 @@ +find_program(GETTEXT_MSGFMT_EXECUTABLE msgfmt) + +if(NOT GETTEXT_MSGFMT_EXECUTABLE) + message( +"------ + NOTE: msgfmt not found. Translations will *not* be installed +------") +else(NOT GETTEXT_MSGFMT_EXECUTABLE) + + set(catalogname ktutorial-editor) + + add_custom_target(translations ALL) + + file(GLOB PO_FILES *.po) + + foreach(_poFile ${PO_FILES}) + get_filename_component(_lang ${_poFile} NAME_WE) + set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) + add_custom_command(TARGET translations + COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile} + DEPENDS ${_poFile}) + install(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_lang}/LC_MESSAGES/ RENAME ${catalogname}.mo) + endforeach(_poFile ${PO_FILES}) + +endif(NOT GETTEXT_MSGFMT_EXECUTABLE) Property changes on: trunk/ktutorial/ktutorial-editor/po/CMakeLists.txt ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/po/Messages.sh =================================================================== --- trunk/ktutorial/ktutorial-editor/po/Messages.sh (rev 0) +++ trunk/ktutorial/ktutorial-editor/po/Messages.sh 2010-03-10 18:47:21 UTC (rev 145) @@ -0,0 +1,48 @@ +#!/bin/sh + +BASEDIR="../src/" # root of translatable sources +PROJECT="ktutorial-editor" # project name +BUGADDR="http://sourceforge.net/tracker/?group_id=301227&atid=1270278" # MSGID-Bugs +WDIR=`pwd` # working dir + +echo "Preparing rc files" +cd ${BASEDIR} +# we use simple sorting to make sure the lines do not jump around too much from system to system +find . -name '*.rc' -o -name '*.ui' -o -name '*.kcfg' | sort > ${WDIR}/rcfiles.list +xargs --arg-file=${WDIR}/rcfiles.list extractrc > ${WDIR}/rc.cpp +# additional string for KAboutData +echo 'i18nc("NAME OF TRANSLATORS","Your names");' >> ${WDIR}/rc.cpp +echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> ${WDIR}/rc.cpp +cd ${WDIR} +echo "Done preparing rc files" + + +echo "Extracting messages" +cd ${BASEDIR} +# see above on sorting +find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | sort > ${WDIR}/infiles.list +echo "rc.cpp" >> ${WDIR}/infiles.list +cd ${WDIR} +xgettext --from-code=UTF-8 -C -kde -ki18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \ + -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \ + --msgid-bugs-address="${BUGADDR}" \ + --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o ${PROJECT}.pot || { echo "error while calling xgettext. aborting."; exit 1; } +echo "Done extracting messages" + + +echo "Merging translations" +catalogs=`find . -name '*.po'` +for cat in $catalogs; do + echo $cat + msgmerge -o $cat.new $cat ${PROJECT}.pot + mv $cat.new $cat +done +echo "Done merging translations" + + +echo "Cleaning up" +cd ${WDIR} +rm rcfiles.list +rm infiles.list +rm rc.cpp +echo "Done" Property changes on: trunk/ktutorial/ktutorial-editor/po/Messages.sh ___________________________________________________________________ Added: svn:executable + * Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/po/es.po =================================================================== --- trunk/ktutorial/ktutorial-editor/po/es.po (rev 0) +++ trunk/ktutorial/ktutorial-editor/po/es.po 2010-03-10 18:47:21 UTC (rev 145) @@ -0,0 +1,423 @@ +# Spanish translations for ktutorial-editor package +# Traducciones al español para el paquete ktutorial-editor. +# Copyright (C) 2010 Daniel Calviño Sánchez +# This file is distributed under the same license as the ktutorial-editor package. +# +# Daniel Calviño Sánchez <dan...@gm...>, 2010. +msgid "" +msgstr "" +"Project-Id-Version: ktutorial-editor\n" +"Report-Msgid-Bugs-To: http://sourceforge." +"net/tracker/?group_id=301227&atid=1270278\n" +"POT-Creation-Date: 2010-03-10 19:41+0100\n" +"PO-Revision-Date: 2010-03-10 19:41-0500\n" +"Last-Translator: Daniel Calviño Sánchez <dan...@gm...>\n" +"Language-Team: Spanish <>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.0\n" + +#: KTutorialEditor.cpp:77 +msgctxt "@title" +msgid "Edit tutorial" +msgstr "Editar tutorial" + +#: KTutorialEditor.cpp:82 +msgctxt "@title" +msgid "Edit step" +msgstr "Editar paso" + +#: KTutorialEditor.cpp:94 +msgctxt "@action" +msgid "Set information..." +msgstr "Establecer información..." + +#: KTutorialEditor.cpp:95 +msgctxt "@info:status" +msgid "Set the name and description of the tutorial." +msgstr "Establecer el nombre y la descripción del tutorial." + +#: KTutorialEditor.cpp:104 +msgctxt "@action" +msgid "Set license..." +msgstr "Establecer licencia..." + +#: KTutorialEditor.cpp:105 +msgctxt "@info:status" +msgid "Set the license text of the tutorial." +msgstr "Establecer el texto de licencia del tutorial." + +#: KTutorialEditor.cpp:113 KTutorialEditor.cpp:153 +msgctxt "@action" +msgid "Set setup code..." +msgstr "Establecer código de inicialización..." + +#: KTutorialEditor.cpp:114 +msgctxt "@info:status" +msgid "Set the custom code to be executed when the tutorial starts." +msgstr "" +"Establecer el código propio para ser ejecutado cuando comience el tutorial." + +#: KTutorialEditor.cpp:122 KTutorialEditor.cpp:163 +msgctxt "@action" +msgid "Set tear down code..." +msgstr "Establecer el código de finalización..." + +#: KTutorialEditor.cpp:123 +msgctxt "@info:status" +msgid "Set the custom code to be executed when the tutorial finishes." +msgstr "" +"Establecer el código propio para ser ejecutado cuando termine el tutorial." + +#: KTutorialEditor.cpp:134 +msgctxt "@action" +msgid "Add step..." +msgstr "Añadir paso..." + +#: KTutorialEditor.cpp:135 +msgctxt "@info:status" +msgid "Add a new step to the tutorial." +msgstr "Añadir un nuevo paso al tutorial." + +#: KTutorialEditor.cpp:143 +msgctxt "@action" +msgid "Set data..." +msgstr "Establecer datos..." + +#: KTutorialEditor.cpp:144 +msgctxt "@info:status" +msgid "Set the name and text of the currently selected step." +msgstr "Establecer el nombre y el texto del paso seleccionado actualmente." + +#: KTutorialEditor.cpp:154 +msgctxt "@info:status" +msgid "" +"Set the custom code to be executed when the tutorial passes to the currently " +"selected step." +msgstr "" +"Establecer el código propio para ser ejecutado cuando el tutorial cambie al " +"paso seleccionado actualmente." + +#: KTutorialEditor.cpp:164 +msgctxt "@info:status" +msgid "" +"Set the custom code to be executed when the tutorial changes from the " +"currently selected step to another step." +msgstr "" +"Establecer el código propio para ser ejecutado cuando el tutorial cambie del " +"paso seleccionado actualmente a otro paso." + +#: KTutorialEditor.cpp:174 +msgctxt "@action" +msgid "Remove step" +msgstr "Eliminar paso" + +#: KTutorialEditor.cpp:175 +msgctxt "@info:status" +msgid "Removes the currently selected step from the tutorial." +msgstr "Elimina del tutorial el paso seleccionado actualmente." + +#: main.cpp:27 +msgctxt "@title" +msgid "KTutorial editor" +msgstr "Editor para KTutorial" + +#: main.cpp:29 +msgctxt "@title" +msgid "An editor to create tutorials for <application>KTutorial</application>." +msgstr "" +"Un editor para crear tutoriales para <application>KTutorial</application>." + +#: main.cpp:32 +msgctxt "@info:credit" +msgid "Copyright (c) 2010 Daniel Calviño Sánchez" +msgstr "Copyright (c) 2010 Daniel Calviño Sánchez" + +#: main.cpp:33 +msgctxt "@info:credit" +msgid "Daniel Calviño Sánchez" +msgstr "Daniel Calviño Sánchez" + +#: main.cpp:34 +msgctxt "@info:credit" +msgid "Main developer" +msgstr "Desarrollador principal" + +#: view/StepCustomCodeWidget.cpp:39 +msgctxt "@title" +msgid "Step setup code" +msgstr "Código de inicialización del paso" + +#: view/StepCustomCodeWidget.cpp:40 +msgctxt "@title" +msgid "Set the step setup code" +msgstr "Establecer el código de inicialización del paso" + +#: view/StepCustomCodeWidget.cpp:41 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorials passes to the step.</" +"para><para>The code will be written as is to the setup of the step, after " +"the setup code generated automatically by the editor. This means that the " +"code must be written in the same programming language the tutorial will be " +"exported to.</para>" +msgstr "" +"<para>Establece el código que se ejecutará cuando el tutorial cambie al paso." +"</para><para>El código se escribirá tal cuál en la inicialización del paso, " +"tras el código de inicialización generado automáticamente por el editor. " +"Esto quiere decir que el código debe estar escrito en el mismo lenguaje de " +"programación que en el que se exportará el tutorial.</para>" + +#: view/StepCustomCodeWidget.cpp:50 +msgctxt "@title" +msgid "Step tear down code" +msgstr "Código de finalización del paso" + +#: view/StepCustomCodeWidget.cpp:51 +msgctxt "@title" +msgid "Set the step tear down code" +msgstr "Establecer el código de finalización del paso" + +#: view/StepCustomCodeWidget.cpp:52 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial changes from this step " +"to another.</para><para>The code will be written as is to the tear down of " +"the step, before the tear down code generated automatically by the editor. " +"This means that the code must be written in the same programming language " +"the tutorial will be exported to.</para>" +msgstr "" +"<para>Establece el código que se ejecutará cuando el tutorial cambie de este " +"paso a otro.</para><para>El código se escribirá tal cuál en la finalización " +"del paso, tras el código de finalización generado automáticamente por el " +"editor. Esto quiere decir que el código debe estar escrito en el mismo " +"lenguaje de programación que en el que se exportará el tutorial.</para>" + +#: view/StepTreeItem.cpp:45 +msgctxt "@item Noun, a step in a tutorial" +msgid "Step" +msgstr "Paso" + +#: view/StepTreeItem.cpp:48 +msgctxt "@item Noun, a step in a tutorial" +msgid "Step %1" +msgstr "Paso %1" + +#: view/StepTreeItem.cpp:74 +msgctxt "@item" +msgid "Text: %1" +msgstr "Texto: %1" + +#: view/StepTreeItem.cpp:83 view/TutorialTreeItem.cpp:120 +msgctxt "@item" +msgid "Setup:" +msgstr "Inicialización:" + +#: view/StepTreeItem.cpp:93 view/TutorialTreeItem.cpp:130 +msgctxt "@item" +msgid "Tear down:" +msgstr "Finalización:" + +#: view/TutorialCustomCodeWidget.cpp:40 +msgctxt "@title" +msgid "Tutorial setup code" +msgstr "Código de inicialización del tutorial" + +#: view/TutorialCustomCodeWidget.cpp:41 +msgctxt "@title" +msgid "Set the tutorial setup code" +msgstr "Establecer el código de inicialización del tutorial" + +#: view/TutorialCustomCodeWidget.cpp:42 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial starts.</para><para>The " +"code will be written as is to the setup of the tutorial, after the setup " +"code generated automatically by the editor. This means that the code must be " +"written in the same programming language the tutorial will be exported to.</" +"para>" +msgstr "" +"<para>Establece el código que se ejecutará cuando el tutorial comience.</" +"para><para>El código se escribirá tal cuál en la inicialización del " +"tutorial, tras el código de inicialización generado automáticamente por el " +"editor. Esto quiere decir que el código debe estar escrito en el mismo " +"lenguaje de programación que en el que se exportará el tutorial.</para>" + +#: view/TutorialCustomCodeWidget.cpp:51 +msgctxt "@title" +msgid "Tutorial tear down code" +msgstr "Código de finalización del tutorial" + +#: view/TutorialCustomCodeWidget.cpp:52 +msgctxt "@title" +msgid "Set the tutorial tear down code" +msgstr "Establecer el código de finalización del tutorial..." + +#: view/TutorialCustomCodeWidget.cpp:53 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial finishes.</" +"para><para>The code will be written as is to the tear down of the tutorial, " +"before the tear down code generated automatically by the editor. This means " +"that the code must be written in the same programming language the tutorial " +"will be exported to.</para>" +msgstr "" +"<para>Establece el código que se ejecutará cuando el tutorial termine.</" +"para><para>El código se escribirá tal cuál en la finalización del tutorial, " +"tras el código de finalización generado automáticamente por el editor. Esto " +"quiere decir que el código debe estar escrito en el mismo lenguaje de " +"programación que en el que se exportará el tutorial.</para>" + +#: view/TutorialTreeItem.cpp:55 +msgctxt "@item" +msgid "Tutorial" +msgstr "Tutorial" + +#: view/TutorialTreeItem.cpp:58 +msgctxt "@item" +msgid "Tutorial %1" +msgstr "Tutorial %1" + +#: view/TutorialTreeItem.cpp:88 +msgctxt "@item Noun, the name of a tutorial" +msgid "Name: %1" +msgstr "Nombre: %1" + +#: view/TutorialTreeItem.cpp:100 +msgctxt "@item" +msgid "Description: %1" +msgstr "Descripción: %1" + +#: view/TutorialTreeItem.cpp:110 +msgctxt "@item" +msgid "License:" +msgstr "Licencia:" + +#: view/TutorialTreeItem.cpp:142 +msgctxt "@item" +msgid "Steps:" +msgstr "Pasos:" + +#: rc.cpp:3 +msgctxt "@title:menu" +msgid "Tutorial" +msgstr "Tutorial" + +#: rc.cpp:6 +msgctxt "@title:menu Noun, a step in a tutorial" +msgid "Step" +msgstr "Paso" + +#: rc.cpp:9 +msgctxt "@title:menu" +msgid "Panels" +msgstr "Paneles" + +#: rc.cpp:12 +msgctxt "@title" +msgid "Set tutorial license" +msgstr "Establecer licencia del tutorial" + +#: rc.cpp:15 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the license of the tutorial.</para>\n" +"<para>The license is copied, commented, to the top of the exported tutorial " +"file. That is, you don't have to worry about how comments are written in the " +"programming language the tutorial will be exported to. Just set the pure " +"text of the license, and the editor will take care of adding the necessary " +"characters in each line to mark them as comments instead of source code.</" +"para>" +msgstr "" +"<para>Establece la licencia del tutorial.</para>\n" +"<para>La licencia se copia, comentada, en la parte superior del archivo al " +"que se exporta el tutorial. Es decir, no tienes que preocuparte de cómo se " +"escriben los comentarios en el lenguaje de programación en el que se " +"exportará. Simplemente establece el texto puro de la licencia, y el editor " +"se encargará de añadirle los caracteres necesarios en cada línea para " +"indicar que son comentarios en lugar de código fuente.</para>" + +#: rc.cpp:19 +msgctxt "@title" +msgid "License text" +msgstr "Texto de la licencia" + +#: rc.cpp:22 +msgctxt "@title" +msgid "Set step data" +msgstr "Establecer datos del paso" + +#: rc.cpp:25 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the id and the text of the step</para>\n" +"<para>The text is shown to the user when the tutorial changes to that step.</" +"para>\n" +"<para>On the other hand, the id is only used internally and never shown to " +"the user. It is used to identify the steps in the tutorial when it has to " +"change from one to step to another.</para>" +msgstr "" +"<para>Establecer el identificador y el texto del paso</para>\n" +"<para>El texto se muestra al usuario cuando el tutorial cambia a ese paso.</" +"para>\n" +"<para>En cambio, el identificador sólo se utiliza internamente y nunca se " +"muestra al usuario. Se utiliza para identificar los pasos en el tutorial " +"cuando tiene que cambiar de un paso a otro.</para>" + +#: rc.cpp:30 +msgctxt "@title" +msgid "Step data" +msgstr "Datos del paso" + +#: rc.cpp:33 +msgctxt "@label:textbox" +msgid "Id:" +msgstr "Identificador:" + +#: rc.cpp:36 +msgctxt "@label:textbox" +msgid "Text:" +msgstr "Texto:" + +#: rc.cpp:39 +msgctxt "@title" +msgid "Set tutorial information" +msgstr "Establecer información del tutorial" + +#: rc.cpp:42 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the name and description of the tutorial.</para>\n" +"<para>The name and the description are shown in the dialog where the " +"tutorial to be started is selected.</para>" +msgstr "" +"<para>Establecer el nombre y la descripción del tutorial.</para>\n" +"<para>El nombre y la descripción se muestran en el diálogo en el que se " +"selecciona qué tutorial se empezará.</para>" + +#: rc.cpp:46 +msgctxt "@title" +msgid "Tutorial information" +msgstr "Información del tutorial" + +#: rc.cpp:49 +msgctxt "@label:textbox Noun, the name of a tutorial" +msgid "Name:" +msgstr "Nombre:" + +#: rc.cpp:52 +msgctxt "@label:textbox" +msgid "Description:" +msgstr "Descripción:" + +#: rc.cpp:53 +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "Daniel Calviño Sánchez" + +#: rc.cpp:54 +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "dan...@gm..." Added: trunk/ktutorial/ktutorial-editor/po/ktutorial-editor.pot =================================================================== --- trunk/ktutorial/ktutorial-editor/po/ktutorial-editor.pot (rev 0) +++ trunk/ktutorial/ktutorial-editor/po/ktutorial-editor.pot 2010-03-10 18:47:21 UTC (rev 145) @@ -0,0 +1,378 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" +"group_id=301227&atid=1270278\n" +"POT-Creation-Date: 2010-03-10 19:41+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL...@li...>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: KTutorialEditor.cpp:77 +msgctxt "@title" +msgid "Edit tutorial" +msgstr "" + +#: KTutorialEditor.cpp:82 +msgctxt "@title" +msgid "Edit step" +msgstr "" + +#: KTutorialEditor.cpp:94 +msgctxt "@action" +msgid "Set information..." +msgstr "" + +#: KTutorialEditor.cpp:95 +msgctxt "@info:status" +msgid "Set the name and description of the tutorial." +msgstr "" + +#: KTutorialEditor.cpp:104 +msgctxt "@action" +msgid "Set license..." +msgstr "" + +#: KTutorialEditor.cpp:105 +msgctxt "@info:status" +msgid "Set the license text of the tutorial." +msgstr "" + +#: KTutorialEditor.cpp:113 KTutorialEditor.cpp:153 +msgctxt "@action" +msgid "Set setup code..." +msgstr "" + +#: KTutorialEditor.cpp:114 +msgctxt "@info:status" +msgid "Set the custom code to be executed when the tutorial starts." +msgstr "" + +#: KTutorialEditor.cpp:122 KTutorialEditor.cpp:163 +msgctxt "@action" +msgid "Set tear down code..." +msgstr "" + +#: KTutorialEditor.cpp:123 +msgctxt "@info:status" +msgid "Set the custom code to be executed when the tutorial finishes." +msgstr "" + +#: KTutorialEditor.cpp:134 +msgctxt "@action" +msgid "Add step..." +msgstr "" + +#: KTutorialEditor.cpp:135 +msgctxt "@info:status" +msgid "Add a new step to the tutorial." +msgstr "" + +#: KTutorialEditor.cpp:143 +msgctxt "@action" +msgid "Set data..." +msgstr "" + +#: KTutorialEditor.cpp:144 +msgctxt "@info:status" +msgid "Set the name and text of the currently selected step." +msgstr "" + +#: KTutorialEditor.cpp:154 +msgctxt "@info:status" +msgid "" +"Set the custom code to be executed when the tutorial passes to the currently " +"selected step." +msgstr "" + +#: KTutorialEditor.cpp:164 +msgctxt "@info:status" +msgid "" +"Set the custom code to be executed when the tutorial changes from the " +"currently selected step to another step." +msgstr "" + +#: KTutorialEditor.cpp:174 +msgctxt "@action" +msgid "Remove step" +msgstr "" + +#: KTutorialEditor.cpp:175 +msgctxt "@info:status" +msgid "Removes the currently selected step from the tutorial." +msgstr "" + +#: main.cpp:27 +msgctxt "@title" +msgid "KTutorial editor" +msgstr "" + +#: main.cpp:29 +msgctxt "@title" +msgid "An editor to create tutorials for <application>KTutorial</application>." +msgstr "" + +#: main.cpp:32 +msgctxt "@info:credit" +msgid "Copyright (c) 2010 Daniel Calviño Sánchez" +msgstr "" + +#: main.cpp:33 +msgctxt "@info:credit" +msgid "Daniel Calviño Sánchez" +msgstr "" + +#: main.cpp:34 +msgctxt "@info:credit" +msgid "Main developer" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:39 +msgctxt "@title" +msgid "Step setup code" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:40 +msgctxt "@title" +msgid "Set the step setup code" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:41 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorials passes to the step.</" +"para><para>The code will be written as is to the setup of the step, after " +"the setup code generated automatically by the editor. This means that the " +"code must be written in the same programming language the tutorial will be " +"exported to.</para>" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:50 +msgctxt "@title" +msgid "Step tear down code" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:51 +msgctxt "@title" +msgid "Set the step tear down code" +msgstr "" + +#: view/StepCustomCodeWidget.cpp:52 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial changes from this step " +"to another.</para><para>The code will be written as is to the tear down of " +"the step, before the tear down code generated automatically by the editor. " +"This means that the code must be written in the same programming language " +"the tutorial will be exported to.</para>" +msgstr "" + +#: view/StepTreeItem.cpp:45 +msgctxt "@item Noun, a step in a tutorial" +msgid "Step" +msgstr "" + +#: view/StepTreeItem.cpp:48 +msgctxt "@item Noun, a step in a tutorial" +msgid "Step %1" +msgstr "" + +#: view/StepTreeItem.cpp:74 +msgctxt "@item" +msgid "Text: %1" +msgstr "" + +#: view/StepTreeItem.cpp:83 view/TutorialTreeItem.cpp:120 +msgctxt "@item" +msgid "Setup:" +msgstr "" + +#: view/StepTreeItem.cpp:93 view/TutorialTreeItem.cpp:130 +msgctxt "@item" +msgid "Tear down:" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:40 +msgctxt "@title" +msgid "Tutorial setup code" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:41 +msgctxt "@title" +msgid "Set the tutorial setup code" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:42 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial starts.</para><para>The " +"code will be written as is to the setup of the tutorial, after the setup " +"code generated automatically by the editor. This means that the code must be " +"written in the same programming language the tutorial will be exported to.</" +"para>" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:51 +msgctxt "@title" +msgid "Tutorial tear down code" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:52 +msgctxt "@title" +msgid "Set the tutorial tear down code" +msgstr "" + +#: view/TutorialCustomCodeWidget.cpp:53 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the code to be executed when the tutorial finishes.</" +"para><para>The code will be written as is to the tear down of the tutorial, " +"before the tear down code generated automatically by the editor. This means " +"that the code must be written in the same programming language the tutorial " +"will be exported to.</para>" +msgstr "" + +#: view/TutorialTreeItem.cpp:55 +msgctxt "@item" +msgid "Tutorial" +msgstr "" + +#: view/TutorialTreeItem.cpp:58 +msgctxt "@item" +msgid "Tutorial %1" +msgstr "" + +#: view/TutorialTreeItem.cpp:88 +msgctxt "@item Noun, the name of a tutorial" +msgid "Name: %1" +msgstr "" + +#: view/TutorialTreeItem.cpp:100 +msgctxt "@item" +msgid "Description: %1" +msgstr "" + +#: view/TutorialTreeItem.cpp:110 +msgctxt "@item" +msgid "License:" +msgstr "" + +#: view/TutorialTreeItem.cpp:142 +msgctxt "@item" +msgid "Steps:" +msgstr "" + +#: rc.cpp:3 +msgctxt "@title:menu" +msgid "Tutorial" +msgstr "" + +#: rc.cpp:6 +msgctxt "@title:menu Noun, a step in a tutorial" +msgid "Step" +msgstr "" + +#: rc.cpp:9 +msgctxt "@title:menu" +msgid "Panels" +msgstr "" + +#: rc.cpp:12 +msgctxt "@title" +msgid "Set tutorial license" +msgstr "" + +#: rc.cpp:15 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the license of the tutorial.</para>\n" +"<para>The license is copied, commented, to the top of the exported tutorial " +"file. That is, you don't have to worry about how comments are written in the " +"programming language the tutorial will be exported to. Just set the pure " +"text of the license, and the editor will take care of adding the necessary " +"characters in each line to mark them as comments instead of source code.</" +"para>" +msgstr "" + +#: rc.cpp:19 +msgctxt "@title" +msgid "License text" +msgstr "" + +#: rc.cpp:22 +msgctxt "@title" +msgid "Set step data" +msgstr "" + +#: rc.cpp:25 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the id and the text of the step</para>\n" +"<para>The text is shown to the user when the tutorial changes to that step.</" +"para>\n" +"<para>On the other hand, the id is only used internally and never shown to " +"the user. It is used to identify the steps in the tutorial when it has to " +"change from one to step to another.</para>" +msgstr "" + +#: rc.cpp:30 +msgctxt "@title" +msgid "Step data" +msgstr "" + +#: rc.cpp:33 +msgctxt "@label:textbox" +msgid "Id:" +msgstr "" + +#: rc.cpp:36 +msgctxt "@label:textbox" +msgid "Text:" +msgstr "" + +#: rc.cpp:39 +msgctxt "@title" +msgid "Set tutorial information" +msgstr "" + +#: rc.cpp:42 +msgctxt "@info:whatsthis" +msgid "" +"<para>Set the name and description of the tutorial.</para>\n" +"<para>The name and the description are shown in the dialog where the " +"tutorial to be started is selected.</para>" +msgstr "" + +#: rc.cpp:46 +msgctxt "@title" +msgid "Tutorial information" +msgstr "" + +#: rc.cpp:49 +msgctxt "@label:textbox Noun, the name of a tutorial" +msgid "Name:" +msgstr "" + +#: rc.cpp:52 +msgctxt "@label:textbox" +msgid "Description:" +msgstr "" + +#: rc.cpp:53 +msgctxt "NAME OF TRANSLATORS" +msgid "Your names" +msgstr "" + +#: rc.cpp:54 +msgctxt "EMAIL OF TRANSLATORS" +msgid "Your emails" +msgstr "" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-12 00:08:31
|
Revision: 147 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=147&view=rev Author: danxuliu Date: 2010-03-12 00:08:24 +0000 (Fri, 12 Mar 2010) Log Message: ----------- Add WaitFor and subclasses to store the data of conditions to wait for to be met. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/WaitFor.cpp trunk/ktutorial/ktutorial-editor/src/WaitFor.h trunk/ktutorial/ktutorial-editor/src/WaitForComposed.cpp trunk/ktutorial/ktutorial-editor/src/WaitForComposed.h trunk/ktutorial/ktutorial-editor/src/WaitForNot.cpp trunk/ktutorial/ktutorial-editor/src/WaitForNot.h trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h trunk/ktutorial/ktutorial-editor/tests/unit/WaitForComposedTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/WaitForNotTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-11 19:36:17 UTC (rev 146) +++ trunk/ktutorial/ktutorial-editor/src/CMakeLists.txt 2010-03-12 00:08:24 UTC (rev 147) @@ -10,6 +10,10 @@ KTutorialEditor.cpp Step.cpp Tutorial.cpp + WaitFor.cpp + WaitForComposed.cpp + WaitForNot.cpp + WaitForSignal.cpp ) # Instead of compiling the executable directly from the sources, the sources are Added: trunk/ktutorial/ktutorial-editor/src/WaitFor.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitFor.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitFor.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitFor.h" + +//public: + +WaitFor::WaitFor(QObject* parent): QObject(parent) { +} Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitFor.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitFor.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitFor.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitFor.h 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFOR_H +#define WAITFOR_H + +#include <QObject> + +/** + * Base class for conditions to wait for to be met. + * Its subclasses store the data used in KTutorial wait for subclasses, but they + * have nothing to do with them (they don't even know each others). Its purpose + * is store the data needed to generate the code to initialize a true + * KTutorial::WaitFor subclass object. + * + * Subclasses must emit dataChanged(Step*) signal when their data is modified + * (including the data of child conditions). + */ +class WaitFor: public QObject { +Q_OBJECT +public: + + /** + * Creates a new WaitFor. + * + * @param parent The parent QObject. + */ + WaitFor(QObject* parent = 0); + +Q_SIGNALS: + + /** + * Emitted when any data in the WaitFor changed. + * Subclasses must emit this signal when needed. + * + * @param waitFor This WaitFor. + */ + void dataChanged(WaitFor* waitFor); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitFor.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForComposed.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForComposed.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForComposed.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForComposed.h" + +//public: + +WaitForComposed::WaitForComposed(QObject* parent): + WaitFor(parent), + mCompositionType(And) { +} + +WaitForComposed::~WaitForComposed() { + qDeleteAll(mWaitFors); +} + +WaitForComposed::CompositionType WaitForComposed::compositionType() const { + return mCompositionType; +} + +void WaitForComposed::setCompositionType(CompositionType compositionType) { + mCompositionType = compositionType; + + emit dataChanged(this); +} + +void WaitForComposed::addWaitFor(WaitFor* waitFor) { + Q_ASSERT(!mWaitFors.contains(waitFor)); + + mWaitFors.append(waitFor); + + emit waitForAdded(waitFor); +} + +QList<WaitFor*> WaitForComposed::waitFors() const { + return mWaitFors; +} + +void WaitForComposed::removeWaitFor(WaitFor* waitFor) { + Q_ASSERT(mWaitFors.contains(waitFor)); + + mWaitFors.removeOne(waitFor); + + emit waitForRemoved(waitFor); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForComposed.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForComposed.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForComposed.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForComposed.h 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORCOMPOSED_H +#define WAITFORCOMPOSED_H + +#include "WaitFor.h" + +/** + * Container for composed conditions to wait for data. + * It stores the data used in KTutorial WaitForAnd and WaitForOr, but it has + * nothing to do with them (they don't even know each other). Its purpose is + * store the data needed to generate the code to initialize a true + * KTutorial::WaitForComposed subclass object. + * + * When the composition type is modified, dataChanged(WaitFor*) signal is + * emitted. When WaitFors are added or removed, waitForAdded(WaitFor*) and + * waitForRemoved(WaitFor*) are emitted. + */ +class WaitForComposed: public WaitFor { +Q_OBJECT +public: + + enum CompositionType { + And, + Or + }; + + /** + * Creates a new WaitForComposed. + * + * @param parent The parent QObject. + */ + WaitForComposed(QObject* parent = 0); + virtual ~WaitForComposed(); + + CompositionType compositionType() const; + void setCompositionType(CompositionType compositionType); + + /** + * Adds a new WaitFor to this WaitForComposed. + * This WaitForComposed gets ownership of the added WaitFor, so it is + * deleted when this WaitForComposed is deleted. + * + * @param waitFor The WaitFor to add. + */ + void addWaitFor(WaitFor* waitFor); + QList<WaitFor*> waitFors() const; + + /** + * Removes a WaitFor from this WaitForComposed. + * The WaitFor must be deleted explicitly. + * + * @param waitFor The WaitFor to remove. + */ + void removeWaitFor(WaitFor* waitFor); + +Q_SIGNALS: + + /** + * Emitted when the WaitFor is added to this WaitForComposed. + * + * @param waitFor The WaitFor added. + */ + void waitForAdded(WaitFor* waitFor); + + /** + * Emitted when the WaitFor is removed from this WaitForComposed. + * + * @param waitFor The WaitFor removed. + */ + void waitForRemoved(WaitFor* waitFor); + +private: + + CompositionType mCompositionType; + QList<WaitFor*> mWaitFors; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForComposed.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForNot.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForNot.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForNot.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForNot.h" + +//public: + +WaitForNot::WaitForNot(QObject* parent): + WaitFor(parent), + mNegatedWaitFor(0) { +} + +WaitForNot::~WaitForNot() { + delete mNegatedWaitFor; +} + +WaitFor* WaitForNot::negatedWaitFor() const { + return mNegatedWaitFor; +} + +void WaitForNot::setNegatedWaitFor(WaitFor* waitFor) { + mNegatedWaitFor = waitFor; + + emit dataChanged(this); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForNot.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForNot.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForNot.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForNot.h 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORNOT_H +#define WAITFORNOT_H + +#include "WaitFor.h" + +/** + * Container for negated wait for data. + * It stores the data used in KTutorial WaitForNot, but it has nothing to do + * with it (they don't even know each other). Its purpose is store the data + * needed to generate the code to initialize a true KTutorial::WaitForNot + * object. + * + * When the negated wait for is modified, dataChanged(WaitFor*) signal is + * emitted. + */ +class WaitForNot: public WaitFor { +Q_OBJECT +public: + + /** + * Creates a new WaitForNot. + * + * @param parent The parent QObject. + */ + WaitForNot(QObject* parent = 0); + virtual ~WaitForNot(); + + WaitFor* negatedWaitFor() const; + + /** + * Sets the negated WaitFor. + * The WaitFor will be destroyed when this WaitForNot is destroyed. However, + * if a WaitFor is set over a previous one, the previous one must be deleted + * explicitly. + * + * @param waitFor The WaitFor to set. + */ + void setNegatedWaitFor(WaitFor* waitFor); + +private: + + WaitFor* mNegatedWaitFor; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForNot.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignal.h" + +//public: + +WaitForSignal::WaitForSignal(QObject* parent): WaitFor(parent) { +} + +QString WaitForSignal::objectName() const { + return mObjectName; +} + +void WaitForSignal::setObjectName(const QString& objectName) { + mObjectName = objectName; + + emit dataChanged(this); +} + +QString WaitForSignal::signalName() const { + return mSignalName; +} + +void WaitForSignal::setSignalName(const QString& signalName) { + mSignalName = signalName; + + emit dataChanged(this); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORSIGNAL_H +#define WAITFORSIGNAL_H + +#include "WaitFor.h" + +/** + * Container for conditions that wait for a signal to be emitted data. + * It stores the data used in KTutorial WaitForSignal, but it has nothing to do + * with it (they don't even know each other). Its purpose is store the data + * needed to generate the code to initialize a true KTutorial::WaitForSignal + * object. + * + * When any attribute is modified, dataChanged(WaitFor*) signal is emitted. + */ +class WaitForSignal: public WaitFor { +Q_OBJECT +public: + + /** + * Creates a new WaitForSignal. + * + * @param parent The parent QObject. + */ + WaitForSignal(QObject* parent = 0); + + QString objectName() const; + void setObjectName(const QString& objectName); + + QString signalName() const; + void setSignalName(const QString& signalName); + +private: + + QString mObjectName; + QString mSignalName; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-11 19:36:17 UTC (rev 146) +++ trunk/ktutorial/ktutorial-editor/tests/unit/CMakeLists.txt 2010-03-12 00:08:24 UTC (rev 147) @@ -17,6 +17,9 @@ unit_tests( Step Tutorial + WaitForComposed + WaitForNot + WaitForSignal ) MACRO(MEM_TESTS) @@ -28,4 +31,7 @@ mem_tests( Step Tutorial + WaitForComposed + WaitForNot + WaitForSignal ) Added: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForComposedTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/WaitForComposedTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/WaitForComposedTest.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,143 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForComposed.h" + +class WaitForComposedTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + + void testSetCompositionType(); + + void testAddWaitFor(); + void testRemoveWaitFor(); + +private: + + int mWaitForStarType; + + void assertWaitForSignal(const QSignalSpy& spy, int index, + WaitFor* waitFor); + +}; + +void WaitForComposedTest::initTestCase() { + //WaitFor* must be registered in order to be used with QSignalSpy + mWaitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*"); +} + +void WaitForComposedTest::testConstructor() { + QObject parent; + WaitForComposed* waitForComposed = new WaitForComposed(&parent); + + QCOMPARE(waitForComposed->parent(), &parent); + QCOMPARE(waitForComposed->compositionType(), WaitForComposed::And); +} + +void WaitForComposedTest::testSetCompositionType() { + WaitForComposed waitForComposed; + + QSignalSpy dataChangedSpy(&waitForComposed, SIGNAL(dataChanged(WaitFor*))); + + waitForComposed.setCompositionType(WaitForComposed::Or); + + QCOMPARE(waitForComposed.compositionType(), WaitForComposed::Or); + QCOMPARE(dataChangedSpy.count(), 1); + assertWaitForSignal(dataChangedSpy, 0, &waitForComposed); +} + +void WaitForComposedTest::testAddWaitFor() { + WaitForComposed waitForComposed; + WaitFor* waitFor1 = new WaitFor(); + WaitFor* waitFor2 = new WaitFor(); + WaitFor* waitFor3 = new WaitFor(); + + QSignalSpy waitForAddedSpy(&waitForComposed, + SIGNAL(waitForAdded(WaitFor*))); + + waitForComposed.addWaitFor(waitFor1); + waitForComposed.addWaitFor(waitFor2); + waitForComposed.addWaitFor(waitFor3); + + QCOMPARE(waitForComposed.waitFors().count(), 3); + QCOMPARE(waitForComposed.waitFors()[0], waitFor1); + QCOMPARE(waitForComposed.waitFors()[1], waitFor2); + QCOMPARE(waitForComposed.waitFors()[2], waitFor3); + QCOMPARE(waitForAddedSpy.count(), 3); + assertWaitForSignal(waitForAddedSpy, 0, waitFor1); + assertWaitForSignal(waitForAddedSpy, 1, waitFor2); + assertWaitForSignal(waitForAddedSpy, 2, waitFor3); +} + +void WaitForComposedTest::testRemoveWaitFor() { + WaitForComposed waitForComposed; + + //They will be removed and not deleted by the WaitForComposed, so they are + //created in stack + WaitFor waitFor1; + WaitFor waitFor2; + WaitFor waitFor3; + + waitForComposed.addWaitFor(&waitFor1); + waitForComposed.addWaitFor(&waitFor2); + waitForComposed.addWaitFor(&waitFor3); + + QSignalSpy waitForRemovedSpy(&waitForComposed, + SIGNAL(waitForRemoved(WaitFor*))); + + waitForComposed.removeWaitFor(&waitFor2); + + QCOMPARE(waitForComposed.waitFors().count(), 2); + QCOMPARE(waitForComposed.waitFors()[0], &waitFor1); + QCOMPARE(waitForComposed.waitFors()[1], &waitFor3); + QCOMPARE(waitForRemovedSpy.count(), 1); + assertWaitForSignal(waitForRemovedSpy, 0, &waitFor2); + + waitForComposed.removeWaitFor(&waitFor1); + waitForComposed.removeWaitFor(&waitFor3); + + QCOMPARE(waitForComposed.waitFors().count(), 0); + QCOMPARE(waitForRemovedSpy.count(), 3); + assertWaitForSignal(waitForRemovedSpy, 1, &waitFor1); + assertWaitForSignal(waitForRemovedSpy, 2, &waitFor3); +} + +//WaitFor* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(WaitFor*); + +/////////////////////////////////// Helpers //////////////////////////////////// + +void WaitForComposedTest::assertWaitForSignal(const QSignalSpy& spy, int index, + WaitFor* waitFor) { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mWaitForStarType); + QCOMPARE(qvariant_cast<WaitFor*>(argument), waitFor); +} + +QTEST_MAIN(WaitForComposedTest) + +#include "WaitForComposedTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForComposedTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForNotTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/WaitForNotTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/WaitForNotTest.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForNot.h" + +class WaitForNotTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSetNegatedWaitFor(); + +}; + +void WaitForNotTest::testConstructor() { + QObject parent; + WaitForNot* waitForNot = new WaitForNot(&parent); + + QCOMPARE(waitForNot->parent(), &parent); + QCOMPARE(waitForNot->negatedWaitFor(), (WaitFor*)0); +} + +//WaitFor* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(WaitFor*); + +void WaitForNotTest::testSetNegatedWaitFor() { + WaitForNot waitForNot; + WaitFor* negatedWaitFor = new WaitFor(); + + //WaitFor* must be registered in order to be used with QSignalSpy + int waitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*"); + QSignalSpy dataChangedSpy(&waitForNot, SIGNAL(dataChanged(WaitFor*))); + + waitForNot.setNegatedWaitFor(negatedWaitFor); + + QCOMPARE(waitForNot.negatedWaitFor(), negatedWaitFor); + QCOMPARE(dataChangedSpy.count(), 1); + QVariant argument = dataChangedSpy.at(0).at(0); + QCOMPARE(argument.userType(), waitForStarType); + QCOMPARE(qvariant_cast<WaitFor*>(argument), &waitForNot); +} + +QTEST_MAIN(WaitForNotTest) + +#include "WaitForNotTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForNotTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp 2010-03-12 00:08:24 UTC (rev 147) @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignal.h" + +class WaitForSignalTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + + void testSetObjectName(); + + void testSetSignalName(); + +private: + + int mWaitForStarType; + + void assertWaitForSignal(const QSignalSpy& spy, int index, + WaitFor* waitFor); + +}; + +void WaitForSignalTest::initTestCase() { + //WaitFor* must be registered in order to be used with QSignalSpy + mWaitForStarType = qRegisterMetaType<WaitFor*>("WaitFor*"); +} + +void WaitForSignalTest::testConstructor() { + QObject parent; + WaitForSignal* waitForSignal = new WaitForSignal(&parent); + + QCOMPARE(waitForSignal->parent(), &parent); +} + +void WaitForSignalTest::testSetObjectName() { + WaitForSignal waitForSignal; + + QSignalSpy dataChangedSpy(&waitForSignal, SIGNAL(dataChanged(WaitFor*))); + + waitForSignal.setObjectName("The object name"); + + QCOMPARE(waitForSignal.objectName(), QString("The object name")); + QCOMPARE(dataChangedSpy.count(), 1); + assertWaitForSignal(dataChangedSpy, 0, &waitForSignal); +} + +void WaitForSignalTest::testSetSignalName() { + WaitForSignal waitForSignal; + + QSignalSpy dataChangedSpy(&waitForSignal, SIGNAL(dataChanged(WaitFor*))); + + waitForSignal.setSignalName("The signal name"); + + QCOMPARE(waitForSignal.signalName(), QString("The signal name")); + QCOMPARE(dataChangedSpy.count(), 1); + assertWaitForSignal(dataChangedSpy, 0, &waitForSignal); +} + +//WaitFor* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(WaitFor*); + +/////////////////////////////////// Helpers //////////////////////////////////// + +void WaitForSignalTest::assertWaitForSignal(const QSignalSpy& spy, int index, + WaitFor* waitFor) { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mWaitForStarType); + QCOMPARE(qvariant_cast<WaitFor*>(argument), waitFor); +} + +QTEST_MAIN(WaitForSignalTest) + +#include "WaitForSignalTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-12 17:06:09
|
Revision: 148 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=148&view=rev Author: danxuliu Date: 2010-03-12 17:05:56 +0000 (Fri, 12 Mar 2010) Log Message: ----------- Rename objectName to emitterName to avoid clashing with QObject:objectName(). Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp 2010-03-12 00:08:24 UTC (rev 147) +++ trunk/ktutorial/ktutorial-editor/src/WaitForSignal.cpp 2010-03-12 17:05:56 UTC (rev 148) @@ -23,12 +23,12 @@ WaitForSignal::WaitForSignal(QObject* parent): WaitFor(parent) { } -QString WaitForSignal::objectName() const { - return mObjectName; +QString WaitForSignal::emitterName() const { + return mEmitterName; } -void WaitForSignal::setObjectName(const QString& objectName) { - mObjectName = objectName; +void WaitForSignal::setEmitterName(const QString& emitterName) { + mEmitterName = emitterName; emit dataChanged(this); } Modified: trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h 2010-03-12 00:08:24 UTC (rev 147) +++ trunk/ktutorial/ktutorial-editor/src/WaitForSignal.h 2010-03-12 17:05:56 UTC (rev 148) @@ -41,15 +41,15 @@ */ WaitForSignal(QObject* parent = 0); - QString objectName() const; - void setObjectName(const QString& objectName); + QString emitterName() const; + void setEmitterName(const QString& emitterName); QString signalName() const; void setSignalName(const QString& signalName); private: - QString mObjectName; + QString mEmitterName; QString mSignalName; }; Modified: trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp 2010-03-12 00:08:24 UTC (rev 147) +++ trunk/ktutorial/ktutorial-editor/tests/unit/WaitForSignalTest.cpp 2010-03-12 17:05:56 UTC (rev 148) @@ -29,7 +29,7 @@ void testConstructor(); - void testSetObjectName(); + void testSetEmitterName(); void testSetSignalName(); @@ -54,14 +54,14 @@ QCOMPARE(waitForSignal->parent(), &parent); } -void WaitForSignalTest::testSetObjectName() { +void WaitForSignalTest::testSetEmitterName() { WaitForSignal waitForSignal; QSignalSpy dataChangedSpy(&waitForSignal, SIGNAL(dataChanged(WaitFor*))); - waitForSignal.setObjectName("The object name"); + waitForSignal.setEmitterName("The emitter name"); - QCOMPARE(waitForSignal.objectName(), QString("The object name")); + QCOMPARE(waitForSignal.emitterName(), QString("The emitter name")); QCOMPARE(dataChangedSpy.count(), 1); assertWaitForSignal(dataChangedSpy, 0, &waitForSignal); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-12 17:10:59
|
Revision: 149 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=149&view=rev Author: danxuliu Date: 2010-03-12 17:10:49 +0000 (Fri, 12 Mar 2010) Log Message: ----------- Add TreeItems to represents WaitFor subclasses. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.h trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.h trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.h trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForComposedTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForNotTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalTreeItemTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForTreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-12 17:05:56 UTC (rev 148) +++ trunk/ktutorial/ktutorial-editor/src/view/CMakeLists.txt 2010-03-12 17:10:49 UTC (rev 149) @@ -16,6 +16,10 @@ TutorialInformationWidget.cpp TutorialTreeItem.cpp TutorialTreeSelectionManager.cpp + WaitForComposedTreeItem.cpp + WaitForNotTreeItem.cpp + WaitForSignalTreeItem.cpp + WaitForTreeItem.cpp ) kde4_add_ui_files(ktutorial_editor_view_SRCS Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForComposedTreeItem.h" + +#include <KLocalizedString> + +#include "../WaitForComposed.h" + +//public: + +WaitForComposedTreeItem::WaitForComposedTreeItem( + WaitForComposed* waitForComposed, TreeItem* parent): + WaitForTreeItem(waitForComposed, parent) { + mCompositionType = waitForComposed->compositionType(); + + foreach (WaitFor* waitFor, waitForComposed->waitFors()) { + addWaitFor(waitFor); + } + + connect(waitForComposed, SIGNAL(dataChanged(WaitFor*)), + this, SLOT(update(WaitFor*))); + connect(waitForComposed, SIGNAL(waitForAdded(WaitFor*)), + this, SLOT(addWaitFor(WaitFor*))); + connect(waitForComposed, SIGNAL(waitForRemoved(WaitFor*)), + this, SLOT(removeWaitFor(WaitFor*))); +} + +QString WaitForComposedTreeItem::text() const { + if (mCompositionType == WaitForComposed::And) { + return i18nc("@item", "When all the contained conditions match"); + } + + return i18nc("@item", "When any of the contained conditions match"); +} + +//private: + +WaitForTreeItem* WaitForComposedTreeItem::treeItemForWaitFor(WaitFor* waitFor) { + foreach (WaitForTreeItem* waitForTreeItem, mWaitForTreeItems) { + if (waitForTreeItem->waitFor() == waitFor) { + return waitForTreeItem; + } + } + + return 0; +} + +//private slots: + +void WaitForComposedTreeItem::update(WaitFor* waitFor) { + mCompositionType = + static_cast<WaitForComposed*>(waitFor)->compositionType(); + + emit dataChanged(this); +} + +void WaitForComposedTreeItem::addWaitFor(WaitFor* waitFor) { + WaitForTreeItem* item = WaitForTreeItem::treeItemForWaitFor(waitFor, this); + appendChild(item); + mWaitForTreeItems.append(item); +} + +void WaitForComposedTreeItem::removeWaitFor(WaitFor* waitFor) { + WaitForTreeItem* item = treeItemForWaitFor(waitFor); + + removeChild(item); + mWaitForTreeItems.removeOne(item); + delete item; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.h 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORCOMPOSEDTREEITEM_H +#define WAITFORCOMPOSEDTREEITEM_H + +#include "WaitForTreeItem.h" +#include "../WaitForComposed.h" + +/** + * A TreeItem that represents a WaitForComposed. + * The tree representation of a WaitForComposed is: + * TextThatDependsOnTheTypeOfWaitForComposed + * |-Representation of first WaitFor child + * |-Representation of second WaitFor child + * ... + * + * The text that depends on the type of the WaitForComposed is + * -"When all the contained conditions match" for And type + * -"When any of the contained conditions match" for Or type + * + * Whenever the WaitForComposed data changes, a child is added or a child is + * removed, the WaitForComposedTreeItem and its child items are updated as + * needed. + */ +class WaitForComposedTreeItem: public WaitForTreeItem { +Q_OBJECT +public: + + /** + * Creates a new WaitForComposedTreeItem for the given WaitForComposed and + * with the given parent. + * + * @param waitForComposed The WaitForComposed to represent. + * @param parent The parent TreeItem. + */ + explicit WaitForComposedTreeItem(WaitForComposed* waitForComposed, + TreeItem* parent = 0); + + /** + * Returns the appropriate text for the type of the WaitForComposed. + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + +private: + + /** + * The composition type of the WaitForComposed. + */ + WaitForComposed::CompositionType mCompositionType; + + /** + * The WaitForTreeItem for each child of the WaitForComposed. + */ + QList<WaitForTreeItem*> mWaitForTreeItems; + + /** + * Returns the WaitForTreeItem for the given WaitFor. + * + * @param waitFor The WaitFor to get its WaitForTreeItem. + * @return The WaitForTreeItem. + */ + WaitForTreeItem* treeItemForWaitFor(WaitFor* waitFor); + +private Q_SLOTS: + + /** + * Updates this WaitForComposedTreeItem when the data of its WaitForComposed + * changed. + * + * @param waitFor The WaitForComposed. + */ + void update(WaitFor* waitFor); + + /** + * Adds a new WaitForTreeItem when a WaitFor is added to the + * WaitForComposed. + * + * @param waitFor The WaitFor added in the WaitForComposed. + */ + void addWaitFor(WaitFor* waitFor); + + /** + * Removes the WaitForTreeItem for the WaitFor removed from the + * WaitForComposed. + * + * @param waitFor The WaitFor removed from the WaitForComposed. + */ + void removeWaitFor(WaitFor* waitFor); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForComposedTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForNotTreeItem.h" + +#include <KLocalizedString> + +#include "../WaitForNot.h" + +//public: + +WaitForNotTreeItem::WaitForNotTreeItem(WaitForNot* waitForNot, + TreeItem* parent): + WaitForTreeItem(waitForNot, parent), + mNegatedWaitForItem(0) { + + update(waitForNot); + + connect(waitForNot, SIGNAL(dataChanged(WaitFor*)), + this, SLOT(update(WaitFor*))); +} + +QString WaitForNotTreeItem::text() const { + return i18nc("@item", "The contained condition can't have been met"); +} + +//private slots: + +void WaitForNotTreeItem::update(WaitFor* waitFor) { + if (mNegatedWaitForItem) { + removeChild(mNegatedWaitForItem); + delete mNegatedWaitForItem; + mNegatedWaitForItem = 0; + } + + WaitForNot* waitForNot = static_cast<WaitForNot*>(waitFor); + WaitFor* negatedWaitFor = waitForNot->negatedWaitFor(); + if (negatedWaitFor) { + mNegatedWaitForItem = WaitForTreeItem::treeItemForWaitFor( + negatedWaitFor, this); + + appendChild(mNegatedWaitForItem); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.h 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORNOTTREEITEM_H +#define WAITFORNOTTREEITEM_H + +#include "WaitForTreeItem.h" + +class WaitForNot; + +/** + * A TreeItem that represents a WaitForNot. + * The tree representation of a WaitForNot is: + * The contained condition can't have been met + * -Representation of the negated WaitFor + * + * Whenever another negated WaitFor is set, the child item of the + * WaitForNotTreeItem is updated as needed. + */ +class WaitForNotTreeItem: public WaitForTreeItem { +Q_OBJECT +public: + + /** + * Creates a new WaitForNotTreeItem for the given WaitForNot and with the + * given parent. + * + * @param waitForNot The WaitForNot to represent. + * @param parent The parent TreeItem. + */ + explicit WaitForNotTreeItem(WaitForNot* waitForNot, TreeItem* parent = 0); + + /** + * Returns "The contained condition can't have been met". + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + +private: + + /** + * The representation of the negated WaitFor. + */ + WaitForTreeItem* mNegatedWaitForItem; + +private Q_SLOTS: + + /** + * Updates the child WaitForTreeItem when the negated WaitFor changes in the + * given WaitFor. + * + * @param waitFor The WaitForNot. + */ + void update(WaitFor* waitFor); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForNotTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignalTreeItem.h" + +#include <KLocalizedString> + +#include "../WaitForSignal.h" + +//public: + +WaitForSignalTreeItem::WaitForSignalTreeItem(WaitForSignal* waitForSignal, + TreeItem* parent): + WaitForTreeItem(waitForSignal, parent) { + mEmitterName = waitForSignal->emitterName(); + mSignalName = waitForSignal->signalName(); + + connect(waitForSignal, SIGNAL(dataChanged(WaitFor*)), + this, SLOT(update(WaitFor*))); +} + +QString WaitForSignalTreeItem::text() const { + QString emitterName; + if (mEmitterName.isEmpty()) { + emitterName = i18nc("@item", "(object not set)"); + } else { + emitterName = "\"" + mEmitterName + "\""; + } + + QString signalName; + if (mSignalName.isEmpty()) { + signalName = i18nc("@item", "(signal not set)"); + } else { + signalName = "\"" + mSignalName + "\""; + } + + return i18nc("@item", "When the signal %1 is emitted by object %2", + signalName, emitterName); +} + +//private: + +void WaitForSignalTreeItem::update(WaitFor* waitFor) { + WaitForSignal* waitForSignal = static_cast<WaitForSignal*>(waitFor); + mEmitterName = waitForSignal->emitterName(); + mSignalName = waitForSignal->signalName(); + + emit dataChanged(this); +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.h 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORSIGNALTREEITEM_H +#define WAITFORSIGNALTREEITEM_H + +#include "WaitForTreeItem.h" + +class WaitForSignal; + +/** + * A TreeItem that represents a WaitForSignal. + * The tree representation of a WaitForSignal is a plain text: + * When the signal "signal name" is emitted by the object "object name" + * + * If the signal or the emitter name aren't set yet, a placeholder is put + * instead. Signal placeholder is "(signal not set)", and the emitter name + * placeholder is "(object name not set)" (without quotes, but with + * parenthesis). + * + * Whenever the WaitForSignal data changes, the WaitForSignalTreeItem text is + * updated as needed. + */ +class WaitForSignalTreeItem: public WaitForTreeItem { +Q_OBJECT +public: + + /** + * Creates a new WaitForSignalTreeItem for the given WaitForSignal and with + * the given parent. + * + * @param waitForSignal The WaitForSignal to represent. + * @param parent The parent TreeItem. + */ + explicit WaitForSignalTreeItem(WaitForSignal* waitForSignal, + TreeItem* parent = 0); + + /** + * Returns the description of the WaitForSignal. + * + * @return The text for this TreeItem. + */ + virtual QString text() const; + +private: + + /** + * The emitter name of the WaitForSignal. + */ + QString mEmitterName; + + /** + * The signal name of the WaitForSignal. + */ + QString mSignalName; + +private Q_SLOTS: + + /** + * Updates this WaitForSignalTreeItem when the data of its WaitForSignal + * changed. + * + * @param waitFor The WaitForSignal. + */ + void update(WaitFor* waitFor); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForTreeItem.h" +#include "WaitForComposedTreeItem.h" +#include "WaitForNotTreeItem.h" +#include "WaitForSignalTreeItem.h" +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +//public: + +WaitForTreeItem* WaitForTreeItem::treeItemForWaitFor(WaitFor* waitFor, + TreeItem* parent) { + if (qobject_cast<WaitForComposed*>(waitFor)) { + return new WaitForComposedTreeItem( + static_cast<WaitForComposed*>(waitFor), parent); + } + + if (qobject_cast<WaitForNot*>(waitFor)) { + return new WaitForNotTreeItem(static_cast<WaitForNot*>(waitFor), + parent); + } + + if (qobject_cast<WaitForSignal*>(waitFor)) { + return new WaitForSignalTreeItem(static_cast<WaitForSignal*>(waitFor), + parent); + } + + Q_ASSERT(false); + return 0; +} + +WaitForTreeItem::WaitForTreeItem(WaitFor* waitFor, TreeItem* parent): + TreeItem(parent), + mWaitFor(waitFor) { +} + +WaitFor* WaitForTreeItem::waitFor() const { + return mWaitFor; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.h 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORTREEITEM_H +#define WAITFORTREEITEM_H + +#include "TreeItem.h" + +class WaitFor; + +/** + * Abstract base class for TreeItems that represent WaitFors. + * It provides a static method, treeItemForWaitFor(WaitFor*), to create a new + * WaitForTreeItem subclass object suitable for the given WaitFor. + * + * Subclasses must provide the full representation of its WaitFor, implementing + * text() method and adding the necessary child tree items. + */ +class WaitForTreeItem: public TreeItem { +Q_OBJECT +public: + + /** + * Returns a new TreeItem that represents the given WaitFor. + * + * @param waitFor The WaitFor to create its representation. + * @param parent The parent TreeItem. + * @return The new WaitForTreeItem to represent the given WaitFor. + */ + static WaitForTreeItem* treeItemForWaitFor(WaitFor* waitFor, + TreeItem* parent); + + /** + * Creates a new WaitForTreeItem for the given WaitFor and with the given + * parent. + * + * @param waitFor The WaitFor to represent. + * @param parent The parent TreeItem. + */ + explicit WaitForTreeItem(WaitFor* waitFor, TreeItem* parent = 0); + + /** + * Returns the WaitFor. + * + * @return The WaitFor. + */ + WaitFor* waitFor() const; + +private: + + /** + * The WaitFor. + */ + WaitFor* mWaitFor; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForTreeItem.h ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-12 17:05:56 UTC (rev 148) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/CMakeLists.txt 2010-03-12 17:10:49 UTC (rev 149) @@ -31,6 +31,10 @@ TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager + WaitForComposedTreeItem + WaitForNotTreeItem + WaitForSignalTreeItem + WaitForTreeItem ) MACRO(MEM_TESTS) @@ -54,4 +58,8 @@ TutorialInformationWidget TutorialTreeItem TutorialTreeSelectionManager + WaitForComposedTreeItem + WaitForNotTreeItem + WaitForSignalTreeItem + WaitForTreeItem ) Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForComposedTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForComposedTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForComposedTreeItemTest.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,212 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForComposedTreeItem.h" + +#include <KLocalizedString> + +#include "WaitForSignalTreeItem.h" +#include "../WaitForComposed.h" +#include "../WaitForSignal.h" + +class WaitForComposedTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + void testConstructorFull(); + + void testWaitForComposedSetAndType(); + void testWaitForComposedSetOrType(); + void testWaitForComposedSetTypeChange(); + + void testWaitForAddWaitFor(); + + void testWaitForRemoveWaitFor(); + +private: + + int mTreeItemStarType; + + void assertSignalItem(TreeItem* item, WaitForSignal* waitForSignal) const; + + void assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const; + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void WaitForComposedTreeItemTest::initTestCase() { + //TreeItem* must be registered in order to be used with QSignalSpy + mTreeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); +} + +void WaitForComposedTreeItemTest::testConstructor() { + WaitForComposed waitForComposed; + + StubTreeItem parent; + WaitForComposedTreeItem item(&waitForComposed, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForComposed); + QCOMPARE(item.childCount(), 0); +} + +void WaitForComposedTreeItemTest::testConstructorFull() { + WaitForComposed waitForComposed; + + WaitForSignal* waitFor1 = new WaitForSignal(); + waitForComposed.addWaitFor(waitFor1); + + WaitForSignal* waitFor2 = new WaitForSignal(); + waitForComposed.addWaitFor(waitFor2); + + WaitForSignal* waitFor3 = new WaitForSignal(); + waitForComposed.addWaitFor(waitFor3); + + StubTreeItem parent; + WaitForComposedTreeItem item(&waitForComposed, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForComposed); + QCOMPARE(item.childCount(), 3); + assertSignalItem(item.child(0), waitFor1); + assertSignalItem(item.child(1), waitFor2); + assertSignalItem(item.child(2), waitFor3); +} + +void WaitForComposedTreeItemTest::testWaitForComposedSetAndType() { + WaitForComposed waitForComposed; + waitForComposed.setCompositionType(WaitForComposed::And); + + WaitForComposedTreeItem item(&waitForComposed); + + QCOMPARE(item.text(), i18nc("@item", + "When all the contained conditions match")); + QCOMPARE(item.childCount(), 0); +} + +void WaitForComposedTreeItemTest::testWaitForComposedSetOrType() { + WaitForComposed waitForComposed; + waitForComposed.setCompositionType(WaitForComposed::Or); + + WaitForComposedTreeItem item(&waitForComposed); + + QCOMPARE(item.text(), i18nc("@item", + "When any of the contained conditions match")); + QCOMPARE(item.childCount(), 0); +} + +void WaitForComposedTreeItemTest::testWaitForComposedSetTypeChange() { + WaitForComposed waitForComposed; + waitForComposed.setCompositionType(WaitForComposed::And); + + WaitForComposedTreeItem item(&waitForComposed); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + waitForComposed.setCompositionType(WaitForComposed::Or); + + QCOMPARE(item.text(), i18nc("@item", + "When any of the contained conditions match")); + QCOMPARE(item.childCount(), 0); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void WaitForComposedTreeItemTest::testWaitForAddWaitFor() { + WaitForComposed waitForComposed; + WaitForSignal* waitFor1 = new WaitForSignal(); + WaitForSignal* waitFor2 = new WaitForSignal(); + WaitForSignal* waitFor3 = new WaitForSignal(); + + WaitForComposedTreeItem item(&waitForComposed); + + waitForComposed.addWaitFor(waitFor1); + waitForComposed.addWaitFor(waitFor2); + waitForComposed.addWaitFor(waitFor3); + + QCOMPARE(item.childCount(), 3); + assertSignalItem(item.child(0), waitFor1); + assertSignalItem(item.child(1), waitFor2); + assertSignalItem(item.child(2), waitFor3); +} + +void WaitForComposedTreeItemTest::testWaitForRemoveWaitFor() { + WaitForComposed waitForComposed; + + //They will be removed and not deleted by the WaitForComposed, so they are + //created in stack + WaitForSignal waitFor1; + WaitForSignal waitFor2; + WaitForSignal waitFor3; + + WaitForComposedTreeItem item(&waitForComposed); + + waitForComposed.addWaitFor(&waitFor1); + waitForComposed.addWaitFor(&waitFor2); + waitForComposed.addWaitFor(&waitFor3); + + waitForComposed.removeWaitFor(&waitFor2); + + QCOMPARE(item.childCount(), 2); + assertSignalItem(item.child(0), &waitFor1); + assertSignalItem(item.child(1), &waitFor3); + + waitForComposed.removeWaitFor(&waitFor1); + waitForComposed.removeWaitFor(&waitFor3); + + QCOMPARE(item.childCount(), 0); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void WaitForComposedTreeItemTest::assertSignalItem(TreeItem* item, + WaitForSignal* waitForSignal) const { + QVERIFY(qobject_cast<WaitForSignalTreeItem*>(item)); + QCOMPARE(static_cast<WaitForSignalTreeItem*>(item)->waitFor(), + waitForSignal); +} + +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + +void WaitForComposedTreeItemTest::assertDataChanged(const QSignalSpy& spy, + int index, + TreeItem* item) const { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); +} + +QTEST_MAIN(WaitForComposedTreeItemTest) + +#include "WaitForComposedTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForComposedTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForNotTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForNotTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForNotTreeItemTest.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForNotTreeItem.h" + +#include <KLocalizedString> + +#include "WaitForSignalTreeItem.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +class WaitForNotTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + void testConstructorFull(); + + void testWaitForNotSetNegatedWaitFor(); + void testWaitForNotSetNegatedWaitForChange(); + void testWaitForNotSetNegatedWaitForEmpty(); + +private: + + void assertSignalItem(TreeItem* item, WaitForSignal* waitForSignal) const; + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void WaitForNotTreeItemTest::testConstructor() { + WaitForNot waitForNot; + + StubTreeItem parent; + WaitForNotTreeItem item(&waitForNot, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForNot); + QCOMPARE(item.text(), + i18nc("@item", "The contained condition can't have been met")); + QCOMPARE(item.childCount(), 0); +} + +void WaitForNotTreeItemTest::testConstructorFull() { + WaitForNot waitForNot; + WaitForSignal* waitForSignal = new WaitForSignal(); + waitForNot.setNegatedWaitFor(waitForSignal); + + StubTreeItem parent; + WaitForNotTreeItem item(&waitForNot, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForNot); + QCOMPARE(item.text(), + i18nc("@item", "The contained condition can't have been met")); + QCOMPARE(item.childCount(), 1); + assertSignalItem(item.child(0), waitForSignal); +} + +void WaitForNotTreeItemTest::testWaitForNotSetNegatedWaitFor() { + WaitForNot waitForNot; + WaitForSignal* waitForSignal = new WaitForSignal(); + WaitForNotTreeItem item(&waitForNot); + + waitForNot.setNegatedWaitFor(waitForSignal); + + QCOMPARE(item.childCount(), 1); + assertSignalItem(item.child(0), waitForSignal); +} + +void WaitForNotTreeItemTest::testWaitForNotSetNegatedWaitForChange() { + WaitForNot waitForNot; + //It will be removed and not deleted by the WaitForNot, so it is created in + //stack + WaitForSignal waitForSignal1; + WaitForNotTreeItem item(&waitForNot); + + waitForNot.setNegatedWaitFor(&waitForSignal1); + + WaitForSignal* waitForSignal2 = new WaitForSignal(); + waitForNot.setNegatedWaitFor(waitForSignal2); + + QCOMPARE(item.childCount(), 1); + assertSignalItem(item.child(0), waitForSignal2); +} + +void WaitForNotTreeItemTest::testWaitForNotSetNegatedWaitForEmpty() { + WaitForNot waitForNot; + //It will be removed and not deleted by the WaitForNot, so it is created in + //stack + WaitForSignal waitForSignal; + WaitForNotTreeItem item(&waitForNot); + + waitForNot.setNegatedWaitFor(&waitForSignal); + waitForNot.setNegatedWaitFor(0); + + QCOMPARE(item.childCount(), 0); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void WaitForNotTreeItemTest::assertSignalItem(TreeItem* item, + WaitForSignal* waitForSignal) const { + QVERIFY(qobject_cast<WaitForSignalTreeItem*>(item)); + QCOMPARE(static_cast<WaitForSignalTreeItem*>(item)->waitFor(), + waitForSignal); +} + +QTEST_MAIN(WaitForNotTreeItemTest) + +#include "WaitForNotTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForNotTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalTreeItemTest.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,161 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignalTreeItem.h" + +#include <KLocalizedString> + +#include "../WaitForSignal.h" + +class WaitForSignalTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void initTestCase(); + + void testConstructor(); + void testConstructorFull(); + + void testWaitForSignalSetEmitterName(); + void testWaitForSignalSetEmitterNameChange(); + + void testWaitForSignalSetSignalName(); + void testWaitForSignalSetSignalNameChange(); + +private: + + int mTreeItemStarType; + + void assertDataChanged(const QSignalSpy& spy, int index, + TreeItem* item) const; + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +void WaitForSignalTreeItemTest::initTestCase() { + //TreeItem* must be registered in order to be used with QSignalSpy + mTreeItemStarType = qRegisterMetaType<TreeItem*>("TreeItem*"); +} + +void WaitForSignalTreeItemTest::testConstructor() { + WaitForSignal waitForSignal; + + StubTreeItem parent; + WaitForSignalTreeItem item(&waitForSignal, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForSignal); + QCOMPARE(item.text(), i18nc("@item", "When the signal (signal not set) is " + "emitted by object (object not set)")); +} + +void WaitForSignalTreeItemTest::testConstructorFull() { + WaitForSignal waitForSignal; + waitForSignal.setEmitterName("emitterName"); + waitForSignal.setSignalName("signalName"); + + StubTreeItem parent; + WaitForSignalTreeItem item(&waitForSignal, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitForSignal); + QCOMPARE(item.text(), i18nc("@item", "When the signal \"signalName\" is " + "emitted by object \"emitterName\"")); +} + +void WaitForSignalTreeItemTest::testWaitForSignalSetEmitterName() { + WaitForSignal waitForSignal; + waitForSignal.setEmitterName("emitterName"); + + WaitForSignalTreeItem item(&waitForSignal); + + QCOMPARE(item.text(), i18nc("@item", "When the signal (signal not set) is " + "emitted by object \"emitterName\"")); +} + +void WaitForSignalTreeItemTest::testWaitForSignalSetEmitterNameChange() { + WaitForSignal waitForSignal; + WaitForSignalTreeItem item(&waitForSignal); + + waitForSignal.setEmitterName("emitterName"); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + waitForSignal.setEmitterName("emitterNameChanged"); + + QCOMPARE(item.text(), i18nc("@item", "When the signal (signal not set) is " + "emitted by object " + "\"emitterNameChanged\"")); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +void WaitForSignalTreeItemTest::testWaitForSignalSetSignalName() { + WaitForSignal waitForSignal; + waitForSignal.setSignalName("signalName"); + + WaitForSignalTreeItem item(&waitForSignal); + + QCOMPARE(item.text(), i18nc("@item", "When the signal \"signalName\" is " + "emitted by object (object not set)")); +} + +void WaitForSignalTreeItemTest::testWaitForSignalSetSignalNameChange() { + WaitForSignal waitForSignal; + WaitForSignalTreeItem item(&waitForSignal); + + waitForSignal.setSignalName("signalName"); + + QSignalSpy dataChangedSpy(&item, SIGNAL(dataChanged(TreeItem*))); + + waitForSignal.setSignalName("signalNameChanged"); + + QCOMPARE(item.text(), i18nc("@item", "When the signal " + "\"signalNameChanged\" is emitted by " + "object (object not set)")); + QCOMPARE(dataChangedSpy.count(), 1); + assertDataChanged(dataChangedSpy, 0, &item); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +//TreeItem* must be declared as a metatype to be used in qvariant_cast +Q_DECLARE_METATYPE(TreeItem*); + +void WaitForSignalTreeItemTest::assertDataChanged(const QSignalSpy& spy, + int index, + TreeItem* item) const { + QCOMPARE(spy.at(index).count(), 1); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mTreeItemStarType); + QCOMPARE(qvariant_cast<TreeItem*>(argument), item); +} + +QTEST_MAIN(WaitForSignalTreeItemTest) + +#include "WaitForSignalTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForTreeItemTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForTreeItemTest.cpp 2010-03-12 17:10:49 UTC (rev 149) @@ -0,0 +1,123 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForTreeItem.h" + +#include "WaitForComposedTreeItem.h" +#include "WaitForNotTreeItem.h" +#include "WaitForSignalTreeItem.h" +#include "../WaitFor.h" +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +class WaitForTreeItemTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testTreeItemForWaitForComposed(); + void testTreeItemForWaitForNot(); + void testTreeItemForWaitForSignal(); + +}; + +class StubTreeItem: public TreeItem { +public: + virtual QString text() const { + return ""; + } +}; + +class StubWaitForTreeItem: public WaitForTreeItem { +public: + StubWaitForTreeItem(WaitFor* waitFor, TreeItem* parent = 0): + WaitForTreeItem(waitFor, parent) { + } + + virtual QString text() const { + return ""; + } +}; + +class StubWaitFor: public WaitFor { +public: + StubWaitFor(QObject* parent = 0): WaitFor(parent) { + } +}; + +void WaitForTreeItemTest::testConstructor() { + StubWaitFor waitFor; + + StubTreeItem parent; + StubWaitForTreeItem item(&waitFor, &parent); + + QCOMPARE(item.parent(), &parent); + QCOMPARE(item.waitFor(), &waitFor); + QCOMPARE(item.childCount(), 0); +} + +void WaitForTreeItemTest::testTreeItemForWaitForComposed() { + WaitForComposed waitFor; + StubTreeItem parent; + + WaitForTreeItem* item = WaitForTreeItem::treeItemForWaitFor(&waitFor, + &parent); + + QVERIFY(qobject_cast<WaitForComposedTreeItem*>(item)); + QCOMPARE(item->parent(), &parent); + QCOMPARE(item->waitFor(), &waitFor); + + delete item; +} + +void WaitForTreeItemTest::testTreeItemForWaitForNot() { + WaitForNot waitFor; + StubTreeItem parent; + + WaitForTreeItem* item = WaitForTreeItem::treeItemForWaitFor(&waitFor, + &parent); + + QVERIFY(qobject_cast<WaitForNotTreeItem*>(item)); + QCOMPARE(item->parent(), &parent); + QCOMPARE(item->waitFor(), &waitFor); + + delete item; +} + +void WaitForTreeItemTest::testTreeItemForWaitForSignal() { + WaitForSignal waitFor; + StubTreeItem parent; + + WaitForTreeItem* item = WaitForTreeItem::treeItemForWaitFor(&waitFor, + &parent); + + QVERIFY(qobject_cast<WaitForSignalTreeItem*>(item)); + QCOMPARE(item->parent(), &parent); + QCOMPARE(item->waitFor(), &waitFor); + + delete item; +} + +QTEST_MAIN(WaitForTreeItemTest) + +#include "WaitForTreeItemTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForTreeItemTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dan...@us...> - 2010-03-13 18:38:56
|
Revision: 150 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=150&view=rev Author: danxuliu Date: 2010-03-13 18:38:49 +0000 (Sat, 13 Mar 2010) Log Message: ----------- Add widgets to edit WaitFors. Added Paths: ----------- trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.h trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.ui trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.h trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.ui trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.h trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.ui trunk/ktutorial/ktutorial-editor/tests/unit/view/NewWaitForWidgetTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalWidgetTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForWidgetTest.cpp Added: trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "NewWaitForWidget.h" + +#include "ui_NewWaitForWidget.h" +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +//public: + +NewWaitForWidget::NewWaitForWidget(QWidget* parent): QWidget(parent) { + ui = new Ui::NewWaitForWidget(); + ui->setupUi(this); +} + +NewWaitForWidget::~NewWaitForWidget() { + delete ui; +} + +WaitFor* NewWaitForWidget::waitFor() const { + int index = ui->waitForTypeComboBox->currentIndex(); + + if (index == 0) { + WaitForComposed* waitFor = new WaitForComposed(); + waitFor->setCompositionType(WaitForComposed::And); + return waitFor; + } else if (index == 1) { + WaitForComposed* waitFor = new WaitForComposed(); + waitFor->setCompositionType(WaitForComposed::Or); + return waitFor; + } else if (index == 2) { + return new WaitForNot(); + } else if (index == 3) { + return new WaitForSignal(); + } + + return 0; +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.h 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2010 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 NEWWAITFORWIDGET_H +#define NEWWAITFORWIDGET_H + +#include <QWidget> + +class WaitFor; + +namespace Ui { +class NewWaitForWidget; +} + +/** + * Widget to create a new condition. + * Note that this is not an edition widget, as it has no data to edit. It + * creates a new object, which can be got using waitFor() method. + */ +class NewWaitForWidget: public QWidget { +Q_OBJECT +public: + + /** + * Creates a new NewWaitForWidget. + * + * @param parent The parent QWidget. + */ + explicit NewWaitForWidget(QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~NewWaitForWidget(); + + /** + * Return the new WaitFor. + * + * @return The new WaitFor. + */ + WaitFor* waitFor() const; + +private: + + /** + * The Ui Designer generated class. + */ + Ui::NewWaitForWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/NewWaitForWidget.ui 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>NewWaitForWidget</class> + <widget class="QWidget" name="NewWaitForWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">New condition to wait for</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Selects the type of the new condition.</para></string> + </property> + <layout class="QVBoxLayout" name="NewWaitForWidgetVerticalLayout"> + <item> + <widget class="QGroupBox" name="waitForTypeGroupBox"> + <property name="title"> + <string comment="@title">Condition to wait for type</string> + </property> + <layout class="QHBoxLayout" name="waitForTypeGroupBoxHorizontalLayout"> + <item> + <widget class="QLabel" name="waitForTypeLabel"> + <property name="text"> + <string>Type:</string> + </property> + <property name="buddy"> + <cstring>waitForTypeComboBox</cstring> + </property> + </widget> + </item> + <item> + <widget class="KComboBox" name="waitForTypeComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <item> + <property name="text"> + <string comment="@item:inlistbox">All the contained conditions must match</string> + </property> + </item> + <item> + <property name="text"> + <string comment="@item:inlistbox">Any of the contained conditions must match</string> + </property> + </item> + <item> + <property name="text"> + <string comment="@item:inlistbox">The contained condition can't match</string> + </property> + </item> + <item> + <property name="text"> + <string comment="@item:inlistbox">The specified signal is emitted</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="newWaitForWidgetSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>215</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KComboBox</class> + <extends>QComboBox</extends> + <header>kcombobox.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignalWidget.h" + +#include "ui_WaitForSignalWidget.h" +#include "../WaitForSignal.h" + +//public: + +WaitForSignalWidget::WaitForSignalWidget(WaitForSignal* waitForSignal, + QWidget* parent): + EditionWidget(parent), + mWaitForSignal(waitForSignal) { + + ui = new Ui::WaitForSignalWidget(); + ui->setupUi(this); + + ui->emitterNameLineEdit->setText(waitForSignal->emitterName()); + ui->signalNameLineEdit->setText(waitForSignal->signalName()); +} + +WaitForSignalWidget::~WaitForSignalWidget() { + delete ui; +} + +void WaitForSignalWidget::saveChanges() { + QString emitterName = ui->emitterNameLineEdit->text(); + if (mWaitForSignal->emitterName() != emitterName) { + mWaitForSignal->setEmitterName(emitterName); + } + + QString signalName = ui->signalNameLineEdit->text(); + if (mWaitForSignal->signalName() != signalName) { + mWaitForSignal->setSignalName(signalName); + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.h 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORSIGNALWIDGET_H +#define WAITFORSIGNALWIDGET_H + +#include "EditionWidget.h" + +class WaitForSignal; + +namespace Ui { +class WaitForSignalWidget; +} + +/** + * Edition widget for the condition to wait for a signal. + */ +class WaitForSignalWidget: public EditionWidget { +Q_OBJECT +public: + + /** + * Creates a new WaitForSignalWidget for the given WaitForSignal. + * + * @param waitForSignal The WaitForSignal to set its data. + * @param parent The parent QWidget. + */ + explicit WaitForSignalWidget(WaitForSignal* waitForSignal, + QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~WaitForSignalWidget(); + + /** + * Saves the emitter name and the signal name in the WaitForSignal. + */ + virtual void saveChanges(); + +private: + + /** + * The WaitForSignal to edit. + */ + WaitForSignal* mWaitForSignal; + + /** + * The Ui Designer generated class. + */ + Ui::WaitForSignalWidget* ui; + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForSignalWidget.ui 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>WaitForSignalWidget</class> + <widget class="QWidget" name="WaitForSignalWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Edit signal to wait for</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Set the emitter name and the signal to wait for.</para></string> + </property> + <layout class="QVBoxLayout" name="WaitForSignalVerticalLayout"> + <item> + <widget class="QGroupBox" name="waitForSignalGroupBox"> + <property name="title"> + <string comment="@title:group">Wait for signal</string> + </property> + <layout class="QHBoxLayout" name="waitForSignalGroupBoxHorizontalLayout"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="emitterNameLabel"> + <property name="text"> + <string>Emitter name:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>emitterNameLineEdit</cstring> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="signalNameLabel"> + <property name="text"> + <string>Signal name:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>signalNameLineEdit</cstring> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="KLineEdit" name="emitterNameLineEdit"> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>The name of the QObject that emits the signal.</para> +<para>Note that the name is not the class of the object, but the string returned by its objectName() method.</para></string> + </property> + </widget> + </item> + <item> + <widget class="KLineEdit" name="signalNameLineEdit"> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>The name of the signal.</para> +<para>The name must be written as <em>signalName(TypeOfFirstArgument, TypeOfSecondArgument, TypeOfThirdArgument...)</em>, without including <em>SIGNAL()</em> wrapping text.</para></string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="waitForSignalWidgetSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>182</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KLineEdit</class> + <extends>QLineEdit</extends> + <header>klineedit.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,243 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForWidget.h" + +#include "ui_WaitForWidget.h" +#include "EditionDialog.h" +#include "NewWaitForWidget.h" +#include "TextTreeItem.h" +#include "TreeModel.h" +#include "WaitForSignalWidget.h" +#include "WaitForTreeItem.h" +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +//public: + +WaitForWidget::WaitForWidget(WaitFor* waitFor, QWidget* parent): + QWidget(parent), + mWaitFor(waitFor), + mCurrentWaitFor(0) { + + ui = new Ui::WaitForWidget(); + ui->setupUi(this); + + ui->addButton->setIcon(KIcon("list-add")); + ui->editButton->setIcon(KIcon("document-edit")); + ui->removeButton->setIcon(KIcon("list-remove")); + + setupTreeView(waitFor); + + updateWaitForSelection(0); + + connect(ui->addButton, SIGNAL(clicked(bool)), this, SLOT(addWaitFor())); + connect(ui->editButton, SIGNAL(clicked(bool)), this, SLOT(editWaitFor())); + connect(ui->removeButton, SIGNAL(clicked(bool)), + this, SLOT(removeWaitFor())); +} + +WaitForWidget::~WaitForWidget() { + delete ui; +} + +WaitFor* WaitForWidget::waitFor() const { + return mWaitFor; +} + +//private: + +void WaitForWidget::setupTreeView(WaitFor* waitFor) { + TextTreeItem* rootItem = new TextTreeItem(); + if (waitFor) { + TreeItem* item = WaitForTreeItem::treeItemForWaitFor(waitFor, rootItem); + rootItem->appendChild(item); + } + + QTreeView* treeView = ui->waitForTreeView; + TreeModel* model = new TreeModel(rootItem, treeView); + + QAbstractItemModel* oldModel = treeView->model(); + treeView->setModel(model); + delete oldModel; + + connect(treeView->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, + SLOT(handleSelectionChanged(QItemSelection, QItemSelection))); +} + +void WaitForWidget::updateWaitForSelection(WaitFor* selectedWaitFor) { + mCurrentWaitFor = selectedWaitFor; + + if (!selectedWaitFor) { + if (mWaitFor) { + ui->addButton->setEnabled(false); + } else { + ui->addButton->setEnabled(true); + } + ui->editButton->setEnabled(false); + ui->removeButton->setEnabled(false); + + return; + } + + if (qobject_cast<WaitForComposed*>(selectedWaitFor)) { + ui->addButton->setEnabled(true); + ui->editButton->setEnabled(false); + ui->removeButton->setEnabled(true); + + return; + } + + if (qobject_cast<WaitForNot*>(selectedWaitFor)) { + if (static_cast<WaitForNot*>(selectedWaitFor)->negatedWaitFor()) { + ui->addButton->setEnabled(false); + } else { + ui->addButton->setEnabled(true); + } + ui->editButton->setEnabled(false); + ui->removeButton->setEnabled(true); + + return; + } + + if (qobject_cast<WaitForSignal*>(selectedWaitFor)) { + ui->addButton->setEnabled(false); + ui->editButton->setEnabled(true); + ui->removeButton->setEnabled(true); + + return; + } +} + +//private slots: + +void WaitForWidget::handleSelectionChanged(const QItemSelection& selected, + const QItemSelection& deselected) { + //Only single selections are supported + Q_ASSERT(selected.count() <= 1); + Q_ASSERT(deselected.count() <= 1); + + WaitFor* selectedWaitFor = 0; + + if (selected.count() == 1) { + Q_ASSERT(selected.at(0).indexes().count() == 1); + + QModelIndex index = selected.at(0).indexes().at(0); + WaitForTreeItem* item = + static_cast<WaitForTreeItem*>(index.internalPointer()); + + selectedWaitFor = item->waitFor(); + } + + updateWaitForSelection(selectedWaitFor); +} + +void WaitForWidget::addWaitFor() { + WaitFor* newWaitFor = 0; + + KDialog* dialog = new KDialog(this); + NewWaitForWidget* widget = new NewWaitForWidget(dialog); + dialog->setMainWidget(widget); + dialog->setObjectName("addWaitForDialog"); + if (dialog->exec() == QDialog::Accepted) { + newWaitFor = widget->waitFor(); + } + dialog->deleteLater(); + + if (!mWaitFor) { + mWaitFor = newWaitFor; + return; + } + + if (qobject_cast<WaitForComposed*>(mCurrentWaitFor)) { + WaitForComposed* waitForComposed = + static_cast<WaitForComposed*>(mCurrentWaitFor); + + waitForComposed->addWaitFor(newWaitFor); + return; + } + + if (qobject_cast<WaitForNot*>(mCurrentWaitFor)) { + WaitForNot* waitForNot = static_cast<WaitForNot*>(mCurrentWaitFor); + + waitForNot->setNegatedWaitFor(newWaitFor); + return; + } +} + +void WaitForWidget::editWaitFor() { + EditionWidget* editionWidget = 0; + if (qobject_cast<WaitForSignal*>(mCurrentWaitFor)) { + WaitForSignal* waitForSignal = + static_cast<WaitForSignal*>(mCurrentWaitFor); + editionWidget = new WaitForSignalWidget(waitForSignal, this); + } + + Q_ASSERT(editionWidget); + + EditionDialog* dialog = new EditionDialog(editionWidget, this); + dialog->setObjectName("editionDialog"); + dialog->exec(); + dialog->deleteLater(); +} + +void WaitForWidget::removeWaitFor() { + QModelIndex index = + ui->waitForTreeView->selectionModel()->selectedIndexes()[0]; + QModelIndex parent = index.parent(); + + if (!parent.isValid()) { + delete mWaitFor; + mWaitFor = 0; + + return; + } + + WaitFor* parentWaitFor = + static_cast<WaitForTreeItem*>(parent.internalPointer())->waitFor(); + + if (qobject_cast<WaitForComposed*>(parentWaitFor)) { + WaitForComposed* waitForComposed = + static_cast<WaitForComposed*>(parentWaitFor); + + //When the WaitFor is removed, mCurrentWaitFor changes because the + //selected item in the tree view changes. The WaitFor to be removed must + //be stord to properly delete it. + WaitFor* waitForToRemove = mCurrentWaitFor; + waitForComposed->removeWaitFor(waitForToRemove); + delete waitForToRemove; + + return; + } + + if (qobject_cast<WaitForNot*>(parentWaitFor)) { + WaitForNot* waitForNot = static_cast<WaitForNot*>(parentWaitFor); + + //When the WaitFor is removed, mCurrentWaitFor changes because the + //selected item in the tree view changes. The WaitFor to be removed must + //be stord to properly delete it. + WaitFor* waitForToRemove = mCurrentWaitFor; + waitForNot->setNegatedWaitFor(0); + delete waitForToRemove; + + return; + } +} Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.h (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.h 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2010 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 WAITFORWIDGET_H +#define WAITFORWIDGET_H + +#include <QWidget> + +class QItemSelection; +class WaitFor; + +namespace Ui { +class WaitForWidget; +} + +/** + * Widget to create or edit a WaitFor. + * The following operations can be done: add a WaitFor, edit a WaitFor or remove + * a WaitFor. + * + * A WaitFor can be added only as the first WaitFor (when the list is empty), or + * as a child of a composed WaitFor (selecting the one that will be its parent). + * + * A WaitFor can be edited if it is a plain condition, that is, it is not + * composed from other WaitFors. + * + * Finally, any WaitFor can be removed. + * + * The WaitFor, returned by waitFor() method, must be explicitly deleted. + * However, the WaitFor set in the constructor may have been deleted by the + * widget if the user removed the root WaitFor. + */ +class WaitForWidget: public QWidget { +Q_OBJECT +public: + + /** + * Creates a new WaitForWidget. + * + * @param parent The parent QWidget. + */ + explicit WaitForWidget(WaitFor* waitFor, QWidget* parent = 0); + + /** + * Destroys this widget. + */ + virtual ~WaitForWidget(); + + /** + * Returns the WaitFor. + * + * @return The WaitFor, if any. + */ + WaitFor* waitFor() const; + +private: + + /** + * The WaitFor to edit. + */ + WaitFor* mWaitFor; + + /** + * The WaitFor currently selected. + */ + WaitFor* mCurrentWaitFor; + + /** + * The Ui Designer generated class. + */ + Ui::WaitForWidget* ui; + + /** + * Sets up the tree view for the WaitFor to be edited. + * + * @param waitFor The WaitFor to be edited. + */ + void setupTreeView(WaitFor* waitFor); + + /** + * Sets the current WaitFor and enables or disables the buttons as needed. + * + * @param selectedWaitFor The selected WaitFor. + */ + void updateWaitForSelection(WaitFor* selectedWaitFor); + +private Q_SLOTS: + + /** + * Handles a change in the selection in the tree view. + * + * @param selected The item selection of selected items. + * @param selected The item selection of deselected items. + */ + void handleSelectionChanged(const QItemSelection& selected, + const QItemSelection& deselected); + + /** + * Shows a dialog with a NewWaitForWidget and adds the new WaitFor. + * The WaitFor is added to the selected WaitFor, or as the root WaitFor if + * there is none. + */ + void addWaitFor(); + + /** + * Shows an EditionDialog for the selected WaitFor. + */ + void editWaitFor(); + + /** + * Removes the selected WaitFor. + */ + void removeWaitFor(); + +}; + +#endif Property changes on: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.h ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.ui =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.ui (rev 0) +++ trunk/ktutorial/ktutorial-editor/src/view/WaitForWidget.ui 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>WaitForWidget</class> + <widget class="QWidget" name="WaitForWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string comment="@title">Edit condition to wait for</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Edit a condition to wait for until it is met.</para> +<para>A condition can be a plain condition or a composed condition. Plain conditions wait for some specific thing to happen, for example, they wait until a signal is emitted. Composed conditions contain other conditions (plain or also composed) and wait until something happens in its contained conditions, for example, wait until all the contained conditions were met.</para></string> + </property> + <layout class="QVBoxLayout" name="waitForWidgetVerticalLayout"> + <item> + <widget class="QTreeView" name="waitForTreeView"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="KPushButton" name="addButton"> + <property name="toolTip"> + <string comment="@info:tooltip">Add a new condition</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Adds a new condition.</para> +<para>A condition has to be added to composed conditions, that is, conditions that contain other conditions, or as the root condition when there is no other condition.</para></string> + </property> + <property name="text"> + <string comment="@action:button">Add...</string> + </property> + </widget> + </item> + <item> + <widget class="KPushButton" name="editButton"> + <property name="toolTip"> + <string comment="@info:tooltip">Edit the selected condition</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis"><para>Edits the selected condition.</para> +<para>Only plain conditions, that is, conditions that aren't composed by other conditions, can be edited.</para></string> + </property> + <property name="text"> + <string comment="@action:button">Edit...</string> + </property> + </widget> + </item> + <item> + <widget class="KPushButton" name="removeButton"> + <property name="toolTip"> + <string comment="@info:tooltip">Remove the selected condition</string> + </property> + <property name="whatsThis"> + <string comment="@info:whatsthis">Removes the selected condition.</string> + </property> + <property name="text"> + <string comment="@action:button">Remove</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>KPushButton</class> + <extends>QPushButton</extends> + <header>kpushbutton.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/NewWaitForWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/NewWaitForWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/NewWaitForWidgetTest.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "NewWaitForWidget.h" + +#include <KComboBox> + +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +class NewWaitForWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testWaitForWhenAndConditionIsSelected(); + void testWaitForWhenOrConditionIsSelected(); + void testWaitForWhenNotConditionIsSelected(); + void testWaitForWhenSignalConditionIsSelected(); + +private: + + void selectOption(NewWaitForWidget* widget, int index) const; + +}; + +void NewWaitForWidgetTest::testConstructor() { + QWidget parent; + NewWaitForWidget* widget = new NewWaitForWidget(&parent); + + QCOMPARE(widget->parentWidget(), &parent); +} + +void NewWaitForWidgetTest::testWaitForWhenAndConditionIsSelected() { + NewWaitForWidget widget; + + selectOption(&widget, 0); + + WaitForComposed* waitFor = qobject_cast<WaitForComposed*>(widget.waitFor()); + QVERIFY(waitFor); + QCOMPARE(waitFor->compositionType(), WaitForComposed::And); + delete waitFor; +} + +void NewWaitForWidgetTest::testWaitForWhenOrConditionIsSelected() { + NewWaitForWidget widget; + + selectOption(&widget, 1); + + WaitForComposed* waitFor = qobject_cast<WaitForComposed*>(widget.waitFor()); + QVERIFY(waitFor); + QCOMPARE(waitFor->compositionType(), WaitForComposed::Or); + delete waitFor; +} + +void NewWaitForWidgetTest::testWaitForWhenNotConditionIsSelected() { + NewWaitForWidget widget; + + selectOption(&widget, 2); + + WaitForNot* waitFor = qobject_cast<WaitForNot*>(widget.waitFor()); + QVERIFY(waitFor); + delete waitFor; +} + +void NewWaitForWidgetTest::testWaitForWhenSignalConditionIsSelected() { + NewWaitForWidget widget; + + selectOption(&widget, 3); + + WaitForSignal* waitFor = qobject_cast<WaitForSignal*>(widget.waitFor()); + QVERIFY(waitFor); + delete waitFor; +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void NewWaitForWidgetTest::selectOption(NewWaitForWidget* widget, + int index) const { + KComboBox* comboBox = widget->findChild<KComboBox*>("waitForTypeComboBox"); + + QVERIFY(comboBox); + comboBox->setCurrentIndex(index); +} + +QTEST_MAIN(NewWaitForWidgetTest) + +#include "NewWaitForWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/NewWaitForWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalWidgetTest.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForSignalWidget.h" + +#include <KLineEdit> + +#include "../WaitForSignal.h" + +class WaitForSignalWidgetTest: public QObject { +Q_OBJECT + +private slots: + + void testConstructor(); + + void testSaveChanges(); + +private: + + KLineEdit* emitterNameLineEdit(WaitForSignalWidget* widget) const; + KLineEdit* signalNameLineEdit(WaitForSignalWidget* widget) const; + +}; + +void WaitForSignalWidgetTest::testConstructor() { + WaitForSignal waitFor; + waitFor.setEmitterName("The emitter name"); + waitFor.setSignalName("The signal name"); + + QWidget parent; + WaitForSignalWidget* widget = new WaitForSignalWidget(&waitFor, &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(emitterNameLineEdit(widget)->text(), QString("The emitter name")); + QCOMPARE(signalNameLineEdit(widget)->text(), QString("The signal name")); +} + +void WaitForSignalWidgetTest::testSaveChanges() { + WaitForSignal waitFor; + waitFor.setEmitterName("The emitter name"); + waitFor.setSignalName("The signal name"); + + WaitForSignalWidget widget(&waitFor); + emitterNameLineEdit(&widget)->setText("The new emitter name"); + signalNameLineEdit(&widget)->setText("The new signal name"); + + widget.saveChanges(); + + QCOMPARE(waitFor.emitterName(), QString("The new emitter name")); + QCOMPARE(waitFor.signalName(), QString("The new signal name")); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +KLineEdit* WaitForSignalWidgetTest::emitterNameLineEdit( + WaitForSignalWidget* widget) const { + return widget->findChild<KLineEdit*>("emitterNameLineEdit"); +} + +KLineEdit* WaitForSignalWidgetTest::signalNameLineEdit( + WaitForSignalWidget* widget) const { + return widget->findChild<KLineEdit*>("signalNameLineEdit"); +} + +QTEST_MAIN(WaitForSignalWidgetTest) + +#include "WaitForSignalWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForSignalWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForWidgetTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForWidgetTest.cpp (rev 0) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForWidgetTest.cpp 2010-03-13 18:38:49 UTC (rev 150) @@ -0,0 +1,359 @@ +/*************************************************************************** + * Copyright (C) 2010 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 "WaitForWidget.h" + +#include <QTreeView> + +#include <KComboBox> +#include <KLineEdit> +#include <KPushButton> + +#include "EditionDialog.h" +#include "../WaitForComposed.h" +#include "../WaitForNot.h" +#include "../WaitForSignal.h" + +class WaitForWidgetTest: public QObject { +Q_OBJECT +public slots: + + void addWaitForSignal() const; + + void setSignalData() const; + +private slots: + + void init(); + void cleanup(); + + void testConstructor(); + void testConstructorFull(); + + void testSelectWaitForAnd(); + void testSelectWaitForOr(); + void testSelectWaitForNot(); + void testSelectWaitForNotEmpty(); + void testSelectWaitForSignal(); + void testClearSelection(); + + void testAddWaitForWhenEmpty(); + void testAddWaitForToWaitForComposed(); + void testAddWaitForToWaitForNot(); + + void testEditWaitForSignal(); + + void testRemoveWaitForFromRoot(); + void testRemoveWaitForFromWaitForComposed(); + void testRemoveWaitForFromWaitForNot(); + +private: + + WaitForComposed* mWaitFor; + WaitForSignal* mWaitFor1; + WaitForComposed* mWaitFor2; + WaitForNot* mWaitFor3; + WaitForSignal* mWaitFor3_1; + WaitForNot* mWaitFor4; + + WaitForWidget* mWidget; + + QModelIndex getIndex(int row, + const QModelIndex& parent = QModelIndex()) const; + + void selectItem(const QModelIndex& index) const; + + KPushButton* button(const QString& name, WaitForWidget* widget = 0) const; + + void assertButtonEnabled(bool addButtonEnabled, + bool editButtonEnabled, + bool removeButtonEnabled, + WaitForWidget* widget = 0) const; + +}; + +void WaitForWidgetTest::init() { + mWaitFor = new WaitForComposed(); + mWaitFor->setCompositionType(WaitForComposed::And); + + mWaitFor1 = new WaitForSignal(); + mWaitFor1->setEmitterName("emitter1"); + mWaitFor1->setSignalName("signal1"); + mWaitFor->addWaitFor(mWaitFor1); + + mWaitFor2 = new WaitForComposed(); + mWaitFor2->setCompositionType(WaitForComposed::Or); + mWaitFor->addWaitFor(mWaitFor2); + + mWaitFor3 = new WaitForNot(); + mWaitFor->addWaitFor(mWaitFor3); + + mWaitFor3_1 = new WaitForSignal(); + mWaitFor3_1->setEmitterName("emitter2"); + mWaitFor3_1->setSignalName("signal2"); + mWaitFor3->setNegatedWaitFor(mWaitFor3_1); + + mWaitFor4 = new WaitForNot(); + mWaitFor->addWaitFor(mWaitFor4); + + mWidget = new WaitForWidget(mWaitFor); +} + +void WaitForWidgetTest::cleanup() { + delete mWidget; + delete mWaitFor; +} + +void WaitForWidgetTest::testConstructor() { + QWidget parent; + WaitForWidget* widget = new WaitForWidget(0, &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(widget->waitFor(), (WaitFor*)0); + assertButtonEnabled(true, false, false, widget); +} + +void WaitForWidgetTest::testConstructorFull() { + QWidget parent; + WaitForWidget* widget = new WaitForWidget(mWaitFor, &parent); + + QCOMPARE(widget->parentWidget(), &parent); + QCOMPARE(widget->waitFor(), (WaitFor*)mWaitFor); + assertButtonEnabled(false, false, false, widget); +} + +void WaitForWidgetTest::testSelectWaitForAnd() { + selectItem(getIndex(0)); + + assertButtonEnabled(true, false, true); +} + +void WaitForWidgetTest::testSelectWaitForOr() { + selectItem(getIndex(1, getIndex(0))); + + assertButtonEnabled(true, false, true); +} + +void WaitForWidgetTest::testSelectWaitForNot() { + selectItem(getIndex(2, getIndex(0))); + + assertButtonEnabled(false, false, true); +} + +void WaitForWidgetTest::testSelectWaitForNotEmpty() { + selectItem(getIndex(3, getIndex(0))); + + assertButtonEnabled(true, false, true); +} + +void WaitForWidgetTest::testSelectWaitForSignal() { + selectItem(getIndex(0, getIndex(0))); + + assertButtonEnabled(false, true, true); +} + +void WaitForWidgetTest::testClearSelection() { + selectItem(getIndex(0)); + selectItem(QModelIndex()); + + assertButtonEnabled(false, false, false); +} + +void WaitForWidgetTest::testAddWaitForWhenEmpty() { + delete mWidget; + mWidget = new WaitForWidget(0); + + //The dialog is modal, so it won't return to the test code until it is + //closed. Thus, the commands to execute on the dialog must be "queued", + //as calling addWaitForSignal after the button click won't work. + QTimer::singleShot(500, this, SLOT(addWaitForSignal())); + + button("addButton")->click(); + + QVERIFY(mWidget->waitFor()); + QVERIFY(qobject_cast<WaitForSignal*>(mWidget->waitFor())); + delete mWidget->waitFor(); +} + +void WaitForWidgetTest::testAddWaitForToWaitForComposed() { + selectItem(getIndex(1, getIndex(0))); + + //The dialog is modal, so it won't return to the test code until it is + //closed. Thus, the commands to execute on the dialog must be "queued", + //as calling addWaitForSignal after the button click won't work. + QTimer::singleShot(500, this, SLOT(addWaitForSignal())); + + button("addButton")->click(); + + selectItem(getIndex(0)); + + QTimer::singleShot(500, this, SLOT(addWaitForSignal())); + + button("addButton")->click(); + + QCOMPARE(mWaitFor->waitFors().count(), 5); + QCOMPARE(mWaitFor->waitFors()[0], mWaitFor1); + QCOMPARE(mWaitFor->waitFors()[1], mWaitFor2); + QCOMPARE(mWaitFor->waitFors()[2], mWaitFor3); + QCOMPARE(mWaitFor->waitFors()[3], mWaitFor4); + QVERIFY(qobject_cast<WaitForSignal*>(mWaitFor->waitFors()[4])); + QCOMPARE(mWaitFor2->waitFors().count(), 1); + QVERIFY(qobject_cast<WaitForSignal*>(mWaitFor2->waitFors()[0])); + QVERIFY(mWaitFor->waitFors()[4] != mWaitFor2->waitFors()[0]); +} + +void WaitForWidgetTest::testAddWaitForToWaitForNot() { + selectItem(getIndex(3, getIndex(0))); + + //The dialog is modal, so it won't return to the test code until it is + //closed. Thus, the commands to execute on the dialog must be "queued", + //as calling addWaitForSignal after the button click won't work. + QTimer::singleShot(500, this, SLOT(addWaitForSignal())); + + button("addButton")->click(); + + QCOMPARE(mWaitFor->waitFors().count(), 4); + QCOMPARE(mWaitFor->waitFors()[0], mWaitFor1); + QCOMPARE(mWaitFor->waitFors()[1], mWaitFor2); + QCOMPARE(mWaitFor->waitFors()[2], mWaitFor3); + QCOMPARE(mWaitFor->waitFors()[3], mWaitFor4); + QVERIFY(qobject_cast<WaitForSignal*>(mWaitFor4->negatedWaitFor())); +} + +void WaitForWidgetTest::testEditWaitForSignal() { + selectItem(getIndex(0, getIndex(0))); + + //The dialog is modal, so it won't return to the test code until it is + //closed. Thus, the commands to execute on the dialog must be "queued", + //as calling setSignalData after the button click won't work. + QTimer::singleShot(500, this, SLOT(setSignalData())); + + button("editButton")->click(); + + QCOMPARE(mWaitFor1->emitterName(), QString("The new emitter name")); + QCOMPARE(mWaitFor1->signalName(), QString("The new signal name")); +} + +void WaitForWidgetTest::testRemoveWaitForFromRoot() { + delete mWidget; + WaitForSignal* waitForSignal = new WaitForSignal(); + mWidget = new WaitForWidget(waitForSignal); + + selectItem(getIndex(0)); + button("removeButton")->click(); + + QVERIFY(!mWidget->waitFor()); +} + +void WaitForWidgetTest::testRemoveWaitForFromWaitForComposed() { + selectItem(getIndex(2, getIndex(0))); + button("removeButton")->click(); + + QCOMPARE(mWaitFor->waitFors().count(), 3); + QCOMPARE(mWaitFor->waitFors()[0], mWaitFor1); + QCOMPARE(mWaitFor->waitFors()[1], mWaitFor2); + QCOMPARE(mWaitFor->waitFors()[2], mWaitFor4); +} + +void WaitForWidgetTest::testRemoveWaitForFromWaitForNot() { + selectItem(getIndex(0, getIndex(2, getIndex(0)))); + button("removeButton")->click(); + + QCOMPARE(mWaitFor->waitFors().count(), 4); + QCOMPARE(mWaitFor->waitFors()[0], mWaitFor1); + QCOMPARE(mWaitFor->waitFors()[1], mWaitFor2); + QCOMPARE(mWaitFor->waitFors()[2], mWaitFor3); + QCOMPARE(mWaitFor->waitFors()[3], mWaitFor4); + QVERIFY(!mWaitFor3->negatedWaitFor()); +} + +/////////////////////////////////// Helpers //////////////////////////////////// + +void WaitForWidgetTest::addWaitForSignal() const { + KComboBox* comboBox = mWidget->findChild<KComboBox*>("waitForTypeComboBox"); + QVERIFY(comboBox); + comboBox->setCurrentIndex(3); + + KDialog* dialog = mWidget->findChild<KDialog*>("addWaitForDialog"); + QVERIFY(dialog); + dialog->button(KDialog::Ok)->click(); +} + +void WaitForWidgetTest::setSignalData() const { + KLineEdit* emitterNameLineEdit = + mWidget->findChild<KLineEdit*>("emitterNameLineEdit"); + QVERIFY(emitterNameLineEdit); + emitterNameLineEdit->setText("The new emitter name"); + + KLineEdit* signalNameLineEdit = + mWidget->findChild<KLineEdit*>("signalNameLineEdit"); + QVERIFY(signalNameLineEdit); + signalNameLineEdit->setText("The new signal name"); + + EditionDialog* dialog = mWidget->findChild<EditionDialog*>("editionDialog"); + QVERIFY(dialog); + dialog->button(KDialog::Ok)->click(); +} + +QModelIndex WaitForWidgetTest::getIndex(int row, + const QModelIndex& parent) const { + QTreeView* tree = mWidget->findChild<QTreeView*>("waitForTreeView"); + return tree->model()->index(row, 0, parent); +} + +void WaitForWidgetTest::selectItem(const QModelIndex& index) const { + QTreeView* tree = mWidget->findChild<QTreeView*>("waitForTreeView"); + QItemSelectionModel* model = tree->selectionModel(); + model->select(index, QItemSelectionModel::SelectCurrent); +} + +KPushButton* WaitForWidgetTest::button(const QString& name, + WaitForWidget* widget) const { + if (!widget) { + widget = mWidget; + } + + return widget->findChild<KPushButton*>(name); +} + +void WaitForWidgetTest::assertButtonEnabled(bool addButtonEnabled, + bool editButtonEnabled, + bool removeButtonEnabled, + WaitForWidget* widget) const { + if (!widget) { + widget = mWidget; + } + + KPushButton* addButton = button("addButton", widget); + QVERIFY(addButton); + QCOMPARE(addButton->isEnabled(), addButtonEnabled); + + KPushButton* editButton = button("editButton", widget); + QVERIFY(editButton); + QCOMPARE(editButton->isEnabled(), editButtonEnabled); + + KPushButton* removeButton = button("removeButton", widget); + QVERIFY(removeButton); + QCOMPARE(removeButton->isEnabled(), removeButtonEnabled); +} + +QTEST_MAIN(WaitForWidgetTest) + +#include "WaitForWidgetTest.moc" Property changes on: trunk/ktutorial/ktutorial-editor/tests/unit/view/WaitForWidgetTest.cpp ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |