libs/flake
KoPathPointMergeCommand.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "KoPathPointMergeCommand.h"
00022 #include "KoPathPoint.h"
00023 #include "KoPathPointData.h"
00024 #include "KoPathShape.h"
00025 #include <KLocale>
00026 #include <QPointF>
00027
00028 class KoPathPointMergeCommand::Private
00029 {
00030 public:
00031 Private(const KoPathPointData &pointData1, const KoPathPointData &pointData2)
00032 : pathShape(pointData1.pathShape)
00033 , endPoint(pointData1.pointIndex)
00034 , startPoint(pointData2.pointIndex)
00035 , splitIndex(KoPathPointIndex(-1, -1))
00036 , removedPoint(0)
00037 , reverse(ReverseNone)
00038 {
00039 }
00040
00041 ~Private()
00042 {
00043 delete removedPoint;
00044 }
00045
00046 KoPathPoint * mergePoints( KoPathPoint * p1, KoPathPoint * p2)
00047 {
00048 QPointF mergePosition = 0.5 * (p1->point() + p2->point());
00049 QPointF mergeControlPoint1 = mergePosition + (p1->controlPoint1() - p1->point());
00050 QPointF mergeControlPoint2 = mergePosition + (p2->controlPoint2() - p2->point());
00051
00052
00053 p1->setPoint( mergePosition );
00054 if (p1->activeControlPoint1()) {
00055 p1->setControlPoint1(mergeControlPoint1);
00056 }
00057 if (p2->activeControlPoint2()) {
00058 p1->setControlPoint2(mergeControlPoint2);
00059 }
00060
00061
00062 KoPathPointIndex removeIndex = pathShape->pathPointIndex(p2);
00063 return pathShape->removePoint(removeIndex);
00064 }
00065
00066 void resetPoints( KoPathPointIndex index1, KoPathPointIndex index2 )
00067 {
00068 KoPathPoint * p1 = pathShape->pointByIndex(index1);
00069 KoPathPoint * p2 = pathShape->pointByIndex(index2);
00070 p1->setPoint(pathShape->documentToShape(oldNodePoint1));
00071 p2->setPoint(pathShape->documentToShape(oldNodePoint2));
00072 if (p1->activeControlPoint1()) {
00073 p1->setControlPoint1(pathShape->documentToShape(oldControlPoint1));
00074 }
00075 if (p2->activeControlPoint2()) {
00076 p2->setControlPoint2(pathShape->documentToShape(oldControlPoint2));
00077 }
00078 }
00079
00080 KoPathShape * pathShape;
00081 KoPathPointIndex endPoint;
00082 KoPathPointIndex startPoint;
00083 KoPathPointIndex splitIndex;
00084
00085
00086 QPointF oldNodePoint1;
00087 QPointF oldControlPoint1;
00088 QPointF oldNodePoint2;
00089 QPointF oldControlPoint2;
00090
00091 KoPathPoint * removedPoint;
00092
00093 enum Reverse {
00094 ReverseNone = 0,
00095 ReverseFirst = 1,
00096 ReverseSecond = 2
00097 };
00098 int reverse;
00099 };
00100
00107 KoPathPointMergeCommand::KoPathPointMergeCommand(const KoPathPointData &pointData1, const KoPathPointData &pointData2, QUndoCommand *parent)
00108 : QUndoCommand(parent), d(new Private(pointData1, pointData2))
00109 {
00110 Q_ASSERT(pointData1.pathShape == pointData2.pathShape);
00111 Q_ASSERT(d->pathShape);
00112 Q_ASSERT(!d->pathShape->isClosedSubpath(d->endPoint.first));
00113 Q_ASSERT(d->endPoint.second == 0 ||
00114 d->endPoint.second == d->pathShape->pointCountSubpath(d->endPoint.first) - 1);
00115 Q_ASSERT(!d->pathShape->isClosedSubpath(d->startPoint.first));
00116 Q_ASSERT(d->startPoint.second == 0 ||
00117 d->startPoint.second == d->pathShape->pointCountSubpath(d->startPoint.first) - 1);
00118
00119
00120 if (d->endPoint.first != d->startPoint.first) {
00121
00122 if (d->startPoint < d->endPoint)
00123 qSwap(d->endPoint, d->startPoint);
00124
00125 if (d->endPoint.second == 0 && d->pathShape->pointCountSubpath(d->endPoint.first) > 1)
00126 d->reverse |= Private::ReverseFirst;
00127
00128 if (d->startPoint.second != 0 && d->pathShape->pointCountSubpath(d->startPoint.first) > 1)
00129 d->reverse |= Private::ReverseSecond;
00130 } else {
00131 Q_ASSERT(d->endPoint.second != d->startPoint.second);
00132 if (d->endPoint < d->startPoint)
00133 qSwap(d->endPoint, d->startPoint);
00134 }
00135
00136 KoPathPoint * p1 = d->pathShape->pointByIndex(d->endPoint);
00137 KoPathPoint * p2 = d->pathShape->pointByIndex(d->startPoint);
00138
00139 d->oldNodePoint1 = d->pathShape->shapeToDocument(p1->point());
00140 if (d->reverse & Private::ReverseFirst) {
00141 d->oldControlPoint1 = d->pathShape->shapeToDocument(p1->controlPoint2());
00142 } else {
00143 d->oldControlPoint1 = d->pathShape->shapeToDocument(p1->controlPoint1());
00144 }
00145 d->oldNodePoint2 = d->pathShape->shapeToDocument(p2->point());
00146 if (d->reverse & Private::ReverseSecond) {
00147 d->oldControlPoint2 = d->pathShape->shapeToDocument(p2->controlPoint1());
00148 } else {
00149 d->oldControlPoint2 = d->pathShape->shapeToDocument(p2->controlPoint2());
00150 }
00151
00152 setText(i18n("Merge points"));
00153 }
00154
00155 KoPathPointMergeCommand::~KoPathPointMergeCommand()
00156 {
00157 delete d;
00158 }
00159
00160 void KoPathPointMergeCommand::redo()
00161 {
00162 QUndoCommand::redo();
00163
00164 if (d->removedPoint)
00165 return;
00166
00167 d->pathShape->update();
00168
00169 KoPathPoint * endPoint = d->pathShape->pointByIndex(d->endPoint);
00170 KoPathPoint * startPoint = d->pathShape->pointByIndex(d->startPoint);
00171
00172
00173 if (d->endPoint.first == d->startPoint.first) {
00174
00175 d->removedPoint = d->mergePoints(endPoint, startPoint);
00176
00177 endPoint->setProperty(KoPathPoint::CloseSubpath);
00178
00179 KoPathPointIndex newStartIndex(d->startPoint.first,0);
00180 d->pathShape->pointByIndex(newStartIndex)->setProperty(KoPathPoint::CloseSubpath);
00181 } else {
00182
00183 if (d->reverse & Private::ReverseFirst) {
00184 d->pathShape->reverseSubpath(d->endPoint.first);
00185 }
00186 if (d->reverse & Private::ReverseSecond) {
00187 d->pathShape->reverseSubpath(d->startPoint.first);
00188 }
00189
00190 d->pathShape->moveSubpath(d->startPoint.first, d->endPoint.first + 1);
00191 d->splitIndex = d->pathShape->pathPointIndex(endPoint);
00192
00193 d->pathShape->join(d->endPoint.first);
00194
00195 d->removedPoint = d->mergePoints(endPoint, startPoint);
00196 }
00197
00198 d->pathShape->normalize();
00199 d->pathShape->update();
00200 }
00201
00202 void KoPathPointMergeCommand::undo()
00203 {
00204 QUndoCommand::undo();
00205
00206 if (!d->removedPoint)
00207 return;
00208
00209 d->pathShape->update();
00210
00211
00212 if (d->endPoint.first == d->startPoint.first) {
00213
00214 d->pathShape->openSubpath(d->startPoint);
00215
00216 d->pathShape->insertPoint(d->removedPoint, d->startPoint);
00217
00218 d->resetPoints(d->endPoint, d->startPoint);
00219 } else {
00220
00221 d->pathShape->breakAfter(d->splitIndex);
00222
00223 d->pathShape->insertPoint(d->removedPoint, KoPathPointIndex(d->splitIndex.first+1,0));
00224
00225 d->resetPoints(d->splitIndex, KoPathPointIndex(d->splitIndex.first+1,0));
00226
00227 d->pathShape->moveSubpath(d->splitIndex.first+1, d->startPoint.first);
00228
00229 if (d->reverse & Private::ReverseFirst) {
00230 d->pathShape->reverseSubpath(d->endPoint.first);
00231 }
00232 if (d->reverse & Private::ReverseSecond) {
00233 d->pathShape->reverseSubpath(d->startPoint.first);
00234 }
00235 }
00236
00237 d->pathShape->normalize();
00238 d->pathShape->update();
00239
00240
00241 d->removedPoint = 0;
00242 }
|