00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KoShapeContainer.h"
00021
00022 #include <QPointF>
00023 #include <QPainter>
00024
00025 KoShapeContainer::KoShapeContainer() : KoShape() {
00026 m_children = 0;
00027 }
00028
00029 KoShapeContainer::KoShapeContainer(KoShapeContainerModel *model)
00030 : KoShape()
00031 , m_children(model) {
00032 }
00033
00034 KoShapeContainer::~KoShapeContainer() {
00035 delete m_children;
00036 }
00037
00038 void KoShapeContainer::addChild(KoShape *shape) {
00039 Q_ASSERT(shape);
00040 if(m_children == 0)
00041 m_children = new ChildrenData();
00042 m_children->add(shape);
00043 if( shape->parent() )
00044 shape->parent()->removeChild( shape );
00045 shape->setParent(this);
00046 childCountChanged();
00047 }
00048
00049 void KoShapeContainer::removeChild(KoShape *shape) {
00050 Q_ASSERT(shape);
00051 if(m_children == 0)
00052 return;
00053 m_children->remove(shape);
00054 shape->setParent(0);
00055 childCountChanged();
00056 }
00057
00058 int KoShapeContainer::childCount() const {
00059 if(m_children == 0)
00060 return 0;
00061 return m_children->count();
00062 }
00063
00064 void KoShapeContainer::setClipping(const KoShape *child, bool clipping) {
00065 if(m_children == 0)
00066 return;
00067 m_children->setClipping(child, clipping);
00068 }
00069
00070 void KoShapeContainer::paint(QPainter &painter, const KoViewConverter &converter) {
00071 painter.save();
00072 applyConversion(painter, converter);
00073 paintComponent(painter, converter);
00074 painter.restore();
00075 if(m_children == 0 || m_children->count() == 0)
00076 return;
00077
00078 QList<KoShape*> sorterdObjects = m_children->iterator();
00079 qSort(sorterdObjects.begin(), sorterdObjects.end(), KoShape::compareShapeZIndex);
00080 painter.setMatrix( m_invMatrix * painter.matrix() );
00081 QMatrix myMatrix = transformationMatrix(&converter);
00082 foreach (KoShape *shape, sorterdObjects) {
00083 if(! shape->isVisible())
00084 continue;
00085
00086
00087
00088
00089
00090 if(! childClipped(shape) )
00091 continue;
00092 painter.save();
00093 QRectF clipRect(QPointF(0, 0), size());
00094 clipRect = converter.documentToView(clipRect);
00095
00096 QPolygon clip = myMatrix.mapToPolygon(clipRect.toRect());
00097 clip.translate( (position() - converter.documentToView(position())).toPoint() );
00098 painter.setClipRegion(QRegion(clip));
00099
00100
00101
00102 painter.setMatrix( shape->transformationMatrix(&converter) * painter.matrix() );
00103 shape->paint(painter, converter);
00104 painter.restore();
00105 }
00106 }
00107
00108 void KoShapeContainer::shapeChanged(ChangeType type) {
00109 Q_UNUSED(type);
00110 if(m_children == 0)
00111 return;
00112 m_children->containerChanged(this);
00113 foreach (KoShape *shape, m_children->iterator())
00114 shape->recalcMatrix();
00115 }
00116
00117 bool KoShapeContainer::childClipped(const KoShape *child) const {
00118 if(m_children == 0)
00119 return false;
00120 return m_children->childClipped(child);
00121 }
00122
00123
00124
00125 KoShapeContainer::ChildrenData::ChildrenData() {
00126 }
00127
00128 KoShapeContainer::ChildrenData::~ChildrenData() {
00129 qDeleteAll(m_relations);
00130 }
00131
00132 void KoShapeContainer::ChildrenData::add(KoShape *child) {
00133 Relation *r = new Relation(child);
00134 m_relations.append(r);
00135 }
00136
00137 KoShapeContainer::ChildrenData::Relation* KoShapeContainer::ChildrenData::findRelation(const KoShape *child) const {
00138 foreach(Relation *relation, m_relations) {
00139 if(relation->child() == child)
00140 return relation;
00141 }
00142 return 0;
00143 }
00144
00145 void KoShapeContainer::ChildrenData::setClipping(const KoShape *child, bool clipping) {
00146 Relation *relation = findRelation(child);
00147 if(relation == 0)
00148 return;
00149 if(relation->m_inside == clipping)
00150 return;
00151 relation->m_inside = clipping;
00152 relation->child()->repaint();
00153 relation->child()->recalcMatrix();
00154 relation->child()->repaint();
00155 }
00156
00157 void KoShapeContainer::ChildrenData::remove(KoShape *child) {
00158 Relation *relation = findRelation(child);
00159 if(relation == 0)
00160 return;
00161 m_relations.removeAll(relation);
00162 }
00163
00164 int KoShapeContainer::ChildrenData::count() const {
00165 return m_relations.count();
00166 }
00167
00168 bool KoShapeContainer::ChildrenData::childClipped(const KoShape *child) const {
00169 Relation *relation = findRelation(child);
00170 if(relation == 0)
00171 return false;
00172 return relation->m_inside;
00173 }
00174
00175 QList<KoShape*> KoShapeContainer::ChildrenData::iterator() const {
00176 QList<KoShape*> answer;
00177 foreach (Relation *relation, m_relations)
00178 answer.append(relation->child());
00179 return answer;
00180 }
00181
00182 void KoShapeContainer::ChildrenData::containerChanged(KoShapeContainer *container) {
00183 Q_UNUSED(container);
00184 }
00185
00186 void KoShapeContainer::repaint() const {
00187 KoShape::repaint();
00188 if(m_children)
00189 foreach ( KoShape *shape, m_children->iterator())
00190 shape->repaint();
00191 }
00192
00193 QList<KoShape*> KoShapeContainer::iterator() const {
00194 return m_children->iterator();
00195 }
00196
00197
00198 KoShapeContainer::ChildrenData::Relation::Relation(KoShape *child)
00199 :m_inside(false)
00200 , m_child(child) {
00201 }