File indexing completed on 2024-05-26 04:26:19

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006 Thomas Zander <zander@kde.org>
0003  * SPDX-FileCopyrightText: 2006 Jan Hambrecht <jaham@gmx.net>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "KoShapeMoveCommand.h"
0009 
0010 #include <KoShape.h>
0011 #include <klocalizedstring.h>
0012 #include "kis_command_ids.h"
0013 #include <kis_assert.h>
0014 
0015 class Q_DECL_HIDDEN KoShapeMoveCommand::Private
0016 {
0017 public:
0018     QList<KoShape*> shapes;
0019     QList<QPointF> previousPositions, newPositions;
0020     KoFlake::AnchorPosition anchor;
0021 };
0022 
0023 KoShapeMoveCommand::KoShapeMoveCommand(const QList<KoShape*> &shapes, QList<QPointF> &previousPositions, QList<QPointF> &newPositions, KoFlake::AnchorPosition anchor, KUndo2Command *parent)
0024         : KUndo2Command(kundo2_i18n("Move shapes"), parent),
0025         d(new Private())
0026 {
0027     d->shapes = shapes;
0028     d->previousPositions = previousPositions;
0029     d->newPositions = newPositions;
0030     d->anchor = anchor;
0031     Q_ASSERT(d->shapes.count() == d->previousPositions.count());
0032     Q_ASSERT(d->shapes.count() == d->newPositions.count());
0033 }
0034 
0035 KoShapeMoveCommand::KoShapeMoveCommand(const QList<KoShape *> &shapes, const QPointF &offset, KUndo2Command *parent)
0036     : KUndo2Command(kundo2_i18n("Move shapes"), parent),
0037       d(new Private())
0038 {
0039     d->shapes = shapes;
0040     d->anchor = KoFlake::Center;
0041 
0042     Q_FOREACH (KoShape *shape, d->shapes) {
0043         const QPointF pos = shape->absolutePosition();
0044 
0045         d->previousPositions << pos;
0046         d->newPositions << pos + offset;
0047     }
0048 }
0049 
0050 KoShapeMoveCommand::~KoShapeMoveCommand()
0051 {
0052     delete d;
0053 }
0054 
0055 void KoShapeMoveCommand::redo()
0056 {
0057     KUndo2Command::redo();
0058 
0059     for (int i = 0; i < d->shapes.count(); i++) {
0060         KoShape *shape = d->shapes.at(i);
0061 
0062         const QRectF oldDirtyRect = shape->boundingRect();
0063         shape->setAbsolutePosition(d->newPositions.at(i), d->anchor);
0064         shape->updateAbsolute(oldDirtyRect | shape->boundingRect());
0065     }
0066 }
0067 
0068 void KoShapeMoveCommand::undo()
0069 {
0070     KUndo2Command::undo();
0071     for (int i = 0; i < d->shapes.count(); i++) {
0072         KoShape *shape = d->shapes.at(i);
0073 
0074         const QRectF oldDirtyRect = shape->boundingRect();
0075         shape->setAbsolutePosition(d->previousPositions.at(i), d->anchor);
0076         shape->updateAbsolute(oldDirtyRect | shape->boundingRect());
0077     }
0078 }
0079 
0080 int KoShapeMoveCommand::id() const
0081 {
0082     return KisCommandUtils::MoveShapeId;
0083 }
0084 
0085 bool KoShapeMoveCommand::mergeWith(const KUndo2Command *command)
0086 {
0087     const KoShapeMoveCommand *other = dynamic_cast<const KoShapeMoveCommand*>(command);
0088     KIS_ASSERT(other);
0089 
0090     if (other->d->shapes != d->shapes ||
0091         other->d->anchor != d->anchor) {
0092 
0093         return false;
0094     }
0095 
0096     d->newPositions = other->d->newPositions;
0097     return true;
0098 }