F:/KPlato/koffice/libs/flake/KoShapeContainer.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2006 Thomas Zander <zander@kde.org>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
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         // TODO this is not perfect yet..
00086 //           QRectF clipRect(QPoint(0,0), size()); // old
00087 //           QPolygon clip = (myMatrix * shapeMatrix.inverted()).mapToPolygon(clipRect.toRect());
00088 //           painter.setClipRegion(QRegion(clip));
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 //kDebug() << "rect: " << position() << endl;
00100 //kDebug() << "polygon: " << clip.boundingRect() << endl;
00101         //painter.drawPolygon(clip);
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) // throw exception??
00119         return false;
00120     return m_children->childClipped(child);
00121 }
00122 
00123 
00124 // ##  inner class ChildrenData
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) // throw exception?
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) // throw exception?
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 // ## inner class KoShapeContainerModel::Relation
00198 KoShapeContainer::ChildrenData::Relation::Relation(KoShape *child)
00199 :m_inside(false)
00200 , m_child(child) {
00201 }

Généré le Wed Nov 22 23:40:59 2006 pour KPlato par  doxygen 1.5.1-p1