File indexing completed on 2025-02-02 04:14:48

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2006, 2009 Jan Hambrecht <jaham@gmx.net>
0003  * SPDX-FileCopyrightText: 2006, 2007 Thorsten Zachmann <zachmann@kde.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "KoPathSegmentTypeCommand.h"
0009 
0010 #include <KoPathSegment.h>
0011 #include <klocalizedstring.h>
0012 
0013 KoPathSegmentTypeCommand::KoPathSegmentTypeCommand(const KoPathPointData & pointData, SegmentType segmentType, KUndo2Command *parent)
0014 : KUndo2Command(parent)
0015 , m_segmentType(segmentType)
0016 {
0017     QList<KoPathPointData> pointDataList;
0018     pointDataList.append(pointData);
0019     initialize(pointDataList);
0020 }
0021 
0022 KoPathSegmentTypeCommand::KoPathSegmentTypeCommand(const QList<KoPathPointData> & pointDataList, SegmentType segmentType,
0023         KUndo2Command *parent)
0024         : KUndo2Command(parent)
0025         , m_segmentType(segmentType)
0026 {
0027     initialize(pointDataList);
0028 }
0029 
0030 KoPathSegmentTypeCommand::~KoPathSegmentTypeCommand()
0031 {
0032 }
0033 
0034 void KoPathSegmentTypeCommand::redo()
0035 {
0036     KUndo2Command::redo();
0037     QList<KoPathPointData>::const_iterator it(m_pointDataList.constBegin());
0038     for (; it != m_pointDataList.constEnd(); ++it) {
0039         KoPathShape * pathShape = it->pathShape;
0040         pathShape->update();
0041 
0042         KoPathSegment segment = pathShape->segmentByIndex(it->pointIndex);
0043 
0044         if (m_segmentType == Curve) {
0045             // we change type to curve -> set control point positions
0046             QPointF pointDiff = segment.second()->point() - segment.first()->point();
0047             segment.first()->setControlPoint2(segment.first()->point() + pointDiff / 3.0);
0048             segment.second()->setControlPoint1(segment.first()->point() + pointDiff * 2.0 / 3.0);
0049         } else {
0050             // we are changing type to line -> remove control points
0051             segment.first()->removeControlPoint2();
0052             segment.second()->removeControlPoint1();
0053         }
0054 
0055         pathShape->normalize();
0056         pathShape->update();
0057     }
0058 }
0059 
0060 void KoPathSegmentTypeCommand::undo()
0061 {
0062     KUndo2Command::undo();
0063     for (int i = 0; i < m_pointDataList.size(); ++i) {
0064         const KoPathPointData & pd = m_pointDataList.at(i);
0065         pd.pathShape->update();
0066         KoPathSegment segment = pd.pathShape->segmentByIndex(pd.pointIndex);
0067         const SegmentTypeData segmentData(m_segmentData.at(i));
0068 
0069         if (m_segmentType == Line) {
0070             // change type back to curve -> reactivate control points and their positions
0071             segment.first()->setControlPoint2(pd.pathShape->documentToShape(segmentData.m_controlPoint2));
0072             segment.second()->setControlPoint1(pd.pathShape->documentToShape(segmentData.m_controlPoint1));
0073         } else {
0074             // change back to line -> remove control points
0075             segment.first()->removeControlPoint2();
0076             segment.second()->removeControlPoint1();
0077         }
0078 
0079         segment.first()->setProperties(segmentData.m_properties2);
0080         segment.second()->setProperties(segmentData.m_properties1);
0081 
0082         pd.pathShape->normalize();
0083         pd.pathShape->update();
0084     }
0085 }
0086 
0087 void KoPathSegmentTypeCommand::initialize(const QList<KoPathPointData> & pointDataList)
0088 {
0089     QList<KoPathPointData>::const_iterator it(pointDataList.begin());
0090     for (; it != pointDataList.end(); ++it) {
0091         KoPathSegment segment = it->pathShape->segmentByIndex(it->pointIndex);
0092         if (segment.isValid()) {
0093             if (m_segmentType == Curve) {
0094                 // don not change segment if already a curve
0095                 if (segment.first()->activeControlPoint2() || segment.second()->activeControlPoint1())
0096                     continue;
0097             } else {
0098                 // do not change segment if already a line
0099                 if (! segment.first()->activeControlPoint2() && ! segment.second()->activeControlPoint1())
0100                     continue;
0101             }
0102 
0103             m_pointDataList.append(*it);
0104             SegmentTypeData segmentData;
0105 
0106             KoPathShape * pathShape = segment.first()->parent();
0107 
0108             // we are changing a curve to a line -> save control point positions
0109             if (m_segmentType == Line) {
0110                 segmentData.m_controlPoint2 = pathShape->shapeToDocument(segment.first()->controlPoint2());
0111                 segmentData.m_controlPoint1 = pathShape->shapeToDocument(segment.second()->controlPoint1());
0112             }
0113             // save point properties
0114             segmentData.m_properties2 = segment.first()->properties();
0115             segmentData.m_properties1 = segment.second()->properties();
0116             m_segmentData.append(segmentData);
0117         }
0118     }
0119 
0120     if (m_segmentType == Curve) {
0121         setText(kundo2_i18n("Change segments to curves"));
0122     } else {
0123         setText(kundo2_i18n("Change segments to lines"));
0124     }
0125 }