File indexing completed on 2024-06-23 04:28:11
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2006-2007 Thomas Zander <zander@kde.org> 0003 * SPDX-FileCopyrightText: 2007-2008 Jan Hambrecht <jaham@gmx.net> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "ShapeRotateStrategy.h" 0009 #include "SelectionDecorator.h" 0010 0011 #include <KoToolBase.h> 0012 #include <KoCanvasBase.h> 0013 #include <KoSelection.h> 0014 #include <KoPointerEvent.h> 0015 #include <KoShapeManager.h> 0016 #include <KoCanvasResourceProvider.h> 0017 #include <commands/KoShapeTransformCommand.h> 0018 0019 #include <QPointF> 0020 #include <math.h> 0021 #include <klocalizedstring.h> 0022 0023 ShapeRotateStrategy::ShapeRotateStrategy(KoToolBase *tool, KoSelection *selection, const QPointF &clicked, Qt::MouseButtons buttons) 0024 : KoInteractionStrategy(tool) 0025 , m_start(clicked) 0026 { 0027 /** 0028 * The outline of the selection should look as if it is also rotated, so we 0029 * add it to the transformed shapes list. 0030 */ 0031 m_transformedShapesAndSelection = selection->selectedEditableShapes(); 0032 m_transformedShapesAndSelection << selection; 0033 0034 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) { 0035 m_oldTransforms << shape->transformation(); 0036 } 0037 0038 KoFlake::AnchorPosition anchor = !(buttons & Qt::RightButton) ? 0039 KoFlake::Center : 0040 KoFlake::AnchorPosition(tool->canvas()->resourceManager()->resource(KoFlake::HotPosition).toInt()); 0041 0042 m_rotationCenter = selection->absolutePosition(anchor); 0043 0044 tool->setStatusText(i18n("Press ALT to rotate in 45 degree steps.")); 0045 } 0046 0047 void ShapeRotateStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers) 0048 { 0049 qreal angle = atan2(point.y() - m_rotationCenter.y(), point.x() - m_rotationCenter.x()) - 0050 atan2(m_start.y() - m_rotationCenter.y(), m_start.x() - m_rotationCenter.x()); 0051 angle = angle / M_PI * 180; // convert to degrees. 0052 if (modifiers & (Qt::AltModifier | Qt::ControlModifier)) { 0053 // limit to 45 degree angles 0054 qreal modula = qAbs(angle); 0055 while (modula > 45.0) { 0056 modula -= 45.0; 0057 } 0058 if (modula > 22.5) { 0059 modula -= 45.0; 0060 } 0061 angle += (angle > 0 ? -1 : 1) * modula; 0062 } 0063 0064 rotateBy(angle); 0065 } 0066 0067 void ShapeRotateStrategy::rotateBy(qreal angle) 0068 { 0069 QTransform matrix; 0070 matrix.translate(m_rotationCenter.x(), m_rotationCenter.y()); 0071 matrix.rotate(angle); 0072 matrix.translate(-m_rotationCenter.x(), -m_rotationCenter.y()); 0073 0074 QTransform applyMatrix = matrix * m_rotationMatrix.inverted(); 0075 m_rotationMatrix = matrix; 0076 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) { 0077 QRectF dirtyRect = shape->boundingRect(); 0078 shape->applyAbsoluteTransformation(applyMatrix); 0079 dirtyRect |= shape->boundingRect(); 0080 shape->updateAbsolute(dirtyRect); 0081 } 0082 } 0083 0084 void ShapeRotateStrategy::paint(QPainter &painter, const KoViewConverter &converter) 0085 { 0086 // paint the rotation center 0087 painter.setPen(QPen(Qt::red)); 0088 painter.setBrush(QBrush(Qt::red)); 0089 painter.setRenderHint(QPainter::Antialiasing, true); 0090 QRectF circle(0, 0, handleRadius(), handleRadius()); 0091 circle.moveCenter(converter.documentToView(m_rotationCenter)); 0092 painter.drawEllipse(circle); 0093 } 0094 0095 KUndo2Command *ShapeRotateStrategy::createCommand() 0096 { 0097 QList<QTransform> newTransforms; 0098 Q_FOREACH (KoShape *shape, m_transformedShapesAndSelection) { 0099 newTransforms << shape->transformation(); 0100 } 0101 0102 KoShapeTransformCommand *cmd = new KoShapeTransformCommand(m_transformedShapesAndSelection, m_oldTransforms, newTransforms); 0103 cmd->setText(kundo2_i18n("Rotate")); 0104 return cmd; 0105 }