KD Chart 2 [rev.2.4]
|
00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 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 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "kdganttlegend.h" 00024 #include "kdganttlegend_p.h" 00025 00026 #include "kdganttitemdelegate.h" 00027 00028 #include <QApplication> 00029 #include <QPainter> 00030 00031 #include <cassert> 00032 00033 using namespace KDGantt; 00034 00045 Legend::Legend( QWidget* parent ) 00046 : QAbstractItemView( parent ), 00047 _d( new Private ) 00048 { 00049 setItemDelegate( new ItemDelegate( this ) ); 00050 setFrameStyle( QFrame::NoFrame ); 00051 } 00052 00054 Legend::~Legend() 00055 { 00056 delete _d; 00057 } 00058 00059 #define d d_func() 00060 00061 QModelIndex Legend::indexAt( const QPoint& point ) const 00062 { 00063 Q_UNUSED( point ); 00064 return QModelIndex(); 00065 } 00066 00067 QRect Legend::visualRect( const QModelIndex& index ) const 00068 { 00069 Q_UNUSED( index ); 00070 return QRect(); 00071 } 00072 00073 QSize Legend::sizeHint() const 00074 { 00075 return measureItem( rootIndex() ); 00076 } 00077 00078 QSize Legend::minimumSizeHint() const 00079 { 00080 return measureItem( rootIndex() ); 00081 } 00082 00083 void Legend::setModel( QAbstractItemModel* model ) 00084 { 00085 if( this->model() != 0 ) 00086 { 00087 disconnect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) ); 00088 disconnect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) ); 00089 disconnect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) ); 00090 } 00091 00092 QAbstractItemView::setModel( model ); 00093 d->proxyModel.setSourceModel( model ); 00094 00095 if( this->model() != 0 ) 00096 { 00097 connect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) ); 00098 connect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) ); 00099 connect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) ); 00100 } 00101 00102 } 00103 00106 void Legend::modelDataChanged() 00107 { 00108 updateGeometry(); 00109 viewport()->update(); 00110 } 00111 00112 void Legend::paintEvent( QPaintEvent* event ) 00113 { 00114 Q_UNUSED( event ); 00115 // no model, no legend... 00116 if( model() == 0 ) 00117 return; 00118 00119 QPainter p( viewport() ); 00120 p.fillRect( viewport()->rect(), palette().color( QPalette::Window ) ); 00121 drawItem( &p, rootIndex() ); 00122 } 00123 00127 StyleOptionGanttItem Legend::getStyleOption( const QModelIndex& index ) const 00128 { 00129 StyleOptionGanttItem opt; 00130 opt.displayPosition = StyleOptionGanttItem::Right; 00131 opt.displayAlignment = Qt::Alignment( d->proxyModel.data( index, Qt::TextAlignmentRole ).toInt() ); 00132 opt.text = index.model()->data( index, LegendRole ).toString(); 00133 opt.font = qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) ); 00134 return opt; 00135 } 00136 00142 QRect Legend::drawItem( QPainter* painter, const QModelIndex& index, const QPoint& pos ) const 00143 { 00144 int xPos = pos.x(); 00145 int yPos = pos.y(); 00146 00147 if( index.isValid() && index.model() == &d->proxyModel ) 00148 { 00149 ItemDelegate* const delegate = qobject_cast< ItemDelegate* >( itemDelegate( index ) ); 00150 assert( delegate != 0 ); 00151 const QRect r( pos, measureItem( index, false ) ); 00152 StyleOptionGanttItem opt = getStyleOption( index ); 00153 opt.rect = r; 00154 opt.rect.setWidth( r.height() ); 00155 00156 const ItemType typ = static_cast<ItemType>( index.model()->data( index, ItemTypeRole ).toInt() ); 00157 const int dx = (typ == TypeEvent) ? (r.height() / 2) : 0; 00158 00159 opt.itemRect = opt.rect.adjusted(dx,0,dx,0); 00160 opt.boundingRect = r; 00161 opt.boundingRect.setWidth( r.width() + r.height() ); 00162 if( !opt.text.isNull() ) 00163 delegate->paintGanttItem( painter, opt, index ); 00164 00165 xPos = r.right(); 00166 yPos = r.bottom(); 00167 } 00168 00169 00170 const int rowCount = d->proxyModel.rowCount( index ); 00171 for( int row = 0; row < rowCount; ++row ) 00172 { 00173 const QRect r = drawItem( painter, d->proxyModel.index( row, 0, index ), QPoint( pos.x(), yPos ) ); 00174 xPos = qMax( xPos, r.right() ); 00175 yPos = qMax( yPos, r.bottom() ); 00176 } 00177 00178 return QRect( pos, QPoint( xPos, yPos ) ); 00179 } 00180 00184 QSize Legend::measureItem( const QModelIndex& index, bool recursive ) const 00185 { 00186 if( model() == 0 ) 00187 return QSize(); 00188 00189 QSize baseSize; 00190 if( index.model() != 0 ) 00191 { 00192 QFontMetrics fm( qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) ) ); 00193 const QString text = index.model()->data( index, LegendRole ).toString(); 00194 if( !text.isEmpty() ) 00195 baseSize += QSize( fm.width( text ) + fm.height() + 2, fm.height() + 2 ); 00196 } 00197 00198 if( !recursive ) 00199 return baseSize; 00200 00201 QSize childrenSize; 00202 00203 const int rowCount = d->proxyModel.rowCount( index ); 00204 for( int row = 0; row < rowCount; ++row ) 00205 { 00206 const QSize childSize = measureItem( d->proxyModel.index( row, 0, index ) ); 00207 childrenSize.setWidth( qMax( childrenSize.width(), childSize.width() ) ); 00208 childrenSize.rheight() += childSize.height(); 00209 } 00210 return baseSize + childrenSize; 00211 }