libs/flake
KoShapeGroupCommand.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
00021 #include "KoShapeGroupCommand.h"
00022 #include "KoShape.h"
00023 #include "KoShapeGroup.h"
00024 #include "KoShapeContainer.h"
00025
00026 #include <klocale.h>
00027
00028 KoShapeGroupCommand * KoShapeGroupCommand::createCommand(KoShapeGroup *container, QList<KoShape *> shapes, QUndoCommand *parent)
00029 {
00030 QList<KoShape*> orderedShapes(shapes);
00031 qSort(orderedShapes.begin(), orderedShapes.end(), KoShape::compareShapeZIndex);
00032 if (!orderedShapes.isEmpty()) {
00033 KoShape * top = orderedShapes.last();
00034 container->setParent(top->parent());
00035 container->setZIndex(top->zIndex());
00036 }
00037
00038 return new KoShapeGroupCommand(container, orderedShapes, parent);
00039 }
00040
00041
00042 KoShapeGroupCommand::KoShapeGroupCommand(KoShapeContainer *container, QList<KoShape *> shapes, QList<bool> clipped,
00043 QUndoCommand *parent)
00044 : QUndoCommand(parent)
00045 , m_shapes(shapes)
00046 , m_clipped(clipped)
00047 , m_container(container)
00048 {
00049 Q_ASSERT(m_clipped.count() == m_shapes.count());
00050 init();
00051 }
00052
00053 KoShapeGroupCommand::KoShapeGroupCommand(KoShapeGroup *container, QList<KoShape *> shapes, QUndoCommand *parent)
00054 : QUndoCommand(parent)
00055 , m_shapes(shapes)
00056 , m_container(container)
00057 {
00058 for (int i = 0; i < shapes.count(); ++i) {
00059 m_clipped.append(false);
00060 }
00061 init();
00062 }
00063
00064 KoShapeGroupCommand::KoShapeGroupCommand(QUndoCommand *parent)
00065 : QUndoCommand(parent)
00066 {
00067 }
00068
00069 void KoShapeGroupCommand::init()
00070 {
00071 foreach(KoShape* shape, m_shapes) {
00072 m_oldParents.append(shape->parent());
00073 m_oldClipped.append(shape->parent() && shape->parent()->childClipped(shape));
00074 m_oldZIndex.append(shape->zIndex());
00075 }
00076
00077 if (m_container->childShapes().isEmpty()) {
00078 setText(i18n("Group shapes"));
00079 }
00080 else {
00081 setText(i18n("Group shapes"));
00082 }
00083 }
00084
00085 void KoShapeGroupCommand::redo()
00086 {
00087 QUndoCommand::redo();
00088
00089 if (dynamic_cast<KoShapeGroup*>(m_container)) {
00090 QRectF bound = containerBoundingRect();
00091 QPointF oldGroupPosition = m_container->absolutePosition(KoFlake::TopLeftCorner);
00092 m_container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeftCorner);
00093 m_container->setSize(bound.size());
00094
00095 if (m_container->childCount() > 0) {
00096
00097
00098 QPointF positionOffset = oldGroupPosition - bound.topLeft();
00099 foreach(KoShape * child, m_container->childShapes())
00100 child->setAbsolutePosition(child->absolutePosition() + positionOffset);
00101 }
00102 }
00103
00104 QMatrix groupTransform = m_container->absoluteTransformation(0).inverted();
00105
00106 int zIndex=0;
00107 QList<KoShape*> childShapes(m_container->childShapes());
00108 if (!childShapes.isEmpty()) {
00109 qSort(childShapes.begin(), childShapes.end(), KoShape::compareShapeZIndex);
00110 zIndex = childShapes.last()->zIndex();
00111 }
00112
00113 uint shapeCount = m_shapes.count();
00114 for (uint i = 0; i < shapeCount; ++i) {
00115 KoShape * shape = m_shapes[i];
00116 shape->setZIndex(zIndex++);
00117 shape->applyAbsoluteTransformation(groupTransform);
00118 m_container->addChild(shape);
00119 m_container->setClipping(shape, m_clipped[i]);
00120 }
00121 }
00122
00123 void KoShapeGroupCommand::undo()
00124 {
00125 QUndoCommand::undo();
00126
00127 QMatrix ungroupTransform = m_container->absoluteTransformation(0);
00128 for (int i = 0; i < m_shapes.count(); i++) {
00129 KoShape * shape = m_shapes[i];
00130 m_container->removeChild(shape);
00131 if (m_oldParents.at(i)) {
00132 m_oldParents.at(i)->addChild(shape);
00133 m_oldParents.at(i)->setClipping(shape, m_oldClipped.at(i));
00134 }
00135 shape->applyAbsoluteTransformation(ungroupTransform);
00136 shape->setZIndex(m_oldZIndex[i]);
00137 }
00138
00139 if (dynamic_cast<KoShapeGroup*>(m_container)) {
00140 QPointF oldGroupPosition = m_container->absolutePosition(KoFlake::TopLeftCorner);
00141 if (m_container->childCount() > 0) {
00142 bool boundingRectInitialized = false;
00143 QRectF bound;
00144 foreach(KoShape * shape, m_container->childShapes()) {
00145 if (! boundingRectInitialized) {
00146 bound = shape->boundingRect();
00147 boundingRectInitialized = true;
00148 } else
00149 bound = bound.unite(shape->boundingRect());
00150 }
00151
00152
00153 QPointF positionOffset = oldGroupPosition - bound.topLeft();
00154 foreach(KoShape * child, m_container->childShapes())
00155 child->setAbsolutePosition(child->absolutePosition() + positionOffset);
00156
00157 m_container->setAbsolutePosition(bound.topLeft(), KoFlake::TopLeftCorner);
00158 m_container->setSize(bound.size());
00159 }
00160 }
00161 }
00162
00163 QRectF KoShapeGroupCommand::containerBoundingRect()
00164 {
00165 bool boundingRectInitialized = true;
00166 QRectF bound;
00167 if (m_container->childCount() > 0)
00168 bound = m_container->boundingRect();
00169 else
00170 boundingRectInitialized = false;
00171
00172 foreach(KoShape *shape, m_shapes) {
00173 if (boundingRectInitialized)
00174 bound = bound.unite(shape->boundingRect());
00175 else {
00176 bound = shape->boundingRect();
00177 boundingRectInitialized = true;
00178 }
00179 }
00180 return bound;
00181 }
|