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

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002 
00003    Copyright (C) 2006 Thorsten Zachmann <zachmann@kde.org>
00004    Copyright (C) 2006 Thomas Zander <zander@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "KoShapeManager.h"
00023 #include "KoSelection.h"
00024 #include "KoShape.h"
00025 #include "KoCanvasBase.h"
00026 #include "KoShapeContainer.h"
00027 #include "KoShapeBorderModel.h"
00028 #include "KoShapeGroup.h"
00029 #include "KoToolProxy.h"
00030 
00031 #include <QPainter>
00032 
00033 KoShapeManager::KoShapeManager( KoCanvasBase *canvas, const QList<KoShape *> &shapes )
00034 : m_selection( new KoSelection() )
00035 , m_canvas( canvas )
00036 , m_tree( 4, 2 )
00037 {
00038     Q_ASSERT(m_canvas); // not optional.
00039     connect( m_selection, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()) );
00040     setShapes(shapes);
00041     m_selection->addShapeManager( this );
00042 }
00043 
00044 KoShapeManager::KoShapeManager(KoCanvasBase *canvas)
00045 : m_shapes()
00046 , m_selection( new KoSelection() )
00047 , m_canvas( canvas )
00048 , m_tree( 4, 2 )
00049 {
00050     Q_ASSERT(m_canvas); // not optional.
00051     connect( m_selection, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()) );
00052     m_selection->addShapeManager( this );
00053 }
00054 
00055 
00056 KoShapeManager::~KoShapeManager()
00057 {
00058     foreach(KoShape *shape, m_shapes)
00059         shape->removeShapeManager( this );
00060     delete m_selection;
00061 }
00062 
00063 
00064 void KoShapeManager::setShapes( const QList<KoShape *> &shapes )
00065 {
00066     foreach(KoShape *shape, m_shapes)
00067     {
00068         m_aggregate4update.remove( shape );
00069         m_tree.remove( shape );
00070         shape->removeShapeManager( this );
00071     }
00072     m_shapes = shapes;
00073     foreach(KoShape *shape, m_shapes)
00074     {
00075         add( shape );
00076     }
00077 }
00078 
00079 void KoShapeManager::add( KoShape *shape )
00080 {
00081     shape->addShapeManager( this );
00082     m_shapes.append(shape);
00083     if( ! dynamic_cast<KoShapeGroup*>( shape ))
00084     {
00085         QRectF br( shape->boundingRect() );
00086         m_tree.insert( br, shape );
00087     }
00088     shape->repaint();
00089 }
00090 
00091 void KoShapeManager::remove( KoShape *shape )
00092 {
00093     shape->removeShapeManager( this );
00094     m_selection->deselect( shape );
00095     m_aggregate4update.remove( shape );
00096     m_tree.remove( shape );
00097     m_shapes.removeAll(shape);
00098 }
00099 
00100 void KoShapeManager::paint( QPainter &painter, const KoViewConverter &converter, bool forPrint)
00101 {
00102     updateTree();
00103     QPen pen(Qt::NoPen);  // painters by default have a black stroke, lets turn that off.
00104     painter.setPen(pen);
00105     QList<KoShape*> sorterdShapes( m_tree.intersects( converter.viewToDocument( painter.clipRegion().boundingRect() ) ) );
00106     qSort(sorterdShapes.begin(), sorterdShapes.end(), KoShape::compareShapeZIndex);
00107     const QRegion clipRegion = painter.clipRegion();
00108 
00109     foreach ( KoShape * shape, sorterdShapes ) {
00110         if(! shape->isVisible() || ( shape->parent() && ! shape->parent()->isVisible() ) )
00111             continue;
00112         if(shape->parent() != 0 && shape->parent()->childClipped(shape))
00113             continue;
00114         if(painter.hasClipping()) {
00115             QRectF shapeBox = shape->boundingRect();
00116             shapeBox = converter.documentToView(shapeBox);
00117             QRegion shapeRegion = QRegion(shapeBox.toRect());
00118 
00119             if(clipRegion.intersect(shapeRegion).isEmpty())
00120                 continue;
00121         }
00122         painter.save();
00123         painter.setMatrix( shape->transformationMatrix(&converter) * painter.matrix() );
00124 
00125         painter.save();
00126         shape->paint( painter, converter );
00127         painter.restore();
00128         if(shape->border()) {
00129             painter.save();
00130             shape->border()->paintBorder(shape, painter, converter);
00131             painter.restore();
00132         }
00133         if(! forPrint) {
00134             painter.save();
00135             painter.setRenderHint( QPainter::Antialiasing, false );
00136             shape->paintDecorations( painter, converter, m_selection->isSelected(shape) );
00137             painter.restore();
00138         }
00139         painter.restore();  // for the matrix
00140     }
00141 
00142 #if 0
00143     // paint tree
00144     double zx = 0;
00145     double zy = 0;
00146     converter.zoom( &zx, &zy );
00147     painter.save();
00148     painter.scale( zx, zy );
00149     m_tree.paint( painter );
00150     painter.restore();
00151 #endif
00152 
00153     if(! forPrint)
00154         m_selection->paint( painter, converter );
00155 }
00156 
00157 KoShape * KoShapeManager::shapeAt( const QPointF &position, KoFlake::ShapeSelection selection, bool omitHiddenShapes )
00158 {
00159     updateTree();
00160     QList<KoShape*> sorterdShapes( m_tree.contains( position ) );
00161     qSort(sorterdShapes.begin(), sorterdShapes.end(), KoShape::compareShapeZIndex);
00162     KoShape *firstUnselectedShape = 0;
00163     for(int count = sorterdShapes.count()-1; count >= 0; count--) {
00164         KoShape *shape = sorterdShapes.at(count);
00165         if ( omitHiddenShapes && ! shape->isVisible() )
00166             continue;
00167         if ( ! shape->hitTest( position ) )
00168             continue;
00169 
00170         switch ( selection )
00171         {
00172             case KoFlake::ShapeOnTop:
00173                 return shape;
00174             case KoFlake::Selected:
00175                 if ( m_selection->isSelected( shape ) )
00176                     return shape;
00177                 break;
00178             case KoFlake::Unselected:
00179                 if ( ! m_selection->isSelected( shape ) )
00180                     return shape;
00181                 break;
00182             case KoFlake::NextUnselected:
00183                 // we want an unselected shape
00184                 if ( m_selection->isSelected( shape ) )
00185                     continue;
00186                 // memorize the first unselected shape
00187                 if( ! firstUnselectedShape )
00188                     firstUnselectedShape = shape;
00189                 // check if the shape above is selected
00190                 if( count + 1 < sorterdShapes.count() && m_selection->isSelected( sorterdShapes.at(count + 1) ) )
00191                     return shape;
00192                 break;
00193         }
00194     }
00195     // if we want the next unselected below a selected but there was none selected, 
00196     // return the first found unselected shape
00197     if( selection == KoFlake::NextUnselected && firstUnselectedShape )
00198         return firstUnselectedShape;
00199 
00200     if ( m_selection->hitTest( position ) )
00201         return m_selection;
00202 
00203     return 0; // missed everything
00204 }
00205 
00206 QList<KoShape *> KoShapeManager::shapesAt( const QRectF &rect, bool omitHiddenShapes )
00207 {
00208     updateTree();
00209     //TODO check if object is really in the rect and not 
00210     // only the bounding rect of the object.
00211     if( omitHiddenShapes ) {
00212         QList<KoShape*> intersectedShapes( m_tree.intersects( rect ) );
00213         for(int count = intersectedShapes.count()-1; count >= 0; count--) {
00214             KoShape *shape = intersectedShapes.at( count );
00215             if( ! shape->isVisible() )
00216                 intersectedShapes.removeAt( count );
00217         }
00218         return intersectedShapes;
00219     }
00220     else
00221         return m_tree.intersects( rect );
00222 }
00223 
00224 void KoShapeManager::repaint( QRectF &rect, const KoShape *shape, bool selectionHandles )
00225 {
00226     m_canvas->updateCanvas( rect );
00227     if ( selectionHandles && m_selection->isSelected( shape ) )
00228     {
00229         if ( m_canvas->toolProxy() )
00230             m_canvas->toolProxy()->repaintDecorations();
00231     }
00232 }
00233 
00234 void KoShapeManager::updateTree( KoShape * shape )
00235 {
00236     m_aggregate4update.insert( shape );
00237 }
00238 
00239 void KoShapeManager::updateTree()
00240 {
00241     foreach ( KoShape * shape, m_aggregate4update )
00242     {
00243         m_tree.remove( shape );
00244         QRectF br( shape->boundingRect() );
00245         m_tree.insert( br, shape );
00246     }
00247     m_aggregate4update.clear();
00248 }
00249 
00250 #include "KoShapeManager.moc"

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