Krita Source Code Documentation
Loading...
Searching...
No Matches
KoShapeResizeCommand.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <KoShape.h>
10#include "kis_command_ids.h"
11#include "kis_assert.h"
12
13
27
28
30 qreal scaleX, qreal scaleY,
31 const QPointF &absoluteStillPoint,
32 bool useGLobalMode,
33 bool usePostScaling,
34 const QTransform &postScalingCoveringTransform,
35 KUndo2Command *parent)
36 : SkipFirstRedoBase(false, kundo2_i18n("Resize"), parent),
37 m_d(new Private)
38{
39 m_d->shapes = shapes;
40 m_d->scaleX = scaleX;
41 m_d->scaleY = scaleY;
42 m_d->absoluteStillPoint = absoluteStillPoint;
43 m_d->useGlobalMode = useGLobalMode;
44 m_d->usePostScaling = usePostScaling;
45 m_d->postScalingCoveringTransform = postScalingCoveringTransform;
46
47 Q_FOREACH (KoShape *shape, m_d->shapes) {
48 m_d->oldSizes << shape->size();
49 m_d->oldTransforms << shape->transformation();
50 }
51}
52
56
58{
59 QMap<KoShape*, QRectF> updates = redoNoUpdate();
60
61 for (auto it = updates.begin(); it != updates.end(); ++it) {
62 it.key()->updateAbsolute(it.value());
63 }
64}
65
67{
68 QMap<KoShape*, QRectF> updates = undoNoUpdate();
69
70 for (auto it = updates.begin(); it != updates.end(); ++it) {
71 it.key()->updateAbsolute(it.value());
72 }
73}
74
75QMap<KoShape*, QRectF> KoShapeResizeCommand::redoNoUpdate()
76{
77 QMap<KoShape*,QRectF> updates;
78
79 Q_FOREACH (KoShape *shape, m_d->shapes) {
80 const QRectF oldDirtyRect = shape->boundingRect();
81
83 m_d->scaleX, m_d->scaleY,
84 m_d->absoluteStillPoint,
85 m_d->useGlobalMode,
86 m_d->usePostScaling,
87 m_d->postScalingCoveringTransform);
88
89 updates[shape] = oldDirtyRect | shape->boundingRect();
90 }
91
92 return updates;
93}
94
95QMap<KoShape*, QRectF> KoShapeResizeCommand::undoNoUpdate()
96{
97 QMap<KoShape*,QRectF> updates;
98
99 for (int i = 0; i < m_d->shapes.size(); i++) {
100 KoShape *shape = m_d->shapes[i];
101
102 const QRectF oldDirtyRect = shape->boundingRect();
103 shape->setSize(m_d->oldSizes[i]);
104 shape->setTransformation(m_d->oldTransforms[i]);
105
106 updates[shape] = oldDirtyRect | shape->boundingRect();
107 }
108
109 return updates;
110}
111
116
118{
119 const KoShapeResizeCommand *other = dynamic_cast<const KoShapeResizeCommand*>(command);
120
121 if (!other ||
122 other->m_d->absoluteStillPoint != m_d->absoluteStillPoint ||
123 other->m_d->shapes != m_d->shapes ||
124 other->m_d->useGlobalMode != m_d->useGlobalMode ||
125 other->m_d->usePostScaling != m_d->usePostScaling) {
126
127 return false;
128 }
129
130 // check if the significant orientations coincide
131 if (m_d->useGlobalMode && !m_d->usePostScaling) {
132 Qt::Orientation our = KoFlake::significantScaleOrientation(m_d->scaleX, m_d->scaleY);
133 Qt::Orientation their = KoFlake::significantScaleOrientation(other->m_d->scaleX, other->m_d->scaleY);
134
135 if (our != their) {
136 return false;
137 }
138 }
139
140 m_d->scaleX *= other->m_d->scaleX;
141 m_d->scaleY *= other->m_d->scaleY;
142 return true;
143}
144
145void KoShapeResizeCommand::replaceResizeAction(qreal scaleX, qreal scaleY, const QPointF &absoluteStillPoint)
146{
147 const QMap<KoShape*, QRectF> undoUpdates = undoNoUpdate();
148
149 m_d->scaleX = scaleX;
150 m_d->scaleY = scaleY;
151 m_d->absoluteStillPoint = absoluteStillPoint;
152
153 const QMap<KoShape*, QRectF> redoUpdates = redoNoUpdate();
154
155 KIS_SAFE_ASSERT_RECOVER_NOOP(undoUpdates.size() == redoUpdates.size());
156
157 for (auto it = undoUpdates.begin(); it != undoUpdates.end(); ++it) {
158 KIS_SAFE_ASSERT_RECOVER_NOOP(redoUpdates.contains(it.key()));
159 it.key()->updateAbsolute(it.value() | redoUpdates[it.key()]);
160 }
161}
virtual QSizeF size() const
Get the size of the shape in pt.
Definition KoShape.cpp:820
virtual QRectF boundingRect() const
Get the bounding box of the shape.
Definition KoShape.cpp:335
void setTransformation(const QTransform &matrix)
Definition KoShape.cpp:417
QTransform transformation() const
Returns the shapes local transformation matrix.
Definition KoShape.cpp:424
virtual void setSize(const QSizeF &size)
Resize the shape.
Definition KoShape.cpp:276
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
KUndo2MagicString kundo2_i18n(const char *text)
KRITAFLAKE_EXPORT Qt::Orientation significantScaleOrientation(qreal scaleX, qreal scaleY)
Definition KoFlake.cpp:168
KRITAFLAKE_EXPORT void resizeShapeCommon(KoShape *shape, qreal scaleX, qreal scaleY, const QPointF &absoluteStillPoint, bool useGlobalMode, bool usePostScaling, const QTransform &postScalingCoveringTransform)
Definition KoFlake.cpp:313
QMap< KoShape *, QRectF > redoNoUpdate()
bool mergeWith(const KUndo2Command *command) override
QList< QTransform > oldTransforms
KoShapeResizeCommand(const QList< KoShape * > &shapes, qreal scaleX, qreal scaleY, const QPointF &absoluteStillPoint, bool useGLobalMode, bool usePostScaling, const QTransform &postScalingCoveringTransform, KUndo2Command *parent=0)
void replaceResizeAction(qreal scaleX, qreal scaleY, const QPointF &absoluteStillPoint)
QScopedPointer< Private > const m_d
QMap< KoShape *, QRectF > undoNoUpdate()