00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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 }