1 /*
2 * Copyright (c) 2007 Boudewijn Rempt <boud@valdyas.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "kis_transaction_test.h"
20 #include <QTest>
21 #include <KoColorSpace.h>
22 #include <KoColorSpaceRegistry.h>
23
24 #include <kundo2qstack.h>
25
26 #include "kis_types.h"
27 #include "kis_transform_worker.h"
28 #include "kis_paint_device.h"
29 #include "kis_transaction.h"
30 #include "kis_surrogate_undo_adapter.h"
31 #include "kis_image.h"
32 #include "kis_paint_device_debug_utils.h"
33
testUndo()34 void KisTransactionTest::testUndo()
35 {
36 KisSurrogateUndoAdapter undoAdapter;
37 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
38 KisPaintDeviceSP dev = new KisPaintDevice(cs);
39
40 quint8* pixel = new quint8[cs->pixelSize()];
41 cs->fromQColor(Qt::white, pixel);
42 dev->fill(0, 0, 512, 512, pixel);
43
44 cs->fromQColor(Qt::black, pixel);
45 dev->fill(512, 0, 512, 512, pixel);
46
47 QColor c1, c2;
48 dev->pixel(5, 5, &c1);
49 dev->pixel(517, 5, &c2);
50
51 QVERIFY(c1 == Qt::white);
52 QVERIFY(c2 == Qt::black);
53
54 KisTransaction transaction(kundo2_noi18n("mirror"), dev, 0);
55 KisTransformWorker::mirrorX(dev);
56 transaction.commit(&undoAdapter);
57
58 dev->pixel(5, 5, &c1);
59 dev->pixel(517, 5, &c2);
60
61 QVERIFY(c1 == Qt::black);
62 QVERIFY(c2 == Qt::white);
63
64 undoAdapter.undo();
65
66 dev->pixel(5, 5, &c1);
67 dev->pixel(517, 5, &c2);
68
69 QVERIFY(c1 == Qt::white);
70 QVERIFY(c2 == Qt::black);
71
72 }
73
testRedo()74 void KisTransactionTest::testRedo()
75 {
76 KisSurrogateUndoAdapter undoAdapter;
77
78 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
79 KisPaintDeviceSP dev = new KisPaintDevice(cs);
80
81 quint8* pixel = new quint8[cs->pixelSize()];
82 cs->fromQColor(Qt::white, pixel);
83 dev->fill(0, 0, 512, 512, pixel);
84
85 cs->fromQColor(Qt::black, pixel);
86 dev->fill(512, 0, 512, 512, pixel);
87
88 QColor c1, c2;
89 dev->pixel(5, 5, &c1);
90 dev->pixel(517, 5, &c2);
91
92 QVERIFY(c1 == Qt::white);
93 QVERIFY(c2 == Qt::black);
94
95 KisTransaction transaction(kundo2_noi18n("mirror"), dev, 0);
96 KisTransformWorker::mirrorX(dev);
97 transaction.commit(&undoAdapter);
98
99 dev->pixel(5, 5, &c1);
100 dev->pixel(517, 5, &c2);
101
102 QVERIFY(c1 == Qt::black);
103 QVERIFY(c2 == Qt::white);
104
105
106 undoAdapter.undo();
107
108 dev->pixel(5, 5, &c1);
109 dev->pixel(517, 5, &c2);
110
111 QVERIFY(c1 == Qt::white);
112 QVERIFY(c2 == Qt::black);
113
114 undoAdapter.redo();
115
116 dev->pixel(5, 5, &c1);
117 dev->pixel(517, 5, &c2);
118
119 QVERIFY(c1 == Qt::black);
120 QVERIFY(c2 == Qt::white);
121 }
122
testDeviceMove()123 void KisTransactionTest::testDeviceMove()
124 {
125 KisSurrogateUndoAdapter undoAdapter;
126
127 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
128 KisPaintDeviceSP dev = new KisPaintDevice(cs);
129
130 QCOMPARE(dev->x(), 0);
131 QCOMPARE(dev->y(), 0);
132
133 KisTransaction t1(kundo2_noi18n("move1"), dev, 0);
134 dev->moveTo(10,20);
135 t1.commit(&undoAdapter);
136
137 QCOMPARE(dev->x(), 10);
138 QCOMPARE(dev->y(), 20);
139
140 KisTransaction t2(kundo2_noi18n("move2"), dev, 0);
141 dev->moveTo(7,11);
142 t2.commit(&undoAdapter);
143
144 QCOMPARE(dev->x(), 7);
145 QCOMPARE(dev->y(), 11);
146
147 undoAdapter.undo();
148
149 QCOMPARE(dev->x(), 10);
150 QCOMPARE(dev->y(), 20);
151
152 undoAdapter.undo();
153
154 QCOMPARE(dev->x(), 0);
155 QCOMPARE(dev->y(), 0);
156
157 undoAdapter.redo();
158
159 QCOMPARE(dev->x(), 10);
160 QCOMPARE(dev->y(), 20);
161
162 undoAdapter.redo();
163
164 QCOMPARE(dev->x(), 7);
165 QCOMPARE(dev->y(), 11);
166 }
167
168 #include "kis_keyframe_channel.h"
169 #include "kis_raster_keyframe_channel.h"
170 #include "kis_paint_device_frames_interface.h"
171 #include "testing_timed_default_bounds.h"
172
173 #include <KoColor.h>
174
175
testUndoWithUnswitchedFrames()176 void KisTransactionTest::testUndoWithUnswitchedFrames()
177 {
178 KisSurrogateUndoAdapter undoAdapter;
179 const QRect imageRect(0,0,100,100);
180
181
182 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
183 KisPaintDeviceSP dev = new KisPaintDevice(cs);
184
185 TestUtil::TestingTimedDefaultBounds *bounds = new TestUtil::TestingTimedDefaultBounds();
186 dev->setDefaultBounds(bounds);
187
188 KisRasterKeyframeChannel *channel = dev->createKeyframeChannel(KisKeyframeChannel::Content);
189 QVERIFY(channel);
190
191 KisPaintDeviceFramesInterface *i = dev->framesInterface();
192 QVERIFY(i);
193
194 QCOMPARE(i->frames().size(), 1);
195
196
197 dev->fill(QRect(10,10,20,20), KoColor(Qt::white, cs));
198
199 KIS_DUMP_DEVICE_2(dev, imageRect, "00_f0_w20", "dd");
200 QCOMPARE(dev->exactBounds(), QRect(10,10,20,20));
201
202
203 // add keyframe at position 10
204 channel->addKeyframe(10);
205
206 // add keyframe at position 11
207 channel->addKeyframe(11);
208
209 // add keyframe at position 12
210 channel->addKeyframe(12);
211
212 KIS_DUMP_DEVICE_2(dev, imageRect, "01_f0_b20", "dd");
213 QCOMPARE(dev->exactBounds(), QRect(10,10,20,20));
214
215 {
216 KisTransaction transaction(kundo2_noi18n("first_stroke"), dev, 0);
217
218 dev->clear();
219 dev->fill(QRect(40,40,21,21), KoColor(Qt::red, cs));
220
221 transaction.commit(&undoAdapter);
222
223 KIS_DUMP_DEVICE_2(dev, imageRect, "02_f0_b21_stroke", "dd");
224 QCOMPARE(dev->exactBounds(), QRect(40,40,21,21));
225 }
226
227 // switch to frame 10
228 bounds->testingSetTime(10);
229
230 KIS_DUMP_DEVICE_2(dev, imageRect, "03_f10_b0_switched", "dd");
231 QVERIFY(dev->exactBounds().isEmpty());
232
233 {
234 KisTransaction transaction(kundo2_noi18n("second_stroke"), dev, 0);
235
236 dev->fill(QRect(60,60,22,22), KoColor(Qt::green, cs));
237
238 transaction.commit(&undoAdapter);
239
240 KIS_DUMP_DEVICE_2(dev, imageRect, "04_f10_b22_stroke", "dd");
241 QCOMPARE(dev->exactBounds(), QRect(60,60,22,22));
242 }
243
244 undoAdapter.undo();
245
246 KIS_DUMP_DEVICE_2(dev, imageRect, "05_f10_b0_undone", "dd");
247 QVERIFY(dev->exactBounds().isEmpty());
248
249 bounds->testingSetTime(0);
250 KIS_DUMP_DEVICE_2(dev, imageRect, "06_f0_b21_undone", "dd");
251 QCOMPARE(dev->exactBounds(), QRect(40,40,21,21));
252
253 bounds->testingSetTime(10);
254 QVERIFY(dev->exactBounds().isEmpty());
255
256 undoAdapter.undo();
257
258 KIS_DUMP_DEVICE_2(dev, imageRect, "07_f10_b0_undone_x2", "dd");
259 QVERIFY(dev->exactBounds().isEmpty());
260
261 bounds->testingSetTime(0);
262 KIS_DUMP_DEVICE_2(dev, imageRect, "08_f0_b20_undone_x2", "dd");
263 QCOMPARE(dev->exactBounds(), QRect(10,10,20,20));
264
265 {
266 KisTransaction transaction(kundo2_noi18n("third_move"), dev, 0);
267
268 dev->moveTo(17,17);
269
270 transaction.commit(&undoAdapter);
271
272 KIS_DUMP_DEVICE_2(dev, imageRect, "09_f0_o27_move", "dd");
273 QCOMPARE(dev->exactBounds(), QRect(27,27,20,20));
274 }
275
276 bounds->testingSetTime(10);
277 QVERIFY(dev->exactBounds().isEmpty());
278
279 undoAdapter.undo();
280
281 KIS_DUMP_DEVICE_2(dev, imageRect, "10_f10_b0_undone_x3", "dd");
282 QVERIFY(dev->exactBounds().isEmpty());
283
284 bounds->testingSetTime(0);
285 KIS_DUMP_DEVICE_2(dev, imageRect, "11_f0_b20_undone_x3", "dd");
286 QCOMPARE(dev->exactBounds(), QRect(10,10,20,20));
287 }
288
289 QTEST_MAIN(KisTransactionTest)
290
291
292