Krita Source Code Documentation
Loading...
Searching...
No Matches
KoShapeUngroupCommand.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2006 Thomas Zander <zander@kde.org>
3 * SPDX-FileCopyrightText: 2006 Jan Hambrecht <jaham@gmx.net>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
9#include "KoShapeContainer.h"
11
12#include <klocalizedstring.h>
13#include "kis_assert.h"
14
15
17{
19 const QList<KoShape *> &_shapes,
20 const QList<KoShape*> &_topLevelShapes)
21 : container(_container),
22 shapes(_shapes),
23 topLevelShapes(_topLevelShapes)
24 {
25 std::stable_sort(shapes.begin(), shapes.end(), KoShape::compareShapeZIndex);
27 }
28
29
33 QScopedPointer<KUndo2Command> shapesReorderCommand;
34
35};
36
38 const QList<KoShape*> &topLevelShapes, KUndo2Command *parent)
39 : KUndo2Command(parent),
40 m_d(new Private(container, shapes, topLevelShapes))
41{
42 setText(kundo2_i18n("Ungroup shapes"));
43}
44
48
50{
51 using IndexedShape = KoShapeReorderCommand::IndexedShape;
52
53 KoShapeContainer *newParent = m_d->container->parent();
54
55 QList<IndexedShape> indexedSiblings;
56 QList<KoShape*> perspectiveSiblings;
57
58 if (newParent) {
59 perspectiveSiblings = newParent->shapes();
60 std::sort(perspectiveSiblings.begin(), perspectiveSiblings.end(), KoShape::compareShapeZIndex);
61 } else {
62 perspectiveSiblings = m_d->topLevelShapes;
63 }
64
65 Q_FOREACH (KoShape *shape, perspectiveSiblings) {
66 indexedSiblings.append(shape);
67 }
68
69 // find the place where the ungrouped shapes should be inserted
70 // (right on the top of their current container)
71 auto insertIt = std::upper_bound(indexedSiblings.begin(),
72 indexedSiblings.end(),
73 IndexedShape(m_d->container));
74
75 std::copy(m_d->shapes.begin(), m_d->shapes.end(),
76 std::inserter(indexedSiblings, insertIt));
77
78 indexedSiblings = KoShapeReorderCommand::homogenizeZIndexesLazy(indexedSiblings);
79
80 const QTransform ungroupTransform = m_d->container->absoluteTransformation();
81 for (auto it = m_d->shapes.begin(); it != m_d->shapes.end(); ++it) {
82 KoShape *shape = *it;
83 KIS_SAFE_ASSERT_RECOVER(shape->parent() == m_d->container) { continue; }
84
85 shape->setParent(newParent);
86 shape->applyAbsoluteTransformation(ungroupTransform);
87 }
88
89 if (!indexedSiblings.isEmpty()) {
90 m_d->shapesReorderCommand.reset(new KoShapeReorderCommand(indexedSiblings));
91 m_d->shapesReorderCommand->redo();
92 }
93}
94
96{
97 const QTransform groupTransform = m_d->container->absoluteTransformation().inverted();
98 for (auto it = m_d->shapes.begin(); it != m_d->shapes.end(); ++it) {
99 KoShape *shape = *it;
100
101 shape->setParent(m_d->container);
102 shape->applyAbsoluteTransformation(groupTransform);
103 }
104
105 if (m_d->shapesReorderCommand) {
106 m_d->shapesReorderCommand->undo();
107 m_d->shapesReorderCommand.reset();
108 }
109}
void setText(const KUndo2MagicString &text)
QList< KoShape * > shapes() const
This command allows you to change the zIndex of a number of shapes.
static QList< KoShapeReorderCommand::IndexedShape > homogenizeZIndexesLazy(QList< IndexedShape > shapes)
void undo() override
revert the actions done in redo
void redo() override
redo the command
KoShapeUngroupCommand(KoShapeContainer *container, const QList< KoShape * > &shapes, const QList< KoShape * > &topLevelShapes=QList< KoShape * >(), KUndo2Command *parent=0)
const QScopedPointer< Private > m_d
void applyAbsoluteTransformation(const QTransform &matrix)
Definition KoShape.cpp:400
static bool compareShapeZIndex(KoShape *s1, KoShape *s2)
Definition KoShape.cpp:434
KoShapeContainer * parent() const
Definition KoShape.cpp:1039
void setParent(KoShapeContainer *parent)
Definition KoShape.cpp:535
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
KUndo2MagicString kundo2_i18n(const char *text)
Private(KoShapeContainer *_container, const QList< KoShape * > &_shapes, const QList< KoShape * > &_topLevelShapes)
QScopedPointer< KUndo2Command > shapesReorderCommand