13#include <klocalizedstring.h>
22 : zIndex(_shape->zIndex()), shape(_shape)
28 return zIndex < rhs.
zIndex;
36 : shapes(s), newIndexes(ni)
49 Q_ASSERT(shapes.count() == newIndexes.count());
50 foreach (
KoShape *shape, shapes)
77 for (
int i = 0; i <
d->
shapes.count(); i++) {
88 for (
int i = 0; i <
d->
shapes.count(); i++) {
99 QMap<KoShape*, QList<KoShape*> >::iterator it(newOrder.find(parent));
100 if (it == newOrder.end()) {
103 children = parent->shapes();
113 it = newOrder.insert(parent, children);
116 int index = shapes.indexOf(s);
118 shapes.removeAt(index);
121 index = shapes.size();
124 if (index < shapes.size()) {
137 shapes.insert(index,s);
151 QMap<KoShape*, QList<KoShape*> > newOrder;
155 for (
int i = 0; i < sortedShapes.size(); ++i) {
156 prepare(sortedShapes.at(i), newOrder, manager, move);
160 for (
int i = sortedShapes.size() - 1; i >= 0; --i) {
161 prepare(sortedShapes.at(i), newOrder, manager, move);
165 QMap<KoShape*, QList<KoShape*> >::iterator newIt(newOrder.begin());
166 for (; newIt != newOrder.end(); ++newIt) {
168 order.removeAll(
nullptr);
171 for (; pos < order.size(); ++pos) {
172 if (order[pos]->zIndex() > index) {
173 index = order[pos]->zIndex();
180 if (pos == order.size()) {
184 else if (pos <= order.size() / 2) {
186 int startIndex = order[pos]->zIndex() - pos;
187 for (
int i = 0; i < pos; ++i) {
188 changedShapes.append(order[i]);
189 newIndexes.append(startIndex++);
194 for (
int i = pos; i < order.size(); ++i) {
195 changedShapes.append(order[i]);
196 newIndexes.append(++index);
200 Q_ASSERT(changedShapes.count() == newIndexes.count());
211 const int originalShapeZIndex = newShape->
zIndex();
212 int newShapeZIndex = originalShapeZIndex;
213 int lastOccupiedShapeZIndex = originalShapeZIndex + 1;
215 Q_FOREACH (
KoShape *shape, shapes) {
216 if (shape == newShape)
continue;
218 const int zIndex = shape->
zIndex();
220 if (newShapeZIndex == originalShapeZIndex) {
221 if (zIndex == originalShapeZIndex) {
222 newShapeZIndex = originalShapeZIndex + 1;
223 lastOccupiedShapeZIndex = newShapeZIndex;
225 reindexedShapes << newShape;
226 reindexedIndexes << newShapeZIndex;
229 if (zIndex >= newShapeZIndex &&
230 zIndex <= lastOccupiedShapeZIndex) {
232 lastOccupiedShapeZIndex = zIndex + 1;
233 reindexedShapes << shape;
234 reindexedIndexes << lastOccupiedShapeZIndex;
239 return !reindexedShapes.isEmpty() ?
new KoShapeReorderCommand(reindexedShapes, reindexedIndexes, parent) : 0;
245 if (shapes.isEmpty())
return shapes;
249 int lastIndex = shapes.begin()->zIndex;
251 auto it = shapes.begin() + 1;
252 while (it != shapes.end()) {
253 if (it->zIndex <= lastIndex) {
254 it->zIndex = lastIndex + 1;
256 lastIndex = it->zIndex;
260 const int overflowSize = shapes.last().zIndex - int(std::numeric_limits<qint16>::max());
262 if (overflowSize > 0) {
263 if (shapes.first().zIndex - overflowSize >
int(std::numeric_limits<qint16>::min())) {
264 for (
auto it = shapes.begin(); it != shapes.end(); ++it) {
265 it->zIndex -= overflowSize;
268 int index = shapes.size() < int(std::numeric_limits<qint16>::max()) ?
270 int(std::numeric_limits<qint16>::max()) - shapes.size();
272 for (
auto it = shapes.begin(); it != shapes.end(); ++it) {
287 for (
auto it = shapes.begin(); it != shapes.end();) {
288 if (it->zIndex == it->shape->zIndex()) {
289 it = shapes.erase(it);
305 Q_FOREACH (
KoShape *shape, shapesBelow) {
309 Q_FOREACH (
KoShape *shape, shapesAbove) {
318 dbg.nospace() <<
"IndexedShape (" << indexedShape.
shape <<
", " << indexedShape.
zIndex <<
")";
static void prepare(KoShape *s, QMap< KoShape *, QList< KoShape * > > &newOrder, KoShapeManager *manager, KoShapeReorderCommand::MoveShapeType move)
QDebug operator<<(QDebug dbg, const KoShapeReorderCommand::IndexedShape &indexedShape)
void setText(const KUndo2MagicString &text)
QList< KoShape * > topLevelShapes() const
QList< KoShape * > shapes
QList< int > previousIndexes
KoShapeReorderCommandPrivate()
KoShapeReorderCommandPrivate(const QList< KoShape * > &s, QList< int > &ni)
This command allows you to change the zIndex of a number of shapes.
void undo() override
revert the actions done in redo
static KoShapeReorderCommand * mergeInShape(QList< KoShape * > shapes, KoShape *newShape, KUndo2Command *parent=0)
mergeInShape adjust zIndex of all the shapes and newShape to avoid collisions between shapes and newS...
KoShapeReorderCommand(const QList< KoShape * > &shapes, QList< int > &newIndexes, KUndo2Command *parent=0)
static QList< KoShapeReorderCommand::IndexedShape > homogenizeZIndexes(QList< IndexedShape > shapes)
static QList< IndexedShape > mergeDownShapes(QList< KoShape * > shapesBelow, QList< KoShape * > shapesAbove)
KoShapeReorderCommandPrivate *const d
void redo() override
redo the command
MoveShapeType
An enum for defining what kind of reordering to use.
@ RaiseShape
raise the selected shape to the level that it is above the shape that is on top of it.
@ SendToBack
Lower the selected shape to be below all other shapes.
@ LowerShape
Lower the selected shape to the level that it is below the shape that is below it.
@ BringToFront
Raise the selected shape to be on top of all shapes.
static QList< KoShapeReorderCommand::IndexedShape > homogenizeZIndexesLazy(QList< IndexedShape > shapes)
static KoShapeReorderCommand * createCommand(const QList< KoShape * > &shapes, KoShapeManager *manager, MoveShapeType move, KUndo2Command *parent=0)
~KoShapeReorderCommand() override
static bool compareShapeZIndex(KoShape *s1, KoShape *s2)
KoShapeContainer * parent() const
static const qint16 maxZIndex
KUndo2MagicString kundo2_i18n(const char *text)
bool operator<(const IndexedShape &rhs) const