Krita Source Code Documentation
Loading...
Searching...
No Matches
KoPathPointRemoveCommand.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2006, 2008 Jan Hambrecht <jaham@gmx.net>
3 * SPDX-FileCopyrightText: 2006, 2007 Thorsten Zachmann <zachmann@kde.org>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
10#include "KoShapeController.h"
11#include "KoPathPoint.h"
12#include <klocalizedstring.h>
13
26
28 const QList<KoPathPointData> &pointDataList,
29 KoShapeController *shapeController,
30 KUndo2Command *parent)
31{
32 /*
33 * We want to decide if we have to:
34 * 1. delete only some points of a path or
35 * 2. delete one or more complete subpath or
36 * 3. delete a complete path
37 */
38
39 QList<KoPathPointData> sortedPointData(pointDataList);
40 std::sort(sortedPointData.begin(), sortedPointData.end());
41
42 KoPathPointData last(0, KoPathPointIndex(-1, -1));
43 // add last at the end so that the point date before last will also be put in
44 // the right places.
45 sortedPointData.append(last);
46
47 QList<KoPathPointData> pointsOfSubpath; // points of current subpath
48 QList<KoPathPointData> subpathsOfPath; // subpaths of current path
49 QList<KoPathPointData> pointsToDelete; // single points to delete
50 QList<KoPathPointData> subpathToDelete; // single subpaths to delete
51 QList<KoShape*> shapesToDelete; // single paths to delete
52
53 last = sortedPointData.first();
54
55 QList<KoPathPointData>::const_iterator it(sortedPointData.constBegin());
56 for (; it != sortedPointData.constEnd(); ++it) {
57 // check if we have come to the next subpath of the same or another path
58 if (last.pathShape != it->pathShape || last.pointIndex.first != it->pointIndex.first) {
59 // check if all points of the last subpath should be deleted
60 if (last.pathShape->subpathPointCount(last.pointIndex.first) == pointsOfSubpath.size()) {
61 // all points of subpath to be deleted -> mark subpath as to be deleted
62 subpathsOfPath.append(pointsOfSubpath.first());
63 } else {
64 // not all points of subpath to be deleted -> add them to the delete point list
65 pointsToDelete += pointsOfSubpath;
66 }
67 // clear the suboath point list
68 pointsOfSubpath.clear();
69 }
70
71 // check if we have come to the next shape
72 if (last.pathShape != it->pathShape) {
73 // check if all subpath of the shape should be deleted
74 if (last.pathShape->subpathCount() == subpathsOfPath.size()) {
75 // all subpaths of path to be deleted -> add shape to delete shape list
76 shapesToDelete.append(last.pathShape);
77 } else {
78 // not all subpaths of path to be deleted -> add them to delete subpath list
79 subpathToDelete += subpathsOfPath;
80 }
81 subpathsOfPath.clear();
82 }
83 if (! it->pathShape)
84 continue;
85 // keep reference to last point
86 last = *it;
87 // add this point to the current subpath point list
88 pointsOfSubpath.append(*it);
89 }
90
91 KUndo2Command *cmd = new KUndo2Command(kundo2_i18n("Remove points"), parent);
92
93 if (pointsToDelete.size() > 0) {
94 new KoPathPointRemoveCommand(pointsToDelete, cmd);
95 }
96
97 //Reverse sort the subpath list to account for shifting indices of the subpaths
98 std::sort(subpathToDelete.begin(), subpathToDelete.end(), std::greater<>{});
99
100 Q_FOREACH (const KoPathPointData & pd, subpathToDelete) {
101 new KoSubpathRemoveCommand(pd.pathShape, pd.pointIndex.first, cmd);
102 }
103 if (shapesToDelete.size() > 0) {
104 shapeController->removeShapes(shapesToDelete, cmd);
105 }
106
107 return cmd;
108}
109
111 KUndo2Command *parent)
112 : KUndo2Command(parent),
114{
115 QList<KoPathPointData>::const_iterator it(pointDataList.begin());
116 for (; it != pointDataList.end(); ++it) {
117 KoPathPoint *point = it->pathShape->pointByIndex(it->pointIndex);
118 if (point) {
119 d->pointDataList.append(*it);
120 d->points.append(0);
121 }
122 }
123 std::sort(d->pointDataList.begin(), d->pointDataList.end());
124 setText(kundo2_i18n("Remove points"));
125}
126
131
133{
135 KoPathShape * lastPathShape = 0;
136 int updateBefore = d->pointDataList.size();
137 for (int i = d->pointDataList.size() - 1; i >= 0; --i) {
138 const KoPathPointData &pd = d->pointDataList.at(i);
139 pd.pathShape->update();
141
142 if (lastPathShape != pd.pathShape) {
143 if (lastPathShape) {
144 QPointF offset = lastPathShape->normalize();
145
146 QTransform matrix;
147 matrix.translate(-offset.x(), -offset.y());
148 for (int j = i + 1; j < updateBefore; ++j) {
149 d->points.at(j)->map(matrix);
150 }
151 lastPathShape->update();
152 updateBefore = i + 1;
153 }
154 lastPathShape = pd.pathShape;
155 }
156 }
157
158 if (lastPathShape) {
159 QPointF offset = lastPathShape->normalize();
160
161 QTransform matrix;
162 matrix.translate(-offset.x(), -offset.y());
163 for (int j = 0; j < updateBefore; ++j) {
164 d->points.at(j)->map(matrix);
165 }
166 lastPathShape->update();
167 }
168
169 d->deletePoints = true;
170}
171
173{
175 KoPathShape * lastPathShape = 0;
176
177 QMap<KoPathShape *, QList<KoPathPointIndex>> pointsMap;
178
179 for (int i = 0; i < d->pointDataList.size(); ++i) {
180 const KoPathPointData &pd = d->pointDataList.at(i);
181 if (lastPathShape && lastPathShape != pd.pathShape) {
182 lastPathShape->normalize();
183 lastPathShape->update();
184 }
186 lastPathShape = pd.pathShape;
187
188 pointsMap[pd.pathShape].append(pd.pointIndex);
189 }
190
191 if (lastPathShape) {
192 lastPathShape->normalize();
193 lastPathShape->update();
194 }
195
196 for (auto it = pointsMap.constBegin(); it != pointsMap.constEnd(); ++it) {
197 it.key()->recommendPointSelectionChange(it.value());
198 }
199
200 d->deletePoints = false;
201}
QPair< int, int > KoPathPointIndex
Definition KoPathShape.h:28
virtual void undo()
void setText(const KUndo2MagicString &text)
virtual void redo()
KUndo2Command(KUndo2Command *parent=0)
Describe a KoPathPoint by a KoPathShape and its indices.
KoPathPointIndex pointIndex
position of the point in the path shape
KoPathShape * pathShape
path shape the path point belongs too
void undo() override
revert the actions done in redo
void redo() override
redo the command
static KUndo2Command * createCommand(const QList< KoPathPointData > &pointDataList, KoShapeController *shapeController, KUndo2Command *parent=0)
Create command for removing points from path shapes.
KoPathPointRemoveCommandPrivate * d
KoPathPointRemoveCommand(const QList< KoPathPointData > &pointDataList, KUndo2Command *parent=0)
Command to remove a points from path shapes.
A KoPathPoint represents a point in a path.
The position of a path point within a path shape.
Definition KoPathShape.h:63
int subpathPointCount(int subpathIndex) const
Returns the number of points in a subpath.
virtual QPointF normalize()
Normalizes the path data.
KoPathPoint * removePoint(const KoPathPointIndex &pointIndex)
Removes a point from the path.
int subpathCount() const
Returns the number of subpaths in the path.
bool insertPoint(KoPathPoint *point, const KoPathPointIndex &pointIndex)
Inserts a new point into the given subpath at the specified position.
KUndo2Command * removeShapes(const QList< KoShape * > &shapes, KUndo2Command *parent=0)
virtual void update() const
Definition KoShape.cpp:529
The undo / redo command for removing a subpath.
KUndo2MagicString kundo2_i18n(const char *text)