[Ktutorial-commits] SF.net SVN: ktutorial:[123] trunk/ktutorial/ktutorial-editor
Status: Alpha
Brought to you by:
danxuliu
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. |