libs/flake
KoShapeReorderCommand.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoShapeReorderCommand.h"
00021 #include "KoShape.h"
00022 #include "KoShapeManager.h"
00023 #include "KoShapeContainer.h"
00024
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <limits.h>
00028
00029 KoShapeReorderCommand::KoShapeReorderCommand(const QList<KoShape*> &shapes, QList<int> &newIndexes, QUndoCommand *parent)
00030 : QUndoCommand(parent)
00031 , m_shapes(shapes)
00032 , m_newIndexes(newIndexes)
00033 {
00034 Q_ASSERT(m_shapes.count() == m_newIndexes.count());
00035 foreach(KoShape *shape, shapes)
00036 m_previousIndexes.append(shape->zIndex());
00037
00038 setText(i18n("Reorder shapes"));
00039 }
00040
00041 void KoShapeReorderCommand::redo()
00042 {
00043 QUndoCommand::redo();
00044 for (int i = 0; i < m_shapes.count(); i++) {
00045 m_shapes.at(i)->update();
00046 m_shapes.at(i)->setZIndex(m_newIndexes.at(i));
00047 m_shapes.at(i)->update();
00048 }
00049 }
00050
00051 void KoShapeReorderCommand::undo()
00052 {
00053 QUndoCommand::undo();
00054 for (int i = 0; i < m_shapes.count(); i++) {
00055 m_shapes.at(i)->update();
00056 m_shapes.at(i)->setZIndex(m_previousIndexes.at(i));
00057 m_shapes.at(i)->update();
00058 }
00059 }
00060
00061 void KoShapeReorderCommand::prepare(KoShape * s, QMap<KoShape*, QList<KoShape*> > & newOrder, KoShapeManager * manager, MoveShapeType move)
00062 {
00063 KoShapeContainer * parent = s->parent();
00064 QMap<KoShape*, QList<KoShape*> >::iterator it( newOrder.find( parent ) );
00065 if ( it == newOrder.end() ) {
00066 QList<KoShape*> children;
00067 if ( parent != 0 ) {
00068 children = parent->childShapes();
00069 }
00070 else {
00071
00072 children = manager->topLevelShapes();
00073 }
00074 qSort(children.begin(), children.end(), KoShape::compareShapeZIndex);
00075
00076 children.append(0);
00077 children.prepend(0);
00078 it = newOrder.insert(parent, children);
00079 }
00080 QList<KoShape *> & shapes(newOrder[parent]);
00081 int index = shapes.indexOf(s);
00082 if (index != -1) {
00083 shapes.removeAt(index);
00084 switch ( move ) {
00085 case BringToFront:
00086 index = shapes.size();
00087 break;
00088 case RaiseShape:
00089 if (index < shapes.size()) {
00090 ++index;
00091 }
00092 break;
00093 case LowerShape:
00094 if (index > 0) {
00095 --index;
00096 }
00097 break;
00098 case SendToBack:
00099 index = 0;
00100 break;
00101 }
00102 shapes.insert(index,s);
00103 }
00104 }
00105
00106
00107 KoShapeReorderCommand *KoShapeReorderCommand::createCommand(const QList<KoShape*> &shapes, KoShapeManager *manager, MoveShapeType move, QUndoCommand *parent)
00108 {
00109 QList<int> newIndexes;
00110 QList<KoShape*> changedShapes;
00111 QMap<KoShape*, QList<KoShape*> > newOrder;
00112 QList<KoShape*> sortedShapes(shapes);
00113 qSort(sortedShapes.begin(), sortedShapes.end(), KoShape::compareShapeZIndex);
00114 if ( move == BringToFront || move == LowerShape ) {
00115 for ( int i = 0; i < sortedShapes.size(); ++i ) {
00116 prepare(sortedShapes.at(i), newOrder, manager, move);
00117 }
00118 }
00119 else {
00120 for ( int i = sortedShapes.size() - 1; i >= 0; --i ) {
00121 prepare(sortedShapes.at(i), newOrder, manager, move);
00122 }
00123 }
00124
00125
00126 QMap<KoShape*, QList<KoShape*> >::iterator newIt(newOrder.begin());
00127 for (; newIt!= newOrder.end(); ++newIt) {
00128 QList<KoShape*> order( newIt.value() );
00129 order.removeAll(0);
00130 int index = -2^13;
00131 int pos = 0;
00132 for (; pos < order.size(); ++pos) {
00133 if (order[pos]->zIndex() > index) {
00134 index = order[pos]->zIndex();
00135 }
00136 else {
00137 break;
00138 }
00139 }
00140
00141 if (pos == order.size()) {
00142
00143 continue;
00144 }
00145 else if (pos <= order.size() / 2) {
00146
00147 int startIndex = order[pos]->zIndex() - pos;
00148 for (int i = 0; i < pos; ++i) {
00149 changedShapes.append(order[i]);
00150 newIndexes.append(startIndex++);
00151 }
00152 }
00153 else {
00154
00155 for (int i = pos; i < order.size(); ++i) {
00156 changedShapes.append(order[i]);
00157 newIndexes.append(++index);
00158 }
00159 }
00160 }
00161 Q_ASSERT(changedShapes.count() == newIndexes.count());
00162 return changedShapes.isEmpty() ? 0: new KoShapeReorderCommand(changedShapes, newIndexes, parent);
00163 }
|