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 used under the terms of the GNU General Public
7
** License versions 2.0 or 3.0 as published by the Free Software
8
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
9
** included in the packaging of this file. Alternatively you may (at
10
** your option) use any later version of the GNU General Public
11
** License if such license has been publicly approved by
12
** Klarälvdalens Datakonsult AB (or its successors, if any).
14
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
15
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
16
** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
17
** not expressly granted herein.
19
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
20
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
**********************************************************************/
23
#include "kdganttgraphicsscene.h"
24
#include "kdganttgraphicsscene_p.h"
25
#include "kdganttgraphicsitem.h"
26
#include "kdganttconstraint.h"
27
#include "kdganttconstraintgraphicsitem.h"
28
#include "kdganttitemdelegate.h"
29
#include "kdganttabstractrowcontroller.h"
30
#include "kdganttdatetimegrid.h"
31
#include "kdganttsummaryhandlingproxymodel.h"
32
#include "kdganttgraphicsview.h"
34
#include <QApplication>
36
#include <QGraphicsSceneHelpEvent>
37
#include <QTextDocument>
44
/*!\class KDGantt::GraphicsScene
48
using namespace KDGantt;
50
GraphicsScene::Private::Private( GraphicsScene* _q )
53
itemDelegate( new ItemDelegate( _q ) ),
55
grid( &default_grid ),
57
summaryHandlingModel( new SummaryHandlingProxyModel( _q ) ),
60
default_grid.setStartDateTime( QDateTime::currentDateTime().addDays( -1 ) );
63
void GraphicsScene::Private::resetConstraintItems()
65
q->clearConstraintItems();
66
if ( constraintModel.isNull() ) return;
67
QList<Constraint> clst = constraintModel->constraints();
68
Q_FOREACH( Constraint c, clst ) {
69
createConstraintItem( c );
74
void GraphicsScene::Private::createConstraintItem( const Constraint& c )
76
GraphicsItem* sitem = q->findItem( summaryHandlingModel->mapFromSource( c.startIndex() ) );
77
GraphicsItem* eitem = q->findItem( summaryHandlingModel->mapFromSource( c.endIndex() ) );
79
if ( sitem && eitem ) {
80
ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
81
sitem->addStartConstraint( citem );
82
eitem->addEndConstraint( citem );
88
//q->insertConstraintItem( c, citem );
91
// Delete the constraint item, and clean up pointers in the start- and end item
92
void GraphicsScene::Private::deleteConstraintItem( ConstraintGraphicsItem *citem )
94
//qDebug()<<"GraphicsScene::Private::deleteConstraintItem citem="<<(void*)citem;
98
Constraint c = citem->constraint();
99
GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), 0 );
101
//qDebug()<<"GraphicsScene::Private::deleteConstraintItem startConstraints"<<item<<(void*)citem;
102
item->removeStartConstraint( citem );
103
} //else qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<c.startIndex()<<"start item not found";
104
item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), 0 );
106
//qDebug()<<"GraphicsScene::Private::deleteConstraintItem endConstraints"<<item<<(void*)citem;
107
item->removeEndConstraint( citem );
108
} //else qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<c.endIndex()<<"end item not found";
109
//qDebug()<<"GraphicsScene::Private::deleteConstraintItem"<<citem<<"deleted";
113
void GraphicsScene::Private::deleteConstraintItem( const Constraint& c )
115
//qDebug()<<"GraphicsScene::Private::deleteConstraintItem c="<<c;
116
deleteConstraintItem( findConstraintItem( c ) );
120
/* Very useful functional to compose functions.
121
* Unfortunately an SGI extension and not standard
123
template<typename Operation1,typename Operation2>
124
struct unary_compose : public std::unary_function<typename Operation1::result_type,typename Operation2::argument_type> {
125
unary_compose( const Operation1& f, const Operation2& g ) : _f( f ), _g( g ) {}
127
inline typename Operation1::result_type operator()( const typename Operation2::argument_type& arg ) {
128
return _f( _g( arg ) );
135
template<typename Operation1,typename Operation2>
136
inline unary_compose<Operation1,Operation2> compose1( const Operation1& f, const Operation2& g )
138
return unary_compose<Operation1,Operation2>( f, g );
142
ConstraintGraphicsItem* GraphicsScene::Private::findConstraintItem( const Constraint& c ) const
144
GraphicsItem* item = items.value( summaryHandlingModel->mapFromSource( c.startIndex() ), 0 );
146
QList<ConstraintGraphicsItem*> clst = item->startConstraints();
147
QList<ConstraintGraphicsItem*>::iterator it = clst.begin();
148
//qDebug()<<"GraphicsScene::Private::findConstraintItem start:"<<c<<item<<clst;
149
for( ; it != clst.end() ; ++it )
150
if ((*it)->constraint() == c )
152
if ( it != clst.end() ) {
156
item = items.value( summaryHandlingModel->mapFromSource( c.endIndex() ), 0 );
158
QList<ConstraintGraphicsItem*> clst = item->endConstraints();
159
QList<ConstraintGraphicsItem*>::iterator it = clst.begin();
160
//qDebug()<<"GraphicsScene::Private::findConstraintItem end:"<<c<<item<<clst;
161
for( ; it != clst.end() ; ++it )
162
if ((*it)->constraint() == c )
164
if ( it != clst.end() ) {
168
//qDebug()<<"GraphicsScene::Private::findConstraintItem No item or constraintitem"<<c;
172
GraphicsScene::GraphicsScene( QObject* parent )
173
: QGraphicsScene( parent ), _d( new Private( this ) )
179
GraphicsScene::~GraphicsScene()
181
clearConstraintItems();
186
void GraphicsScene::init()
188
setConstraintModel( new ConstraintModel( this ) );
189
connect( d->grid, SIGNAL( gridChanged() ), this, SLOT( slotGridChanged() ) );
192
/* NOTE: The delegate should really be a property
193
* of the view, but that doesn't really fit at
196
void GraphicsScene::setItemDelegate( ItemDelegate* delegate )
198
if ( !d->itemDelegate.isNull() && d->itemDelegate->parent()==this ) delete d->itemDelegate;
199
d->itemDelegate = delegate;
203
ItemDelegate* GraphicsScene::itemDelegate() const
205
return d->itemDelegate;
208
QAbstractItemModel* GraphicsScene::model() const
210
assert(!d->summaryHandlingModel.isNull());
211
return d->summaryHandlingModel->sourceModel();
214
void GraphicsScene::setModel( QAbstractItemModel* model )
216
assert(!d->summaryHandlingModel.isNull());
217
d->summaryHandlingModel->setSourceModel(model);
218
d->grid->setModel( d->summaryHandlingModel );
219
setSelectionModel( new QItemSelectionModel( model, this ) );
222
QAbstractProxyModel* GraphicsScene::summaryHandlingModel() const
224
return d->summaryHandlingModel;
227
void GraphicsScene::setSummaryHandlingModel( QAbstractProxyModel* proxyModel )
229
proxyModel->setSourceModel( model() );
230
d->summaryHandlingModel = proxyModel;
233
void GraphicsScene::setRootIndex( const QModelIndex& idx )
235
d->grid->setRootIndex( idx );
238
QModelIndex GraphicsScene::rootIndex() const
240
return d->grid->rootIndex();
243
ConstraintModel* GraphicsScene::constraintModel() const
245
return d->constraintModel;
248
void GraphicsScene::setConstraintModel( ConstraintModel* cm )
250
if ( !d->constraintModel.isNull() ) {
251
disconnect( d->constraintModel );
253
d->constraintModel = cm;
255
connect( cm, SIGNAL( constraintAdded( const Constraint& ) ), this, SLOT( slotConstraintAdded( const Constraint& ) ) );
256
connect( cm, SIGNAL( constraintRemoved( const Constraint& ) ), this, SLOT( slotConstraintRemoved( const Constraint& ) ) );
257
d->resetConstraintItems();
260
void GraphicsScene::setSelectionModel( QItemSelectionModel* smodel )
262
d->selectionModel = smodel;
263
// TODO: update selection from model and connect signals
266
QItemSelectionModel* GraphicsScene::selectionModel() const
268
return d->selectionModel;
271
void GraphicsScene::setRowController( AbstractRowController* rc )
273
d->rowController = rc;
276
AbstractRowController* GraphicsScene::rowController() const
278
return d->rowController;
281
void GraphicsScene::setGrid( AbstractGrid* grid )
283
QAbstractItemModel* model = d->grid->model();
284
if ( grid == 0 ) grid = &d->default_grid;
285
if ( d->grid ) disconnect( d->grid );
287
connect( d->grid, SIGNAL( gridChanged() ), this, SLOT( slotGridChanged() ) );
288
d->grid->setModel( model );
292
AbstractGrid* GraphicsScene::grid() const
297
void GraphicsScene::setReadOnly( bool ro )
302
bool GraphicsScene::isReadOnly() const
307
/* Returns the index with column=0 fromt the
308
* same row as idx and with the same parent.
309
* This is used to traverse the tree-structure
312
QModelIndex GraphicsScene::mainIndex( const QModelIndex& idx )
315
if ( idx.isValid() ) {
316
return idx.model()->index( idx.row(), 0,idx.parent() );
318
return QModelIndex();
325
/*! Returns the index pointing to the last column
326
* in the same row as idx. This can be thought of
327
* as in "inverse" of mainIndex()
329
QModelIndex GraphicsScene::dataIndex( const QModelIndex& idx )
332
if ( idx.isValid() ) {
333
const QAbstractItemModel* model = idx.model();
334
return model->index( idx.row(), model->columnCount( idx.parent() )-1,idx.parent() );
336
return QModelIndex();
343
/*! Creates a new item of type type.
344
* TODO: If the user should be allowed to override
345
* this in any way, it needs to be in View!
347
GraphicsItem* GraphicsScene::createItem( ItemType type ) const
351
case TypeEvent: return 0;
352
case TypeTask: return new TaskItem;
353
case TypeSummary: return new SummaryItem;
357
//qDebug() << "GraphicsScene::createItem("<<type<<")";
359
return new GraphicsItem;
362
void GraphicsScene::updateRow( const QModelIndex& rowidx )
364
//qDebug() << "GraphicsScene::updateRow("<<rowidx<<")";
365
if ( !rowidx.isValid() ) return;
366
const QAbstractItemModel* model = rowidx.model(); // why const?
368
assert( rowController() );
369
assert( model == summaryHandlingModel() );
371
const QModelIndex sidx = summaryHandlingModel()->mapToSource( rowidx );
372
const Span rg=rowController()->rowGeometry( sidx );
373
for ( int col = 0; col < summaryHandlingModel()->columnCount( rowidx.parent() ); ++col ) {
374
const QModelIndex idx = summaryHandlingModel()->index( rowidx.row(), col, rowidx.parent() );
375
const int itemtype = summaryHandlingModel()->data( idx, ItemTypeRole ).toInt();
376
if ( itemtype == TypeNone ) {
380
if ( itemtype == TypeMulti ) {
383
while ( ( child = idx.child( cr, 0 ) ).isValid() ) {
384
GraphicsItem* item = findItem( child );
386
item = createItem( static_cast<ItemType>( itemtype ) );
387
item->setIndex( child );
388
insertItem( child, item);
390
item->updateItem( rg, child );
391
setSceneRect( sceneRect().united( item->boundingRect() ) );
396
if ( summaryHandlingModel()->data( rowidx.parent(), ItemTypeRole ).toInt() == TypeMulti ) continue;
398
GraphicsItem* item = findItem( idx );
400
item = createItem( static_cast<ItemType>( itemtype ) );
401
item->setIndex( idx );
402
insertItem(idx, item);
404
item->updateItem( rg, idx );
405
setSceneRect( sceneRect().united( item->boundingRect() ) );
410
void GraphicsScene::insertItem( const QPersistentModelIndex& idx, GraphicsItem* item )
412
if ( !d->constraintModel.isNull() ) {
413
// Create items for constraints
414
const QModelIndex sidx = summaryHandlingModel()->mapToSource( idx );
415
const QList<Constraint> clst = d->constraintModel->constraintsForIndex( sidx );
416
Q_FOREACH( Constraint c, clst ) {
417
QModelIndex other_idx;
418
if ( c.startIndex() == sidx ) {
419
other_idx = c.endIndex();
420
GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),0);
421
if ( !other_item ) continue;
422
ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
423
item->addStartConstraint( citem );
424
other_item->addEndConstraint( citem );
426
} else if ( c.endIndex() == sidx ) {
427
other_idx = c.startIndex();
428
GraphicsItem* other_item = d->items.value(summaryHandlingModel()->mapFromSource( other_idx ),0);
429
if ( !other_item ) continue;
430
ConstraintGraphicsItem* citem = new ConstraintGraphicsItem( c );
431
other_item->addStartConstraint( citem );
432
item->addEndConstraint( citem );
435
assert( 0 ); // Impossible
439
d->items.insert( idx, item );
443
void GraphicsScene::removeItem( const QModelIndex& idx )
445
//qDebug() << "GraphicsScene::removeItem("<<idx<<")";
446
QHash<QPersistentModelIndex,GraphicsItem*>::iterator it = d->items.find( idx );
447
if ( it != d->items.end() ) {
448
GraphicsItem* item = *it;
449
// We have to remove the item from the list first because
450
// there is a good chance there will be reentrant calls
451
d->items.erase( it );
452
//qDebug() << "GraphicsScene::removeItem item="<<item;
454
// Remove any constraintitems starting here
455
const QList<ConstraintGraphicsItem*> clst = item->startConstraints();
456
//qDebug()<<"GraphicsScene::removeItem start:"<<clst;
457
Q_FOREACH( ConstraintGraphicsItem* citem, clst ) {
458
//qDebug()<<"GraphicsScene::removeItem start citem="<<citem;
459
d->deleteConstraintItem( citem );
462
{// Remove any constraintitems ending here
463
const QList<ConstraintGraphicsItem*> clst = item->endConstraints();
464
//qDebug()<<"GraphicsScene::removeItem end:"<<clst;
465
Q_FOREACH( ConstraintGraphicsItem* citem, clst ) {
466
//qDebug()<<"GraphicsScene::removeItem end citem="<<citem;
467
d->deleteConstraintItem( citem );
470
// Get rid of the item
475
GraphicsItem* GraphicsScene::findItem( const QModelIndex& idx ) const
477
if ( !idx.isValid() ) return 0;
478
assert( idx.model() == summaryHandlingModel() );
479
QHash<QPersistentModelIndex,GraphicsItem*>::const_iterator it = d->items.find( idx );
480
return ( it != d->items.end() )?*it:0;
483
GraphicsItem* GraphicsScene::findItem( const QPersistentModelIndex& idx ) const
485
if ( !idx.isValid() ) return 0;
486
assert( idx.model() == summaryHandlingModel() );
487
QHash<QPersistentModelIndex,GraphicsItem*>::const_iterator it = d->items.find( idx );
488
return ( it != d->items.end() )?*it:0;
491
void GraphicsScene::clearItems()
494
qDeleteAll( items() );
498
void GraphicsScene::updateItems()
500
for ( QHash<QPersistentModelIndex,GraphicsItem*>::iterator it = d->items.begin();
501
it != d->items.end(); ++it ) {
502
GraphicsItem* const item = it.value();
503
const QPersistentModelIndex& idx = it.key();
504
item->updateItem( Span( item->pos().y(), item->rect().height() ), idx );
508
void GraphicsScene::deleteSubtree( const QModelIndex& _idx )
510
QModelIndex idx = dataIndex( _idx );
512
for ( int i = 0; i < summaryHandlingModel()->rowCount( _idx ); ++i ) {
513
deleteSubtree( summaryHandlingModel()->index( i, summaryHandlingModel()->columnCount(_idx)-1, _idx ) );
518
ConstraintGraphicsItem* GraphicsScene::findConstraintItem( const Constraint& c ) const
520
return d->findConstraintItem( c );
523
void GraphicsScene::clearConstraintItems()
526
// d->constraintItems.clearConstraintItems();
529
void GraphicsScene::slotConstraintAdded( const Constraint& c )
531
d->createConstraintItem( c );
534
void GraphicsScene::slotConstraintRemoved( const Constraint& c )
536
d->deleteConstraintItem( c );
539
void GraphicsScene::slotGridChanged()
546
void GraphicsScene::helpEvent( QGraphicsSceneHelpEvent *helpEvent )
548
#ifndef QT_NO_TOOLTIP
549
QGraphicsItem *item = itemAt( helpEvent->scenePos() );
550
if ( GraphicsItem* gitem = qgraphicsitem_cast<GraphicsItem*>( item ) ) {
551
QToolTip::showText(helpEvent->screenPos(), gitem->ganttToolTip());
552
} else if ( ConstraintGraphicsItem* citem = qgraphicsitem_cast<ConstraintGraphicsItem*>( item ) ) {
553
QToolTip::showText(helpEvent->screenPos(), citem->ganttToolTip());
555
QGraphicsScene::helpEvent( helpEvent );
557
#endif /* QT_NO_TOOLTIP */
560
void GraphicsScene::drawBackground( QPainter* painter, const QRectF& rect )
562
d->grid->paintGrid( painter, sceneRect(), rect, d->rowController );
565
void GraphicsScene::itemEntered( const QModelIndex& idx )
570
void GraphicsScene::itemPressed( const QModelIndex& idx )
575
void GraphicsScene::itemClicked( const QModelIndex& idx )
580
void GraphicsScene::itemDoubleClicked( const QModelIndex& idx )
582
emit doubleClicked( idx );
585
void GraphicsScene::setDragSource( GraphicsItem* item )
587
d->dragSource = item;
590
GraphicsItem* GraphicsScene::dragSource() const
592
return d->dragSource;
595
#define KDGANTT_LIST_CHART_GAP 0.0
596
QRectF GraphicsScene::printRect( bool drawRowLabels, GraphicsView *view )
598
assert(rowController());
600
int indentation = 20;
601
bool indentRoot = true;
603
qreal leftEdge = sceneRect().left();
604
QVector<QGraphicsTextItem*> labelItems;
605
if ( drawRowLabels ) {
606
labelItems.reserve(d->items.size());
607
qreal textWidth = 0.;
608
qreal rowHeight = 0.;
609
{Q_FOREACH( GraphicsItem* item, d->items ) {
610
QModelIndex sidx = summaryHandlingModel()->mapToSource( item->index() );
611
if ( sidx.parent().isValid() && sidx.parent().data( ItemTypeRole ).toInt() == TypeMulti ) {
614
const Span rg = rowController()->rowGeometry( sidx );
615
const QString txt = item->index().data( Qt::DisplayRole ).toString();
616
QGraphicsTextItem* ti = new QGraphicsTextItem( txt, 0, this );
617
ti->setPos( 0, rg.start() );
618
ti->document()->size().setWidth( ti->document()->size().width() + KDGANTT_LIST_CHART_GAP );
619
int indent = indentation * ( level( item->index() ) + ( indentRoot ? 1 : 0 ) );
620
if ( ti->document()->size().width() + indentation > textWidth ) {
621
textWidth = ti->document()->size().width() + indent;
623
if ( rg.length() > rowHeight ) {
624
rowHeight = rg.length();
628
{Q_FOREACH( QGraphicsTextItem* item, labelItems ) {
629
item->setPos( leftEdge-textWidth-rowHeight, item->pos().y() );
633
QRectF res = itemsBoundingRect();
635
res.setHeight( res.height() + view->headerHeight() );
637
qDeleteAll( labelItems );
638
//qDebug()<<"printRect()"<<res;
642
void GraphicsScene::drawTreeIndication( QPainter *painter, const QModelIndex &idx, const QRect &rect, int indent, bool drawRoot )
644
// qDebug()<<"drawTreeIndication:"<<idx.data().toString()<<rect;
646
QStyleOptionViewItemV4 option;
647
option.rect.setRect( rect.left(), rect.top(), rect.width(), rect.height() );
648
option.state = option.state | QStyle::State_Enabled | QStyle::State_Active | QStyle::State_Item;
649
if ( idx.sibling(idx.row()+1, 0).isValid() ) {
650
option.state |= QStyle::State_Sibling;
652
if ( idx.model()->hasChildren( idx ) ) {
653
option.state |= QStyle::State_Children;
656
QPalette::ColorGroup cg;
657
cg = QPalette::Active;
658
option.palette.setCurrentColorGroup(cg);
660
QModelIndex parent = idx.parent();
661
QModelIndex currentParent = parent;
662
QModelIndex ancestor = currentParent.parent();
664
QRect area( option.rect.right() + 1, option.rect.top(), indent, option.rect.height() ); // moved left before use
666
if ( currentParent.isValid() || drawRoot ) {
668
area.moveLeft(area.left() - indent);
670
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter, 0);
672
option.state &= ~QStyle::State_Item;
673
option.state &= ~QStyle::State_Children;
674
while ( currentParent.isValid() ) {
675
// then draw ancestors
676
if ( ! ancestor.isValid() && ! drawRoot ) {
679
area.moveLeft(area.left() - indent);
681
if ( currentParent.sibling( currentParent.row() + 1, 0 ).isValid() ) {
682
option.state |= QStyle::State_Sibling;
684
option.state &= ~QStyle::State_Sibling;
686
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter);
687
currentParent = ancestor;
688
ancestor = currentParent.parent();
692
int GraphicsScene::level( const QModelIndex &idx ) const
695
for ( QModelIndex p = idx.parent(); p.isValid(); p = p.parent() ) {
701
void GraphicsScene::print( QPainter* painter, const QRectF& target, const QRectF& source, bool drawRowLabels, GraphicsView *view )
703
QRectF targetRect(target);
705
assert(rowController());
707
int indentation = 20;
708
bool indentRoot = true;
711
if ( source.width() > target.width() ) {
712
scale = target.width() / source.width();
714
if ( source.height() > target.height() ) {
715
scale = qMin( scale, target.height() / source.height() );
717
painter->scale( scale, scale );
718
targetRect.setWidth( targetRect.width() / scale );
719
targetRect.setHeight( targetRect.height() / scale );
721
qreal textWidth = 0.;
725
qreal top = view ? view->headerHeight() : 0.0;
726
{Q_FOREACH( GraphicsItem* item, d->items ) {
727
QModelIndex sidx = summaryHandlingModel()->mapToSource( item->index() );
728
if ( sidx.parent().isValid() && sidx.parent().data( ItemTypeRole ).toInt() == TypeMulti ) {
731
const Span rg = rowController()->rowGeometry( sidx );
732
const QString txt = item->index().data( Qt::DisplayRole ).toString();
733
int indent = indentation * (level( item->index() ) + ( indentRoot ? 1 : 0 ) );
734
QRectF r( indent, rg.start() + top, 0.0, rg.length() );
735
r = painter->boundingRect( r, Qt::AlignLeft | Qt::AlignVCenter, txt );
736
painter->drawText( r, Qt::AlignLeft | Qt::AlignVCenter, txt );
737
if ( r.width() > textWidth ) {
738
textWidth = r.width() + indent;
740
QRect rect = r.toRect();
742
rect.setRight( r.left() );
743
drawTreeIndication( painter, item->index(), rect, indentation, indentRoot );
747
QStyle* style = QApplication::style();
748
QRectF r( 0.0, 0.0, textWidth, view->headerHeight() );
749
QStyleOptionHeader opt;
751
opt.rect = r.toRect();
752
opt.text = summaryHandlingModel()->headerData( 0, Qt::Horizontal, Qt::DisplayRole ).toString();
753
opt.textAlignment = Qt::AlignCenter;
754
// NOTE:CE_Header does not honor clipRegion(), so we do the CE_Header logic here
755
style->drawControl( QStyle::CE_HeaderSection, &opt, painter, view );
756
QStyleOptionHeader subopt = opt;
757
subopt.rect = style->subElementRect( QStyle::SE_HeaderLabel, &opt, view );
758
if ( subopt.rect.isValid() ) {
759
style->drawControl( QStyle::CE_HeaderLabel, &subopt, painter, view );
762
if ( textWidth > 0 ) {
763
textWidth += KDGANTT_LIST_CHART_GAP;
766
QRectF oldSceneRect( sceneRect() );
767
setSceneRect( itemsBoundingRect() );
768
QRectF sourceRect = source.adjusted( textWidth, (qreal)0.0, (qreal)0.0, (qreal)0.0 );
769
targetRect.adjust( textWidth, (qreal)0.0, (qreal)0.0, (qreal)0.0 );
770
//qDebug()<<"GraphicsScene::print() 1"<<"scene"<<sceneRect()<<"target"<<targetRect<<"source"<<source<<"sourceRect"<<sourceRect<<"text"<<textWidth<<"scale"<<scale;
772
qreal width = sourceRect.width();
773
qreal height = sourceRect.height();
775
if ( width > targetRect.width() ) {
776
scale = targetRect.width() / width;
778
if ( height > targetRect.height() ) {
779
scale = qMin( scale, targetRect.height() / height );
781
QRectF t = targetRect;
782
QRectF s = sourceRect;
783
s.setHeight( view->headerHeight() );
784
t.setWidth( s.width() * scale );
785
t.setHeight( s.height() * scale );
786
view->renderHeader( painter, t, s, Qt::KeepAspectRatio );
787
targetRect.translate( (qreal)0.0, t.height() );
788
targetRect.setHeight( targetRect.height() - t.height() );
790
//qDebug()<<"GraphicsScene::print() 3"<<sceneRect()<<targetRect<<sourceRect;
792
if ( targetRect.width() > sourceRect.width() && targetRect.height() > sourceRect.height() ) {
794
sourceRect.setSize( targetRect.size() );
795
render( painter, targetRect, sourceRect, Qt::IgnoreAspectRatio );
797
render( painter, targetRect, sourceRect );
800
setSceneRect( oldSceneRect );
804
#include "moc_kdganttgraphicsscene.cpp"