1 /*
2 * This file is part of Calligra tests
3 *
4 * Copyright (C) 2006-2010 Thomas Zander <zander@kde.org>
5 * Copyright (C) 2010 Adam Celarek <kdedev@xibo.at>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 #include "TestShapeContainer.h"
22 #include <MockShapes.h>
23
24 #include <KoShape.h>
25 #include <KoShapeGroupCommand.h>
26 #include <KoShapeUngroupCommand.h>
27 #include <KoShapeTransformCommand.h>
28 #include <KoShapeGroup.h>
29 #include <KoSelection.h>
30
31 #include <QTest>
32
33
testModel()34 void TestShapeContainer::testModel()
35 {
36 MockContainerModel *model = new MockContainerModel();
37 MockContainer container(model);
38 MockShape *shape1 = new MockShape();
39
40 container.addShape(shape1);
41 QCOMPARE(model->containerChangedCalled(), 0);
42 QCOMPARE(model->childChangedCalled(), 1);
43 QCOMPARE(model->proposeMoveCalled(), 0);
44
45 shape1->setPosition(QPointF(300, 300));
46 QCOMPARE(model->containerChangedCalled(), 0);
47 QCOMPARE(model->childChangedCalled(), 2);
48 QCOMPARE(model->proposeMoveCalled(), 0);
49
50 shape1->rotate(10);
51 QCOMPARE(model->containerChangedCalled(), 0);
52 QCOMPARE(model->childChangedCalled(), 3);
53 QCOMPARE(model->proposeMoveCalled(), 0);
54
55 shape1->setAbsolutePosition(shape1->absolutePosition() + QPointF(10., 40.));
56 QCOMPARE(model->containerChangedCalled(), 0);
57 QCOMPARE(model->childChangedCalled(), 5); // we get a generic Matrix as well as a position change...
58 QCOMPARE(model->proposeMoveCalled(), 0);
59
60 shape1->setTransformation(QTransform());
61 QCOMPARE(model->containerChangedCalled(), 0);
62 QCOMPARE(model->childChangedCalled(), 6);
63 QCOMPARE(model->proposeMoveCalled(), 0);
64
65 model->resetCounts();
66 container.setPosition(QPointF(30, 30));
67 QCOMPARE(model->containerChangedCalled(), 1);
68 QCOMPARE(model->childChangedCalled(), 0);
69 QCOMPARE(model->proposeMoveCalled(), 0);
70 }
71
testSetParent()72 void TestShapeContainer::testSetParent()
73 {
74 MockContainerModel *model1 = new MockContainerModel();
75 MockContainer container1(model1);
76 MockContainerModel *model2 = new MockContainerModel();
77 MockContainer container2(model2);
78 MockShape shape;
79 // init test
80 QCOMPARE(model1->shapes().count(), 0);
81 QCOMPARE(model2->shapes().count(), 0);
82
83 shape.setParent(&container1);
84 QCOMPARE(model1->shapes().count(), 1);
85 QCOMPARE(model2->shapes().count(), 0);
86 QCOMPARE(shape.parent(), &container1);
87
88 shape.setParent(&container2);
89 QCOMPARE(model1->shapes().count(), 0);
90 QCOMPARE(container1.shapes().count(), 0);
91 QCOMPARE(model2->shapes().count(), 1);
92 QCOMPARE(container2.shapes().count(), 1);
93 QCOMPARE(shape.parent(), &container2);
94
95 // on destruction shape should have no parent
96 shape.setParent(0);
97 }
98
testSetParent2()99 void TestShapeContainer::testSetParent2()
100 {
101 MockContainerModel *model = new MockContainerModel();
102 MockContainer container(model);
103 MockShape *shape = new MockShape();
104 shape->setParent(&container);
105 QCOMPARE(model->shapes().count(), 1);
106
107 shape->setParent(0);
108 QCOMPARE(model->shapes().count(), 0);
109 }
110
testScaling()111 void TestShapeContainer::testScaling()
112 {
113 KoShape *shape1 = new MockShape();
114 KoShape *shape2 = new MockShape();
115
116 shape1->setSize(QSizeF(10., 10.));
117 shape1->setPosition(QPointF(20., 20.));
118
119 shape2->setSize(QSizeF(30., 10.));
120 shape2->setPosition(QPointF(10., 40.));
121
122 QList<KoShape*> groupedShapes;
123 groupedShapes.append(shape1);
124 groupedShapes.append(shape2);
125
126 KoShapeGroup *group = new KoShapeGroup();
127 KoShapeGroupCommand* groupCommand = KoShapeGroupCommand::createCommand(group, groupedShapes);
128 groupCommand->redo();
129
130 QList<KoShape*> transformShapes;
131 transformShapes.append(groupedShapes);
132
133 QTransform matrix;
134 matrix.scale(0.5, 0.5);
135
136 QList<QTransform> oldTransformations;
137 QList<QTransform> newTransformations;
138 Q_FOREACH (const KoShape* shape, transformShapes) {
139 QTransform oldTransform = shape->transformation();
140 oldTransformations.append(oldTransform);
141 QTransform globalTransform = shape->absoluteTransformation();
142 QTransform localTransform = globalTransform * matrix * globalTransform.inverted();
143 newTransformations.append(localTransform*oldTransform);
144 }
145
146 QList<QPointF> oldPositions;
147 for(int i=0; i< transformShapes.size(); i++) {
148 oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft));
149 }
150
151 KoShapeTransformCommand* transformCommand;
152 transformCommand = new KoShapeTransformCommand(transformShapes, oldTransformations, newTransformations);
153 transformCommand->redo();
154
155 for(int i=0; i< transformShapes.size(); i++) {
156 QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft), oldPositions.at(i)*0.5);
157 }
158
159 transformShapes.takeLast();
160 KoShapeUngroupCommand* ungroupCmd = new KoShapeUngroupCommand(group, transformShapes);
161 ungroupCmd->redo();
162
163 for(int i=0; i< transformShapes.size(); i++) {
164 QCOMPARE(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft), oldPositions.at(i)*0.5);
165 }
166 }
167
testScaling2()168 void TestShapeContainer::testScaling2()
169 {
170 KoShape *shape1 = new MockShape();
171 KoShape *shape2 = new MockShape();
172
173 shape1->setPosition(QPointF(20., 20.));
174 shape1->setSize(QSizeF(10., 10.));
175
176 shape2->setPosition(QPointF(10., 40.));
177 shape2->setSize(QSizeF(30., 10.));
178
179 QList<KoShape*> groupedShapes;
180 groupedShapes.append(shape1);
181 groupedShapes.append(shape2);
182
183 QScopedPointer<KoShapeGroup> group(new KoShapeGroup());
184 QScopedPointer<KoShapeGroupCommand> groupCommand(
185 KoShapeGroupCommand::createCommand(group.data(), groupedShapes));
186 groupCommand->redo();
187
188 QScopedPointer<KoSelection> selection(new KoSelection());
189
190 // the topmost shape is selected, not shape1!
191 selection->select(shape1);
192
193 QList<KoShape*> transformShapes;
194 transformShapes.append(selection->selectedShapes());
195
196 QTransform matrix;
197 matrix.scale(0.5, 0.5);
198
199 QList<QTransform> oldTransformations;
200 QList<QTransform> newTransformations;
201 Q_FOREACH (const KoShape* shape, transformShapes) {
202 QTransform oldTransform = shape->transformation();
203 oldTransformations.append(oldTransform);
204 newTransformations.append(oldTransform*matrix);
205 }
206
207 QList<QPointF> oldPositions;
208 for(int i=0; i< transformShapes.size(); i++) {
209 oldPositions.append(transformShapes.at(i)->absolutePosition(KoFlake::TopLeft));
210 }
211
212 QScopedPointer<KoShapeTransformCommand> transformCommand(
213 new KoShapeTransformCommand(transformShapes, oldTransformations, newTransformations));
214 transformCommand->redo();
215
216 QCOMPARE(selection->boundingRect(), group->boundingRect());
217
218 selection->deselectAll();
219
220 // the topmost shape is selected, not shape1!
221 selection->select(shape1);
222 QCOMPARE(selection->boundingRect(), group->boundingRect());
223 }
224
225 QTEST_MAIN(TestShapeContainer)
226