kdganttgraphicsscene.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002  ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB.  All rights reserved.
00003  **
00004  ** This file is part of the KD Gantt library.
00005  **
00006  ** This file may be distributed and/or modified under the terms of the
00007  ** GNU General Public License version 2 as published by the Free Software
00008  ** Foundation and appearing in the file LICENSE.GPL included in the
00009  ** packaging of this file.
00010  **
00011  ** Licensees holding valid commercial KD Gantt licenses may use this file in
00012  ** accordance with the KD Gantt Commercial License Agreement provided with
00013  ** the Software.
00014  **
00015  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017  **
00018  ** See http://www.kdab.net/kdgantt for
00019  **   information about KD Gantt Commercial License Agreements.
00020  **
00021  ** Contact info@kdab.net if any conditions of this
00022  ** licensing are not clear to you.
00023  **
00024  **********************************************************************/
00025 #include "kdganttgraphicsscene.h"
00026 #include "kdganttgraphicsscene_p.h"
00027 #include "kdganttgraphicsitem.h"
00028 #include "kdganttconstraint.h"
00029 #include "kdganttconstraintgraphicsitem.h"
00030 #include "kdganttitemdelegate.h"
00031 #include "kdganttabstractrowcontroller.h"
00032 #include "kdganttdatetimegrid.h"
00033 #include "kdganttsummaryhandlingproxymodel.h"
00034 
00035 #include <QApplication>
00036 #include <QGraphicsSceneHelpEvent>
00037 #include <QPainter>
00038 #include <QPrinter>
00039 #include <QTextDocument>
00040 #include <QToolTip>
00041 #include <QSet>
00042 
00043 #include <QDebug>
00044 
00045 #include <functional>
00046 #include <algorithm>
00047 #include <cassert>
00048 
00049 /* Older Qt dont have this macro, so define it... */
00050 #ifndef QT_VERSION_CHECK
00051 #  define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
00052 #endif
00053 
00058 using namespace KDGantt;
00059 
00060 GraphicsScene::Private::Private( GraphicsScene* _q )
00061     : q( _q ),
00062       dragSource( 0 ),
00063       itemDelegate( new ItemDelegate( _q ) ),
00064       rowController( 0 ),
00065       grid( &default_grid ),
00066       readOnly( false ),
00067       isPrinting( false ),
00068       summaryHandlingModel( new SummaryHandlingProxyModel( _q ) ),
00069       selectionModel( 0 )
00070 {
00071     default_grid.setStartDateTime( QDateTime::currentDateTime().addDays( -1 ) );
00072 }
00073 
00074 void GraphicsScene::Private::resetConstraintItems()
00075 {
00076     q->clearConstraintItems();
00077     if ( constraintModel.isNull() ) return;
00078     QList<Constraint> clst = constraintModel->constraints();
00079     Q_FOREACH( Constraint c, clst ) {
00080         createConstraintItem( c );
00081     }
00082     q->updateItems();
00083 }
00084 
00085 void GraphicsScene::Private::createConstraintItem( const Constraint& c )
00086 {
00087     GraphicsItem* sitem = q->findItem( summaryHandlingModel->mapFromSource( c.startIndex() ) );
00088     GraphicsItem* eitem = q->findItem( summaryHandlingModel->mapFromSource( c.endIndex() ) );
00089 
00090     if ( sitem && eitem ) {
00091         ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
00092         sitem->addStartConstraint( citem );
00093         eitem->addEndConstraint( citem );
00094         q->addItem( citem );
00095     }
00096 
00097 
00098 
00099     //q->insertConstraintItem( c, citem );
00100 }
00101 
00102 // Delete the constraint item, and clean up pointers in the start- and end item
00103 void GraphicsScene::Private::deleteConstraintItem( ConstraintGraphicsItem *citem )
00104 {
00105     //qDebug()<<"GraphicsScene::Private::deleteConstraintItem citem="<<(void*)citem;
00106     if ( citem == 0 ) {
00107         return;
00108     }
00109     Constraint c = citem->constraint();
00110     GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), 0 );
00111     if ( item ) {
00112         //qDebug()<<"GraphicsScene::Private::deleteConstraintItem startConstraints"<<item<<(void*)citem;
00113         item->removeStartConstraint( citem );
00114     } //else qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<c.startIndex()<<"start item not found";
00115     item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), 0 );
00116     if ( item ) {
00117         //qDebug()<<"GraphicsScene::Private::deleteConstraintItem endConstraints"<<item<<(void*)citem;
00118         item->removeEndConstraint( citem );
00119     } //else qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<c.endIndex()<<"end item not found";
00120     //qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<citem<<"deleted";
00121     delete citem;
00122 }
00123 
00124 void GraphicsScene::Private::deleteConstraintItem( const Constraint& c )
00125 {
00126     //qDebug()<<"GraphicsScene::Private::deleteConstraintItem c="<<c;
00127     deleteConstraintItem( findConstraintItem( c ) );
00128 }
00129 
00130 ConstraintGraphicsItem* GraphicsScene::Private::findConstraintItem( const Constraint& c ) const
00131 {
00132     GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), 0 );
00133     if ( item ) {
00134         QList<ConstraintGraphicsItem*> clst = item->startConstraints();
00135         QList<ConstraintGraphicsItem*>::iterator it = clst.begin();
00136         //qDebug()<<"GraphicsScene::Private::findConstraintItem start:"<<c<<item<<clst;
00137         for( ; it != clst.end() ; ++it )
00138             if ((*it)->constraint() == c )
00139                 break;
00140         if (  it != clst.end() ) {
00141             return *it;
00142         }
00143     }
00144     item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), 0 );
00145     if ( item ) {
00146         QList<ConstraintGraphicsItem*> clst = item->endConstraints();
00147         QList<ConstraintGraphicsItem*>::iterator it = clst.begin();
00148         //qDebug()<<"GraphicsScene::Private::findConstraintItem end:"<<c<<item<<clst;
00149         for( ; it != clst.end() ; ++it )
00150             if ((*it)->constraint() == c )
00151                 break;
00152         if (  it != clst.end() ) {
00153             return *it;
00154         }
00155     }
00156     //qDebug()<<"GraphicsScene::Private::findConstraintItem No item or constraintitem"<<c;
00157     return 0;
00158 }
00159 
00160 GraphicsScene::GraphicsScene( QObject* parent )
00161     : QGraphicsScene( parent ), _d( new Private( this ) )
00162 {
00163     init();
00164 }
00165 
00166 GraphicsScene::~GraphicsScene()
00167 {
00168     clearConstraintItems();
00169     clearItems();
00170 }
00171 
00172 #define d d_func()
00173 
00174 void GraphicsScene::init()
00175 {
00176     setItemIndexMethod( QGraphicsScene::NoIndex );
00177     setConstraintModel( new ConstraintModel( this ) );
00178     connect( d->grid, SIGNAL( gridChanged() ), this, SLOT( slotGridChanged() ) );
00179 }
00180 
00181 /* NOTE: The delegate should really be a property
00182  * of the view, but that doesn't really fit at
00183  * this time
00184  */
00185 void GraphicsScene::setItemDelegate( ItemDelegate* delegate )
00186 {
00187     if ( !d->itemDelegate.isNull() && d->itemDelegate->parent()==this ) delete d->itemDelegate;
00188     d->itemDelegate = delegate;
00189     update();
00190 }
00191 
00192 ItemDelegate* GraphicsScene::itemDelegate() const
00193 {
00194     return d->itemDelegate;
00195 }
00196 
00197 QAbstractItemModel* GraphicsScene::model() const
00198 {
00199     assert(!d->summaryHandlingModel.isNull());
00200     return d->summaryHandlingModel->sourceModel();
00201 }
00202 
00203 void GraphicsScene::setModel( QAbstractItemModel* model )
00204 {
00205     assert(!d->summaryHandlingModel.isNull());
00206     d->summaryHandlingModel->setSourceModel(model);
00207     d->grid->setModel( d->summaryHandlingModel );
00208     setSelectionModel( new QItemSelectionModel( model, this ) );
00209 }
00210 
00211 QAbstractProxyModel* GraphicsScene::summaryHandlingModel() const
00212 {
00213     return d->summaryHandlingModel;
00214 }
00215 
00216 void GraphicsScene::setSummaryHandlingModel( QAbstractProxyModel* proxyModel )
00217 {
00218     proxyModel->setSourceModel( model() );
00219     d->summaryHandlingModel = proxyModel;
00220 }
00221 
00222 void GraphicsScene::setRootIndex( const QModelIndex& idx )
00223 {
00224     d->grid->setRootIndex( idx );
00225 }
00226 
00227 QModelIndex GraphicsScene::rootIndex() const
00228 {
00229     return d->grid->rootIndex();
00230 }
00231 
00232 ConstraintModel* GraphicsScene::constraintModel() const
00233 {
00234     return d->constraintModel;
00235 }
00236 
00237 void GraphicsScene::setConstraintModel( ConstraintModel* cm )
00238 {
00239     if ( !d->constraintModel.isNull() ) {
00240         disconnect( d->constraintModel );
00241     }
00242     d->constraintModel = cm;
00243 
00244     connect( cm, SIGNAL( constraintAdded( const KDGantt::Constraint& ) ), this, SLOT( slotConstraintAdded( const KDGantt::Constraint& ) ) );
00245     connect( cm, SIGNAL( constraintRemoved( const KDGantt::Constraint& ) ), this, SLOT( slotConstraintRemoved( const KDGantt::Constraint& ) ) );
00246     d->resetConstraintItems();
00247 }
00248 
00249 void GraphicsScene::setSelectionModel( QItemSelectionModel* smodel )
00250 {
00251     d->selectionModel = smodel;
00252     // TODO: update selection from model and connect signals
00253 }
00254 
00255 QItemSelectionModel* GraphicsScene::selectionModel() const
00256 {
00257     return d->selectionModel;
00258 }
00259 
00260 void GraphicsScene::setRowController( AbstractRowController* rc )
00261 {
00262     d->rowController = rc;
00263 }
00264 
00265 AbstractRowController* GraphicsScene::rowController() const
00266 {
00267     return d->rowController;
00268 }
00269 
00270 void GraphicsScene::setGrid( AbstractGrid* grid )
00271 {
00272     QAbstractItemModel* model = d->grid->model();
00273     if ( grid == 0 ) grid = &d->default_grid;
00274     if ( d->grid ) disconnect( d->grid );
00275     d->grid = grid;
00276     connect( d->grid, SIGNAL( gridChanged() ), this, SLOT( slotGridChanged() ) );
00277     d->grid->setModel( model );
00278     slotGridChanged();
00279 }
00280 
00281 AbstractGrid* GraphicsScene::grid() const
00282 {
00283     return d->grid;
00284 }
00285 
00286 void GraphicsScene::setReadOnly( bool ro )
00287 {
00288     d->readOnly = ro;
00289 }
00290 
00291 bool GraphicsScene::isReadOnly() const
00292 {
00293     return d->readOnly;
00294 }
00295 
00296 /* Returns the index with column=0 fromt the
00297  * same row as idx and with the same parent.
00298  * This is used to traverse the tree-structure
00299  * of the model
00300  */
00301 QModelIndex GraphicsScene::mainIndex( const QModelIndex& idx )
00302 {
00303 #if 0
00304     if ( idx.isValid() ) {
00305         return idx.model()->index( idx.row(), 0,idx.parent() );
00306     } else {
00307         return QModelIndex();
00308     }
00309 #else
00310     return idx;
00311 #endif
00312 }
00313 
00318 QModelIndex GraphicsScene::dataIndex( const QModelIndex& idx )
00319 {
00320 #if 0
00321     if ( idx.isValid() ) {
00322         const QAbstractItemModel* model = idx.model();
00323         return model->index( idx.row(), model->columnCount( idx.parent() )-1,idx.parent() );
00324     } else {
00325         return QModelIndex();
00326     }
00327 #else
00328     return idx;
00329 #endif
00330 }
00331 
00336 GraphicsItem* GraphicsScene::createItem( ItemType type ) const
00337 {
00338 #if 0
00339     switch( type ) {
00340     case TypeEvent:   return 0;
00341     case TypeTask:    return new TaskItem;
00342     case TypeSummary: return new SummaryItem;
00343     default:          return 0;
00344     }
00345 #endif
00346     //qDebug() << "GraphicsScene::createItem("<<type<<")";
00347     Q_UNUSED( type );
00348     return new GraphicsItem;
00349 }
00350 
00351 void GraphicsScene::Private::recursiveUpdateMultiItem( const Span& span, const QModelIndex& idx )
00352 {
00353     //qDebug() << "recursiveUpdateMultiItem("<<span<<idx<<")";
00354     GraphicsItem* item = q->findItem( idx );
00355     const int itemtype = summaryHandlingModel->data( idx, ItemTypeRole ).toInt();
00356     if (!item) {
00357         item = q->createItem( static_cast<ItemType>( itemtype ) );
00358         item->setIndex( idx );
00359         q->insertItem( idx, item);
00360     }
00361     item->updateItem( span, idx );
00362     QModelIndex child;
00363     int cr = 0;
00364     while ( ( child = idx.child( cr, 0 ) ).isValid() ) {
00365         recursiveUpdateMultiItem( span, child );
00366         ++cr;
00367     }
00368 }
00369 
00370 void GraphicsScene::updateRow( const QModelIndex& rowidx )
00371 {
00372     //qDebug() << "GraphicsScene::updateRow("<<rowidx<<")" << rowidx.data( Qt::DisplayRole );
00373     if ( !rowidx.isValid() ) return;
00374     const QAbstractItemModel* model = rowidx.model(); // why const?
00375     assert( model );
00376     assert( rowController() );
00377     assert( model == summaryHandlingModel() );
00378 
00379     const QModelIndex sidx = summaryHandlingModel()->mapToSource( rowidx );
00380     Span rg = rowController()->rowGeometry( sidx );
00381     for ( QModelIndex treewalkidx = sidx; treewalkidx.isValid(); treewalkidx = treewalkidx.parent() ) {
00382         if ( treewalkidx.data( ItemTypeRole ).toInt() == TypeMulti
00383              && !rowController()->isRowExpanded( treewalkidx )) {
00384             rg = rowController()->rowGeometry( treewalkidx );
00385         }
00386     }
00387 
00388     bool blocked = blockSignals( true );
00389     for ( int col = 0; col < summaryHandlingModel()->columnCount( rowidx.parent() ); ++col ) {
00390         const QModelIndex idx = summaryHandlingModel()->index( rowidx.row(), col, rowidx.parent() );
00391         const QModelIndex sidx = summaryHandlingModel()->mapToSource( idx );
00392         const int itemtype = summaryHandlingModel()->data( idx, ItemTypeRole ).toInt();
00393         const bool isExpanded = rowController()->isRowExpanded( sidx );
00394         if ( itemtype == TypeNone ) {
00395             removeItem( idx );
00396             continue;
00397         }
00398         if ( itemtype == TypeMulti && !isExpanded ) {
00399             d->recursiveUpdateMultiItem( rg, idx );
00400         } else {
00401             if ( summaryHandlingModel()->data( rowidx.parent(), ItemTypeRole ).toInt() == TypeMulti && !isExpanded ) {
00402                 //continue;
00403             }
00404 
00405             GraphicsItem* item = findItem( idx );
00406             if (!item) {
00407                 item = createItem( static_cast<ItemType>( itemtype ) );
00408                 item->setIndex( idx );
00409                 insertItem(idx, item);
00410             }
00411             const Span span = rowController()->rowGeometry( sidx );
00412             item->updateItem( span, idx );
00413         }
00414     }
00415     blockSignals( blocked );
00416 }
00417 
00418 void GraphicsScene::insertItem( const QPersistentModelIndex& idx, GraphicsItem* item )
00419 {
00420     if ( !d->constraintModel.isNull() ) {
00421         // Create items for constraints
00422         const QModelIndex sidx = summaryHandlingModel()->mapToSource( idx );
00423         const QList<Constraint> clst = d->constraintModel->constraintsForIndex( sidx );
00424         Q_FOREACH( Constraint c,  clst ) {
00425             QModelIndex other_idx;
00426             if ( c.startIndex() == sidx ) {
00427                 other_idx = c.endIndex();
00428                 GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),0);
00429                 if ( !other_item ) continue;
00430                 ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
00431                 item->addStartConstraint( citem );
00432                 other_item->addEndConstraint( citem );
00433                 addItem( citem );
00434             } else if ( c.endIndex() == sidx ) {
00435                 other_idx = c.startIndex();
00436                 GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),0);
00437                 if ( !other_item ) continue;
00438                 ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
00439                 other_item->addStartConstraint( citem );
00440                 item->addEndConstraint( citem );
00441                 addItem( citem );
00442             } else {
00443                 assert( 0 ); // Impossible
00444             }
00445         }
00446     }
00447     d->items.insert( idx, item );
00448     addItem( item );
00449 }
00450 
00451 void GraphicsScene::removeItem( const QModelIndex& idx )
00452 {
00453     //qDebug() << "GraphicsScene::removeItem("<<idx<<")";
00454     QHash<QPersistentModelIndex,GraphicsItem*>::iterator it = d->items.find( idx );
00455     if ( it != d->items.end() ) {
00456         GraphicsItem* item = *it;
00457         assert( item );
00458         // We have to remove the item from the list first because
00459         // there is a good chance there will be reentrant calls
00460         d->items.erase( it );
00461         {
00462             // Remove any constraintitems attached
00463             const QSet<ConstraintGraphicsItem*> clst = QSet<ConstraintGraphicsItem*>::fromList( item->startConstraints() ) +
00464                                                        QSet<ConstraintGraphicsItem*>::fromList( item->endConstraints() );
00465             Q_FOREACH( ConstraintGraphicsItem* citem, clst ) {
00466                 d->deleteConstraintItem( citem );
00467             }
00468         }
00469         // Get rid of the item
00470         delete item;
00471     }
00472 }
00473 
00474 GraphicsItem* GraphicsScene::findItem( const QModelIndex& idx ) const
00475 {
00476     if ( !idx.isValid() ) return 0;
00477     assert( idx.model() == summaryHandlingModel() );
00478     QHash<QPersistentModelIndex,GraphicsItem*>::const_iterator it = d->items.find( idx );
00479     return ( it != d->items.end() )?*it:0;
00480 }
00481 
00482 GraphicsItem* GraphicsScene::findItem( const QPersistentModelIndex& idx ) const
00483 {
00484     if ( !idx.isValid() ) return 0;
00485     assert( idx.model() == summaryHandlingModel() );
00486     QHash<QPersistentModelIndex,GraphicsItem*>::const_iterator it = d->items.find( idx );
00487     return ( it != d->items.end() )?*it:0;
00488 }
00489 
00490 void GraphicsScene::clearItems()
00491 {
00492     // TODO constraints
00493     qDeleteAll( items() );
00494     d->items.clear();
00495 }
00496 
00497 void GraphicsScene::updateItems()
00498 {
00499     for ( QHash<QPersistentModelIndex,GraphicsItem*>::iterator it = d->items.begin();
00500           it != d->items.end(); ++it ) {
00501         GraphicsItem* const item = it.value();
00502         const QPersistentModelIndex& idx = it.key();
00503         item->updateItem( Span( item->pos().y(), item->rect().height() ), idx );
00504     }
00505     invalidate( QRectF(), QGraphicsScene::BackgroundLayer );
00506 }
00507 
00508 void GraphicsScene::deleteSubtree( const QModelIndex& _idx )
00509 {
00510     QModelIndex idx = dataIndex( _idx );
00511     if ( !idx.model() ) return;
00512     const QModelIndex parent( idx.parent() );
00513     const int colcount = idx.model()->columnCount( parent );
00514     {for ( int i = 0; i < colcount; ++i ) {
00515         removeItem( parent.child( idx.row(), i ) );
00516     }}
00517     const int rowcount = summaryHandlingModel()->rowCount( _idx );
00518     {for ( int i = 0; i < rowcount; ++i ) {
00519         deleteSubtree( summaryHandlingModel()->index( i, summaryHandlingModel()->columnCount(_idx)-1, _idx ) );
00520     }}
00521 }
00522 
00523 
00524 ConstraintGraphicsItem* GraphicsScene::findConstraintItem( const Constraint& c ) const
00525 {
00526     return d->findConstraintItem( c );
00527 }
00528 
00529 void GraphicsScene::clearConstraintItems()
00530 {
00531     // TODO
00532     // d->constraintItems.clearConstraintItems();
00533 }
00534 
00535 void GraphicsScene::slotConstraintAdded( const KDGantt::Constraint& c )
00536 {
00537     d->createConstraintItem( c );
00538 }
00539 
00540 void GraphicsScene::slotConstraintRemoved( const KDGantt::Constraint& c )
00541 {
00542     d->deleteConstraintItem( c );
00543 }
00544 
00545 void GraphicsScene::slotGridChanged()
00546 {
00547     updateItems();
00548     update();
00549     emit gridChanged();
00550 }
00551 
00552 void GraphicsScene::helpEvent( QGraphicsSceneHelpEvent *helpEvent )
00553 {
00554 #ifndef QT_NO_TOOLTIP
00555     QGraphicsItem *item = itemAt( helpEvent->scenePos() );
00556     if ( GraphicsItem* gitem = qgraphicsitem_cast<GraphicsItem*>( item ) ) {
00557         QToolTip::showText(helpEvent->screenPos(), gitem->ganttToolTip());
00558     } else if ( ConstraintGraphicsItem* citem = qgraphicsitem_cast<ConstraintGraphicsItem*>( item ) ) {
00559         QToolTip::showText(helpEvent->screenPos(), citem->ganttToolTip());
00560     } else {
00561         QGraphicsScene::helpEvent( helpEvent );
00562     }
00563 #endif /* QT_NO_TOOLTIP */
00564 }
00565 
00566 void GraphicsScene::drawBackground( QPainter* painter, const QRectF& _rect )
00567 {
00568     QRectF scn( sceneRect() );
00569     QRectF rect( _rect );
00570     if ( d->isPrinting ) {
00571         QRectF headerRect( scn.topLeft()+QPointF( d->labelsWidth, 0 ),
00572                            QSizeF( scn.width()-d->labelsWidth, d->rowController->headerHeight() ));
00573         d->grid->paintHeader( painter, headerRect, rect, 0, 0 );
00574 
00575         /* We have to blank out the part of the header that is invisible during
00576      * normal rendering when we are printing.
00577      */
00578         QRectF labelsTabRect( scn.topLeft(), QSizeF( d->labelsWidth, headerRect.height() ) );
00579 
00580         QStyleOptionHeader opt;
00581         opt.rect = labelsTabRect.toRect();
00582         opt.text = tr( "" );
00583         opt.textAlignment = Qt::AlignCenter;
00584 #if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
00585         style()->drawControl(QStyle::CE_Header, &opt, painter, 0);
00586 #else
00587         QApplication::style()->drawControl(QStyle::CE_Header, &opt, painter, 0);
00588 #endif
00589         scn.setTop( headerRect.bottom() );
00590         scn.setLeft( headerRect.left() );
00591         rect = rect.intersected( scn );
00592     }
00593     d->grid->paintGrid( painter, scn, rect, d->rowController );
00594 }
00595 
00596 void GraphicsScene::itemEntered( const QModelIndex& idx )
00597 {
00598     emit entered( idx );
00599 }
00600 
00601 void GraphicsScene::itemPressed( const QModelIndex& idx )
00602 {
00603     emit pressed( idx );
00604 }
00605 
00606 void GraphicsScene::itemClicked( const QModelIndex& idx )
00607 {
00608     emit clicked( idx );
00609 }
00610 
00611 void GraphicsScene::itemDoubleClicked( const QModelIndex& idx )
00612 {
00613     emit doubleClicked( idx );
00614 }
00615 
00616 void GraphicsScene::setDragSource( GraphicsItem* item )
00617 {
00618     d->dragSource = item;
00619 }
00620 
00621 GraphicsItem* GraphicsScene::dragSource() const
00622 {
00623     return d->dragSource;
00624 }
00625 
00632 void GraphicsScene::print( QPrinter* printer, bool drawRowLabels )
00633 {
00634     QPainter painter( printer );
00635     doPrint( &painter, printer->pageRect(), sceneRect().left(), sceneRect().right(), printer, drawRowLabels );
00636 }
00637 
00648 void GraphicsScene::print( QPrinter* printer, qreal start, qreal end, bool drawRowLabels )
00649 {
00650     QPainter painter( printer );
00651     doPrint( &painter, printer->pageRect(), start, end, printer, drawRowLabels );
00652 }
00653 
00658 void GraphicsScene::print( QPainter* painter, const QRectF& _targetRect, bool drawRowLabels )
00659 {
00660     QRectF targetRect( _targetRect );
00661     if ( targetRect.isNull() ) {
00662         targetRect = sceneRect();
00663     }
00664 
00665     doPrint( painter, targetRect, sceneRect().left(), sceneRect().right(), 0, drawRowLabels );
00666 }
00667 
00676 void GraphicsScene::print( QPainter* painter, qreal start, qreal end,
00677                            const QRectF& _targetRect, bool drawRowLabels )
00678 {
00679     QRectF targetRect( _targetRect );
00680     if ( targetRect.isNull() ) {
00681         targetRect = sceneRect();
00682     }
00683 
00684     doPrint( painter, targetRect, start, end, 0, drawRowLabels );
00685 }
00686 
00689 void GraphicsScene::doPrint( QPainter* painter, const QRectF& targetRect,
00690                              qreal start, qreal end,
00691                              QPrinter* printer, bool drawRowLabels )
00692 {
00693     assert( painter );
00694     d->isPrinting = true;
00695 #if QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)
00696     QFont sceneFont( font() );
00697     if ( printer ) {
00698         sceneFont = QFont( font(), printer );
00699         sceneFont.setPixelSize( font().pointSize() );
00700     }
00701 #else
00702     QFont sceneFont( painter->font() );
00703     if ( printer ) {
00704         sceneFont = QFont( painter->font(), printer );
00705         sceneFont.setPixelSize( painter->font().pointSize() );
00706     }
00707 #endif
00708 
00709     const QRectF oldScnRect( sceneRect() );
00710     QRectF scnRect( oldScnRect );
00711     scnRect.setLeft( start );
00712     scnRect.setRight( end );
00713     scnRect.setTop( -d->rowController->headerHeight() );
00714     bool b = blockSignals( true );
00715 
00716     /* row labels */
00717     QVector<QGraphicsTextItem*> textLabels;
00718     if ( drawRowLabels ) {
00719         qreal textWidth = 0.;
00720         QModelIndex sidx = summaryHandlingModel()->mapToSource( summaryHandlingModel()->index( 0, 0, rootIndex()) );
00721         do {
00722             QModelIndex idx = summaryHandlingModel()->mapFromSource( sidx );
00723             const Span rg=rowController()->rowGeometry( sidx );
00724             const QString txt = idx.data( Qt::DisplayRole ).toString();
00725             QGraphicsTextItem* item = new QGraphicsTextItem( txt );
00726             addItem( item );
00727             textLabels << item;
00728             item->adjustSize();
00729             textWidth = qMax( item->textWidth(), textWidth );
00730             item->setPos( 0, rg.start() );
00731         } while ( ( sidx = rowController()->indexBelow( sidx ) ).isValid() );
00732         // Add a little margin to textWidth
00733         textWidth += QFontMetricsF(sceneFont).width( QString::fromLatin1( "X" ) );
00734         Q_FOREACH( QGraphicsTextItem* item, textLabels ) {
00735             item->setPos( scnRect.left()-textWidth, item->y() );
00736             item->show();
00737         }
00738         scnRect.setLeft( scnRect.left()-textWidth );
00739         d->labelsWidth = textWidth;
00740     }
00741 
00742     setSceneRect( scnRect );
00743 
00744     painter->save();
00745     painter->setClipRect( targetRect );
00746 
00747     qreal yratio = targetRect.height()/scnRect.height();
00748     /* If we're not printing multiple pages,
00749      * check if the span fits and adjust:
00750      */
00751     if ( !printer && targetRect.width()/scnRect.width() < yratio ) {
00752         yratio = targetRect.width()/scnRect.width();
00753     }
00754 
00755     qreal offset = scnRect.left();
00756     int pagecount = 0;
00757     while ( offset < scnRect.width() ) {
00758         painter->setFont( sceneFont );
00759         render( painter, targetRect, QRectF( QPointF( offset, scnRect.top()),
00760                                              QSizeF( targetRect.width()/yratio, scnRect.height() ) ) );
00761         offset += targetRect.width()/yratio;
00762         ++pagecount;
00763         if ( printer && offset < scnRect.width() ) {
00764             printer->newPage();
00765         } else {
00766             break;
00767         }
00768     }
00769 
00770     d->isPrinting = false;
00771     qDeleteAll( textLabels );
00772     blockSignals( b );
00773     setSceneRect( oldScnRect );
00774     painter->restore();
00775 }
00776 
00777 #include "moc_kdganttgraphicsscene.cpp"
00778 

Generated on Thu Mar 4 23:19:13 2010 for KD Chart 2 by  doxygen 1.5.4