void KarbonPathRefineCommand::redo()
{
    // check if we have to create the insert points commands
    if (! d->initialized) {
        // create insert point commands, one for each point to insert
        // into each segment
        for (uint iteration = 0; iteration < d->insertCount; ++iteration) {
            // in each iteration collect the (iteration+1)th point which starts a segments
            // into which we insert the point of this iteration
            QList<KoPathPointData> pointData;
            // calculate the segment position where to insert the point
            qreal insertPosition = 1.0 / (d->insertCount + 1 - iteration);
            int subpathCount = d->path->subpathCount();
            // iterate over the paths subpaths
            for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
                int pointCount = d->path->subpathPointCount(subpathIndex);
                // iterate over the subpaths points
                for (int pointIndex = 0; pointIndex < pointCount; ++pointIndex) {
                    // we only collect the (iteration+1)th point
                    if ((pointIndex + 1) % (iteration + 1) != 0)
                        continue;
                    pointData.append(KoPathPointData(d->path, KoPathPointIndex(subpathIndex, pointIndex)));
                }
            }
            // create the command and execute it
            QUndoCommand * cmd = new KoPathPointInsertCommand(pointData, insertPosition, this);
            cmd->redo();
        }
        d->initialized = true;
    } else {
        QUndoCommand::redo();
    }
    d->path->update();
}
//------------------------------------------------------------------------------
void AssignmentRuleTest::updateCondition()
{
	AssignmentRule* rule(ruleWithMultipleConditions);
	QUndoCommand* cmd = rule->updateCondition(1,
		AssignmentRule::Condition(AssignmentRule::Date, AssignmentRule::Before, false, "5/5/13"));

	// Assert pre-conditions
	QCOMPARE(rule->conditionCount(), 2);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	QCOMPARE(rule->conditionAt(1).field, AssignmentRule::DepositAccount);
	QCOMPARE(rule->conditionAt(1).op, AssignmentRule::BeginsWith);
	QCOMPARE(rule->conditionAt(1).value, QString("Condition2"));

	cmd->redo();
	QCOMPARE(rule->conditionCount(), 2);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	QCOMPARE(rule->conditionAt(1).field, AssignmentRule::Date);
	QCOMPARE(rule->conditionAt(1).op, AssignmentRule::Before);
	QCOMPARE(rule->conditionAt(1).value, QString("5/5/13"));

	cmd->undo();
	QCOMPARE(rule->conditionCount(), 2);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	QCOMPARE(rule->conditionAt(1).field, AssignmentRule::DepositAccount);
	QCOMPARE(rule->conditionAt(1).op, AssignmentRule::BeginsWith);
	QCOMPARE(rule->conditionAt(1).value, QString("Condition2"));
}
//------------------------------------------------------------------------------
void AssignmentRuleTest::addCondition()
{
	QFETCH(uint, ruleId);
	QFETCH(int, oldCount);
	QFETCH(int, newCount);
	QFETCH(int, newIndex);
	QFETCH(int, existingIndex);

	AssignmentRule* rule = rules->find(ruleId);
	QUndoCommand* cmd = rule->addCondition();

	QCOMPARE(rule->conditionCount(), oldCount);
	AssignmentRule::Field field;
	if (existingIndex >= 0)
	{
		field = rule->conditionAt(existingIndex).field;
	}

	cmd->redo();
	QCOMPARE(rule->conditionCount(), newCount);
	QCOMPARE(rule->conditionAt(newIndex).field, AssignmentRule::FieldNotDefined);
	if (existingIndex >= 0)
	{
		QCOMPARE(rule->conditionAt(existingIndex).field, field);
	}

	cmd->undo();
	QCOMPARE(rule->conditionCount(), oldCount);
	if (existingIndex >= 0)
	{
		QCOMPARE(rule->conditionAt(existingIndex).field, field);
	}
}
Ejemplo n.º 4
0
QString CUndoRedoStack::redoText() const
{
    QUndoCommand* topCmd = d->redoStack.count() ? d->redoStack.top() : 0;
    if(topCmd)
        return topCmd->text();

    return QString();
}
Ejemplo n.º 5
0
void KoInteractionStrategy::cancelInteraction()
{
    QUndoCommand *cmd = createCommand();
    if (cmd) {
        cmd->undo();
        delete cmd;
    }
}
//------------------------------------------------------------------------------
void AssignmentRuleTest::removeConditionFromRuleWithNone()
{
	AssignmentRule* rule(ruleWithNoConditions);
	QUndoCommand* cmd = rule->removeCondition(0);

	QCOMPARE(rule->conditionCount(), 0);
	cmd->redo();
	QCOMPARE(rule->conditionCount(), 0);
	cmd->undo();
	QCOMPARE(rule->conditionCount(), 0);
}
Ejemplo n.º 7
0
void EditActions::addStep() {
    Step* step = new Step();

    QUndoCommand* parentCommand = new QUndoCommand();
    parentCommand->setText(i18nc("@action", "Add step"));
    TutorialCommands(mTutorialEditor->tutorial()).addStep(step, parentCommand);

    StepDataWidget* widget = new StepDataWidget(step);
    widget->enableStepIdCompletion(mTutorialEditor->tutorial());
    widget->setParentUndoCommand(parentCommand);
    if (showEditionDialog(widget) == QDialog::Rejected) {
        delete parentCommand;
    }
}
//------------------------------------------------------------------------------
void AssignmentRuleTest::removeConditionFromRuleWithOne()
{
	AssignmentRule* rule(ruleWithOneCondition);
	QUndoCommand* cmd = rule->removeCondition(0);

	QCOMPARE(rule->conditionCount(), 1);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	cmd->redo();
	QCOMPARE(rule->conditionCount(), 0);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::FieldNotDefined);
	cmd->undo();
	QCOMPARE(rule->conditionCount(), 1);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
}
Ejemplo n.º 9
0
void TestShapeReorderCommand::testMoveDownOverlapping()
{
#if 0 // disable a current alogrithm does not yet support this
    MockShape shape1, shape2, shape3, shape4, shape5;
    
    shape1.setSize(QSizeF(100, 100));
    shape1.setZIndex(1);
    shape2.setSize(QSizeF(100, 100));
    shape2.setZIndex(2);

    shape3.setSize(QSizeF(300, 300));
    shape3.setZIndex(3);
    
    shape4.setSize(QSizeF(100, 100));
    shape4.setPosition(QPointF(200,200));
    shape4.setZIndex(4);
    shape5.setSize(QSizeF(100, 100));
    shape5.setPosition(QPointF(200,200));
    shape5.setZIndex(5);
    
    QList<KShape*> shapes;
    shapes.append(&shape1);
    shapes.append(&shape2);
    shapes.append(&shape3);
    shapes.append(&shape4);
    shapes.append(&shape5);
    
    MockCanvas canvas;
    KShapeManager manager(&canvas, shapes);
    
    QVERIFY(shape1.zIndex() < shape2.zIndex());
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QVERIFY(shape3.zIndex() < shape4.zIndex());
    QVERIFY(shape4.zIndex() < shape5.zIndex());
    
    QList<KShape*> selectedShapes;
    selectedShapes.append(&shape5);
    
    QUndoCommand * cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::LowerShape);
    cmd->redo();
    delete cmd;
    
    QVERIFY(shape1.zIndex() < shape2.zIndex());
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QVERIFY(shape3.zIndex() < shape4.zIndex());
    QVERIFY(shape4.zIndex() > shape5.zIndex());
    QVERIFY(shape3.zIndex() > shape5.zIndex());
#endif
}
Ejemplo n.º 10
0
void ObjectContainer::rendererModification(std::vector<QJsonObject> data)
{
	QUndoCommand * transformation = new QUndoCommand();
	transformation->setText("Modify via 3D view");

	for (const auto& json : data)
	{
		ObjectItem* item = getItem(json["id"].toInt());
		if (!item)
			continue;
		new ModifyObjectCmd(item->data().toJsonObject(), json, item, Position | Scaling | Rotation, transformation); // Add command to command group
	}

	g_undoStack.push(transformation);
}
Ejemplo n.º 11
0
void CUndoRedoStack::redo()
{
    QUndoCommand* topCmd = d->redoStack.count() ? d->redoStack.pop() : 0;
    if(!topCmd)
        return;

    QString cmdText = topCmd->text();
    topCmd->redo();
    d->undoStack.push(topCmd);
    qWarning("Redo: %s", qPrintable(cmdText));

    // emit change notifications.
    emit redone(cmdText);
    emit canUndoChanged(d->undoStack.count());
    emit canRedoChanged(d->redoStack.count());
}
Ejemplo n.º 12
0
void EditActions::addReaction() {
    Q_ASSERT(mCurrentStep);

    Reaction* reaction = new Reaction();

    QUndoCommand* parentCommand = new QUndoCommand();
    parentCommand->setText(i18nc("@action", "Add reaction"));
    StepCommands(mCurrentStep).addReaction(reaction, parentCommand);

    ReactionWidget* widget = new ReactionWidget(reaction);
    widget->enableStepIdCompletion(mTutorialEditor->tutorial(), mCurrentStep);
    widget->setParentUndoCommand(parentCommand);
    if (showEditionDialog(widget) == QDialog::Rejected) {
        delete parentCommand;
    }
}
Ejemplo n.º 13
0
//------------------------------------------------------------------------------
void AssignmentRuleTest::removeConditionFromRuleWithMany()
{
	AssignmentRule* rule(ruleWithMultipleConditions);
	QUndoCommand* cmd = rule->removeCondition(0);

	QCOMPARE(rule->conditionCount(), 2);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	QCOMPARE(rule->conditionAt(1).field, AssignmentRule::DepositAccount);
	cmd->redo();
	QCOMPARE(rule->conditionCount(), 1);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::DepositAccount);
	cmd->undo();
	QCOMPARE(rule->conditionCount(), 2);
	QCOMPARE(rule->conditionAt(0).field, AssignmentRule::Payee);
	QCOMPARE(rule->conditionAt(1).field, AssignmentRule::DepositAccount);
}
Ejemplo n.º 14
0
void TestShapeReorderCommand::testMoveUpOverlapping()
{
    MockShape shape1, shape2, shape3, shape4, shape5;
    
    shape1.setSize(QSizeF(100, 100));
    shape1.setZIndex(1);
    shape2.setSize(QSizeF(100, 100));
    shape2.setZIndex(2);

    shape3.setSize(QSizeF(300, 300));
    shape3.setZIndex(3);
    
    shape4.setSize(QSizeF(100, 100));
    shape4.setPosition(QPointF(200,200));
    shape4.setZIndex(4);
    shape5.setSize(QSizeF(100, 100));
    shape5.setPosition(QPointF(200,200));
    shape5.setZIndex(5);
    
    QList<KShape*> shapes;
    shapes.append(&shape1);
    shapes.append(&shape2);
    shapes.append(&shape3);
    shapes.append(&shape4);
    shapes.append(&shape5);
    
    MockCanvas canvas;
    KShapeManager manager(&canvas, shapes);
    
    QVERIFY(shape1.zIndex() < shape2.zIndex());
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QVERIFY(shape3.zIndex() < shape4.zIndex());
    QVERIFY(shape4.zIndex() < shape5.zIndex());
    
    QList<KShape*> selectedShapes;
    selectedShapes.append(&shape1);
    
    QUndoCommand * cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::RaiseShape);
    cmd->redo();
    delete cmd;
    
    QVERIFY(shape1.zIndex() > shape2.zIndex());
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QVERIFY(shape1.zIndex() < shape3.zIndex());
    QVERIFY(shape3.zIndex() < shape4.zIndex());
    QVERIFY(shape4.zIndex() < shape5.zIndex());
}
Ejemplo n.º 15
0
void CUndoRedoStack::push(QUndoCommand* cmd)
{
    if(!cmd)
        return;

    // First register the undo command into the undo stack.
    QUndoCommand* topCmd = d->undoStack.count() ? d->undoStack.top() : 0;
    if(!topCmd)
    {
        d->undoStack.push(cmd);
        CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd);
        if(cmd2)
            addCommand(cmd2);
    }
    else
    {
        if(topCmd->id() == cmd->id())
        {
            bool success = topCmd->mergeWith(cmd);
            if(!success)
            {
                d->undoStack.push(cmd);
                CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd);
                if(cmd2)
                    addCommand(cmd2);
            }
            else
                delete cmd;
        }
    }

    // Now clear the redo stack.
    for(int i=0; i<d->redoStack.count(); i++)
    {
        QUndoCommand* cmd = d->redoStack.pop();
        CUndoRedoCmdBase* cmd2 = dynamic_cast<CUndoRedoCmdBase*>(cmd);
        if(cmd2)
            removeCommand(cmd2);
        delete cmd;
    }

    // emit change notifications.
    emit canUndoChanged(d->undoStack.count());
    emit canRedoChanged(d->redoStack.count());
    emit countChanged(count());
}
Ejemplo n.º 16
0
void QUndoStack::push(QUndoCommand *cmd)
{
    Q_D(QUndoStack);
    cmd->redo();

    bool macro = !d->macro_stack.isEmpty();

    QUndoCommand *cur = 0;
    if (macro) {
        QUndoCommand *macro_cmd = d->macro_stack.last();
        if (!macro_cmd->d->child_list.isEmpty())
            cur = macro_cmd->d->child_list.last();
    } else {
        if (d->index > 0)
            cur = d->command_list.at(d->index - 1);
        while (d->index < d->command_list.size())
            delete d->command_list.takeLast();
        if (d->clean_index > d->index)
            d->clean_index = -1; // we've deleted the clean state
    }

    bool try_merge = cur != 0
                        && cur->id() != -1
                        && cur->id() == cmd->id()
                        && (macro || d->index != d->clean_index);

    if (try_merge && cur->mergeWith(cmd)) {
        delete cmd;
        if (!macro) {
            emit indexChanged(d->index);
            emit canUndoChanged(canUndo());
            emit undoTextChanged(undoText());
            emit canRedoChanged(canRedo());
            emit redoTextChanged(redoText());
        }
    } else {
        if (macro) {
            d->macro_stack.last()->d->child_list.append(cmd);
        } else {
            d->command_list.append(cmd);
            d->checkUndoLimit();
            d->setIndex(d->index + 1, false);
        }
    }
}
Ejemplo n.º 17
0
/**
 * Duplicates the currently selected layer.
 */
void MapDocument::duplicateLayer()
{
    if (!mCurrentLayer)
        return;

    Layer *duplicate = mCurrentLayer->clone();
    duplicate->setName(tr("Copy of %1").arg(duplicate->name()));

    if (duplicate->layerType() == Layer::ObjectGroupType)
        static_cast<ObjectGroup*>(duplicate)->resetObjectIds();

    auto parentLayer = mCurrentLayer ? mCurrentLayer->parentLayer() : nullptr;
    const int index = layerIndex(mCurrentLayer) + 1;
    QUndoCommand *cmd = new AddLayer(this, index, duplicate, parentLayer);
    cmd->setText(tr("Duplicate Layer"));
    mUndoStack->push(cmd);
    setCurrentLayer(duplicate);
}
Ejemplo n.º 18
0
void ImportCommand::undo()
{
    if ( !folder().isEmpty() ) {
        // we created a group -> just delete it
        DeleteCommand cmd(m_model, m_group);
        cmd.redo();

    } else {
        // we imported at the root -> delete everything
        KBookmarkGroup root = GlobalBookmarkManager::self()->root();
        QUndoCommand *cmd = DeleteCommand::deleteAll(m_model, root);

        cmd->redo();
        delete cmd;

        // and recreate what was there before
        m_cleanUpCmd->undo();
    }
}
static PyObject *meth_QUndoCommand_id(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;
    bool sipSelfWasArg = (!sipSelf || sipIsDerived((sipSimpleWrapper *)sipSelf));

    {
        QUndoCommand *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "B", &sipSelf, sipType_QUndoCommand, &sipCpp))
        {
            int sipRes;

            Py_BEGIN_ALLOW_THREADS
            sipRes = (sipSelfWasArg ? sipCpp->QUndoCommand::id() : sipCpp->id());
            Py_END_ALLOW_THREADS

            return SIPLong_FromLong(sipRes);
        }
    }
Ejemplo n.º 20
0
/**
 * Removes the tileset at the given index. Prompting the user when the tileset
 * is in use by the map.
 */
void TilesetDock::removeTileset(int index)
{
    auto &sharedTileset = mTilesets.at(index);

    int mapTilesetIndex = mMapDocument->map()->tilesets().indexOf(sharedTileset);
    if (mapTilesetIndex == -1)
        return;

    Tileset *tileset = sharedTileset.data();
    const bool inUse = mMapDocument->map()->isTilesetUsed(tileset);

    // If the tileset is in use, warn the user and confirm removal
    if (inUse) {
        QMessageBox warning(QMessageBox::Warning,
                            tr("Remove Tileset"),
                            tr("The tileset \"%1\" is still in use by the "
                               "map!").arg(tileset->name()),
                            QMessageBox::Yes | QMessageBox::No,
                            this);
        warning.setDefaultButton(QMessageBox::Yes);
        warning.setInformativeText(tr("Remove this tileset and all references "
                                      "to the tiles in this tileset?"));

        if (warning.exec() != QMessageBox::Yes)
            return;
    }

    QUndoCommand *remove = new RemoveTileset(mMapDocument, mapTilesetIndex);
    QUndoStack *undoStack = mMapDocument->undoStack();

    if (inUse) {
        // Remove references to tiles in this tileset from the current map
        auto referencesTileset = [tileset] (const Cell &cell) {
            return cell.tileset() == tileset;
        };
        undoStack->beginMacro(remove->text());
        removeTileReferences(mMapDocument, referencesTileset);
    }
    undoStack->push(remove);
    if (inUse)
        undoStack->endMacro();
}
Ejemplo n.º 21
0
static PyObject *meth_QUndoCommand_undo(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;
    bool sipSelfWasArg = (!sipSelf || sipIsDerived((sipSimpleWrapper *)sipSelf));

    {
        QUndoCommand *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "B", &sipSelf, sipType_QUndoCommand, &sipCpp))
        {
            (sipSelfWasArg ? sipCpp->QUndoCommand::undo() : sipCpp->undo());

            Py_INCREF(Py_None);
            return Py_None;
        }
    }

    /* Raise an exception if the arguments couldn't be parsed. */
    sipNoMethod(sipParseErr, sipName_QUndoCommand, sipName_undo, doc_QUndoCommand_undo);

    return NULL;
}
Ejemplo n.º 22
0
void TestShapeReorderCommand::testSendToBack()
{
    MockShape shape1, shape2, shape3;

    shape1.setSize(QSizeF(100, 100));
    shape1.setZIndex(1);
    shape2.setSize(QSizeF(100, 100));
    shape2.setZIndex(2);
    shape3.setSize(QSizeF(100, 100));
    shape3.setZIndex(3);
    QList<KShape*> shapes;
    shapes.append(&shape1);
    shapes.append(&shape2);
    shapes.append(&shape3);

    MockCanvas canvas;
    KShapeManager manager(&canvas, shapes);

    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&shape1), 0);
    QCOMPARE(shapes.indexOf(&shape2), 1);
    QCOMPARE(shapes.indexOf(&shape3), 2);

    QList<KShape*> selectedShapes;
    selectedShapes.append(&shape3);

    QUndoCommand * cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::SendToBack);
    cmd->redo();

    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&shape3), 0);
    QCOMPARE(shapes.indexOf(&shape1), 1);
    QCOMPARE(shapes.indexOf(&shape2), 2);

    delete cmd;
}
Ejemplo n.º 23
0
static PyObject *meth_QUndoCommand_mergeWith(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;
    bool sipSelfWasArg = (!sipSelf || sipIsDerived((sipSimpleWrapper *)sipSelf));

    {
        const QUndoCommand* a0;
        QUndoCommand *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "BJ8", &sipSelf, sipType_QUndoCommand, &sipCpp, sipType_QUndoCommand, &a0))
        {
            bool sipRes;

            sipRes = (sipSelfWasArg ? sipCpp->QUndoCommand::mergeWith(a0) : sipCpp->mergeWith(a0));

            return PyBool_FromLong(sipRes);
        }
    }

    /* Raise an exception if the arguments couldn't be parsed. */
    sipNoMethod(sipParseErr, sipName_QUndoCommand, sipName_mergeWith, doc_QUndoCommand_mergeWith);

    return NULL;
}
Ejemplo n.º 24
0
static PyObject *meth_QUndoCommand_setText(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;

    {
        const QString* a0;
        int a0State = 0;
        QUndoCommand *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "BJ1", &sipSelf, sipType_QUndoCommand, &sipCpp, sipType_QString,&a0, &a0State))
        {
            sipCpp->setText(*a0);
            sipReleaseType(const_cast<QString *>(a0),sipType_QString,a0State);

            Py_INCREF(Py_None);
            return Py_None;
        }
    }

    /* Raise an exception if the arguments couldn't be parsed. */
    sipNoMethod(sipParseErr, sipName_QUndoCommand, sipName_setText, doc_QUndoCommand_setText);

    return NULL;
}
Ejemplo n.º 25
0
void QUndoStack::beginMacro(const QString &text)
{
    Q_D(QUndoStack);
    QUndoCommand *cmd = new QUndoCommand();
    cmd->setText(text);

    if (d->macro_stack.isEmpty()) {
        while (d->index < d->command_list.size())
            delete d->command_list.takeLast();
        if (d->clean_index > d->index)
            d->clean_index = -1; // we've deleted the clean state
        d->command_list.append(cmd);
    } else {
        d->macro_stack.last()->d->child_list.append(cmd);
    }
    d->macro_stack.append(cmd);

    if (d->macro_stack.count() == 1) {
        emit canUndoChanged(false);
        emit undoTextChanged(QString());
        emit canRedoChanged(false);
        emit redoTextChanged(QString());
    }
}
Ejemplo n.º 26
0
void TestShapeReorderCommand::testSendToBackChildren()
{
    MockShape shape1, shape2, shape3;
    
    shape1.setSize(QSizeF(100, 100));
    shape1.setZIndex(1);
    shape2.setSize(QSizeF(100, 100));
    shape2.setZIndex(2);
    shape3.setSize(QSizeF(100, 100));
    shape3.setZIndex(3);
    
    MockContainer container;
    container.addShape(&shape1);
    container.addShape(&shape2);
    container.addShape(&shape3);
    
    QList<KShape*> shapes;
    shapes.append(&shape1);
    shapes.append(&shape2);
    shapes.append(&shape3);
    shapes.append(&container);
    
    MockCanvas canvas;
    KShapeManager manager(&canvas, shapes);
    
    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&container), 0); // atm the parent is always lower than its children
    QCOMPARE(shapes.indexOf(&shape1), 1);
    QCOMPARE(shapes.indexOf(&shape2), 2);
    QCOMPARE(shapes.indexOf(&shape3), 3);
    
    QList<KShape*> selectedShapes;
    selectedShapes.append(&shape3);
    
    QUndoCommand * cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::SendToBack);
    cmd->redo();
    delete cmd;
    
    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&container), 0); // atm the parent is always lower than its children
    QCOMPARE(shapes.indexOf(&shape3), 1);
    QVERIFY(shape3.zIndex() < shape1.zIndex());
    QCOMPARE(shapes.indexOf(&shape1), 2);
    QVERIFY(shape1.zIndex() < shape2.zIndex());
    QCOMPARE(shapes.indexOf(&shape2), 3);
    
    selectedShapes.clear();
    selectedShapes.append(&shape2);
    
    cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::SendToBack);
    cmd->redo();
    delete cmd;
    
    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&container), 0); // atm the parent is always lower than its children
    QCOMPARE(shapes.indexOf(&shape2), 1);
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QCOMPARE(shapes.indexOf(&shape3), 2);
    QVERIFY(shape3.zIndex() < shape1.zIndex());
    QCOMPARE(shapes.indexOf(&shape1), 3);
    
    selectedShapes.clear();
    selectedShapes.append(&shape1);
    
    cmd = KShapeReorderCommand::createCommand(selectedShapes, &manager, KShapeReorderCommand::SendToBack);
    cmd->redo();
    delete cmd;
    
    qSort(shapes.begin(), shapes.end(), KShape::compareShapeZIndex);
    QCOMPARE(shapes.indexOf(&container), 0); // atm the parent is always lower than its children
    QCOMPARE(shapes.indexOf(&shape1), 1);
    QVERIFY(shape1.zIndex() < shape2.zIndex());
    QCOMPARE(shapes.indexOf(&shape2), 2);
    QVERIFY(shape2.zIndex() < shape3.zIndex());
    QCOMPARE(shapes.indexOf(&shape3), 3);
}