1 /* This file is part of the KDE project
2 * Copyright (C) 2006 Jan Hambrecht <jaham@gmx.net>
3 * Copyright (C) 2006,2007 Thorsten Zachmann <zachmann@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "KoPathControlPointMoveCommand.h"
22 #include <klocalizedstring.h>
23 #include <math.h>
24
KoPathControlPointMoveCommand(const KoPathPointData & pointData,const QPointF & offset,KoPathPoint::PointType pointType,KUndo2Command * parent)25 KoPathControlPointMoveCommand::KoPathControlPointMoveCommand(
26 const KoPathPointData &pointData,
27 const QPointF &offset,
28 KoPathPoint::PointType pointType,
29 KUndo2Command *parent)
30 : KUndo2Command(parent)
31 , m_pointData(pointData)
32 , m_pointType(pointType)
33 {
34 Q_ASSERT(offset.x() < 1e14 && offset.y() < 1e14);
35 KoPathShape * pathShape = m_pointData.pathShape;
36 KoPathPoint * point = pathShape->pointByIndex(m_pointData.pointIndex);
37 if (point) {
38 m_offset = point->parent()->documentToShape(offset) - point->parent()->documentToShape(QPointF(0, 0));
39 }
40
41 setText(kundo2_i18n("Move control point"));
42 }
43
redo()44 void KoPathControlPointMoveCommand::redo()
45 {
46 KUndo2Command::redo();
47 KoPathShape * pathShape = m_pointData.pathShape;
48 KoPathPoint * point = pathShape->pointByIndex(m_pointData.pointIndex);
49 if (point) {
50 pathShape->update();
51
52 if (m_pointType == KoPathPoint::ControlPoint1) {
53 point->setControlPoint1(point->controlPoint1() + m_offset);
54 if (point->properties() & KoPathPoint::IsSymmetric) {
55 // set the other control point so that it lies on the line between the moved
56 // control point and the point, with the same distance to the point as the moved point
57 point->setControlPoint2(2.0 * point->point() - point->controlPoint1());
58 } else if (point->properties() & KoPathPoint::IsSmooth) {
59 // move the other control point so that it lies on the line through point and control point
60 // keeping its distance to the point
61 QPointF direction = point->point() - point->controlPoint1();
62 direction /= sqrt(direction.x() * direction.x() + direction.y() * direction.y());
63 QPointF distance = point->point() - point->controlPoint2();
64 qreal length = sqrt(distance.x() * distance.x() + distance.y() * distance.y());
65 point->setControlPoint2(point->point() + length * direction);
66 }
67 } else if (m_pointType == KoPathPoint::ControlPoint2) {
68 point->setControlPoint2(point->controlPoint2() + m_offset);
69 if (point->properties() & KoPathPoint::IsSymmetric) {
70 // set the other control point so that it lies on the line between the moved
71 // control point and the point, with the same distance to the point as the moved point
72 point->setControlPoint1(2.0 * point->point() - point->controlPoint2());
73 } else if (point->properties() & KoPathPoint::IsSmooth) {
74 // move the other control point so that it lies on the line through point and control point
75 // keeping its distance to the point
76 QPointF direction = point->point() - point->controlPoint2();
77 direction /= sqrt(direction.x() * direction.x() + direction.y() * direction.y());
78 QPointF distance = point->point() - point->controlPoint1();
79 qreal length = sqrt(distance.x() * distance.x() + distance.y() * distance.y());
80 point->setControlPoint1(point->point() + length * direction);
81 }
82 }
83
84 pathShape->normalize();
85 pathShape->update();
86 }
87 }
88
undo()89 void KoPathControlPointMoveCommand::undo()
90 {
91 KUndo2Command::undo();
92 m_offset *= -1.0;
93 redo();
94 m_offset *= -1.0;
95 }
96
97