Better wording
[kdepim.git] / kdgantt2 / kdganttgraphicsview.cpp
blobac1c0ac3ea315bcbf42a2b3da8aaf1206c6bfed8
1 /****************************************************************************
2 ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Gantt library.
5 **
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
13 ** the Software.
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"
31 #include <QMenu>
32 #include <QPainter>
33 #include <QPaintEvent>
34 #include <QResizeEvent>
35 #include <QScrollBar>
36 #include <QAbstractProxyModel>
38 #include <cassert>
40 #if defined KDAB_EVAL
41 #include "../evaldialog/evaldialog.h"
42 #endif
44 /*!\class KDGantt::HeaderWidget
45 * \internal
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 )
62 m_offset = v;
63 // QWidget::scroll() wont work properly for me on Mac
64 //scroll( static_cast<int>( old-v ), 0 );
65 update();
68 void HeaderWidget::paintEvent( QPaintEvent* ev )
70 QPainter p( this );
71 view()->grid()->paintHeader( &p, rect(), ev->rect(), m_offset, this );
74 #ifndef QT_NO_CONTEXTMENU
75 void HeaderWidget::contextMenuEvent( QContextMenuEvent* event )
77 QMenu contextMenu;
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;
85 if( grid != 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() )
122 event->ignore();
123 return;
126 const QAction* const action = contextMenu.exec( event->globalPos() );
127 if( action == 0 ) {}
128 else if( action == actionScaleAuto )
130 assert( grid != 0 );
131 grid->setScale( DateTimeGrid::ScaleAuto );
133 else if( action == actionScaleDay )
135 assert( grid != 0 );
136 grid->setScale( DateTimeGrid::ScaleDay );
138 else if( action == actionScaleHour )
140 assert( grid != 0 );
141 grid->setScale( DateTimeGrid::ScaleHour );
143 else if( action == actionZoomIn )
145 assert( grid != 0 );
146 grid->setDayWidth( grid->dayWidth() + 10.0 );
148 else if( action == actionZoomOut )
150 assert( grid != 0 );
151 grid->setDayWidth( grid->dayWidth() - 10.0 );
154 event->accept();
156 #endif
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();
177 q->update();
180 void GraphicsView::Private::slotHorizontalScrollValueChanged( int val )
182 #if QT_VERSION >= 0x040300
183 const QRectF viewRect = q->transform().mapRect( q->sceneRect() );
184 #else
185 const QRectF viewRect = q->sceneRect();
186 #endif
187 headerwidget.scrollTo( val-q->horizontalScrollBar()->minimum()+static_cast<int>( viewRect.left() ) );
190 void GraphicsView::Private::slotColumnsInserted( const QModelIndex& parent, int start, int end )
192 Q_UNUSED( start );
193 Q_UNUSED( end );
194 QModelIndex idx = scene.model()->index( 0, 0, scene.summaryHandlingModel()->mapToSource( parent ) );
195 do {
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 )
204 // TODO
205 Q_UNUSED( start );
206 Q_UNUSED( end );
207 Q_UNUSED( parent );
208 q->updateScene();
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()";
223 q->updateScene();
226 void GraphicsView::Private::slotModelReset()
228 //qDebug() << "slotModelReset()";
229 q->updateScene();
232 void GraphicsView::Private::slotRowsInserted( const QModelIndex& parent, int start, int end )
234 Q_UNUSED( parent );
235 Q_UNUSED( start );
236 Q_UNUSED( 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<<")";
254 // TODO
255 Q_UNUSED( parent );
256 Q_UNUSED( start );
257 Q_UNUSED( end );
259 q->updateScene();
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
284 * \ingroup KDGantt
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
302 * \a parent.
304 GraphicsView::GraphicsView( QWidget* parent )
305 : QGraphicsView( parent ), _d( new Private( this ) )
308 #if defined KDAB_EVAL
309 EvalDialog::checkEvalLicense( "KD Gantt" );
310 #endif
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 );
329 // HACK!
330 setSummaryHandlingModel( _d->scene.summaryHandlingModel() );
332 //setCacheMode( CacheBackground );
335 /*! Destroys this view. */
336 GraphicsView::~GraphicsView()
338 delete _d;
341 #define d d_func()
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
350 * model.
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()) );
365 updateScene();
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)) );
400 updateScene();
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 );
479 updateScene();
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();
558 assert( cmodel );
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() );
601 } else {
602 return QModelIndex();
606 /*! \internal */
607 void GraphicsView::clearItems()
609 d->scene.clearItems();
612 /*! \internal */
613 void GraphicsView::updateRow( const QModelIndex& idx )
615 d->scene.updateRow( d->scene.summaryHandlingModel()->mapFromSource( idx ) );
618 /*! \internal
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
630 r.setTop( 0. );
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
643 * background brush
645 d->scene.invalidate( QRectF(), QGraphicsScene::BackgroundLayer );
648 /*! \internal
649 * Resets the state of the view.
651 void GraphicsView::updateScene()
653 clearItems();
654 if( !model()) return;
655 if( !rowController()) return;
656 QModelIndex idx = model()->index( 0, 0, rootIndex() );
657 do {
658 updateRow( idx );
659 } while ( ( idx = rowController()->indexBelow( idx ) ) != QModelIndex() && rowController()->isRowVisible(idx) );
660 //constraintModel()->cleanup();
661 //qDebug() << constraintModel();
662 updateSceneRect();
663 if ( scene() ) scene()->invalidate( QRectF(), QGraphicsScene::BackgroundLayer );
666 /*! \internal */
667 GraphicsItem* GraphicsView::createItem( ItemType type ) const
669 return d->scene.createItem( type );
672 /*! \internal */
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
680 * on the left side.
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"