kdganttlegend.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2010 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 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 }