[Ktutorial-commits] SF.net SVN: ktutorial:[209] trunk/ktutorial/ktutorial-editor
Status: Alpha
Brought to you by:
danxuliu
From: <dan...@us...> - 2010-03-29 06:46:28
|
Revision: 209 http://ktutorial.svn.sourceforge.net/ktutorial/?rev=209&view=rev Author: danxuliu Date: 2010-03-29 06:46:22 +0000 (Mon, 29 Mar 2010) Log Message: ----------- Fix removing a reaction from the middle and undoing the operation (the reaction was readded at the end). It required being able to add reactions at any position in the step, and not only at the end. Modified Paths: -------------- trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.cpp trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.h trunk/ktutorial/ktutorial-editor/src/data/Step.cpp trunk/ktutorial/ktutorial-editor/src/data/Step.h trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h trunk/ktutorial/ktutorial-editor/tests/unit/commands/StepCommandsTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/data/StepTest.cpp trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp Modified: trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -142,21 +142,46 @@ mDeleteReactionInDestructor = true; } + virtual void undo() { + mDeleteReactionInDestructor = true; + mStep->removeReaction(mReaction); + } + +}; + +class AddReactionAtEnd: public AddReaction { +public: + + AddReactionAtEnd(QUndoCommand* parent = 0): AddReaction(parent) { + } + virtual void redo() { mDeleteReactionInDestructor = false; mStep->addReaction(mReaction); } - virtual void undo() { - mDeleteReactionInDestructor = true; - mStep->removeReaction(mReaction); +}; + +class AddReactionAtIndex: public AddReaction { +public: + + int mIndex; + + AddReactionAtIndex(QUndoCommand* parent = 0): AddReaction(parent) { } + virtual void redo() { + mDeleteReactionInDestructor = false; + mStep->addReaction(mReaction, mIndex); + } + }; class RemoveReaction: public BaseReactionCommand { public: + int mIndex; + RemoveReaction(QUndoCommand* parent = 0): BaseReactionCommand(parent) { setText(i18nc("@action", "Remove reaction")); mDeleteReactionInDestructor = false; @@ -164,12 +189,13 @@ virtual void redo() { mDeleteReactionInDestructor = true; + mIndex = mStep->reactions().indexOf(mReaction); mStep->removeReaction(mReaction); } virtual void undo() { mDeleteReactionInDestructor = false; - mStep->addReaction(mReaction); + mStep->addReaction(mReaction, mIndex); } }; @@ -212,12 +238,21 @@ QUndoCommand* StepCommands::addReaction(Reaction* reaction, QUndoCommand* parent) { - AddReaction* command = new AddReaction(parent); + AddReactionAtEnd* command = new AddReactionAtEnd(parent); command->mStep = mStep; command->mReaction = reaction; return command; } +QUndoCommand* StepCommands::addReaction(Reaction* reaction, int index, + QUndoCommand* parent) { + AddReactionAtIndex* command = new AddReactionAtIndex(parent); + command->mStep = mStep; + command->mReaction = reaction; + command->mIndex = index; + return command; +} + QUndoCommand* StepCommands::removeReaction(Reaction* reaction, QUndoCommand* parent) { RemoveReaction* command = new RemoveReaction(parent); Modified: trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.h 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/commands/StepCommands.h 2010-03-29 06:46:22 UTC (rev 209) @@ -96,6 +96,20 @@ QUndoCommand* addReaction(Reaction* reaction, QUndoCommand* parent = 0); /** + * Creates a new undoable command to add the given reaction to the step at + * the given index. + * If the command was not executed yet, or it was undone, the reaction is + * deleted when the command is deleted. + * + * @param reaction The reaction to add to the step. + * @param index The index to add the reaction at. + * @param parent The parent QUndoCommand. + * @return The new QUndoCommand. + */ + QUndoCommand* addReaction(Reaction* reaction, int index, + QUndoCommand* parent = 0); + + /** * Creates a new undoable command to remove the given reaction from the * step. * If the command was executed and not undone, the reaction is deleted when Modified: trunk/ktutorial/ktutorial-editor/src/data/Step.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/data/Step.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/data/Step.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -69,11 +69,15 @@ } void Step::addReaction(Reaction* reaction) { + addReaction(reaction, mReactions.count()); +} + +void Step::addReaction(Reaction* reaction, int index) { Q_ASSERT(!mReactions.contains(reaction)); - mReactions.append(reaction); + mReactions.insert(index, reaction); - emit reactionAdded(reaction); + emit reactionAdded(reaction, index); } QList<Reaction*> Step::reactions() const { Modified: trunk/ktutorial/ktutorial-editor/src/data/Step.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/data/Step.h 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/data/Step.h 2010-03-29 06:46:22 UTC (rev 209) @@ -30,7 +30,7 @@ * generate the code to create a true KTutorial::Step. * * When any attribute is modified, dataChanged(Step*) signal is emitted. When - * reactions are added or removed, reactionAdded(Reaction*) and + * reactions are added or removed, reactionAdded(Reaction*, int) and * reactionRemoved(Reaction*) are emitted. */ class Step: public QObject { @@ -64,6 +64,17 @@ * @param reaction The reaction to add. */ void addReaction(Reaction* reaction); + + /** + * Adds a new reaction to this Step at the given position. + * The Step gets ownership of the Reaction, so it is deleted when the + * Step is deleted. + * + * @param reaction The reaction to add. + * @param index The index to add the step at. + */ + void addReaction(Reaction* reaction, int index); + QList<Reaction*> reactions() const; /** @@ -87,8 +98,9 @@ * Emitted when the reaction is added to this Step. * * @param reaction The reaction added. + * @param index The index where the reaction was added. */ - void reactionAdded(Reaction* reaction); + void reactionAdded(Reaction* reaction, int index); /** * Emitted when the reaction is removed from this Step. Modified: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -42,10 +42,10 @@ this, SLOT(update(Step*))); foreach(Reaction* reaction, step->reactions()) { - addReaction(reaction); + addReaction(reaction, mReactionTreeItems.count()); } - connect(step, SIGNAL(reactionAdded(Reaction*)), - this, SLOT(addReaction(Reaction*))); + connect(step, SIGNAL(reactionAdded(Reaction*, int)), + this, SLOT(addReaction(Reaction*, int))); connect(step, SIGNAL(reactionRemoved(Reaction*)), this, SLOT(removeReaction(Reaction*))); } @@ -118,12 +118,14 @@ childIndex++; } + + mReactionTreeItemBaseIndex = childIndex; } -void StepTreeItem::addReaction(Reaction* reaction) { +void StepTreeItem::addReaction(Reaction* reaction, int index) { ReactionTreeItem* reactionTreeItem = new ReactionTreeItem(reaction, this); - appendChild(reactionTreeItem); - mReactionTreeItems.append(reactionTreeItem); + insertChild(reactionTreeItem, mReactionTreeItemBaseIndex + index); + mReactionTreeItems.insert(index, reactionTreeItem); } void StepTreeItem::removeReaction(Reaction* reaction) { Modified: trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h =================================================================== --- trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/src/view/StepTreeItem.h 2010-03-29 06:46:22 UTC (rev 209) @@ -127,6 +127,13 @@ QList<ReactionTreeItem*> mReactionTreeItems; /** + * The base index to add new ReactionTreeItems. + * It is the next index to the last optional data item (setup or tear down + * code). + */ + int mReactionTreeItemBaseIndex; + + /** * Returns the ReactionTreeItem for the given Reaction. * * @param reaction The Reaction to get its ReactionTreeItem. @@ -152,8 +159,9 @@ * Adds a new ReactionTreeItem when a Reaction is added in the step. * * @param step The Reaction added in the Step. + * @param index The index where the Reaction was added in the Step. */ - void addReaction(Reaction* reaction); + void addReaction(Reaction* reaction, int index); /** * Removes the ReactionTreeItem for the Reaction removed in the step. Modified: trunk/ktutorial/ktutorial-editor/tests/unit/commands/StepCommandsTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/commands/StepCommandsTest.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/tests/unit/commands/StepCommandsTest.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -47,8 +47,12 @@ void testAddReactionRedo(); void testAddReactionUndo(); + void testAddReactionAtIndexRedo(); + void testAddReactionAtIndexUndo(); + void testRemoveReactionRedo(); void testRemoveReactionUndo(); + void testRemoveReactionAtMiddleUndo(); }; @@ -204,6 +208,50 @@ QCOMPARE(step.reactions().count(), 0); } +void StepCommandsTest::testAddReactionAtIndexRedo() { + Step step; + StepCommands commands(&step); + QUndoCommand parent; + Reaction* reaction1 = new Reaction(); + Reaction* reaction2 = new Reaction(); + Reaction* reaction3 = new Reaction(); + + step.addReaction(reaction1); + step.addReaction(reaction3); + + QUndoCommand* command = commands.addReaction(reaction2, 1, &parent); + command->redo(); + + QCOMPARE(command->text(), i18nc("@action", "Add reaction")); + QCOMPARE(parent.child(0), command); + QCOMPARE(step.reactions().count(), 3); + QCOMPARE(step.reactions()[0], reaction1); + QCOMPARE(step.reactions()[1], reaction2); + QCOMPARE(step.reactions()[2], reaction3); +} + +void StepCommandsTest::testAddReactionAtIndexUndo() { + Step step; + StepCommands commands(&step); + QUndoCommand parent; + Reaction* reaction1 = new Reaction(); + Reaction* reaction2 = new Reaction(); + Reaction* reaction3 = new Reaction(); + + step.addReaction(reaction1); + step.addReaction(reaction3); + + QUndoCommand* command = commands.addReaction(reaction2, 1, &parent); + command->redo(); + command->undo(); + + QCOMPARE(command->text(), i18nc("@action", "Add reaction")); + QCOMPARE(parent.child(0), command); + QCOMPARE(step.reactions().count(), 2); + QCOMPARE(step.reactions()[0], reaction1); + QCOMPARE(step.reactions()[1], reaction3); +} + void StepCommandsTest::testRemoveReactionRedo() { Step step; StepCommands commands(&step); @@ -238,6 +286,30 @@ QCOMPARE(step.reactions()[0], reaction); } +void StepCommandsTest::testRemoveReactionAtMiddleUndo() { + Step step; + StepCommands commands(&step); + QUndoCommand parent; + Reaction* reaction1 = new Reaction(); + Reaction* reaction2 = new Reaction(); + Reaction* reaction3 = new Reaction(); + + step.addReaction(reaction1); + step.addReaction(reaction2); + step.addReaction(reaction3); + + QUndoCommand* command = commands.removeReaction(reaction2, &parent); + command->redo(); + command->undo(); + + QCOMPARE(command->text(), i18nc("@action", "Remove reaction")); + QCOMPARE(parent.child(0), command); + QCOMPARE(step.reactions().count(), 3); + QCOMPARE(step.reactions()[0], reaction1); + QCOMPARE(step.reactions()[1], reaction2); + QCOMPARE(step.reactions()[2], reaction3); +} + QTEST_MAIN(StepCommandsTest) #include "StepCommandsTest.moc" Modified: trunk/ktutorial/ktutorial-editor/tests/unit/data/StepTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/data/StepTest.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/tests/unit/data/StepTest.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -39,14 +39,18 @@ void testSetCustomTearDownCode(); void testAddReaction(); + void testAddReactionAtIndex(); void testRemoveReaction(); private: int mReactionStarType; - void assertReactionSignal(const QSignalSpy& spy, int index, - Reaction* reaction) const; + void assertReactionAddedSignal(const QSignalSpy& spy, int index, + Reaction* reaction, int reactionIndex) const; + void assertReactionRemovedSignal(const QSignalSpy& spy, int index, + Reaction* reaction) const; + }; void StepTest::initTestCase() { @@ -134,7 +138,7 @@ Reaction* reaction2 = new Reaction(); Reaction* reaction3 = new Reaction(); - QSignalSpy reactionAddedSpy(&step, SIGNAL(reactionAdded(Reaction*))); + QSignalSpy reactionAddedSpy(&step, SIGNAL(reactionAdded(Reaction*, int))); step.addReaction(reaction1); step.addReaction(reaction2); @@ -145,11 +149,33 @@ QCOMPARE(step.reactions()[1], reaction2); QCOMPARE(step.reactions()[2], reaction3); QCOMPARE(reactionAddedSpy.count(), 3); - assertReactionSignal(reactionAddedSpy, 0, reaction1); - assertReactionSignal(reactionAddedSpy, 1, reaction2); - assertReactionSignal(reactionAddedSpy, 2, reaction3); + assertReactionAddedSignal(reactionAddedSpy, 0, reaction1, 0); + assertReactionAddedSignal(reactionAddedSpy, 1, reaction2, 1); + assertReactionAddedSignal(reactionAddedSpy, 2, reaction3, 2); } +void StepTest::testAddReactionAtIndex() { + Step step; + Reaction* reaction1 = new Reaction(); + Reaction* reaction2 = new Reaction(); + Reaction* reaction3 = new Reaction(); + + QSignalSpy reactionAddedSpy(&step, SIGNAL(reactionAdded(Reaction*, int))); + + step.addReaction(reaction2, 0); + step.addReaction(reaction1, 0); + step.addReaction(reaction3, 2); + + QCOMPARE(step.reactions().count(), 3); + QCOMPARE(step.reactions()[0], reaction1); + QCOMPARE(step.reactions()[1], reaction2); + QCOMPARE(step.reactions()[2], reaction3); + QCOMPARE(reactionAddedSpy.count(), 3); + assertReactionAddedSignal(reactionAddedSpy, 0, reaction2, 0); + assertReactionAddedSignal(reactionAddedSpy, 1, reaction1, 0); + assertReactionAddedSignal(reactionAddedSpy, 2, reaction3, 2); +} + void StepTest::testRemoveReaction() { Step step; @@ -171,15 +197,15 @@ QCOMPARE(step.reactions()[0], &reaction1); QCOMPARE(step.reactions()[1], &reaction3); QCOMPARE(reactionRemovedSpy.count(), 1); - assertReactionSignal(reactionRemovedSpy, 0, &reaction2); + assertReactionRemovedSignal(reactionRemovedSpy, 0, &reaction2); step.removeReaction(&reaction1); step.removeReaction(&reaction3); QCOMPARE(step.reactions().count(), 0); QCOMPARE(reactionRemovedSpy.count(), 3); - assertReactionSignal(reactionRemovedSpy, 1, &reaction1); - assertReactionSignal(reactionRemovedSpy, 2, &reaction3); + assertReactionRemovedSignal(reactionRemovedSpy, 1, &reaction1); + assertReactionRemovedSignal(reactionRemovedSpy, 2, &reaction3); } /////////////////////////////////// Helpers //////////////////////////////////// @@ -187,8 +213,21 @@ //Reaction* must be declared as a metatype to be used in qvariant_cast Q_DECLARE_METATYPE(Reaction*); -void StepTest::assertReactionSignal(const QSignalSpy& spy, int index, - Reaction* reaction) const { +void StepTest::assertReactionAddedSignal(const QSignalSpy& spy, int index, + Reaction* reaction, + int reactionIndex) const { + QCOMPARE(spy.at(index).count(), 2); + + QVariant argument = spy.at(index).at(0); + QCOMPARE(argument.userType(), mReactionStarType); + QCOMPARE(qvariant_cast<Reaction*>(argument), reaction); + argument = spy.at(index).at(1); + QCOMPARE(argument.type(), QVariant::Int); + QCOMPARE(argument.toInt(), reactionIndex); +} + +void StepTest::assertReactionRemovedSignal(const QSignalSpy& spy, int index, + Reaction* reaction) const { QCOMPARE(spy.at(index).count(), 1); QVariant argument = spy.at(index).at(0); Modified: trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp =================================================================== --- trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp 2010-03-29 05:56:07 UTC (rev 208) +++ trunk/ktutorial/ktutorial-editor/tests/unit/view/StepTreeItemTest.cpp 2010-03-29 06:46:22 UTC (rev 209) @@ -53,6 +53,7 @@ void testStepSetCustomTearDownCodeEmpty(); void testStepAddReaction(); + void testStepAddReactionAtIndex(); void testStepRemoveReaction(); @@ -319,6 +320,26 @@ assertReaction(item.child(1), reaction); } +void StepTreeItemTest::testStepAddReactionAtIndex() { + Step step; + StepTreeItem item(&step); + + Reaction* reaction2 = new Reaction(); + step.addReaction(reaction2, 0); + + Reaction* reaction1 = new Reaction(); + step.addReaction(reaction1, 0); + + Reaction* reaction3 = new Reaction(); + step.addReaction(reaction3, 2); + + QCOMPARE(item.childCount(), 4); + assertEmptyText(item.child(0)); + assertReaction(item.child(1), reaction1); + assertReaction(item.child(2), reaction2); + assertReaction(item.child(3), reaction3); +} + void StepTreeItemTest::testStepRemoveReaction() { Step step; StepTreeItem item(&step); @@ -380,15 +401,28 @@ assertReaction(item.child(3), reaction1); assertReaction(item.child(4), reaction2); + Reaction* reaction3 = new Reaction(); + step.addReaction(reaction3, 1); + + QCOMPARE(item.text(), i18nc("@item", "Step (id not set)")); + QCOMPARE(item.childCount(), 6); + assertText(item.child(0), "The text"); + assertCustomSetupCode(item.child(1), "The setup code"); + assertCustomTearDownCode(item.child(2), "The tear down code"); + assertReaction(item.child(3), reaction1); + assertReaction(item.child(4), reaction3); + assertReaction(item.child(5), reaction2); + step.setId("The id"); QCOMPARE(item.text(), i18nc("@item", "Step %1", "The id")); - QCOMPARE(item.childCount(), 5); + QCOMPARE(item.childCount(), 6); assertText(item.child(0), "The text"); assertCustomSetupCode(item.child(1), "The setup code"); assertCustomTearDownCode(item.child(2), "The tear down code"); assertReaction(item.child(3), reaction1); - assertReaction(item.child(4), reaction2); + assertReaction(item.child(4), reaction3); + assertReaction(item.child(5), reaction2); } void StepTreeItemTest::testChildOrderWhenUnsettingDataInStep() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |