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 return QModelIndex();
00064 }
00065
00066 QRect Legend::visualRect( const QModelIndex& index ) const
00067 {
00068 return QRect();
00069 }
00070
00071 QSize Legend::sizeHint() const
00072 {
00073 return measureItem( rootIndex() );
00074 }
00075
00076 QSize Legend::minimumSizeHint() const
00077 {
00078 return measureItem( rootIndex() );
00079 }
00080
00081 void Legend::setModel( QAbstractItemModel* model )
00082 {
00083 if( this->model() != 0 )
00084 {
00085 disconnect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
00086 disconnect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00087 disconnect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00088 }
00089
00090 QAbstractItemView::setModel( model );
00091 d->proxyModel.setSourceModel( model );
00092
00093 if( this->model() != 0 )
00094 {
00095 connect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
00096 connect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00097 connect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00098 }
00099
00100 }
00101
00104 void Legend::modelDataChanged()
00105 {
00106 updateGeometry();
00107 viewport()->update();
00108 }
00109
00110 void Legend::paintEvent( QPaintEvent* event )
00111 {
00112 Q_UNUSED( event );
00113
00114 if( model() == 0 )
00115 return;
00116
00117 QPainter p( viewport() );
00118 p.fillRect( viewport()->rect(), palette().color( QPalette::Window ) );
00119 drawItem( &p, rootIndex() );
00120 }
00121
00125 StyleOptionGanttItem Legend::getStyleOption( const QModelIndex& index ) const
00126 {
00127 StyleOptionGanttItem opt;
00128 opt.displayPosition = StyleOptionGanttItem::Right;
00129 opt.displayAlignment = Qt::Alignment( d->proxyModel.data( index, Qt::TextAlignmentRole ).toInt() );
00130 opt.text = index.model()->data( index, LegendRole ).toString();
00131 opt.font = qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) );
00132 return opt;
00133 }
00134
00140 QRect Legend::drawItem( QPainter* painter, const QModelIndex& index, const QPoint& pos ) const
00141 {
00142 int xPos = pos.x();
00143 int yPos = pos.y();
00144
00145 if( index.isValid() && index.model() == &d->proxyModel )
00146 {
00147 ItemDelegate* const delegate = qobject_cast< ItemDelegate* >( itemDelegate( index ) );
00148 assert( delegate != 0 );
00149 const QRect r( pos, measureItem( index, false ) );
00150 StyleOptionGanttItem opt = getStyleOption( index );
00151 opt.rect = r;
00152 opt.rect.setWidth( r.height() );
00153 opt.itemRect = opt.rect;
00154 opt.boundingRect = r;
00155 opt.boundingRect.setWidth( r.width() + r.height() );
00156 if( !opt.text.isNull() )
00157 delegate->paintGanttItem( painter, opt, index );
00158
00159 xPos = r.right();
00160 yPos = r.bottom();
00161 }
00162
00163
00164 const int rowCount = d->proxyModel.rowCount( index );
00165 for( int row = 0; row < rowCount; ++row )
00166 {
00167 const QRect r = drawItem( painter, d->proxyModel.index( row, 0, index ), QPoint( pos.x(), yPos ) );
00168 xPos = qMax( xPos, r.right() );
00169 yPos = qMax( yPos, r.bottom() );
00170 }
00171
00172 return QRect( pos, QPoint( xPos, yPos ) );
00173 }
00174
00178 QSize Legend::measureItem( const QModelIndex& index, bool recursive ) const
00179 {
00180 if( model() == 0 )
00181 return QSize();
00182
00183 QSize baseSize;
00184 if( index.model() != 0 )
00185 {
00186 QFontMetrics fm( qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) ) );
00187 const QString text = index.model()->data( index, LegendRole ).toString();
00188 if( !text.isNull() )
00189 baseSize += QSize( fm.width( text ) + fm.height() + 2, fm.height() + 2 );
00190 }
00191
00192 if( !recursive )
00193 return baseSize;
00194
00195 QSize childrenSize;
00196
00197 const int rowCount = d->proxyModel.rowCount( index );
00198 for( int row = 0; row < rowCount; ++row )
00199 {
00200 const QSize childSize = measureItem( d->proxyModel.index( row, 0, index ) );
00201 childrenSize.setWidth( qMax( childrenSize.width(), childSize.width() ) );
00202 childrenSize.rheight() += childSize.height();
00203 }
00204 return baseSize + childrenSize;
00205 }