File indexing completed on 2024-06-23 04:28:11
0001 /* This file is part of the KDE project 0002 0003 SPDX-FileCopyrightText: 2006 Thorsten Zachmann <zachmann@kde.org> 0004 SPDX-FileCopyrightText: 2006-2007 Thomas Zander <zander@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "ShapeMoveStrategy.h" 0010 #include "SelectionDecorator.h" 0011 0012 #include <KoCanvasBase.h> 0013 #include <KoShapeManager.h> 0014 #include <KoShapeContainer.h> 0015 #include <KoShapeContainerModel.h> 0016 #include <KoCanvasResourceProvider.h> 0017 #include <commands/KoShapeMoveCommand.h> 0018 #include <KoSnapGuide.h> 0019 #include <KoPointerEvent.h> 0020 #include <KoToolBase.h> 0021 #include <KoSelection.h> 0022 #include <klocalizedstring.h> 0023 #include <kis_global.h> 0024 0025 #include "kis_debug.h" 0026 0027 ShapeMoveStrategy::ShapeMoveStrategy(KoToolBase *tool, KoSelection *selection, const QPointF &clicked) 0028 : KoInteractionStrategy(tool) 0029 , m_start(clicked) 0030 , m_canvas(tool->canvas()) 0031 { 0032 QList<KoShape *> selectedShapes = selection->selectedEditableShapes(); 0033 0034 Q_FOREACH (KoShape *shape, selectedShapes) { 0035 m_selectedShapes << shape; 0036 m_previousPositions << shape->absolutePosition(KoFlake::Center); 0037 m_newPositions << shape->absolutePosition(KoFlake::Center); 0038 } 0039 0040 KoFlake::AnchorPosition anchor = 0041 KoFlake::AnchorPosition( 0042 m_canvas->resourceManager()->resource(KoFlake::HotPosition).toInt()); 0043 0044 m_initialOffset = selection->absolutePosition(anchor) - m_start; 0045 m_canvas->snapGuide()->setIgnoredShapes(KoShape::linearizeSubtree(m_selectedShapes)); 0046 0047 tool->setStatusText(i18n("Press Shift to hold x- or y-position.")); 0048 } 0049 0050 void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers) 0051 { 0052 if (m_selectedShapes.isEmpty()) { 0053 return; 0054 } 0055 QPointF diff = point - m_start; 0056 0057 if (modifiers & Qt::ShiftModifier) { 0058 // Limit change to one direction only 0059 diff = snapToClosestAxis(diff); 0060 } else { 0061 QPointF positionToSnap = point + m_initialOffset; 0062 QPointF snappedPosition = tool()->canvas()->snapGuide()->snap(positionToSnap, modifiers); 0063 diff = snappedPosition - m_initialOffset - m_start; 0064 } 0065 0066 moveSelection(diff); 0067 m_finalMove = diff; 0068 } 0069 0070 void ShapeMoveStrategy::moveSelection(const QPointF &diff) 0071 { 0072 Q_ASSERT(m_newPositions.count()); 0073 0074 int i = 0; 0075 Q_FOREACH (KoShape *shape, m_selectedShapes) { 0076 QPointF delta = m_previousPositions.at(i) + diff - shape->absolutePosition(KoFlake::Center); 0077 if (shape->parent()) { 0078 shape->parent()->model()->proposeMove(shape, delta); 0079 } 0080 tool()->canvas()->clipToDocument(shape, delta); 0081 QPointF newPos(shape->absolutePosition(KoFlake::Center) + delta); 0082 m_newPositions[i] = newPos; 0083 0084 const QRectF oldDirtyRect = shape->boundingRect(); 0085 shape->setAbsolutePosition(newPos, KoFlake::Center); 0086 shape->updateAbsolute(oldDirtyRect | oldDirtyRect.translated(delta)); 0087 i++; 0088 } 0089 } 0090 0091 KUndo2Command *ShapeMoveStrategy::createCommand() 0092 { 0093 tool()->canvas()->snapGuide()->reset(); 0094 if (m_finalMove.isNull()) { 0095 return 0; 0096 } 0097 return new KoShapeMoveCommand(m_selectedShapes, m_previousPositions, m_newPositions); 0098 } 0099 0100 void ShapeMoveStrategy::finishInteraction(Qt::KeyboardModifiers modifiers) 0101 { 0102 Q_UNUSED(modifiers); 0103 } 0104 0105 void ShapeMoveStrategy::paint(QPainter &painter, const KoViewConverter &converter) 0106 { 0107 Q_UNUSED(painter); 0108 Q_UNUSED(converter); 0109 }