ShapeMoveStrategy.cpp 4.32 KB
Newer Older
1 2 3
/* This file is part of the KDE project

   Copyright (C) 2006 Thorsten Zachmann <zachmann@kde.org>
Thomas Zander's avatar
Thomas Zander committed
4
   Copyright (C) 2006-2007 Thomas Zander <zander@kde.org>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include "ShapeMoveStrategy.h"
#include "SelectionDecorator.h"

Thomas Zander's avatar
Thomas Zander committed
25 26 27 28 29
#include <KoCanvasBase.h>
#include <KoShapeManager.h>
#include <KoShapeContainer.h>
#include <KoShapeContainerModel.h>
#include <commands/KoShapeMoveCommand.h>
30
#include <KoSnapGuide.h>
31
#include <KoPointerEvent.h>
Thomas Zander's avatar
Thomas Zander committed
32
#include <KoToolBase.h>
33
#include <KoSelection.h>
34
#include <klocalizedstring.h>
35
#include <kis_global.h>
36

37 38
#include "kis_debug.h"

Thomas Zander's avatar
Thomas Zander committed
39
ShapeMoveStrategy::ShapeMoveStrategy(KoToolBase *tool, const QPointF &clicked)
40 41 42
    : KoInteractionStrategy(tool)
    , m_start(clicked)
    , m_canvas(tool->canvas())
43
{
44
    QList<KoShape *> selectedShapes = m_canvas->shapeManager()->selection()->selectedShapes();
45

46
    QRectF boundingRect;
47
    Q_FOREACH (KoShape *shape, selectedShapes) {
48
        if (!shape->isEditable()) {
49
            continue;
50
        }
51 52 53
        m_selectedShapes << shape;
        m_previousPositions << shape->position();
        m_newPositions << shape->position();
54
        boundingRect = boundingRect.united(shape->boundingRect());
55
    }
56 57
    KoSelection *selection = m_canvas->shapeManager()->selection();
    m_initialOffset = selection->absolutePosition(SelectionDecorator::hotPosition()) - m_start;
58
    m_canvas->snapGuide()->setIgnoredShapes(KoShape::linearizeSubtree(selection->selectedShapes()));
59

60
    tool->setStatusText(i18n("Press Shift to hold x- or y-position."));
61 62
}

63
void ShapeMoveStrategy::handleMouseMove(const QPointF &point, Qt::KeyboardModifiers modifiers)
64
{
65
    if (m_selectedShapes.isEmpty()) {
66
        return;
67
    }
68
    QPointF diff = point - m_start;
69

70 71 72
    if (modifiers & Qt::ShiftModifier) {
        // Limit change to one direction only
        diff = snapToClosestAxis(diff);
73
    } else {
74
        QPointF positionToSnap = point + m_initialOffset;
75 76 77
        tool()->canvas()->updateCanvas(tool()->canvas()->snapGuide()->boundingRect());
        QPointF snappedPosition = tool()->canvas()->snapGuide()->snap(positionToSnap, modifiers);
        tool()->canvas()->updateCanvas(tool()->canvas()->snapGuide()->boundingRect());
78 79
        diff = snappedPosition - m_initialOffset - m_start;
    }
80

81 82
    moveSelection(diff);
    m_finalMove = diff;
83 84
}

85
void ShapeMoveStrategy::moveSelection(const QPointF &diff)
86
{
87 88
    Q_ASSERT(m_newPositions.count());

89
    int i = 0;
90
    Q_FOREACH (KoShape *shape, m_selectedShapes) {
91
        QPointF delta = m_previousPositions.at(i) + diff - shape->position();
92
        if (shape->parent()) {
93
            shape->parent()->model()->proposeMove(shape, delta);
94
        }
Thomas Zander's avatar
Thomas Zander committed
95
        tool()->canvas()->clipToDocument(shape, delta);
96
        QPointF newPos(shape->position() + delta);
97 98 99 100 101 102 103 104
        m_newPositions[i] = newPos;
        shape->update();
        shape->setPosition(newPos);
        shape->update();
        i++;
    }
}

105
KUndo2Command *ShapeMoveStrategy::createCommand()
106
{
Thomas Zander's avatar
Thomas Zander committed
107
    tool()->canvas()->snapGuide()->reset();
108
    if (m_finalMove.isNull()) {
109
        return 0;
110
    }
111 112 113
    return new KoShapeMoveCommand(m_selectedShapes, m_previousPositions, m_newPositions);
}

114 115 116 117 118 119
void ShapeMoveStrategy::finishInteraction(Qt::KeyboardModifiers modifiers)
{
    Q_UNUSED(modifiers);
    tool()->canvas()->updateCanvas(tool()->canvas()->snapGuide()->boundingRect());
}

120
void ShapeMoveStrategy::paint(QPainter &painter, const KoViewConverter &converter)
121
{
122
    SelectionDecorator decorator(KoFlake::NoHandle, false, false);
Thomas Zander's avatar
Thomas Zander committed
123
    decorator.setSelection(tool()->canvas()->shapeManager()->selection());
124
    decorator.setHandleRadius(handleRadius());
125 126
    decorator.paint(painter, converter);
}