00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "kdganttlegend.h"
00026 #include "kdganttlegend_p.h"
00027
00028 #include "kdganttitemdelegate.h"
00029
00030 #include <QApplication>
00031 #include <QPainter>
00032
00033 #include <cassert>
00034
00035 using namespace KDGantt;
00036
00047 Legend::Legend( QWidget* parent )
00048 : QAbstractItemView( parent ),
00049 _d( new Private )
00050 {
00051 setItemDelegate( new ItemDelegate( this ) );
00052 setFrameStyle( QFrame::NoFrame );
00053 }
00054
00056 Legend::~Legend()
00057 {
00058 delete _d;
00059 }
00060
00061 #define d d_func()
00062
00063 QModelIndex Legend::indexAt( const QPoint& point ) const
00064 {
00065 Q_UNUSED( point );
00066 return QModelIndex();
00067 }
00068
00069 QRect Legend::visualRect( const QModelIndex& index ) const
00070 {
00071 Q_UNUSED( index );
00072 return QRect();
00073 }
00074
00075 QSize Legend::sizeHint() const
00076 {
00077 return measureItem( rootIndex() );
00078 }
00079
00080 QSize Legend::minimumSizeHint() const
00081 {
00082 return measureItem( rootIndex() );
00083 }
00084
00085 void Legend::setModel( QAbstractItemModel* model )
00086 {
00087 if( this->model() != 0 )
00088 {
00089 disconnect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
00090 disconnect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00091 disconnect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00092 }
00093
00094 QAbstractItemView::setModel( model );
00095 d->proxyModel.setSourceModel( model );
00096
00097 if( this->model() != 0 )
00098 {
00099 connect( this->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) );
00100 connect( this->model(), SIGNAL( rowsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00101 connect( this->model(), SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( modelDataChanged() ) );
00102 }
00103
00104 }
00105
00108 void Legend::modelDataChanged()
00109 {
00110 updateGeometry();
00111 viewport()->update();
00112 }
00113
00114 void Legend::paintEvent( QPaintEvent* event )
00115 {
00116 Q_UNUSED( event );
00117
00118 if( model() == 0 )
00119 return;
00120
00121 QPainter p( viewport() );
00122 p.fillRect( viewport()->rect(), palette().color( QPalette::Window ) );
00123 drawItem( &p, rootIndex() );
00124 }
00125
00129 StyleOptionGanttItem Legend::getStyleOption( const QModelIndex& index ) const
00130 {
00131 StyleOptionGanttItem opt;
00132 opt.displayPosition = StyleOptionGanttItem::Right;
00133 opt.displayAlignment = Qt::Alignment( d->proxyModel.data( index, Qt::TextAlignmentRole ).toInt() );
00134 opt.text = index.model()->data( index, LegendRole ).toString();
00135 opt.font = qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) );
00136 return opt;
00137 }
00138
00144 QRect Legend::drawItem( QPainter* painter, const QModelIndex& index, const QPoint& pos ) const
00145 {
00146 int xPos = pos.x();
00147 int yPos = pos.y();
00148
00149 if( index.isValid() && index.model() == &d->proxyModel )
00150 {
00151 ItemDelegate* const delegate = qobject_cast< ItemDelegate* >( itemDelegate( index ) );
00152 assert( delegate != 0 );
00153 const QRect r( pos, measureItem( index, false ) );
00154 StyleOptionGanttItem opt = getStyleOption( index );
00155 opt.rect = r;
00156 opt.rect.setWidth( r.height() );
00157
00158 const ItemType typ = static_cast<ItemType>( index.model()->data( index, ItemTypeRole ).toInt() );
00159 const int dx = (typ == TypeEvent) ? (r.height() / 2) : 0;
00160
00161 opt.itemRect = opt.rect.adjusted(dx,0,dx,0);
00162 opt.boundingRect = r;
00163 opt.boundingRect.setWidth( r.width() + r.height() );
00164 if( !opt.text.isNull() )
00165 delegate->paintGanttItem( painter, opt, index );
00166
00167 xPos = r.right();
00168 yPos = r.bottom();
00169 }
00170
00171
00172 const int rowCount = d->proxyModel.rowCount( index );
00173 for( int row = 0; row < rowCount; ++row )
00174 {
00175 const QRect r = drawItem( painter, d->proxyModel.index( row, 0, index ), QPoint( pos.x(), yPos ) );
00176 xPos = qMax( xPos, r.right() );
00177 yPos = qMax( yPos, r.bottom() );
00178 }
00179
00180 return QRect( pos, QPoint( xPos, yPos ) );
00181 }
00182
00186 QSize Legend::measureItem( const QModelIndex& index, bool recursive ) const
00187 {
00188 if( model() == 0 )
00189 return QSize();
00190
00191 QSize baseSize;
00192 if( index.model() != 0 )
00193 {
00194 QFontMetrics fm( qVariantValue< QFont >( index.model()->data( index, Qt::FontRole ) ) );
00195 const QString text = index.model()->data( index, LegendRole ).toString();
00196 if( !text.isEmpty() )
00197 baseSize += QSize( fm.width( text ) + fm.height() + 2, fm.height() + 2 );
00198 }
00199
00200 if( !recursive )
00201 return baseSize;
00202
00203 QSize childrenSize;
00204
00205 const int rowCount = d->proxyModel.rowCount( index );
00206 for( int row = 0; row < rowCount; ++row )
00207 {
00208 const QSize childSize = measureItem( d->proxyModel.index( row, 0, index ) );
00209 childrenSize.setWidth( qMax( childrenSize.width(), childSize.width() ) );
00210 childrenSize.rheight() += childSize.height();
00211 }
00212 return baseSize + childrenSize;
00213 }