1 /****************************************************************************
2 ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB. All rights reserved.
4 ** This file is part of the KD Gantt library.
6 ** This file may be distributed and/or modified under the terms of the
7 ** GNU General Public License version 2 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.GPL included in the
9 ** packaging of this file.
11 ** Licensees holding valid commercial KD Gantt licenses may use this file in
12 ** accordance with the KD Gantt Commercial License Agreement provided with
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 ** See http://www.kdab.net/kdgantt for
19 ** information about KD Gantt Commercial License Agreements.
21 ** Contact info@kdab.net if any conditions of this
22 ** licensing are not clear to you.
24 **********************************************************************/
25 #include "kdganttgraphicsview.h"
26 #include "kdganttgraphicsview_p.h"
27 #include "kdganttabstractrowcontroller.h"
28 #include "kdganttgraphicsitem.h"
29 #include "kdganttconstraintmodel.h"
33 #include <QPaintEvent>
34 #include <QResizeEvent>
36 #include <QAbstractProxyModel>
41 #include "../evaldialog/evaldialog.h"
44 /*!\class KDGantt::HeaderWidget
48 using namespace KDGantt
;
50 HeaderWidget::HeaderWidget( GraphicsView
* parent
)
51 : QWidget( parent
), m_offset( 0. )
53 assert( parent
); // Parent must be set
56 HeaderWidget::~HeaderWidget()
60 void HeaderWidget::scrollTo( int v
)
63 // QWidget::scroll() wont work properly for me on Mac
64 //scroll( static_cast<int>( old-v ), 0 );
68 void HeaderWidget::paintEvent( QPaintEvent
* ev
)
71 view()->grid()->paintHeader( &p
, rect(), ev
->rect(), m_offset
, this );
74 #ifndef QT_NO_CONTEXTMENU
75 void HeaderWidget::contextMenuEvent( QContextMenuEvent
* event
)
79 DateTimeGrid
* const grid
= qobject_cast
< DateTimeGrid
* >( view()->grid() );
80 QAction
* actionScaleAuto
= 0;
81 QAction
* actionScaleDay
= 0;
82 QAction
* actionScaleHour
= 0;
83 QAction
* actionZoomIn
= 0;
84 QAction
* actionZoomOut
= 0;
87 QMenu
* menuScale
= new QMenu( tr( "Scale" ), &contextMenu
);
88 QActionGroup
* scaleGroup
= new QActionGroup( &contextMenu
);
89 scaleGroup
->setExclusive( true );
91 actionScaleAuto
= new QAction( tr( "Auto" ), menuScale
);
92 actionScaleAuto
->setCheckable( true );
93 actionScaleAuto
->setChecked( grid
->scale() == DateTimeGrid::ScaleAuto
);
94 actionScaleDay
= new QAction( tr( "Day" ), menuScale
);
95 actionScaleDay
->setCheckable( true );
96 actionScaleDay
->setChecked( grid
->scale() == DateTimeGrid::ScaleDay
);
97 actionScaleHour
= new QAction( tr( "Hour" ), menuScale
);
98 actionScaleHour
->setCheckable( true );
99 actionScaleHour
->setChecked( grid
->scale() == DateTimeGrid::ScaleHour
);
101 scaleGroup
->addAction( actionScaleAuto
);
102 menuScale
->addAction( actionScaleAuto
);
104 scaleGroup
->addAction( actionScaleDay
);
105 menuScale
->addAction( actionScaleDay
);
107 scaleGroup
->addAction( actionScaleHour
);
108 menuScale
->addAction( actionScaleHour
);
110 contextMenu
.addMenu( menuScale
);
112 contextMenu
.addSeparator();
114 actionZoomIn
= new QAction( tr( "Zoom In" ), &contextMenu
);
115 contextMenu
.addAction( actionZoomIn
);
116 actionZoomOut
= new QAction( tr( "Zoom Out" ), &contextMenu
);
117 contextMenu
.addAction( actionZoomOut
);
120 if( contextMenu
.isEmpty() )
126 const QAction
* const action
= contextMenu
.exec( event
->globalPos() );
128 else if( action
== actionScaleAuto
)
131 grid
->setScale( DateTimeGrid::ScaleAuto
);
133 else if( action
== actionScaleDay
)
136 grid
->setScale( DateTimeGrid::ScaleDay
);
138 else if( action
== actionScaleHour
)
141 grid
->setScale( DateTimeGrid::ScaleHour
);
143 else if( action
== actionZoomIn
)
146 grid
->setDayWidth( grid
->dayWidth() + 10.0 );
148 else if( action
== actionZoomOut
)
151 grid
->setDayWidth( grid
->dayWidth() - 10.0 );
158 GraphicsView::Private::Private( GraphicsView
* _q
)
159 : q( _q
), rowcontroller(0), headerwidget( _q
)
163 void GraphicsView::Private::updateHeaderGeometry()
165 q
->setViewportMargins(0,rowcontroller
->headerHeight(),0,0);
166 headerwidget
.setGeometry( q
->viewport()->x(),
167 q
->viewport()->y() - rowcontroller
->headerHeight(),
168 q
->viewport()->width(),
169 rowcontroller
->headerHeight() );
172 void GraphicsView::Private::slotGridChanged()
174 updateHeaderGeometry();
175 headerwidget
.update();
176 q
->updateSceneRect();
180 void GraphicsView::Private::slotHorizontalScrollValueChanged( int val
)
182 #if QT_VERSION >= 0x040300
183 const QRectF viewRect
= q
->transform().mapRect( q
->sceneRect() );
185 const QRectF viewRect
= q
->sceneRect();
187 headerwidget
.scrollTo( val
-q
->horizontalScrollBar()->minimum()+static_cast<int>( viewRect
.left() ) );
190 void GraphicsView::Private::slotColumnsInserted( const QModelIndex
& parent
, int start
, int end
)
194 QModelIndex idx
= scene
.model()->index( 0, 0, scene
.summaryHandlingModel()->mapToSource( parent
) );
196 scene
.updateRow( scene
.summaryHandlingModel()->mapFromSource( idx
) );
197 } while ( ( idx
= rowcontroller
->indexBelow( idx
) ) != QModelIndex() && rowcontroller
->isRowVisible( idx
) );
198 //} while ( ( idx = d->treeview.indexBelow( idx ) ) != QModelIndex() && d->treeview.visualRect(idx).isValid() );
199 q
->updateSceneRect();
202 void GraphicsView::Private::slotColumnsRemoved( const QModelIndex
& parent
, int start
, int end
)
211 void GraphicsView::Private::slotDataChanged( const QModelIndex
& topLeft
, const QModelIndex
& bottomRight
)
213 //qDebug() << "GraphicsView::slotDataChanged("<<topLeft<<bottomRight<<")";
214 const QModelIndex parent
= topLeft
.parent();
215 for ( int row
= topLeft
.row(); row
<= bottomRight
.row(); ++row
) {
216 scene
.updateRow( scene
.summaryHandlingModel()->index( row
, 0, parent
) );
220 void GraphicsView::Private::slotLayoutChanged()
222 //qDebug() << "slotLayoutChanged()";
226 void GraphicsView::Private::slotModelReset()
228 //qDebug() << "slotModelReset()";
232 void GraphicsView::Private::slotRowsInserted( const QModelIndex
& parent
, int start
, int end
)
237 q
->updateScene(); // TODO: This might be optimised
240 void GraphicsView::Private::slotRowsAboutToBeRemoved( const QModelIndex
& parent
, int start
, int end
)
242 //qDebug() << "GraphicsView::Private::slotRowsAboutToBeRemoved("<<parent<<start<<end<<")";
243 for ( int row
= start
; row
<= end
; ++row
) {
244 for ( int col
= 0; col
< scene
.summaryHandlingModel()->columnCount( parent
); ++col
) {
245 //qDebug() << "removing "<<scene.summaryHandlingModel()->index( row, col, parent );
246 scene
.removeItem( scene
.summaryHandlingModel()->index( row
, col
, parent
) );
251 void GraphicsView::Private::slotRowsRemoved( const QModelIndex
& parent
, int start
, int end
)
253 //qDebug() << "GraphicsView::Private::slotRowsRemoved("<<parent<<start<<end<<")";
262 void GraphicsView::Private::slotItemClicked( const QModelIndex
& idx
)
264 QModelIndex sidx
= idx
;//scene.summaryHandlingModel()->mapToSource( idx );
265 emit q
->clicked( sidx
);
266 if (q
->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick
, 0, q
))
267 emit q
->activated( sidx
);
270 void GraphicsView::Private::slotItemDoubleClicked( const QModelIndex
& idx
)
272 QModelIndex sidx
= idx
;//scene.summaryHandlingModel()->mapToSource( idx );
273 emit q
->doubleClicked( sidx
);
274 if (!q
->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick
, 0, q
))
275 emit q
->activated( sidx
);
278 void GraphicsView::Private::slotHeaderContextMenuRequested( const QPoint
& pt
)
280 emit q
->headerContextMenuRequested( headerwidget
.mapToGlobal( pt
) );
283 /*!\class KDGantt::GraphicsView kdganttgraphicsview.h KDGanttGraphicsView
285 * \brief The GraphicsView class provides a model/view implementation of a gantt chart.
290 /*! \signal void GraphicsView::activated( const QModelIndex & index ) */
291 /*! \signal void GraphicsView::clicked( const QModelIndex & index ); */
292 /*! \signal void GraphicsView::doubleClicked( const QModelIndex & index ); */
293 /*! \signal void GraphicsView::entered( const QModelIndex & index ); */
294 /*! \signal void GraphicsView::pressed( const QModelIndex & index ); */
295 /*! \signal void GraphicsView::headerContextMenuRequested( const QPoint& pt )
296 * This signal is emitted when the header has contextMenuPolicy Qt::CustomContextMenu
297 * and the widget wants to show a contextmenu for the header. Unlike in
298 * QWidget::customContextMenuRequested() signal, \a pt is here in global coordinates.
301 /*! Constructor. Creates a new KDGantt::GraphicsView with parent
304 GraphicsView::GraphicsView( QWidget
* parent
)
305 : QGraphicsView( parent
), _d( new Private( this ) )
308 #if defined KDAB_EVAL
309 EvalDialog::checkEvalLicense( "KD Gantt" );
311 connect( horizontalScrollBar(), SIGNAL(valueChanged(int)),
312 this, SLOT(slotHorizontalScrollValueChanged(int)) );
313 connect( &_d
->scene
, SIGNAL(gridChanged()),
314 this, SLOT(slotGridChanged()) );
315 connect( &_d
->scene
, SIGNAL(entered(QModelIndex
)),
316 this, SIGNAL(entered(QModelIndex
)) );
317 connect( &_d
->scene
, SIGNAL(pressed(QModelIndex
)),
318 this, SIGNAL(pressed(QModelIndex
)) );
319 connect( &_d
->scene
, SIGNAL(clicked(QModelIndex
)),
320 this, SLOT(slotItemClicked(QModelIndex
)) );
321 connect( &_d
->scene
, SIGNAL(doubleClicked(QModelIndex
)),
322 this, SLOT(slotItemDoubleClicked(QModelIndex
)) );
323 connect( &_d
->scene
, SIGNAL(sceneRectChanged(QRectF
)),
324 this, SLOT(updateSceneRect()) );
325 connect( &_d
->headerwidget
, SIGNAL(customContextMenuRequested(QPoint
)),
326 this, SLOT(slotHeaderContextMenuRequested(QPoint
)) );
327 setScene( &_d
->scene
);
330 setSummaryHandlingModel( _d
->scene
.summaryHandlingModel() );
332 //setCacheMode( CacheBackground );
335 /*! Destroys this view. */
336 GraphicsView::~GraphicsView()
343 /*! Sets the model to be displayed in this view to
344 * \a model. The view does not take ownership of the model.
346 * To make a model work well with GraphicsView it must
347 * have a certain layout. Whether the model is flat or has a
348 * treestrucure is not important, as long as an
349 * AbstractRowController is provided that can navigate the
352 * GraphicsView operates per row in the model. The data is always
353 * taken from the _last_ item in the row. The ItemRoles used are
354 * Qt::DisplayRole and the roles defined in KDGantt::ItemDataRole.
356 void GraphicsView::setModel( QAbstractItemModel
* model
)
358 if ( d
->scene
.model() ) {
359 disconnect( d
->scene
.model() );
362 d
->scene
.setModel( model
);
363 connect( model
, SIGNAL(dataChanged(QModelIndex
,QModelIndex
)),
364 this, SLOT(updateSceneRect()) );
368 /*! \returns the current model displayed by this view
370 QAbstractItemModel
* GraphicsView::model() const
372 return d
->scene
.model();
375 void GraphicsView::setSummaryHandlingModel( QAbstractProxyModel
* proxyModel
)
377 disconnect( d
->scene
.summaryHandlingModel() );
378 d
->scene
.setSummaryHandlingModel( proxyModel
);
380 /* Connections. We have to rely on the treeview
381 * to receive the signals before we do(!)
383 connect( proxyModel
, SIGNAL(columnsInserted(QModelIndex
,int,int)),
384 this, SLOT(slotColumnsInserted(QModelIndex
,int,int)) );
385 connect( proxyModel
, SIGNAL(columnsRemoved(QModelIndex
,int,int)),
386 this, SLOT(slotColumnsRemoved(QModelIndex
,int,int)) );
387 connect( proxyModel
, SIGNAL(dataChanged(QModelIndex
,QModelIndex
)),
388 this, SLOT(slotDataChanged(QModelIndex
,QModelIndex
)) );
389 connect( proxyModel
, SIGNAL(layoutChanged()),
390 this, SLOT(slotLayoutChanged()) );
391 connect( proxyModel
, SIGNAL(modelReset()),
392 this, SLOT(slotModelReset()) );
393 connect( proxyModel
, SIGNAL(rowsInserted(QModelIndex
,int,int)),
394 this, SLOT(slotRowsInserted(QModelIndex
,int,int)) );
395 connect( proxyModel
, SIGNAL(rowsAboutToBeRemoved(QModelIndex
,int,int)),
396 this, SLOT(slotRowsAboutToBeRemoved(QModelIndex
,int,int)) );
397 connect( proxyModel
, SIGNAL(rowsRemoved(QModelIndex
,int,int)),
398 this, SLOT(slotRowsRemoved(QModelIndex
,int,int)) );
403 /*! Sets the constraintmodel displayed by this view.
404 * \see KDGantt::ConstraintModel.
406 void GraphicsView::setConstraintModel( ConstraintModel
* cmodel
)
408 d
->scene
.setConstraintModel( cmodel
);
411 /*! \returns the KDGantt::ConstraintModel displayed by this view.
413 ConstraintModel
* GraphicsView::constraintModel() const
415 return d
->scene
.constraintModel();
418 /*! \returns the KDGantt::SummaryHandlingProxyModel used by this view.
420 QAbstractProxyModel
* GraphicsView::summaryHandlingModel() const
422 return d
->scene
.summaryHandlingModel();
425 /*! Sets the root index of the model displayed by this view.
426 * Similar to QAbstractItemView::setRootIndex, default is QModelIndex().
428 void GraphicsView::setRootIndex( const QModelIndex
& idx
)
430 d
->scene
.setRootIndex( idx
);
433 /*! \returns the rootindex for this view.
435 QModelIndex
GraphicsView::rootIndex() const
437 return d
->scene
.rootIndex();
440 /*! Sets the QItemSelectionModel used by this view to manage
441 * selections. Similar to QAbstractItemView::setSelectionModel
443 void GraphicsView::setSelectionModel( QItemSelectionModel
* model
)
445 d
->scene
.setSelectionModel( model
);
448 /*! \returns the QItemSelectionModel used by this view
450 QItemSelectionModel
* GraphicsView::selectionModel() const
452 return d
->scene
.selectionModel();
455 /*! Sets the KDGantt::ItemDelegate used for rendering items on this
456 * view. \see ItemDelegate and QAbstractItemDelegate.
458 void GraphicsView::setItemDelegate( ItemDelegate
* delegate
)
460 d
->scene
.setItemDelegate( delegate
);
463 /*! \returns the ItemDelegate used by this view to render items
465 ItemDelegate
* GraphicsView::itemDelegate() const
467 return d
->scene
.itemDelegate();
470 /*! Sets the AbstractRowController used by this view. The
471 * AbstractRowController deals with the height and position
472 * of each row and with which parts of the model are
473 * displayed. \see AbstractRowController
475 void GraphicsView::setRowController( AbstractRowController
* rowcontroller
)
477 d
->rowcontroller
= rowcontroller
;
478 d
->scene
.setRowController( rowcontroller
);
482 /*! \returns the AbstractRowController
483 * for this view. \see setRowController
485 AbstractRowController
* GraphicsView::rowController() const
487 return d
->rowcontroller
;
490 /*! Sets the AbstractGrid for this view. The grid is an
491 * object that controls how QModelIndexes are mapped
492 * to and from the view and how the background and header
493 * is rendered. \see AbstractGrid and DateTimeGrid.
495 void GraphicsView::setGrid( AbstractGrid
* grid
)
497 d
->scene
.setGrid( grid
);
498 d
->slotGridChanged();
501 /*! \returns the AbstractGrid used by this view.
503 AbstractGrid
* GraphicsView::grid() const
505 return d
->scene
.grid();
508 /*! Sets the view to read-only mode if \a to is true. The default is
509 * read/write if the model permits it.
511 void GraphicsView::setReadOnly( bool ro
)
513 d
->scene
.setReadOnly( ro
);
516 /*!\returns true iff the view is in read-only mode
518 bool GraphicsView::isReadOnly() const
520 return d
->scene
.isReadOnly();
523 /*! Sets the context menu policy for the header. The default value
524 * Qt::DefaultContextMenu results in a standard context menu on the header
525 * that allows the user to set the scale and zoom.
527 * Setting this to Qt::CustomContextMenu will cause the signal
528 * headerContextMenuRequested(const QPoint& pt) to be emitted instead.
530 * \see QWidget::setContextMenuPolicy( Qt::ContextMenuPolicy )
532 void GraphicsView::setHeaderContextMenuPolicy( Qt::ContextMenuPolicy p
)
534 d
->headerwidget
.setContextMenuPolicy( p
);
537 /*! \returns the context menu policy for the header
539 Qt::ContextMenuPolicy
GraphicsView::headerContextMenuPolicy() const
541 return d
->headerwidget
.contextMenuPolicy();
544 /*! Adds a constraint from \a from to \a to. \a modifiers are the
545 * keyboard modifiers pressed by the user when the action is invoked.
547 * Override this to control how contraints are added. The default
548 * implementation adds a soft constraint unless the Shift key is pressed,
549 * in that case it adds a hard constraint. If a constraint is already
550 * present, it is removed and nothing is added.
552 void GraphicsView::addConstraint( const QModelIndex
& from
,
553 const QModelIndex
& to
,
554 Qt::KeyboardModifiers modifiers
)
556 if ( isReadOnly() ) return;
557 ConstraintModel
* cmodel
= constraintModel();
559 Constraint
c( from
, to
, ( modifiers
&Qt::ShiftModifier
)?Constraint::TypeHard
:Constraint::TypeSoft
);
560 if ( cmodel
->hasConstraint( c
) ) cmodel
->removeConstraint( c
);
561 else cmodel
->addConstraint( c
);
564 void GraphicsView::resizeEvent( QResizeEvent
* ev
)
566 d
->updateHeaderGeometry();
567 QRectF r
= scene()->itemsBoundingRect();
568 // To scroll more to the left than the actual item start, bug #4516
569 r
.setLeft( qMin
<qreal
>( 0.0, r
.left() ) );
570 // TODO: take scrollbars into account (if not always on)
571 // The scene should be at least the size of the viewport
572 QSizeF size
= viewport()->size();
573 //TODO: why -2 below? size should be ex. frames etc?
574 if ( size
.width() > r
.width() ) {
575 r
.setWidth( size
.width() - 2 );
577 if ( size
.height() > r
.height() ) {
578 r
.setHeight( size
.height() - 2 );
580 const int totalh
= rowController()->totalHeight();
581 if ( r
.height() < totalh
) {
582 r
.setHeight( totalh
);
585 scene()->setSceneRect( r
);
587 QGraphicsView::resizeEvent( ev
);
590 /*!\returns The QModelIndex for the item located at
591 * position \a pos in the view or an invalid index
592 * if no item was present at that position.
594 * This is useful for for example contextmenus.
596 QModelIndex
GraphicsView::indexAt( const QPoint
& pos
) const
598 QGraphicsItem
* item
= itemAt( pos
);
599 if ( GraphicsItem
* gitem
= qgraphicsitem_cast
<GraphicsItem
*>( item
) ) {
600 return d
->scene
.summaryHandlingModel()->mapToSource( gitem
->index() );
602 return QModelIndex();
607 void GraphicsView::clearItems()
609 d
->scene
.clearItems();
613 void GraphicsView::updateRow( const QModelIndex
& idx
)
615 d
->scene
.updateRow( d
->scene
.summaryHandlingModel()->mapFromSource( idx
) );
619 * Adjusts the bounding rectangle of the scene.
621 void GraphicsView::updateSceneRect()
623 /* What to do with this? We need to shrink the view to
624 * make collapsing items work
626 qreal range
= horizontalScrollBar()->maximum()-horizontalScrollBar()->minimum();
627 const qreal hscroll
= horizontalScrollBar()->value()/( range
>0?range
:1 );
628 QRectF r
= d
->scene
.itemsBoundingRect();
629 // To scroll more to the left than the actual item start, bug #4516
631 r
.setLeft( qMin
<qreal
>( 0.0, r
.left() ) );
632 r
.setSize( r
.size().expandedTo( viewport()->size() ) );
633 const int totalh
= rowController()->totalHeight();
634 if ( r
.height() < totalh
) r
.setHeight( totalh
);
635 d
->scene
.setSceneRect( r
);
637 /* set scrollbar to keep the same time in view */
638 range
= horizontalScrollBar()->maximum()-horizontalScrollBar()->minimum();
639 if ( range
>0 ) horizontalScrollBar()->setValue( qRound( hscroll
*range
) );
641 /* We have to update here to adjust for any rows with no
642 * information because they are painted with a different
645 d
->scene
.invalidate( QRectF(), QGraphicsScene::BackgroundLayer
);
649 * Resets the state of the view.
651 void GraphicsView::updateScene()
654 if( !model()) return;
655 if( !rowController()) return;
656 QModelIndex idx
= model()->index( 0, 0, rootIndex() );
659 } while ( ( idx
= rowController()->indexBelow( idx
) ) != QModelIndex() && rowController()->isRowVisible(idx
) );
660 //constraintModel()->cleanup();
661 //qDebug() << constraintModel();
663 if ( scene() ) scene()->invalidate( QRectF(), QGraphicsScene::BackgroundLayer
);
667 GraphicsItem
* GraphicsView::createItem( ItemType type
) const
669 return d
->scene
.createItem( type
);
673 void GraphicsView::deleteSubtree( const QModelIndex
& idx
)
675 d
->scene
.deleteSubtree( d
->scene
.summaryHandlingModel()->mapFromSource( idx
) );
678 /*! Print the Gantt chart using \a printer. If \a drawRowLabels
679 * is true (the default), each row will have it's label printed
682 * This version of print() will print multiple pages.
684 void GraphicsView::print( QPrinter
* printer
, bool drawRowLabels
)
686 d
->scene
.print( printer
, drawRowLabels
);
689 /*! Print part of the Gantt chart from \a start to \a end using \a printer.
690 * If \a drawRowLabels is true (the default), each row will have it's
691 * label printed on the left side.
693 * This version of print() will print multiple pages.
695 * To print a certain range of a chart with a DateTimeGrid, use
696 * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const
697 * to figure out the values for \a start and \a end.
699 void GraphicsView::print( QPrinter
* printer
, qreal start
, qreal end
, bool drawRowLabels
)
701 d
->scene
.print( printer
, start
, end
, drawRowLabels
);
704 /*! Render the GanttView inside the rectangle \a target using the painter \a painter.
705 * If \a drawRowLabels is true (the default), each row will have it's
706 * label printed on the left side.
708 void GraphicsView::print( QPainter
* painter
, const QRectF
& targetRect
, bool drawRowLabels
)
710 d
->scene
.print(painter
,targetRect
,drawRowLabels
);
713 /*! Render the GanttView inside the rectangle \a target using the painter \a painter.
714 * If \a drawRowLabels is true (the default), each row will have it's
715 * label printed on the left side.
717 * To print a certain range of a chart with a DateTimeGrid, use
718 * qreal DateTimeGrid::mapFromDateTime( const QDateTime& dt) const
719 * to figure out the values for \a start and \a end.
721 void GraphicsView::print( QPainter
* painter
, qreal start
, qreal end
,
722 const QRectF
& targetRect
, bool drawRowLabels
)
724 d
->scene
.print(painter
, start
, end
, targetRect
, drawRowLabels
);
728 #include "moc_kdganttgraphicsview.cpp"
729 #include "moc_kdganttgraphicsview_p.cpp"