00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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);
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);
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);
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();
00140 }
00141
00142 #if 0
00143
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
00184 if ( m_selection->isSelected( shape ) )
00185 continue;
00186
00187 if( ! firstUnselectedShape )
00188 firstUnselectedShape = shape;
00189
00190 if( count + 1 < sorterdShapes.count() && m_selection->isSelected( sorterdShapes.at(count + 1) ) )
00191 return shape;
00192 break;
00193 }
00194 }
00195
00196
00197 if( selection == KoFlake::NextUnselected && firstUnselectedShape )
00198 return firstUnselectedShape;
00199
00200 if ( m_selection->hitTest( position ) )
00201 return m_selection;
00202
00203 return 0;
00204 }
00205
00206 QList<KoShape *> KoShapeManager::shapesAt( const QRectF &rect, bool omitHiddenShapes )
00207 {
00208 updateTree();
00209
00210
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"